public function processRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $preferences = $user->loadPreferences();
     $pref_dark_console = PhabricatorUserPreferences::PREFERENCE_DARK_CONSOLE;
     $dark_console_value = $preferences->getPreference($pref_dark_console);
     if ($request->isFormPost()) {
         $new_dark_console = $request->getBool($pref_dark_console);
         $preferences->setPreference($pref_dark_console, $new_dark_console);
         // If the user turned Dark Console on, enable it (as though they had hit
         // "`").
         if ($new_dark_console && !$dark_console_value) {
             $user->setConsoleVisible(true);
             $user->save();
         }
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $is_console_enabled = PhabricatorEnv::getEnvConfig('darkconsole.enabled');
     $preamble = pht("**DarkConsole** is a developer console which can help build and " . "debug Phabricator applications. It includes tools for understanding " . "errors, performance, service calls, and other low-level aspects of " . "Phabricator's inner workings.");
     if ($is_console_enabled) {
         $instructions = pht("%s\n\n" . 'You can enable it for your account below. Enabling DarkConsole will ' . 'slightly decrease performance, but give you access to debugging ' . 'tools. You may want to disable it again later if you only need it ' . 'temporarily.' . "\n\n" . 'NOTE: After enabling DarkConsole, **press the ##%s## key on your ' . 'keyboard** to show or hide it.', $preamble, '`');
     } else {
         $instructions = pht("%s\n\n" . 'Before you can turn on DarkConsole, it needs to be enabled in ' . 'the configuration for this install (`%s`).', $preamble, 'darkconsole.enabled');
     }
     $form = id(new AphrontFormView())->setUser($user)->appendRemarkupInstructions($instructions)->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Dark Console'))->setName($pref_dark_console)->setValue($dark_console_value)->setOptions(array(0 => pht('Disable DarkConsole'), 1 => pht('Enable DarkConsole')))->setDisabled(!$is_console_enabled))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Developer Settings'))->setFormSaved($request->getBool('saved'))->setForm($form);
     return array($form_box);
 }
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $viewer = $request->getUser();
     $drequest = $this->diffusionRequest;
     $repository = $drequest->getRepository();
     $repository = id(new PhabricatorRepositoryQuery())->setViewer($viewer)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withIDs(array($repository->getID()))->executeOne();
     if (!$repository) {
         return new Aphront404Response();
     }
     $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/');
     // NOTE: We're inverting these here, because the storage is silly.
     $v_notify = !$repository->getHumanReadableDetail('herald-disabled');
     $v_autoclose = !$repository->getHumanReadableDetail('disable-autoclose');
     if ($request->isFormPost()) {
         $v_notify = $request->getBool('notify');
         $v_autoclose = $request->getBool('autoclose');
         $xactions = array();
         $template = id(new PhabricatorRepositoryTransaction());
         $type_notify = PhabricatorRepositoryTransaction::TYPE_NOTIFY;
         $type_autoclose = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE;
         $xactions[] = id(clone $template)->setTransactionType($type_notify)->setNewValue($v_notify);
         $xactions[] = id(clone $template)->setTransactionType($type_autoclose)->setNewValue($v_autoclose);
         id(new PhabricatorRepositoryEditor())->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->setActor($viewer)->applyTransactions($repository, $xactions);
         return id(new AphrontRedirectResponse())->setURI($edit_uri);
     }
     $content = array();
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Edit Actions'));
     $title = pht('Edit Actions (%s)', $repository->getName());
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($repository)->execute();
     $form = id(new AphrontFormView())->setUser($viewer)->appendRemarkupInstructions(pht("Normally, Phabricator publishes notifications when it discovers " . "new commits. You can disable publishing for this repository by " . "turning off **Notify/Publish**. This will disable notifications, " . "feed, and Herald (including audits and build plans) for this " . "repository.\n\n" . "When Phabricator discovers a new commit, it can automatically " . "close associated revisions and tasks. If you don't want " . "Phabricator to close objects when it discovers new commits in " . "this repository, you can disable **Autoclose**."))->appendChild(id(new AphrontFormSelectControl())->setName('notify')->setLabel(pht('Notify/Publish'))->setValue((int) $v_notify)->setOptions(array(1 => pht('Enable Notifications, Feed and Herald'), 0 => pht('Disable Notifications, Feed and Herald'))))->appendChild(id(new AphrontFormSelectControl())->setName('autoclose')->setLabel(pht('Autoclose'))->setValue((int) $v_autoclose)->setOptions(array(1 => pht('Enable Autoclose'), 0 => pht('Disable Autoclose'))))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Actions'))->addCancelButton($edit_uri));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($title)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $title));
 }
 /**
  * @phutil-external-symbol class PhabricatorStartup
  */
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     // NOTE: Throws if valid CSRF token is not present in the request.
     $request->validateCSRF();
     $name = $request->getStr('name');
     $file_phid = $request->getStr('phid');
     // If there's no explicit view policy, make it very restrictive by default.
     // This is the correct policy for files dropped onto objects during
     // creation, comment and edit flows.
     $view_policy = $request->getStr('viewPolicy');
     if (!$view_policy) {
         $view_policy = $viewer->getPHID();
     }
     $is_chunks = $request->getBool('querychunks');
     if ($is_chunks) {
         $params = array('filePHID' => $file_phid);
         $result = id(new ConduitCall('file.querychunks', $params))->setUser($viewer)->execute();
         return id(new AphrontAjaxResponse())->setContent($result);
     }
     $is_allocate = $request->getBool('allocate');
     if ($is_allocate) {
         $params = array('name' => $name, 'contentLength' => $request->getInt('length'), 'viewPolicy' => $view_policy);
         $result = id(new ConduitCall('file.allocate', $params))->setUser($viewer)->execute();
         $file_phid = $result['filePHID'];
         if ($file_phid) {
             $file = $this->loadFile($file_phid);
             $result += $file->getDragAndDropDictionary();
         }
         return id(new AphrontAjaxResponse())->setContent($result);
     }
     // Read the raw request data. We're either doing a chunk upload or a
     // vanilla upload, so we need it.
     $data = PhabricatorStartup::getRawInput();
     $is_chunk_upload = $request->getBool('uploadchunk');
     if ($is_chunk_upload) {
         $params = array('filePHID' => $file_phid, 'byteStart' => $request->getInt('byteStart'), 'data' => $data);
         $result = id(new ConduitCall('file.uploadchunk', $params))->setUser($viewer)->execute();
         $file = $this->loadFile($file_phid);
         if ($file->getIsPartial()) {
             $result = array();
         } else {
             $result = array('complete' => true) + $file->getDragAndDropDictionary();
         }
         return id(new AphrontAjaxResponse())->setContent($result);
     }
     $file = PhabricatorFile::newFromXHRUpload($data, array('name' => $request->getStr('name'), 'authorPHID' => $viewer->getPHID(), 'viewPolicy' => $view_policy, 'isExplicitUpload' => true));
     $result = $file->getDragAndDropDictionary();
     return id(new AphrontAjaxResponse())->setContent($result);
 }
 public function processRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $preferences = $user->loadPreferences();
     $pref_jump = PhabricatorUserPreferences::PREFERENCE_SEARCHBAR_JUMP;
     $pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT;
     if ($request->isFormPost()) {
         $preferences->setPreference($pref_jump, $request->getBool($pref_jump));
         $preferences->setPreference($pref_shortcut, $request->getBool($pref_shortcut));
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormCheckboxControl())->addCheckbox($pref_jump, 1, pht('Enable jump nav functionality in all search boxes.'), $preferences->getPreference($pref_jump, 1))->addCheckbox($pref_shortcut, 1, pht("Press '/' to focus the search input."), $preferences->getPreference($pref_shortcut, 1)))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Search Preferences'))->setFormSaved($request->getStr('saved') === 'true')->setForm($form);
     return array($form_box);
 }
 protected function getValueFromRequest(AphrontRequest $request, $key)
 {
     if (!strlen($request->getStr($key))) {
         return null;
     }
     return $request->getBool($key);
 }
 public function processRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $preferences = $this->getPreferences();
     $notifications_key = PhabricatorDesktopNotificationsSetting::SETTINGKEY;
     $notifications_value = $preferences->getSettingValue($notifications_key);
     if ($request->isFormPost()) {
         $this->writeSetting($preferences, $notifications_key, $request->getInt($notifications_key));
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $title = pht('Desktop Notifications');
     $control_id = celerity_generate_unique_node_id();
     $status_id = celerity_generate_unique_node_id();
     $browser_status_id = celerity_generate_unique_node_id();
     $cancel_ask = pht('The dialog asking for permission to send desktop notifications was ' . 'closed without granting permission. Only application notifications ' . 'will be sent.');
     $accept_ask = pht('Click "Save Preference" to persist these changes.');
     $reject_ask = pht('Permission for desktop notifications was denied. Only application ' . 'notifications will be sent.');
     $no_support = pht('This web browser does not support desktop notifications. Only ' . 'application notifications will be sent for this browser regardless of ' . 'this preference.');
     $default_status = phutil_tag('span', array(), array(pht('This browser has not yet granted permission to send desktop ' . 'notifications for this Phabricator instance.'), phutil_tag('br'), phutil_tag('br'), javelin_tag('button', array('sigil' => 'desktop-notifications-permission-button', 'class' => 'green'), pht('Grant Permission'))));
     $granted_status = phutil_tag('span', array(), pht('This browser has been granted permission to send desktop ' . 'notifications for this Phabricator instance.'));
     $denied_status = phutil_tag('span', array(), pht('This browser has denied permission to send desktop notifications ' . 'for this Phabricator instance. Consult your browser settings / ' . 'documentation to figure out how to clear this setting, do so, ' . 'and then re-visit this page to grant permission.'));
     $status_box = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_NOTICE)->setID($status_id)->setIsHidden(true)->appendChild($accept_ask);
     $control_config = array('controlID' => $control_id, 'statusID' => $status_id, 'browserStatusID' => $browser_status_id, 'defaultMode' => 0, 'desktopMode' => 1, 'cancelAsk' => $cancel_ask, 'grantedAsk' => $accept_ask, 'deniedAsk' => $reject_ask, 'defaultStatus' => $default_status, 'deniedStatus' => $denied_status, 'grantedStatus' => $granted_status, 'noSupport' => $no_support);
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormSelectControl())->setLabel($title)->setControlID($control_id)->setName($notifications_key)->setValue($notifications_value)->setOptions(array(1 => pht('Send Desktop Notifications Too'), 0 => pht('Send Application Notifications Only')))->setCaption(pht('Should Phabricator send desktop notifications? These are sent ' . 'in addition to the notifications within the Phabricator ' . 'application.'))->initBehavior('desktop-notifications-control', $control_config))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preference')));
     $test_button = id(new PHUIButtonView())->setTag('a')->setWorkflow(true)->setText(pht('Send Test Notification'))->setHref('/notification/test/')->setIcon('fa-exclamation-triangle');
     $form_box = id(new PHUIObjectBoxView())->setHeader(id(new PHUIHeaderView())->setHeader(pht('Desktop Notifications'))->addActionLink($test_button))->setForm($form)->setInfoView($status_box)->setFormSaved($request->getBool('saved'));
     $browser_status_box = id(new PHUIInfoView())->setID($browser_status_id)->setSeverity(PHUIInfoView::SEVERITY_NOTICE)->setIsHidden(true)->appendChild($default_status);
     return array($form_box, $browser_status_box);
 }
 public function readRequest(PhabricatorConfigOption $option, AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $view_policy = PhabricatorPolicies::POLICY_PUBLIC;
     if ($request->getBool('removeLogo')) {
         $logo_image_phid = null;
     } else {
         if ($request->getFileExists('logoImage')) {
             $logo_image = PhabricatorFile::newFromPHPUpload(idx($_FILES, 'logoImage'), array('name' => 'logo', 'authorPHID' => $viewer->getPHID(), 'viewPolicy' => $view_policy, 'canCDN' => true, 'isExplicitUpload' => true));
             $logo_image_phid = $logo_image->getPHID();
         } else {
             $logo_image_phid = self::getLogoImagePHID();
         }
     }
     $wordmark_text = $request->getStr('wordmarkText');
     $value = array('logoImagePHID' => $logo_image_phid, 'wordmarkText' => $wordmark_text);
     $errors = array();
     $e_value = null;
     try {
         $this->validateOption($option, $value);
     } catch (Exception $ex) {
         $e_value = pht('Invalid');
         $errors[] = $ex->getMessage();
         $value = array();
     }
     return array($e_value, $errors, $value, phutil_json_encode($value));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $phid = $request->getURIData('phid');
     $file = id(new PhabricatorFileQuery())->setViewer($request->getUser())->withPHIDs(array($phid))->executeOne();
     if (!$file) {
         return new Aphront404Response();
     }
     $data = $file->loadFileData();
     try {
         $data = phutil_json_decode($data);
     } catch (PhutilJSONParserException $ex) {
         throw new PhutilProxyException(pht('Failed to unserialize XHProf profile!'), $ex);
     }
     $symbol = $request->getStr('symbol');
     $is_framed = $request->getBool('frame');
     if ($symbol) {
         $view = new PhabricatorXHProfProfileSymbolView();
         $view->setSymbol($symbol);
     } else {
         $view = new PhabricatorXHProfProfileTopLevelView();
         $view->setFile($file);
         $view->setLimit(100);
     }
     $view->setBaseURI($request->getRequestURI()->getPath());
     $view->setIsFramed($is_framed);
     $view->setProfileData($data);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('%s Profile', $symbol));
     return $this->buildStandardPageResponse(array($crumbs, $view), array('title' => pht('Profile'), 'frame' => $is_framed));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $this->requireApplicationCapability(PhabricatorMacroManageCapability::CAPABILITY);
     $macro = id(new PhabricatorMacroQuery())->setViewer($viewer)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW))->withIDs(array($id))->executeOne();
     if (!$macro) {
         return new Aphront404Response();
     }
     $errors = array();
     $view_uri = $this->getApplicationURI('/view/' . $macro->getID() . '/');
     $e_file = null;
     $file = null;
     if ($request->isFormPost()) {
         $xactions = array();
         if ($request->getBool('behaviorForm')) {
             $xactions[] = id(new PhabricatorMacroTransaction())->setTransactionType(PhabricatorMacroTransaction::TYPE_AUDIO_BEHAVIOR)->setNewValue($request->getStr('audioBehavior'));
         } else {
             $file = null;
             if ($request->getFileExists('file')) {
                 $file = PhabricatorFile::newFromPHPUpload($_FILES['file'], array('name' => $request->getStr('name'), 'authorPHID' => $viewer->getPHID(), 'isExplicitUpload' => true));
             }
             if ($file) {
                 if (!$file->isAudio()) {
                     $errors[] = pht('You must upload audio.');
                     $e_file = pht('Invalid');
                 } else {
                     $xactions[] = id(new PhabricatorMacroTransaction())->setTransactionType(PhabricatorMacroTransaction::TYPE_AUDIO)->setNewValue($file->getPHID());
                 }
             } else {
                 $errors[] = pht('You must upload an audio file.');
                 $e_file = pht('Required');
             }
         }
         if (!$errors) {
             id(new PhabricatorMacroEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->applyTransactions($macro, $xactions);
             return id(new AphrontRedirectResponse())->setURI($view_uri);
         }
     }
     $form = id(new AphrontFormView())->addHiddenInput('behaviorForm', 1)->setUser($viewer);
     $options = id(new AphrontFormRadioButtonControl())->setLabel(pht('Audio Behavior'))->setName('audioBehavior')->setValue(nonempty($macro->getAudioBehavior(), PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE));
     $options->addButton(PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE, pht('Do Not Play'), pht('Do not play audio.'));
     $options->addButton(PhabricatorFileImageMacro::AUDIO_BEHAVIOR_ONCE, pht('Play Once'), pht('Play audio once, when the viewer looks at the macro.'));
     $options->addButton(PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP, pht('Play Continuously'), pht('Play audio continuously, treating the macro as an audio source. ' . 'Best for ambient sounds.'));
     $form->appendChild($options);
     $form->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Audio Behavior'))->addCancelButton($view_uri));
     $crumbs = $this->buildApplicationCrumbs();
     $title = pht('Edit Audio: %s', $macro->getName());
     $crumb = pht('Edit Audio');
     $crumbs->addTextCrumb(pht('Macro "%s"', $macro->getName()), $view_uri);
     $crumbs->addTextCrumb($crumb, $request->getRequestURI());
     $crumbs->setBorder(true);
     $upload_form = id(new AphrontFormView())->setEncType('multipart/form-data')->setUser($viewer)->appendChild(id(new AphrontFormFileControl())->setLabel(pht('Audio File'))->setName('file'))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Upload File')));
     $upload = id(new PHUIObjectBoxView())->setHeaderText(pht('Upload New Audio'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($upload_form);
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Behavior'))->setFormErrors($errors)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-pencil');
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($form_box, $upload));
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     if ($request->getStr('jump') != 'no') {
         $response = PhabricatorJumpNavHandler::getJumpResponse($viewer, $request->getStr('query'));
         if ($response) {
             return $response;
         }
     }
     $engine = new PhabricatorSearchApplicationSearchEngine();
     $engine->setViewer($viewer);
     // If we're coming from primary search, do some special handling to
     // interpret the scope selector and query.
     if ($request->getBool('search:primary')) {
         // If there's no query, just take the user to advanced search.
         if (!strlen($request->getStr('query'))) {
             $advanced_uri = '/search/query/advanced/';
             return id(new AphrontRedirectResponse())->setURI($advanced_uri);
         }
         // First, load or construct a template for the search by examining
         // the current search scope.
         $scope = $request->getStr('search:scope');
         $saved = null;
         if ($scope == self::SCOPE_CURRENT_APPLICATION) {
             $application = id(new PhabricatorApplicationQuery())->setViewer($viewer)->withClasses(array($request->getStr('search:application')))->executeOne();
             if ($application) {
                 $types = $application->getApplicationSearchDocumentTypes();
                 if ($types) {
                     $saved = id(new PhabricatorSavedQuery())->setEngineClassName(get_class($engine))->setParameter('types', $types)->setParameter('statuses', array('open'));
                 }
             }
         }
         if (!$saved && !$engine->isBuiltinQuery($scope)) {
             $saved = id(new PhabricatorSavedQueryQuery())->setViewer($viewer)->withQueryKeys(array($scope))->executeOne();
         }
         if (!$saved) {
             if (!$engine->isBuiltinQuery($scope)) {
                 $scope = 'all';
             }
             $saved = $engine->buildSavedQueryFromBuiltin($scope);
         }
         // Add the user's query, then save this as a new saved query and send
         // the user to the results page.
         $saved->setParameter('query', $request->getStr('query'));
         $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         try {
             $saved->setID(null)->save();
         } catch (AphrontDuplicateKeyQueryException $ex) {
             // Ignore, this is just a repeated search.
         }
         unset($unguarded);
         $query_key = $saved->getQueryKey();
         $results_uri = $engine->getQueryResultsPageURI($query_key) . '#R';
         return id(new AphrontRedirectResponse())->setURI($results_uri);
     }
     $controller = id(new PhabricatorApplicationSearchController())->setQueryKey($request->getURIData('queryKey'))->setSearchEngine($engine)->setNavigation($this->buildSideNavView());
     return $this->delegateToController($controller);
 }
 public function testRequestDataAccess()
 {
     $r = new AphrontRequest('http://example.com/', '/');
     $r->setRequestData(array('str_empty' => '', 'str' => 'derp', 'str_true' => 'true', 'str_false' => 'false', 'zero' => '0', 'one' => '1', 'arr_empty' => array(), 'arr_num' => array(1, 2, 3), 'comma' => ',', 'comma_1' => 'a, b', 'comma_2' => ' ,a ,, b ,,,, ,, ', 'comma_3' => '0', 'comma_4' => 'a, a, b, a', 'comma_5' => "a\nb, c\n\nd\n\n\n,\n"));
     $this->assertEqual(1, $r->getInt('one'));
     $this->assertEqual(0, $r->getInt('zero'));
     $this->assertEqual(null, $r->getInt('does-not-exist'));
     $this->assertEqual(0, $r->getInt('str_empty'));
     $this->assertEqual(true, $r->getBool('one'));
     $this->assertEqual(false, $r->getBool('zero'));
     $this->assertEqual(true, $r->getBool('str_true'));
     $this->assertEqual(false, $r->getBool('str_false'));
     $this->assertEqual(true, $r->getBool('str'));
     $this->assertEqual(null, $r->getBool('does-not-exist'));
     $this->assertEqual(false, $r->getBool('str_empty'));
     $this->assertEqual('derp', $r->getStr('str'));
     $this->assertEqual('', $r->getStr('str_empty'));
     $this->assertEqual(null, $r->getStr('does-not-exist'));
     $this->assertEqual(array(), $r->getArr('arr_empty'));
     $this->assertEqual(array(1, 2, 3), $r->getArr('arr_num'));
     $this->assertEqual(null, $r->getArr('str_empty', null));
     $this->assertEqual(null, $r->getArr('str_true', null));
     $this->assertEqual(null, $r->getArr('does-not-exist', null));
     $this->assertEqual(array(), $r->getArr('does-not-exist'));
     $this->assertEqual(array(), $r->getStrList('comma'));
     $this->assertEqual(array('a', 'b'), $r->getStrList('comma_1'));
     $this->assertEqual(array('a', 'b'), $r->getStrList('comma_2'));
     $this->assertEqual(array('0'), $r->getStrList('comma_3'));
     $this->assertEqual(array('a', 'a', 'b', 'a'), $r->getStrList('comma_4'));
     $this->assertEqual(array('a', 'b', 'c', 'd'), $r->getStrList('comma_5'));
     $this->assertEqual(array(), $r->getStrList('does-not-exist'));
     $this->assertEqual(null, $r->getStrList('does-not-exist', null));
     $this->assertEqual(true, $r->getExists('str'));
     $this->assertEqual(false, $r->getExists('does-not-exist'));
 }
 public static function getScopesFromRequest(AphrontRequest $request)
 {
     $scopes = self::getScopesDict();
     $requested_scopes = array();
     foreach ($scopes as $scope => $bit) {
         if ($request->getBool($scope)) {
             $requested_scopes[$scope] = 1;
         }
     }
     return $requested_scopes;
 }
 public function processRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $preferences = $user->loadPreferences();
     $pref_jump = PhabricatorUserPreferences::PREFERENCE_SEARCHBAR_JUMP;
     $pref_shortcut = PhabricatorUserPreferences::PREFERENCE_SEARCH_SHORTCUT;
     if ($request->isFormPost()) {
         $preferences->setPreference($pref_jump, $request->getBool($pref_jump));
         $preferences->setPreference($pref_shortcut, $request->getBool($pref_shortcut));
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormCheckboxControl())->addCheckbox($pref_jump, 1, 'Enable jump nav functionality in all search boxes.', $preferences->getPreference($pref_jump, 1))->addCheckbox($pref_shortcut, 1, "Press '/' to focus the search input.", $preferences->getPreference($pref_shortcut, 1)))->appendChild(id(new AphrontFormSubmitControl())->setValue('Save'));
     $panel = new AphrontPanelView();
     $panel->setWidth(AphrontPanelView::WIDTH_FORM);
     $panel->setHeader('Search Preferences');
     $panel->appendChild($form);
     $error_view = null;
     if ($request->getStr('saved') === 'true') {
         $error_view = id(new AphrontErrorView())->setTitle('Preferences Saved')->setSeverity(AphrontErrorView::SEVERITY_NOTICE)->setErrors(array('Your preferences have been saved.'));
     }
     return array($error_view, $panel);
 }
 public function processRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $preferences = $user->loadPreferences();
     $pref = PhabricatorUserPreferences::PREFERENCE_CONPH_NOTIFICATIONS;
     if ($request->isFormPost()) {
         $notifications = $request->getInt($pref);
         $preferences->setPreference($pref, $notifications);
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Conpherence Notifications'))->setName($pref)->setValue($preferences->getPreference($pref))->setOptions(array(ConpherenceSettings::EMAIL_ALWAYS => pht('Email Always'), ConpherenceSettings::NOTIFICATIONS_ONLY => pht('Notifications Only')))->setCaption(pht('Should Conpherence send emails for updates or ' . 'notifications only? This global setting can be overridden ' . 'on a per-thread basis within Conpherence.')))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Conpherence Preferences'))->setForm($form)->setFormSaved($request->getBool('saved'));
     return array($form_box);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $book_name = $request->getStr('book');
     $query_text = $request->getStr('name');
     $book = null;
     if ($book_name) {
         $book = id(new DivinerBookQuery())->setViewer($viewer)->withNames(array($book_name))->executeOne();
         if (!$book) {
             return new Aphront404Response();
         }
     }
     $query = id(new DivinerAtomQuery())->setViewer($viewer);
     if ($book) {
         $query->withBookPHIDs(array($book->getPHID()));
     }
     $context = $request->getStr('context');
     if (strlen($context)) {
         $query->withContexts(array($context));
     }
     $type = $request->getStr('type');
     if (strlen($type)) {
         $query->withTypes(array($type));
     }
     $query->withGhosts(false);
     $query->withIsDocumentable(true);
     $name_query = clone $query;
     $name_query->withNames(array($query_text, phutil_utf8_strtolower($query_text)));
     $atoms = $name_query->execute();
     if (!$atoms) {
         $title_query = clone $query;
         $title_query->withTitles(array($query_text));
         $atoms = $title_query->execute();
     }
     $not_found_uri = $this->getApplicationURI();
     if (!$atoms) {
         $dialog = id(new AphrontDialogView())->setUser($viewer)->setTitle(pht('Documentation Not Found'))->appendChild(pht('Unable to find the specified documentation. ' . 'You may have followed a bad or outdated link.'))->addCancelButton($not_found_uri, pht('Read More Documentation'));
         return id(new AphrontDialogResponse())->setDialog($dialog);
     }
     if (count($atoms) == 1 && $request->getBool('jump')) {
         $atom_uri = head($atoms)->getURI();
         return id(new AphrontRedirectResponse())->setURI($atom_uri);
     }
     $list = $this->renderAtomList($atoms);
     return $this->newPage()->setTitle(array(pht('Find'), pht('"%s"', $query_text)))->appendChild(array($list));
 }
 public function processRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $preferences = $user->loadPreferences();
     $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
     if ($request->isFormPost()) {
         $filetree = $request->getInt($pref_filetree);
         if ($filetree && !$preferences->getPreference($pref_filetree)) {
             $preferences->setPreference(PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED, false);
         }
         $preferences->setPreference($pref_filetree, $filetree);
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Show Filetree'))->setName($pref_filetree)->setValue($preferences->getPreference($pref_filetree))->setOptions(array(0 => pht('Disable Filetree'), 1 => pht('Enable Filetree')))->setCaption(pht('When looking at a revision or commit, enable a sidebar ' . 'showing affected files. You can press %s to show or hide ' . 'the sidebar.', phutil_tag('tt', array(), 'f'))))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Diff Preferences'))->setFormSaved($request->getBool('saved'))->setForm($form);
     return array($form_box);
 }
 public function readValueFromRequest(AphrontRequest $request)
 {
     $day = $request->getInt($this->getDayInputName());
     $month = $request->getInt($this->getMonthInputName());
     $year = $request->getInt($this->getYearInputName());
     $time = $request->getStr($this->getTimeInputName());
     $enabled = $request->getBool($this->getCheckboxInputName());
     if ($this->allowNull && !$enabled) {
         $this->setError(null);
         $this->setValue(null);
         return;
     }
     $err = $this->getError();
     if ($day || $month || $year || $time) {
         $this->valueDay = $day;
         $this->valueMonth = $month;
         $this->valueYear = $year;
         $this->valueTime = $time;
         // Assume invalid.
         $err = 'Invalid';
         $zone = $this->getTimezone();
         try {
             $date = new DateTime("{$year}-{$month}-{$day} {$time}", $zone);
             $value = $date->format('U');
         } catch (Exception $ex) {
             $value = null;
         }
         if ($value) {
             $this->setValue($value);
             $err = null;
         } else {
             $this->setValue(null);
         }
     } else {
         $value = $this->getInitialValue();
         if ($value) {
             $this->setValue($value);
         } else {
             $this->setValue(null);
         }
     }
     $this->setError($err);
     return $this->getValue();
 }
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $drequest = $this->diffusionRequest;
     $viewer = $request->getUser();
     $repository = $drequest->getRepository();
     $page_size = $request->getInt('pagesize', 100);
     $offset = $request->getInt('offset', 0);
     $params = array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath(), 'offset' => $offset, 'limit' => $page_size + 1);
     if (!$request->getBool('copies')) {
         $params['needDirectChanges'] = true;
         $params['needChildChanges'] = true;
     }
     $history_results = $this->callConduitWithDiffusionRequest('diffusion.historyquery', $params);
     $history = DiffusionPathChange::newFromConduit($history_results['pathChanges']);
     $pager = new AphrontPagerView();
     $pager->setPageSize($page_size);
     $pager->setOffset($offset);
     $history = $pager->sliceResults($history);
     $pager->setURI($request->getRequestURI(), 'offset');
     $show_graph = !strlen($drequest->getPath());
     $content = array();
     $history_table = new DiffusionHistoryTableView();
     $history_table->setUser($request->getUser());
     $history_table->setDiffusionRequest($drequest);
     $history_table->setHistory($history);
     $history_table->loadRevisions();
     $phids = $history_table->getRequiredHandlePHIDs();
     $handles = $this->loadViewerHandles($phids);
     $history_table->setHandles($handles);
     if ($show_graph) {
         $history_table->setParents($history_results['parents']);
         $history_table->setIsHead($offset == 0);
     }
     $history_panel = new PHUIObjectBoxView();
     $history_panel->setHeaderText(pht('History'));
     $history_panel->appendChild($history_table);
     $content[] = $history_panel;
     $header = id(new PHUIHeaderView())->setUser($viewer)->setPolicyObject($repository)->setHeader($this->renderPathLinks($drequest, $mode = 'history'));
     $actions = $this->buildActionView($drequest);
     $properties = $this->buildPropertyView($drequest, $actions);
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties);
     $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'history'));
     return $this->buildApplicationPage(array($crumbs, $object_box, $content, $pager), array('title' => array(pht('History'), pht('%s Repository', $drequest->getRepository()->getCallsign()))));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $is_symbolic = $request->getBool('isSymbolic');
     $template = $request->getStr('template');
     if (!$is_symbolic && !$template) {
         $template = ReleephBranchTemplate::getDefaultTemplate();
     }
     $repository_phid = $request->getInt('repositoryPHID');
     $fake_commit_handle = ReleephBranchTemplate::getFakeCommitHandleFor($repository_phid, $request->getUser());
     list($name, $errors) = id(new ReleephBranchTemplate())->setCommitHandle($fake_commit_handle)->setReleephProjectName($request->getStr('projectName'))->setSymbolic($is_symbolic)->interpolate($template);
     $markup = '';
     if ($name) {
         $markup = phutil_tag('div', array('class' => 'name'), $name);
     }
     if ($errors) {
         $markup .= phutil_tag('div', array('class' => 'error'), head($errors));
     }
     return id(new AphrontAjaxResponse())->setContent(array('markup' => $markup));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $dblob = $request->getURIData('dblob');
     $parents = $this->loadParentFragments($dblob);
     if ($parents === null) {
         return new Aphront404Response();
     }
     $fragment = idx($parents, count($parents) - 1, null);
     $error_view = null;
     if ($request->isFormPost()) {
         $errors = array();
         $v_view_policy = $request->getStr('viewPolicy');
         $v_edit_policy = $request->getStr('editPolicy');
         $v_replace_children = $request->getBool('replacePoliciesOnChildren');
         $fragment->setViewPolicy($v_view_policy);
         $fragment->setEditPolicy($v_edit_policy);
         $fragment->save();
         if ($v_replace_children) {
             // If you can edit a fragment, you can forcibly set the policies
             // on child fragments, regardless of whether you can see them or not.
             $children = id(new PhragmentFragmentQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withLeadingPath($fragment->getPath() . '/')->execute();
             $children_phids = mpull($children, 'getPHID');
             $fragment->openTransaction();
             foreach ($children as $child) {
                 $child->setViewPolicy($v_view_policy);
                 $child->setEditPolicy($v_edit_policy);
                 $child->save();
             }
             $fragment->saveTransaction();
         }
         return id(new AphrontRedirectResponse())->setURI('/phragment/browse/' . $fragment->getPath());
     }
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($fragment)->execute();
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($fragment)->setCapability(PhabricatorPolicyCapability::CAN_VIEW)->setPolicies($policies))->appendChild(id(new AphrontFormPolicyControl())->setName('editPolicy')->setPolicyObject($fragment)->setCapability(PhabricatorPolicyCapability::CAN_EDIT)->setPolicies($policies))->appendChild(id(new AphrontFormCheckboxControl())->addCheckbox('replacePoliciesOnChildren', 'true', pht('Replace policies on child fragments with ' . 'the policies above.')))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Fragment Policies'))->addCancelButton($this->getApplicationURI('browse/' . $fragment->getPath())));
     $crumbs = $this->buildApplicationCrumbsWithPath($parents);
     $crumbs->addTextCrumb(pht('Edit Fragment Policies'));
     $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Edit Fragment Policies: %s', $fragment->getPath()))->setValidationException(null)->setForm($form);
     $title = pht('Edit Fragment Policies');
     $view = array($this->renderConfigurationWarningIfRequired(), $box);
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }
 public function readValueFromRequest(AphrontRequest $request)
 {
     $date = $request->getStr($this->getDateInputName());
     $time = $request->getStr($this->getTimeInputName());
     $enabled = $request->getBool($this->getCheckboxInputName());
     if ($this->allowNull && !$enabled) {
         $this->setError(null);
         $this->setValue(null);
         return;
     }
     $err = $this->getError();
     if ($date || $time) {
         $this->valueDate = $date;
         $this->valueTime = $time;
         // Assume invalid.
         $err = pht('Invalid');
         $zone = $this->getTimezone();
         try {
             $datetime = new DateTime("{$date} {$time}", $zone);
             $value = $datetime->format('U');
         } catch (Exception $ex) {
             $value = null;
         }
         if ($value) {
             $this->setValue($value);
             $err = null;
         } else {
             $this->setValue(null);
         }
     } else {
         $value = $this->getInitialValue();
         if ($value) {
             $this->setValue($value);
         } else {
             $this->setValue(null);
         }
     }
     $this->setError($err);
     return $this->getValue();
 }
 public function processRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $preferences = $user->loadPreferences();
     $pref_unified = PhabricatorUserPreferences::PREFERENCE_DIFF_UNIFIED;
     $pref_ghosts = PhabricatorUserPreferences::PREFERENCE_DIFF_GHOSTS;
     $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
     if ($request->isFormPost()) {
         $filetree = $request->getInt($pref_filetree);
         if ($filetree && !$preferences->getPreference($pref_filetree)) {
             $preferences->setPreference(PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED, false);
         }
         $preferences->setPreference($pref_filetree, $filetree);
         $unified = $request->getStr($pref_unified);
         $preferences->setPreference($pref_unified, $unified);
         $ghosts = $request->getStr($pref_ghosts);
         $preferences->setPreference($pref_ghosts, $ghosts);
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $form = id(new AphrontFormView())->setUser($user)->appendRemarkupInstructions(pht('Phabricator normally shows diffs in a side-by-side layout on ' . 'large screens, and automatically switches to a unified ' . 'view on small screens (like mobile phones). If you prefer ' . 'unified diffs even on large screens, you can select them as ' . 'the default layout.'))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Show Unified Diffs'))->setName($pref_unified)->setValue($preferences->getPreference($pref_unified))->setOptions(array('default' => pht('On Small Screens'), 'unified' => pht('Always'))))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Show Older Inlines'))->setName($pref_ghosts)->setValue($preferences->getPreference($pref_ghosts))->setOptions(array('default' => pht('Enabled'), 'disabled' => pht('Disabled'))))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Show Filetree'))->setName($pref_filetree)->setValue($preferences->getPreference($pref_filetree))->setOptions(array(0 => pht('Disable Filetree'), 1 => pht('Enable Filetree')))->setCaption(pht('When looking at a revision or commit, enable a sidebar ' . 'showing affected files. You can press %s to show or hide ' . 'the sidebar.', phutil_tag('tt', array(), 'f'))))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Diff Preferences'))->setFormSaved($request->getBool('saved'))->setForm($form);
     return array($form_box);
 }
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $this->name = $request->getURIData('name');
     $query = id(new DiffusionSymbolQuery())->setViewer($user)->setName($this->name);
     if ($request->getStr('context')) {
         $query->setContext($request->getStr('context'));
     }
     if ($request->getStr('type')) {
         $query->setType($request->getStr('type'));
     }
     if ($request->getStr('lang')) {
         $query->setLanguage($request->getStr('lang'));
     }
     if ($request->getStr('repositories')) {
         $phids = $request->getStr('repositories');
         $phids = explode(',', $phids);
         $phids = array_filter($phids);
         if ($phids) {
             $repos = id(new PhabricatorRepositoryQuery())->setViewer($request->getUser())->withPHIDs($phids)->execute();
             $repos = mpull($repos, 'getPHID');
             if ($repos) {
                 $query->withRepositoryPHIDs($repos);
             }
         }
     }
     $query->needPaths(true);
     $query->needRepositories(true);
     $symbols = $query->execute();
     $external_query = id(new DiffusionExternalSymbolQuery())->withNames(array($this->name));
     if ($request->getStr('context')) {
         $external_query->withContexts(array($request->getStr('context')));
     }
     if ($request->getStr('type')) {
         $external_query->withTypes(array($request->getStr('type')));
     }
     if ($request->getStr('lang')) {
         $external_query->withLanguages(array($request->getStr('lang')));
     }
     $external_sources = id(new PhutilClassMapQuery())->setAncestorClass('DiffusionExternalSymbolsSource')->execute();
     $results = array($symbols);
     foreach ($external_sources as $source) {
         $results[] = $source->executeQuery($external_query);
     }
     $symbols = array_mergev($results);
     if ($request->getBool('jump') && count($symbols) == 1) {
         // If this is a clickthrough from Differential, just jump them
         // straight to the target if we got a single hit.
         $symbol = head($symbols);
         return id(new AphrontRedirectResponse())->setIsExternal($symbol->isExternal())->setURI($symbol->getURI());
     }
     $rows = array();
     foreach ($symbols as $symbol) {
         $href = $symbol->getURI();
         if ($symbol->isExternal()) {
             $source = $symbol->getSource();
             $location = $symbol->getLocation();
         } else {
             $repo = $symbol->getRepository();
             $file = $symbol->getPath();
             $line = $symbol->getLineNumber();
             $source = $repo->getMonogram();
             $location = $file . ':' . $line;
         }
         $location = phutil_tag('a', array('href' => $href), $location);
         $rows[] = array($symbol->getSymbolType(), $symbol->getSymbolContext(), $symbol->getSymbolName(), $symbol->getSymbolLanguage(), $source, $location);
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array(pht('Type'), pht('Context'), pht('Name'), pht('Language'), pht('Source'), pht('Location')));
     $table->setColumnClasses(array('', '', 'pri', '', '', ''));
     $table->setNoDataString(pht('No matching symbol could be found in any indexed repository.'));
     $panel = new PHUIObjectBoxView();
     $panel->setHeaderText(pht('Similar Symbols'));
     $panel->setTable($table);
     return $this->buildApplicationPage($panel, array('title' => pht('Find Symbol')));
 }
 protected function processDiffusionRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     // This controller doesn't use blob/path stuff, just pass the dictionary
     // in directly instead of using the AphrontRequest parsing mechanism.
     $data = $request->getURIMap();
     $data['user'] = $user;
     $drequest = DiffusionRequest::newFromDictionary($data);
     $this->diffusionRequest = $drequest;
     if ($request->getStr('diff')) {
         return $this->buildRawDiffResponse($drequest);
     }
     $repository = $drequest->getRepository();
     $callsign = $repository->getCallsign();
     $content = array();
     $commit = id(new DiffusionCommitQuery())->setViewer($request->getUser())->withRepository($repository)->withIdentifiers(array($drequest->getCommit()))->needCommitData(true)->needAuditRequests(true)->executeOne();
     $crumbs = $this->buildCrumbs(array('commit' => true));
     if (!$commit) {
         $exists = $this->callConduitWithDiffusionRequest('diffusion.existsquery', array('commit' => $drequest->getCommit()));
         if (!$exists) {
             return new Aphront404Response();
         }
         $error = id(new PHUIInfoView())->setTitle(pht('Commit Still Parsing'))->appendChild(pht('Failed to load the commit because the commit has not been ' . 'parsed yet.'));
         return $this->buildApplicationPage(array($crumbs, $error), array('title' => pht('Commit Still Parsing')));
     }
     $audit_requests = $commit->getAudits();
     $this->auditAuthorityPHIDs = PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
     $commit_data = $commit->getCommitData();
     $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
     if ($is_foreign) {
         $subpath = $commit_data->getCommitDetail('svn-subpath');
         $error_panel = new PHUIInfoView();
         $error_panel->setTitle(pht('Commit Not Tracked'));
         $error_panel->setSeverity(PHUIInfoView::SEVERITY_WARNING);
         $error_panel->appendChild(pht("This Diffusion repository is configured to track only one " . "subdirectory of the entire Subversion repository, and this commit " . "didn't affect the tracked subdirectory ('%s'), so no " . "information is available.", $subpath));
         $content[] = $error_panel;
     } else {
         $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
         $engine->setConfig('viewer', $user);
         require_celerity_resource('phabricator-remarkup-css');
         $parents = $this->callConduitWithDiffusionRequest('diffusion.commitparentsquery', array('commit' => $drequest->getCommit()));
         if ($parents) {
             $parents = id(new DiffusionCommitQuery())->setViewer($user)->withRepository($repository)->withIdentifiers($parents)->execute();
         }
         $headsup_view = id(new PHUIHeaderView())->setHeader(nonempty($commit->getSummary(), pht('Commit Detail')));
         $headsup_actions = $this->renderHeadsupActionList($commit, $repository);
         $commit_properties = $this->loadCommitProperties($commit, $commit_data, $parents, $audit_requests);
         $property_list = id(new PHUIPropertyListView())->setHasKeyboardShortcuts(true)->setUser($user)->setObject($commit);
         foreach ($commit_properties as $key => $value) {
             $property_list->addProperty($key, $value);
         }
         $message = $commit_data->getCommitMessage();
         $revision = $commit->getCommitIdentifier();
         $message = $this->linkBugtraq($message);
         $message = $engine->markupText($message);
         $property_list->invokeWillRenderEvent();
         $property_list->setActionList($headsup_actions);
         $detail_list = new PHUIPropertyListView();
         $detail_list->addSectionHeader(pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
         $detail_list->addTextContent(phutil_tag('div', array('class' => 'diffusion-commit-message phabricator-remarkup'), $message));
         $headsup_view->setTall(true);
         $object_box = id(new PHUIObjectBoxView())->setHeader($headsup_view)->addPropertyList($property_list)->addPropertyList($detail_list);
         $content[] = $object_box;
     }
     $content[] = $this->buildComments($commit);
     $hard_limit = 1000;
     if ($commit->isImported()) {
         $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest($drequest);
         $change_query->setLimit($hard_limit + 1);
         $changes = $change_query->loadChanges();
     } else {
         $changes = array();
     }
     $was_limited = count($changes) > $hard_limit;
     if ($was_limited) {
         $changes = array_slice($changes, 0, $hard_limit);
     }
     $content[] = $this->buildMergesTable($commit);
     $highlighted_audits = $commit->getAuthorityAudits($user, $this->auditAuthorityPHIDs);
     $count = count($changes);
     $bad_commit = null;
     if ($count == 0) {
         $bad_commit = queryfx_one(id(new PhabricatorRepository())->establishConnection('r'), 'SELECT * FROM %T WHERE fullCommitName = %s', PhabricatorRepository::TABLE_BADCOMMIT, 'r' . $callsign . $commit->getCommitIdentifier());
     }
     $show_changesets = false;
     if ($bad_commit) {
         $content[] = $this->renderStatusMessage(pht('Bad Commit'), $bad_commit['description']);
     } else {
         if ($is_foreign) {
             // Don't render anything else.
         } else {
             if (!$commit->isImported()) {
                 $content[] = $this->renderStatusMessage(pht('Still Importing...'), pht('This commit is still importing. Changes will be visible once ' . 'the import finishes.'));
             } else {
                 if (!count($changes)) {
                     $content[] = $this->renderStatusMessage(pht('Empty Commit'), pht('This commit is empty and does not affect any paths.'));
                 } else {
                     if ($was_limited) {
                         $content[] = $this->renderStatusMessage(pht('Enormous Commit'), pht('This commit is enormous, and affects more than %d files. ' . 'Changes are not shown.', $hard_limit));
                     } else {
                         $show_changesets = true;
                         // The user has clicked "Show All Changes", and we should show all the
                         // changes inline even if there are more than the soft limit.
                         $show_all_details = $request->getBool('show_all');
                         $change_panel = new PHUIObjectBoxView();
                         $header = new PHUIHeaderView();
                         $header->setHeader(pht('Changes (%s)', new PhutilNumber($count)));
                         $change_panel->setID('toc');
                         if ($count > self::CHANGES_LIMIT && !$show_all_details) {
                             $icon = id(new PHUIIconView())->setIconFont('fa-files-o');
                             $button = id(new PHUIButtonView())->setText(pht('Show All Changes'))->setHref('?show_all=true')->setTag('a')->setIcon($icon);
                             $warning_view = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_WARNING)->setTitle(pht('Very Large Commit'))->appendChild(pht('This commit is very large. Load each file individually.'));
                             $change_panel->setInfoView($warning_view);
                             $header->addActionLink($button);
                         }
                         $changesets = DiffusionPathChange::convertToDifferentialChangesets($user, $changes);
                         // TODO: This table and panel shouldn't really be separate, but we need
                         // to clean up the "Load All Files" interaction first.
                         $change_table = $this->buildTableOfContents($changesets);
                         $change_panel->setTable($change_table);
                         $change_panel->setHeader($header);
                         $content[] = $change_panel;
                         $vcs = $repository->getVersionControlSystem();
                         switch ($vcs) {
                             case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
                                 $vcs_supports_directory_changes = true;
                                 break;
                             case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
                             case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
                                 $vcs_supports_directory_changes = false;
                                 break;
                             default:
                                 throw new Exception(pht('Unknown VCS.'));
                         }
                         $references = array();
                         foreach ($changesets as $key => $changeset) {
                             $file_type = $changeset->getFileType();
                             if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
                                 if (!$vcs_supports_directory_changes) {
                                     unset($changesets[$key]);
                                     continue;
                                 }
                             }
                             $references[$key] = $drequest->generateURI(array('action' => 'rendering-ref', 'path' => $changeset->getFilename()));
                         }
                         // TODO: Some parts of the views still rely on properties of the
                         // DifferentialChangeset. Make the objects ephemeral to make sure we don't
                         // accidentally save them, and then set their ID to the appropriate ID for
                         // this application (the path IDs).
                         $path_ids = array_flip(mpull($changes, 'getPath'));
                         foreach ($changesets as $changeset) {
                             $changeset->makeEphemeral();
                             $changeset->setID($path_ids[$changeset->getFilename()]);
                         }
                         if ($count <= self::CHANGES_LIMIT || $show_all_details) {
                             $visible_changesets = $changesets;
                         } else {
                             $visible_changesets = array();
                             $inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments($user, $commit->getPHID());
                             $path_ids = mpull($inlines, null, 'getPathID');
                             foreach ($changesets as $key => $changeset) {
                                 if (array_key_exists($changeset->getID(), $path_ids)) {
                                     $visible_changesets[$key] = $changeset;
                                 }
                             }
                         }
                         $change_list_title = DiffusionView::nameCommit($repository, $commit->getCommitIdentifier());
                         $change_list = new DifferentialChangesetListView();
                         $change_list->setTitle($change_list_title);
                         $change_list->setChangesets($changesets);
                         $change_list->setVisibleChangesets($visible_changesets);
                         $change_list->setRenderingReferences($references);
                         $change_list->setRenderURI('/diffusion/' . $callsign . '/diff/');
                         $change_list->setRepository($repository);
                         $change_list->setUser($user);
                         // TODO: Try to setBranch() to something reasonable here?
                         $change_list->setStandaloneURI('/diffusion/' . $callsign . '/diff/');
                         $change_list->setRawFileURIs(null, '/diffusion/' . $callsign . '/diff/?view=r');
                         $change_list->setInlineCommentControllerURI('/diffusion/inline/edit/' . phutil_escape_uri($commit->getPHID()) . '/');
                         $content[] = $change_list->render();
                     }
                 }
             }
         }
     }
     $content[] = $this->renderAddCommentPanel($commit, $audit_requests);
     $commit_id = 'r' . $callsign . $commit->getCommitIdentifier();
     $short_name = DiffusionView::nameCommit($repository, $commit->getCommitIdentifier());
     $prefs = $user->loadPreferences();
     $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
     $pref_collapse = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED;
     $show_filetree = $prefs->getPreference($pref_filetree);
     $collapsed = $prefs->getPreference($pref_collapse);
     if ($show_changesets && $show_filetree) {
         $nav = id(new DifferentialChangesetFileTreeSideNavBuilder())->setTitle($short_name)->setBaseURI(new PhutilURI('/' . $commit_id))->build($changesets)->setCrumbs($crumbs)->setCollapsed((bool) $collapsed)->appendChild($content);
         $content = $nav;
     } else {
         $content = array($crumbs, $content);
     }
     return $this->buildApplicationPage($content, array('title' => $commit_id, 'pageObjects' => array($commit->getPHID())));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $current_version = null;
     if ($id) {
         $document = id(new PhrictionDocumentQuery())->setViewer($viewer)->withIDs(array($id))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$document) {
             return new Aphront404Response();
         }
         $current_version = $document->getContent()->getVersion();
         $revert = $request->getInt('revert');
         if ($revert) {
             $content = id(new PhrictionContent())->loadOneWhere('documentID = %d AND version = %d', $document->getID(), $revert);
             if (!$content) {
                 return new Aphront404Response();
             }
         } else {
             $content = $document->getContent();
         }
     } else {
         $slug = $request->getStr('slug');
         $slug = PhabricatorSlug::normalize($slug);
         if (!$slug) {
             return new Aphront404Response();
         }
         $document = id(new PhrictionDocumentQuery())->setViewer($viewer)->withSlugs(array($slug))->needContent(true)->executeOne();
         if ($document) {
             $content = $document->getContent();
             $current_version = $content->getVersion();
         } else {
             $document = PhrictionDocument::initializeNewDocument($viewer, $slug);
             $content = $document->getContent();
         }
     }
     if ($request->getBool('nodraft')) {
         $draft = null;
         $draft_key = null;
     } else {
         if ($document->getPHID()) {
             $draft_key = $document->getPHID() . ':' . $content->getVersion();
         } else {
             $draft_key = 'phriction:' . $content->getSlug();
         }
         $draft = id(new PhabricatorDraft())->loadOneWhere('authorPHID = %s AND draftKey = %s', $viewer->getPHID(), $draft_key);
     }
     if ($draft && strlen($draft->getDraft()) && $draft->getDraft() != $content->getContent()) {
         $content_text = $draft->getDraft();
         $discard = phutil_tag('a', array('href' => $request->getRequestURI()->alter('nodraft', true)), pht('discard this draft'));
         $draft_note = new PHUIInfoView();
         $draft_note->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
         $draft_note->setTitle(pht('Recovered Draft'));
         $draft_note->appendChild(hsprintf('<p>%s</p>', pht('Showing a saved draft of your edits, you can %s.', $discard)));
     } else {
         $content_text = $content->getContent();
         $draft_note = null;
     }
     require_celerity_resource('phriction-document-css');
     $e_title = true;
     $e_content = true;
     $validation_exception = null;
     $notes = null;
     $title = $content->getTitle();
     $overwrite = false;
     $v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID($document->getPHID());
     if ($request->isFormPost()) {
         $title = $request->getStr('title');
         $content_text = $request->getStr('content');
         $notes = $request->getStr('description');
         $current_version = $request->getInt('contentVersion');
         $v_view = $request->getStr('viewPolicy');
         $v_edit = $request->getStr('editPolicy');
         $v_cc = $request->getArr('cc');
         $xactions = array();
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_TITLE)->setNewValue($title);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_CONTENT)->setNewValue($content_text);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($v_view);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)->setNewValue($v_edit);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('=' => $v_cc));
         $editor = id(new PhrictionTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setDescription($notes)->setProcessContentVersionError(!$request->getBool('overwrite'))->setContentVersion($current_version);
         try {
             $editor->applyTransactions($document, $xactions);
             if ($draft) {
                 $draft->delete();
             }
             $uri = PhrictionDocument::getSlugURI($document->getSlug());
             return id(new AphrontRedirectResponse())->setURI($uri);
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $validation_exception = $ex;
             $e_title = nonempty($ex->getShortMessage(PhrictionTransaction::TYPE_TITLE), true);
             $e_content = nonempty($ex->getShortMessage(PhrictionTransaction::TYPE_CONTENT), true);
             // if we're not supposed to process the content version error, then
             // overwrite that content...!
             if (!$editor->getProcessContentVersionError()) {
                 $overwrite = true;
             }
             $document->setViewPolicy($v_view);
             $document->setEditPolicy($v_edit);
         }
     }
     if ($document->getID()) {
         $panel_header = pht('Edit Document: %s', $content->getTitle());
         $page_title = pht('Edit Document');
         $header_icon = 'fa-pencil';
         if ($overwrite) {
             $submit_button = pht('Overwrite Changes');
         } else {
             $submit_button = pht('Save Changes');
         }
     } else {
         $panel_header = pht('Create New Phriction Document');
         $submit_button = pht('Create Document');
         $page_title = pht('Create Document');
         $header_icon = 'fa-plus-square';
     }
     $uri = $document->getSlug();
     $uri = PhrictionDocument::getSlugURI($uri);
     $uri = PhabricatorEnv::getProductionURI($uri);
     $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($document)->execute();
     $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
     $edit_capability = PhabricatorPolicyCapability::CAN_EDIT;
     $form = id(new AphrontFormView())->setUser($viewer)->addHiddenInput('slug', $document->getSlug())->addHiddenInput('nodraft', $request->getBool('nodraft'))->addHiddenInput('contentVersion', $current_version)->addHiddenInput('overwrite', $overwrite)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Title'))->setValue($title)->setError($e_title)->setName('title'))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('URI'))->setValue($uri))->appendChild(id(new PhabricatorRemarkupControl())->setLabel(pht('Content'))->setValue($content_text)->setError($e_content)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('content')->setID('document-textarea')->setUser($viewer))->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Subscribers'))->setName('cc')->setValue($v_cc)->setUser($viewer)->setDatasource(new PhabricatorMetaMTAMailableDatasource()))->appendChild(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($document)->setCapability($view_capability)->setPolicies($policies)->setCaption($document->describeAutomaticCapability($view_capability)))->appendChild(id(new AphrontFormPolicyControl())->setName('editPolicy')->setPolicyObject($document)->setCapability($edit_capability)->setPolicies($policies)->setCaption($document->describeAutomaticCapability($edit_capability)))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Edit Notes'))->setValue($notes)->setError(null)->setName('description'))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_button));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Document'))->setValidationException($validation_exception)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $preview = id(new PHUIRemarkupPreviewPanel())->setHeader($content->getTitle())->setPreviewURI('/phriction/preview/' . $document->getSlug())->setControlID('document-textarea')->setPreviewType(PHUIRemarkupPreviewPanel::DOCUMENT);
     $crumbs = $this->buildApplicationCrumbs();
     if ($document->getID()) {
         $crumbs->addTextCrumb($content->getTitle(), PhrictionDocument::getSlugURI($document->getSlug()));
         $crumbs->addTextCrumb(pht('Edit'));
     } else {
         $crumbs->addTextCrumb(pht('Create'));
     }
     $crumbs->setBorder(true);
     $header = id(new PHUIHeaderView())->setHeader($panel_header)->setHeaderIcon($header_icon);
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($draft_note, $form_box, $preview));
     return $this->newPage()->setTitle($page_title)->setCrumbs($crumbs)->appendChild($view);
 }
 public function handleRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $id = $request->getURIData('id');
     if (!$id) {
         $is_create = true;
         $this->requireApplicationCapability(LegalpadCreateDocumentsCapability::CAPABILITY);
         $document = LegalpadDocument::initializeNewDocument($user);
         $body = id(new LegalpadDocumentBody())->setCreatorPHID($user->getPHID());
         $document->attachDocumentBody($body);
         $document->setDocumentBodyPHID(PhabricatorPHIDConstants::PHID_VOID);
     } else {
         $is_create = false;
         $document = id(new LegalpadDocumentQuery())->setViewer($user)->needDocumentBodies(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withIDs(array($id))->executeOne();
         if (!$document) {
             return new Aphront404Response();
         }
     }
     $e_title = true;
     $e_text = true;
     $title = $document->getDocumentBody()->getTitle();
     $text = $document->getDocumentBody()->getText();
     $v_signature_type = $document->getSignatureType();
     $v_preamble = $document->getPreamble();
     $v_require_signature = $document->getRequireSignature();
     $errors = array();
     $can_view = null;
     $can_edit = null;
     if ($request->isFormPost()) {
         $xactions = array();
         $title = $request->getStr('title');
         if (!strlen($title)) {
             $e_title = pht('Required');
             $errors[] = pht('The document title may not be blank.');
         } else {
             $xactions[] = id(new LegalpadTransaction())->setTransactionType(LegalpadTransaction::TYPE_TITLE)->setNewValue($title);
         }
         $text = $request->getStr('text');
         if (!strlen($text)) {
             $e_text = pht('Required');
             $errors[] = pht('The document may not be blank.');
         } else {
             $xactions[] = id(new LegalpadTransaction())->setTransactionType(LegalpadTransaction::TYPE_TEXT)->setNewValue($text);
         }
         $can_view = $request->getStr('can_view');
         $xactions[] = id(new LegalpadTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($can_view);
         $can_edit = $request->getStr('can_edit');
         $xactions[] = id(new LegalpadTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)->setNewValue($can_edit);
         if ($is_create) {
             $v_signature_type = $request->getStr('signatureType');
             $xactions[] = id(new LegalpadTransaction())->setTransactionType(LegalpadTransaction::TYPE_SIGNATURE_TYPE)->setNewValue($v_signature_type);
         }
         $v_preamble = $request->getStr('preamble');
         $xactions[] = id(new LegalpadTransaction())->setTransactionType(LegalpadTransaction::TYPE_PREAMBLE)->setNewValue($v_preamble);
         $v_require_signature = $request->getBool('requireSignature', 0);
         if ($v_require_signature) {
             if (!$user->getIsAdmin()) {
                 $errors[] = pht('Only admins may require signature.');
             }
             $individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
             if ($v_signature_type != $individual) {
                 $errors[] = pht('Only documents with signature type "individual" may require ' . 'signing to use Phabricator.');
             }
         }
         if ($user->getIsAdmin()) {
             $xactions[] = id(new LegalpadTransaction())->setTransactionType(LegalpadTransaction::TYPE_REQUIRE_SIGNATURE)->setNewValue($v_require_signature);
         }
         if (!$errors) {
             $editor = id(new LegalpadDocumentEditor())->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setActor($user);
             $xactions = $editor->applyTransactions($document, $xactions);
             return id(new AphrontRedirectResponse())->setURI($this->getApplicationURI('view/' . $document->getID()));
         }
     }
     if ($errors) {
         // set these to what was specified in the form on post
         $document->setViewPolicy($can_view);
         $document->setEditPolicy($can_edit);
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormTextControl())->setID('document-title')->setLabel(pht('Title'))->setError($e_title)->setValue($title)->setName('title'));
     if ($is_create) {
         $form->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Who Should Sign?'))->setName(pht('signatureType'))->setValue($v_signature_type)->setOptions(LegalpadDocument::getSignatureTypeMap()));
         $show_require = true;
         $caption = pht('Applies only to documents individuals sign.');
     } else {
         $form->appendChild(id(new AphrontFormMarkupControl())->setLabel(pht('Who Should Sign?'))->setValue($document->getSignatureTypeName()));
         $individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
         $show_require = $document->getSignatureType() == $individual;
         $caption = null;
     }
     if ($show_require) {
         $form->appendChild(id(new AphrontFormCheckboxControl())->setDisabled(!$user->getIsAdmin())->setLabel(pht('Require Signature'))->addCheckbox('requireSignature', 'requireSignature', pht('Should signing this document be required to use Phabricator?'), $v_require_signature)->setCaption($caption));
     }
     $form->appendChild(id(new PhabricatorRemarkupControl())->setUser($user)->setID('preamble')->setLabel(pht('Preamble'))->setValue($v_preamble)->setName('preamble')->setCaption(pht('Optional help text for users signing this document.')))->appendChild(id(new PhabricatorRemarkupControl())->setUser($user)->setID('document-text')->setLabel(pht('Document Body'))->setError($e_text)->setValue($text)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('text'));
     $policies = id(new PhabricatorPolicyQuery())->setViewer($user)->setObject($document)->execute();
     $form->appendChild(id(new AphrontFormPolicyControl())->setUser($user)->setCapability(PhabricatorPolicyCapability::CAN_VIEW)->setPolicyObject($document)->setPolicies($policies)->setName('can_view'))->appendChild(id(new AphrontFormPolicyControl())->setUser($user)->setCapability(PhabricatorPolicyCapability::CAN_EDIT)->setPolicyObject($document)->setPolicies($policies)->setName('can_edit'));
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
     $submit = new AphrontFormSubmitControl();
     if ($is_create) {
         $submit->setValue(pht('Create Document'));
         $submit->addCancelButton($this->getApplicationURI());
         $title = pht('Create Document');
         $short = pht('Create');
     } else {
         $submit->setValue(pht('Save Document'));
         $submit->addCancelButton($this->getApplicationURI('view/' . $document->getID()));
         $title = pht('Edit Document');
         $short = pht('Edit');
         $crumbs->addTextCrumb($document->getMonogram(), $this->getApplicationURI('view/' . $document->getID()));
     }
     $form->appendChild($submit);
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($title)->setFormErrors($errors)->setForm($form);
     $crumbs->addTextCrumb($short);
     $preview = id(new PHUIRemarkupPreviewPanel())->setHeader(pht('Document Preview'))->setPreviewURI($this->getApplicationURI('document/preview/'))->setControlID('document-text')->addClass('phui-document-view');
     return $this->buildApplicationPage(array($crumbs, $form_box, $preview), array('title' => $title));
 }
 public static function hasCaptchaResponse(AphrontRequest $request)
 {
     return $request->getBool('recaptcha_response_field');
 }
 public function processRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $user = $this->getUser();
     $preferences = $user->loadPreferences();
     $pref_re_prefix = PhabricatorUserPreferences::PREFERENCE_RE_PREFIX;
     $pref_vary = PhabricatorUserPreferences::PREFERENCE_VARY_SUBJECT;
     $prefs_html_email = PhabricatorUserPreferences::PREFERENCE_HTML_EMAILS;
     $errors = array();
     if ($request->isFormPost()) {
         if (PhabricatorMetaMTAMail::shouldMultiplexAllMail()) {
             if ($request->getStr($pref_re_prefix) == 'default') {
                 $preferences->unsetPreference($pref_re_prefix);
             } else {
                 $preferences->setPreference($pref_re_prefix, $request->getBool($pref_re_prefix));
             }
             if ($request->getStr($pref_vary) == 'default') {
                 $preferences->unsetPreference($pref_vary);
             } else {
                 $preferences->setPreference($pref_vary, $request->getBool($pref_vary));
             }
             if ($request->getStr($prefs_html_email) == 'default') {
                 $preferences->unsetPreference($prefs_html_email);
             } else {
                 $preferences->setPreference($prefs_html_email, $request->getBool($prefs_html_email));
             }
         }
         $preferences->save();
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $re_prefix_default = PhabricatorEnv::getEnvConfig('metamta.re-prefix') ? pht('Enabled') : pht('Disabled');
     $vary_default = PhabricatorEnv::getEnvConfig('metamta.vary-subjects') ? pht('Vary') : pht('Do Not Vary');
     $html_emails_default = pht('Plain Text');
     $re_prefix_value = $preferences->getPreference($pref_re_prefix);
     if ($re_prefix_value === null) {
         $re_prefix_value = 'default';
     } else {
         $re_prefix_value = $re_prefix_value ? 'true' : 'false';
     }
     $vary_value = $preferences->getPreference($pref_vary);
     if ($vary_value === null) {
         $vary_value = 'default';
     } else {
         $vary_value = $vary_value ? 'true' : 'false';
     }
     $html_emails_value = $preferences->getPreference($prefs_html_email);
     if ($html_emails_value === null) {
         $html_emails_value = 'default';
     } else {
         $html_emails_value = $html_emails_value ? 'true' : 'false';
     }
     $form = new AphrontFormView();
     $form->setUser($viewer);
     if (PhabricatorMetaMTAMail::shouldMultiplexAllMail()) {
         $html_email_control = id(new AphrontFormSelectControl())->setName($prefs_html_email)->setOptions(array('default' => pht('Default (%s)', $html_emails_default), 'true' => pht('Send HTML Email'), 'false' => pht('Send Plain Text Email')))->setValue($html_emails_value);
         $re_control = id(new AphrontFormSelectControl())->setName($pref_re_prefix)->setOptions(array('default' => pht('Use Server Default (%s)', $re_prefix_default), 'true' => pht('Enable "Re:" prefix'), 'false' => pht('Disable "Re:" prefix')))->setValue($re_prefix_value);
         $vary_control = id(new AphrontFormSelectControl())->setName($pref_vary)->setOptions(array('default' => pht('Use Server Default (%s)', $vary_default), 'true' => pht('Vary Subjects'), 'false' => pht('Do Not Vary Subjects')))->setValue($vary_value);
     } else {
         $html_email_control = id(new AphrontFormStaticControl())->setValue(pht('Server Default (%s)', $html_emails_default));
         $re_control = id(new AphrontFormStaticControl())->setValue(pht('Server Default (%s)', $re_prefix_default));
         $vary_control = id(new AphrontFormStaticControl())->setValue(pht('Server Default (%s)', $vary_default));
     }
     $form->appendRemarkupInstructions(pht('These settings fine-tune some technical aspects of how email is ' . 'formatted. You may be able to adjust them to make mail more ' . 'useful or improve threading.'));
     if (!PhabricatorMetaMTAMail::shouldMultiplexAllMail()) {
         $form->appendRemarkupInstructions(pht('NOTE: This install of Phabricator is configured to send a ' . 'single mail message to all recipients, so all settings are ' . 'locked at the server default value.'));
     }
     $form->appendRemarkupInstructions(pht("You can use the **HTML Email** setting to control whether " . "Phabricator send you HTML email (which has more color and " . "formatting) or plain text email (which is more compatible).\n" . "\n" . "WARNING: This feature is new and experimental! If you enable " . "it, mail may not render properly and replying to mail may not " . "work as well."))->appendChild($html_email_control->setLabel(pht('HTML Email')))->appendRemarkupInstructions('')->appendRemarkupInstructions(pht('The **Add "Re:" Prefix** setting adds "Re:" in front of all ' . 'messages, even if they are not replies. If you use **Mail.app** on ' . 'Mac OS X, this may improve mail threading.' . "\n\n" . "| Setting                | Example Mail Subject\n" . "|------------------------|----------------\n" . "| Enable \"Re:\" Prefix  | " . "`Re: [Differential] [Accepted] D123: Example Revision`\n" . "| Disable \"Re:\" Prefix | " . "`[Differential] [Accepted] D123: Example Revision`"))->appendChild($re_control->setLabel(pht('Add "Re:" Prefix')))->appendRemarkupInstructions('')->appendRemarkupInstructions(pht('With **Vary Subjects** enabled, most mail subject lines will ' . 'include a brief description of their content, like **[Closed]** ' . 'for a notification about someone closing a task.' . "\n\n" . "| Setting              | Example Mail Subject\n" . "|----------------------|----------------\n" . "| Vary Subjects        | " . "`[Maniphest] [Closed] T123: Example Task`\n" . "| Do Not Vary Subjects | " . "`[Maniphest] T123: Example Task`\n" . "\n" . 'This can make mail more useful, but some clients have difficulty ' . 'threading these messages. Disabling this option may improve ' . 'threading, at the cost of less useful subject lines.'))->appendChild($vary_control->setLabel(pht('Vary Subjects')));
     $form->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Email Format'))->setFormSaved($request->getStr('saved'))->setFormErrors($errors)->setForm($form);
     return id(new AphrontNullView())->appendChild(array($form_box));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     if ($id) {
         $poll = id(new PhabricatorSlowvoteQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$poll) {
             return new Aphront404Response();
         }
         $is_new = false;
     } else {
         $poll = PhabricatorSlowvotePoll::initializeNewPoll($viewer);
         $is_new = true;
     }
     if ($is_new) {
         $v_projects = array();
     } else {
         $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs($poll->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
         $v_projects = array_reverse($v_projects);
     }
     $e_question = true;
     $e_response = true;
     $errors = array();
     $v_question = $poll->getQuestion();
     $v_description = $poll->getDescription();
     $v_responses = $poll->getResponseVisibility();
     $v_shuffle = $poll->getShuffle();
     $v_space = $poll->getSpacePHID();
     $responses = $request->getArr('response');
     if ($request->isFormPost()) {
         $v_question = $request->getStr('question');
         $v_description = $request->getStr('description');
         $v_responses = (int) $request->getInt('responses');
         $v_shuffle = (int) $request->getBool('shuffle');
         $v_view_policy = $request->getStr('viewPolicy');
         $v_projects = $request->getArr('projects');
         $v_space = $request->getStr('spacePHID');
         if ($is_new) {
             $poll->setMethod($request->getInt('method'));
         }
         if (!strlen($v_question)) {
             $e_question = pht('Required');
             $errors[] = pht('You must ask a poll question.');
         } else {
             $e_question = null;
         }
         if ($is_new) {
             $responses = array_filter($responses);
             if (empty($responses)) {
                 $errors[] = pht('You must offer at least one response.');
                 $e_response = pht('Required');
             } else {
                 $e_response = null;
             }
         }
         $xactions = array();
         $template = id(new PhabricatorSlowvoteTransaction());
         $xactions[] = id(clone $template)->setTransactionType(PhabricatorSlowvoteTransaction::TYPE_QUESTION)->setNewValue($v_question);
         $xactions[] = id(clone $template)->setTransactionType(PhabricatorSlowvoteTransaction::TYPE_DESCRIPTION)->setNewValue($v_description);
         $xactions[] = id(clone $template)->setTransactionType(PhabricatorSlowvoteTransaction::TYPE_RESPONSES)->setNewValue($v_responses);
         $xactions[] = id(clone $template)->setTransactionType(PhabricatorSlowvoteTransaction::TYPE_SHUFFLE)->setNewValue($v_shuffle);
         $xactions[] = id(clone $template)->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($v_view_policy);
         $xactions[] = id(clone $template)->setTransactionType(PhabricatorTransactions::TYPE_SPACE)->setNewValue($v_space);
         if (empty($errors)) {
             $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
             $xactions[] = id(new PhabricatorSlowvoteTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $proj_edge_type)->setNewValue(array('=' => array_fuse($v_projects)));
             $editor = id(new PhabricatorSlowvoteEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request);
             $xactions = $editor->applyTransactions($poll, $xactions);
             if ($is_new) {
                 $poll->save();
                 foreach ($responses as $response) {
                     $option = new PhabricatorSlowvoteOption();
                     $option->setName($response);
                     $option->setPollID($poll->getID());
                     $option->save();
                 }
             }
             return id(new AphrontRedirectResponse())->setURI('/V' . $poll->getID());
         } else {
             $poll->setViewPolicy($v_view_policy);
         }
     }
     $instructions = phutil_tag('p', array('class' => 'aphront-form-instructions'), pht('Resolve issues and build consensus through ' . 'protracted deliberation.'));
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild($instructions)->appendChild(id(new AphrontFormTextAreaControl())->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)->setLabel(pht('Question'))->setName('question')->setValue($v_question)->setError($e_question))->appendChild(id(new PhabricatorRemarkupControl())->setUser($viewer)->setLabel(pht('Description'))->setName('description')->setValue($v_description))->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($v_projects)->setDatasource(new PhabricatorProjectDatasource()));
     if ($is_new) {
         for ($ii = 0; $ii < 10; $ii++) {
             $n = $ii + 1;
             $response = id(new AphrontFormTextControl())->setLabel(pht('Response %d', $n))->setName('response[]')->setValue(idx($responses, $ii, ''));
             if ($ii == 0) {
                 $response->setError($e_response);
             }
             $form->appendChild($response);
         }
     }
     $poll_type_options = array(PhabricatorSlowvotePoll::METHOD_PLURALITY => pht('Plurality (Single Choice)'), PhabricatorSlowvotePoll::METHOD_APPROVAL => pht('Approval (Multiple Choice)'));
     $response_type_options = array(PhabricatorSlowvotePoll::RESPONSES_VISIBLE => pht('Allow anyone to see the responses'), PhabricatorSlowvotePoll::RESPONSES_VOTERS => pht('Require a vote to see the responses'), PhabricatorSlowvotePoll::RESPONSES_OWNER => pht('Only I can see the responses'));
     if ($is_new) {
         $form->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Vote Type'))->setName('method')->setValue($poll->getMethod())->setOptions($poll_type_options));
     } else {
         $form->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Vote Type'))->setValue(idx($poll_type_options, $poll->getMethod())));
     }
     if ($is_new) {
         $title = pht('Create Slowvote');
         $button = pht('Create');
         $cancel_uri = $this->getApplicationURI();
     } else {
         $title = pht('Edit %s', 'V' . $poll->getID());
         $button = pht('Save Changes');
         $cancel_uri = '/V' . $poll->getID();
     }
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($poll)->execute();
     $form->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Responses'))->setName('responses')->setValue($v_responses)->setOptions($response_type_options))->appendChild(id(new AphrontFormCheckboxControl())->setLabel(pht('Shuffle'))->addCheckbox('shuffle', 1, pht('Show choices in random order.'), $v_shuffle))->appendChild(id(new AphrontFormPolicyControl())->setUser($viewer)->setName('viewPolicy')->setPolicyObject($poll)->setPolicies($policies)->setCapability(PhabricatorPolicyCapability::CAN_VIEW)->setSpacePHID($v_space))->appendChild(id(new AphrontFormSubmitControl())->setValue($button)->addCancelButton($cancel_uri));
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
     $crumbs->addTextCrumb($title);
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($title)->setFormErrors($errors)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box), array('title' => $title));
 }
 public function readValueFromRequest(AphrontRequest $request)
 {
     $this->setFieldValue((bool) $request->getBool($this->getFieldKey()));
 }