public function renderModuleStatus(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $types = PhabricatorPHIDType::getAllTypes();
     $types = msort($types, 'getTypeConstant');
     $rows = array();
     foreach ($types as $key => $type) {
         $class_name = $type->getPHIDTypeApplicationClass();
         if ($class_name !== null) {
             $app = PhabricatorApplication::getByClass($class_name);
             $app_name = $app->getName();
             $icon = $app->getFontIcon();
             if ($icon) {
                 $app_icon = id(new PHUIIconView())->setIcon($icon);
             } else {
                 $app_icon = null;
             }
         } else {
             $app_name = null;
             $app_icon = null;
         }
         $icon = $type->getTypeIcon();
         if ($icon) {
             $type_icon = id(new PHUIIconView())->setIcon($icon);
         } else {
             $type_icon = null;
         }
         $rows[] = array($type->getTypeConstant(), get_class($type), $app_icon, $app_name, $type_icon, $type->getTypeName());
     }
     $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Constant'), pht('Class'), null, pht('Application'), null, pht('Name')))->setColumnClasses(array(null, 'pri', 'icon', null, 'icon', 'wide'));
     return id(new PHUIObjectBoxView())->setHeaderText(pht('PHID Types'))->setTable($table);
 }
 public function renderView()
 {
     $view = $this->newStoryView();
     $handle = $this->getHandle($this->getPrimaryObjectPHID());
     $view->setHref($handle->getURI());
     $type = phid_get_type($handle->getPHID());
     $phid_types = PhabricatorPHIDType::getAllTypes();
     $icon = null;
     if (!empty($phid_types[$type])) {
         $phid_type = $phid_types[$type];
         $class = $phid_type->getPHIDTypeApplicationClass();
         if ($class) {
             $application = PhabricatorApplication::getByClass($class);
             $icon = $application->getIcon();
         }
     }
     $view->setAppIcon($icon);
     $xaction_phids = $this->getValue('transactionPHIDs');
     $xaction = $this->getPrimaryTransaction();
     $xaction->setHandles($this->getHandles());
     $view->setTitle($xaction->getTitleForFeed());
     foreach ($xaction_phids as $xaction_phid) {
         $secondary_xaction = $this->getObject($xaction_phid);
         $secondary_xaction->setHandles($this->getHandles());
         $body = $secondary_xaction->getBodyForFeed($this);
         if (nonempty($body)) {
             $view->appendChild($body);
         }
     }
     $view->setImage($this->getHandle($xaction->getAuthorPHID())->getImageURI());
     return $view;
 }
 private function getApplicationObjectTypeName()
 {
     $types = PhabricatorPHIDType::getAllTypes();
     $type = idx($types, $this->getApplicationTransactionType());
     if ($type) {
         return $type->getTypeName();
     }
     return pht('Object');
 }
 private function buildResults()
 {
     $types = PhabricatorSearchApplicationSearchEngine::getIndexableDocumentTypes();
     $icons = mpull(PhabricatorPHIDType::getAllTypes(), 'getTypeIcon', 'getTypeConstant');
     $results = array();
     foreach ($types as $type => $name) {
         $results[$type] = id(new PhabricatorTypeaheadResult())->setPHID($type)->setName($name)->setIcon(idx($icons, $type));
     }
     return $results;
 }
 public function testGetPHIDTypeApplicationClass()
 {
     $types = PhabricatorPHIDType::getAllTypes();
     foreach ($types as $type) {
         $application_class = $type->getPHIDTypeApplicationClass();
         if ($application_class !== null) {
             $this->assertTrue(class_exists($application_class));
         }
     }
 }
 public function renderModuleStatus(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $types = PhabricatorPHIDType::getAllTypes();
     $types = msort($types, 'getTypeConstant');
     $rows = array();
     foreach ($types as $key => $type) {
         $rows[] = array($type->getTypeConstant(), get_class($type), $type->getTypeName());
     }
     $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Constant'), pht('Class'), pht('Name')))->setColumnClasses(array(null, 'pri', 'wide'));
     return id(new PHUIObjectBoxView())->setHeaderText(pht('PHID Types'))->setTable($table);
 }
 protected function loadPage()
 {
     $types = PhabricatorPHIDType::getAllTypes();
     $phids = array_unique($this->phids);
     if (!$phids) {
         return array();
     }
     $object_query = id(new PhabricatorObjectQuery())->withPHIDs($phids)->setParentQuery($this)->requireCapabilities($this->getRequiredObjectCapabilities())->setViewer($this->getViewer());
     // We never want the subquery to raise policy exceptions, even if this
     // query is being executed via executeOne(). Policy exceptions are not
     // meaningful or relevant for handles, which load in an "Unknown" or
     // "Restricted" state after encountering a policy violation.
     $object_query->setRaisePolicyExceptions(false);
     $objects = $object_query->execute();
     $filtered = $object_query->getPolicyFilteredPHIDs();
     $groups = array();
     foreach ($phids as $phid) {
         $type = phid_get_type($phid);
         $groups[$type][] = $phid;
     }
     $results = array();
     foreach ($groups as $type => $phid_group) {
         $handles = array();
         foreach ($phid_group as $key => $phid) {
             if (isset($handles[$phid])) {
                 unset($phid_group[$key]);
                 // The input had a duplicate PHID; just skip it.
                 continue;
             }
             $handles[$phid] = id(new PhabricatorObjectHandle())->setType($type)->setPHID($phid);
             if (isset($objects[$phid])) {
                 $handles[$phid]->setComplete(true);
             } else {
                 if (isset($filtered[$phid])) {
                     $handles[$phid]->setPolicyFiltered(true);
                 }
             }
         }
         if (isset($types[$type])) {
             $type_objects = array_select_keys($objects, $phid_group);
             if ($type_objects) {
                 $have_object_phids = array_keys($type_objects);
                 $types[$type]->loadHandles($this, array_select_keys($handles, $have_object_phids), $type_objects);
             }
         }
         $results += $handles;
     }
     return $results;
 }
 public static function establishConnection($phid_type, $conn_type)
 {
     $map = PhabricatorPHIDType::getAllTypes();
     if (isset($map[$phid_type])) {
         $type = $map[$phid_type];
         $object = $type->newObject();
         if ($object) {
             return $object->establishConnection($conn_type);
         }
     }
     static $class_map = array(PhabricatorPHIDConstants::PHID_TYPE_TOBJ => 'HarbormasterObject', PhabricatorPHIDConstants::PHID_TYPE_XOBJ => 'DoorkeeperExternalObject');
     $class = idx($class_map, $phid_type);
     if (!$class) {
         throw new Exception(pht("Edges are not available for objects of type '%s'!", $phid_type));
     }
     return newv($class, array())->establishConnection($conn_type);
 }
 private function buildResults()
 {
     $viewer = $this->getViewer();
     $types = PhabricatorSearchApplicationSearchEngine::getIndexableDocumentTypes($viewer);
     $phid_types = mpull(PhabricatorPHIDType::getAllTypes(), null, 'getTypeConstant');
     $results = array();
     foreach ($types as $type => $name) {
         $type_object = idx($phid_types, $type);
         if (!$type_object) {
             continue;
         }
         $application_class = $type_object->getPHIDTypeApplicationClass();
         $application = PhabricatorApplication::getByClass($application_class);
         $application_name = $application->getName();
         $results[$type] = id(new PhabricatorTypeaheadResult())->setPHID($type)->setName($name)->addAttribute($application_name)->setIcon($type_object->getTypeIcon());
     }
     return $results;
 }
 public function loadPage()
 {
     $types = PhabricatorPHIDType::getAllTypes();
     $phids = array_unique($this->phids);
     if (!$phids) {
         return array();
     }
     $object_query = id(new PhabricatorObjectQuery())->withPHIDs($phids)->setViewer($this->getViewer());
     $objects = $object_query->execute();
     $filtered = $object_query->getPolicyFilteredPHIDs();
     $groups = array();
     foreach ($phids as $phid) {
         $type = phid_get_type($phid);
         $groups[$type][] = $phid;
     }
     $results = array();
     foreach ($groups as $type => $phid_group) {
         $handles = array();
         foreach ($phid_group as $key => $phid) {
             if (isset($handles[$phid])) {
                 unset($phid_group[$key]);
                 // The input had a duplicate PHID; just skip it.
                 continue;
             }
             $handles[$phid] = id(new PhabricatorObjectHandle())->setType($type)->setPHID($phid);
             if (isset($objects[$phid])) {
                 $handles[$phid]->setComplete(true);
             } else {
                 if (isset($filtered[$phid])) {
                     $handles[$phid]->setPolicyFiltered(true);
                 }
             }
         }
         if (isset($types[$type])) {
             $type_objects = array_select_keys($objects, $phid_group);
             if ($type_objects) {
                 $have_object_phids = array_keys($type_objects);
                 $types[$type]->loadHandles($this, array_select_keys($handles, $have_object_phids), $type_objects);
             }
         }
         $results += $handles;
     }
     return $results;
 }
 protected function loadPage()
 {
     if ($this->namedResults === null) {
         $this->namedResults = array();
     }
     $types = PhabricatorPHIDType::getAllTypes();
     if ($this->types) {
         $types = array_select_keys($types, $this->types);
     }
     $names = array_unique($this->names);
     $phids = $this->phids;
     // We allow objects to be named by their PHID in addition to their normal
     // name so that, e.g., CLI tools which accept object names can also accept
     // PHIDs and work as users expect.
     $actually_phids = array();
     if ($names) {
         foreach ($names as $key => $name) {
             if (!strncmp($name, 'PHID-', 5)) {
                 $actually_phids[] = $name;
                 $phids[] = $name;
                 unset($names[$key]);
             }
         }
     }
     $phids = array_unique($phids);
     if ($names) {
         $name_results = $this->loadObjectsByName($types, $names);
     } else {
         $name_results = array();
     }
     if ($phids) {
         $phid_results = $this->loadObjectsByPHID($types, $phids);
     } else {
         $phid_results = array();
     }
     foreach ($actually_phids as $phid) {
         if (isset($phid_results[$phid])) {
             $name_results[$phid] = $phid_results[$phid];
         }
     }
     $this->namedResults += $name_results;
     return $phid_results + mpull($name_results, null, 'getPHID');
 }
 private function getObjectFilterOptions()
 {
     $objects = id(new PhutilSymbolLoader())->setAncestorClass('PhabricatorFlaggableInterface')->loadObjects();
     $all_types = PhabricatorPHIDType::getAllTypes();
     $options = array();
     foreach ($objects as $object) {
         $phid = $object->generatePHID();
         $phid_type = phid_get_type($phid);
         $type_object = idx($all_types, $phid_type);
         if ($type_object) {
             $options[$phid_type] = $type_object->getTypeName();
         }
     }
     // sort it alphabetically...
     asort($options);
     $default_option = array(0 => pht('All Object Types'));
     // ...and stick the default option on front
     $options = array_merge($default_option, $options);
     return $options;
 }
示例#13
0
     continue;
 }
 $user = id(new PhabricatorUser())->setUsername($username)->setRealName(pht('Mailing List "%s"', $name))->setIsApproved(1)->setIsMailingList(1);
 $email_object = id(new PhabricatorUserEmail())->setAddress($email)->setIsVerified(1);
 try {
     id(new PhabricatorUserEditor())->setActor($user)->createNewUser($user, $email_object);
 } catch (Exception $ex) {
     echo pht('Failed to migrate mailing list "%s": %s.', $name, $ex->getMessage()) . "\n";
     continue;
 }
 $new_phid = $user->getPHID();
 // NOTE: After the PHID type is removed we can't use any Edge code to
 // modify edges.
 $edge_type = PhabricatorSubscribedToObjectEdgeType::EDGECONST;
 $edge_inverse = PhabricatorObjectHasSubscriberEdgeType::EDGECONST;
 $map = PhabricatorPHIDType::getAllTypes();
 foreach ($map as $type => $spec) {
     try {
         $object = $spec->newObject();
         if (!$object) {
             continue;
         }
         $object_conn_w = $object->establishConnection('w');
         queryfx($object_conn_w, 'UPDATE %T SET dst = %s WHERE dst = %s AND type = %s', PhabricatorEdgeConfig::TABLE_NAME_EDGE, $new_phid, $old_phid, $edge_inverse);
     } catch (Exception $ex) {
         // Just ignore these; they're mostly tables not existing.
         continue;
     }
 }
 try {
     $dst_phids = queryfx_all($conn_w, 'SELECT dst FROM %T WHERE src = %s AND type = %s', PhabricatorEdgeConfig::TABLE_NAME_EDGE, $old_phid, $edge_type);
 public function handleRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $application = $request->getURIData('application');
     $application = id(new PhabricatorApplicationQuery())->setViewer($user)->withClasses(array($application))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$application) {
         return new Aphront404Response();
     }
     $title = $application->getName();
     $view_uri = $this->getApplicationURI('view/' . get_class($application) . '/');
     $policies = id(new PhabricatorPolicyQuery())->setViewer($user)->setObject($application)->execute();
     if ($request->isFormPost()) {
         $result = array();
         foreach ($application->getCapabilities() as $capability) {
             $old = $application->getPolicy($capability);
             $new = $request->getStr('policy:' . $capability);
             if ($old == $new) {
                 // No change to the setting.
                 continue;
             }
             if (empty($policies[$new])) {
                 // Not a standard policy, check for a custom policy.
                 $policy = id(new PhabricatorPolicyQuery())->setViewer($user)->withPHIDs(array($new))->executeOne();
                 if (!$policy) {
                     // Not a custom policy either. Can't set the policy to something
                     // invalid, so skip this.
                     continue;
                 }
             }
             if ($new == PhabricatorPolicies::POLICY_PUBLIC) {
                 $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
                 if (!$capobj || !$capobj->shouldAllowPublicPolicySetting()) {
                     // Can't set non-public policies to public.
                     continue;
                 }
             }
             $result[$capability] = $new;
         }
         if ($result) {
             $key = 'phabricator.application-settings';
             $config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
             $value = $config_entry->getValue();
             $phid = $application->getPHID();
             if (empty($value[$phid])) {
                 $value[$application->getPHID()] = array();
             }
             if (empty($value[$phid]['policy'])) {
                 $value[$phid]['policy'] = array();
             }
             $value[$phid]['policy'] = $result + $value[$phid]['policy'];
             // Don't allow users to make policy edits which would lock them out of
             // applications, since they would be unable to undo those actions.
             PhabricatorEnv::overrideConfig($key, $value);
             PhabricatorPolicyFilter::mustRetainCapability($user, $application, PhabricatorPolicyCapability::CAN_VIEW);
             PhabricatorPolicyFilter::mustRetainCapability($user, $application, PhabricatorPolicyCapability::CAN_EDIT);
             PhabricatorConfigEditor::storeNewValue($user, $config_entry, $value, PhabricatorContentSource::newFromRequest($request));
         }
         return id(new AphrontRedirectResponse())->setURI($view_uri);
     }
     $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions($user, $application);
     $form = id(new AphrontFormView())->setUser($user);
     $locked_policies = PhabricatorEnv::getEnvConfig('policy.locked');
     foreach ($application->getCapabilities() as $capability) {
         $label = $application->getCapabilityLabel($capability);
         $can_edit = $application->isCapabilityEditable($capability);
         $locked = idx($locked_policies, $capability);
         $caption = $application->getCapabilityCaption($capability);
         if (!$can_edit || $locked) {
             $form->appendChild(id(new AphrontFormStaticControl())->setLabel($label)->setValue(idx($descriptions, $capability))->setCaption($caption));
         } else {
             $control = id(new AphrontFormPolicyControl())->setUser($user)->setDisabled($locked)->setCapability($capability)->setPolicyObject($application)->setPolicies($policies)->setLabel($label)->setName('policy:' . $capability)->setCaption($caption);
             $template = $application->getCapabilityTemplatePHIDType($capability);
             if ($template) {
                 $phid_types = PhabricatorPHIDType::getAllTypes();
                 $phid_type = idx($phid_types, $template);
                 if ($phid_type) {
                     $template_object = $phid_type->newObject();
                     if ($template_object) {
                         $template_policies = id(new PhabricatorPolicyQuery())->setViewer($user)->setObject($template_object)->execute();
                         // NOTE: We want to expose both any object template policies
                         // (like "Subscribers") and any custom policy.
                         $all_policies = $template_policies + $policies;
                         $control->setPolicies($all_policies);
                         $control->setTemplateObject($template_object);
                     }
                 }
                 $control->setTemplatePHIDType($template);
             }
             $form->appendControl($control);
         }
     }
     $form->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Policies'))->addCancelButton($view_uri));
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($application->getName(), $view_uri);
     $crumbs->addTextCrumb(pht('Edit Policies'));
     $header = id(new PHUIHeaderView())->setHeader(pht('Edit Policies: %s', $application->getName()));
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $object_box), array('title' => $title));
 }
 /**
  * If the datasource did not specify an icon explicitly, try to select a
  * default based on PHID type.
  */
 private function getDefaultIcon()
 {
     static $icon_map;
     if ($icon_map === null) {
         $types = PhabricatorPHIDType::getAllTypes();
         $map = array();
         foreach ($types as $type) {
             $icon = $type->getTypeIcon();
             if ($icon !== null) {
                 $map[$type->getTypeConstant()] = $icon;
             }
         }
         $icon_map = $map;
     }
     $phid_type = phid_get_type($this->phid);
     if (isset($icon_map[$phid_type])) {
         return $icon_map[$phid_type];
     }
     return null;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $object_phid = $request->getURIData('objectPHID');
     if ($object_phid) {
         $object = id(new PhabricatorObjectQuery())->setViewer($viewer)->withPHIDs(array($object_phid))->executeOne();
         if (!$object) {
             return new Aphront404Response();
         }
     } else {
         $object_type = $request->getURIData('objectType');
         if (!$object_type) {
             $object_type = $request->getURIData('templateType');
         }
         $phid_types = PhabricatorPHIDType::getAllInstalledTypes($viewer);
         if (empty($phid_types[$object_type])) {
             return new Aphront404Response();
         }
         $object = $phid_types[$object_type]->newObject();
         if (!$object) {
             return new Aphront404Response();
         }
     }
     $action_options = array(PhabricatorPolicy::ACTION_ALLOW => pht('Allow'), PhabricatorPolicy::ACTION_DENY => pht('Deny'));
     $rules = id(new PhutilClassMapQuery())->setAncestorClass('PhabricatorPolicyRule')->execute();
     foreach ($rules as $key => $rule) {
         if (!$rule->canApplyToObject($object)) {
             unset($rules[$key]);
         }
     }
     $rules = msort($rules, 'getRuleOrder');
     $default_rule = array('action' => head_key($action_options), 'rule' => head_key($rules), 'value' => null);
     $phid = $request->getURIData('phid');
     if ($phid) {
         $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->withPHIDs(array($phid))->execute();
         if (!$policies) {
             return new Aphront404Response();
         }
         $policy = head($policies);
     } else {
         $policy = id(new PhabricatorPolicy())->setRules(array($default_rule))->setDefaultAction(PhabricatorPolicy::ACTION_DENY);
     }
     $root_id = celerity_generate_unique_node_id();
     $default_action = $policy->getDefaultAction();
     $rule_data = $policy->getRules();
     $errors = array();
     if ($request->isFormPost()) {
         $data = $request->getStr('rules');
         try {
             $data = phutil_json_decode($data);
         } catch (PhutilJSONParserException $ex) {
             throw new PhutilProxyException(pht('Failed to JSON decode rule data!'), $ex);
         }
         $rule_data = array();
         foreach ($data as $rule) {
             $action = idx($rule, 'action');
             switch ($action) {
                 case 'allow':
                 case 'deny':
                     break;
                 default:
                     throw new Exception(pht("Invalid action '%s'!", $action));
             }
             $rule_class = idx($rule, 'rule');
             if (empty($rules[$rule_class])) {
                 throw new Exception(pht("Invalid rule class '%s'!", $rule_class));
             }
             $rule_obj = $rules[$rule_class];
             $value = $rule_obj->getValueForStorage(idx($rule, 'value'));
             $rule_data[] = array('action' => $action, 'rule' => $rule_class, 'value' => $value);
         }
         // Filter out nonsense rules, like a "users" rule without any users
         // actually specified.
         $valid_rules = array();
         foreach ($rule_data as $rule) {
             $rule_class = $rule['rule'];
             if ($rules[$rule_class]->ruleHasEffect($rule['value'])) {
                 $valid_rules[] = $rule;
             }
         }
         if (!$valid_rules) {
             $errors[] = pht('None of these policy rules have any effect.');
         }
         // NOTE: Policies are immutable once created, and we always create a new
         // policy here. If we didn't, we would need to lock this endpoint down,
         // as users could otherwise just go edit the policies of objects with
         // custom policies.
         if (!$errors) {
             $new_policy = new PhabricatorPolicy();
             $new_policy->setRules($valid_rules);
             $new_policy->setDefaultAction($request->getStr('default'));
             $new_policy->save();
             $data = array('phid' => $new_policy->getPHID(), 'info' => array('name' => $new_policy->getName(), 'full' => $new_policy->getName(), 'icon' => $new_policy->getIcon()));
             return id(new AphrontAjaxResponse())->setContent($data);
         }
     }
     // Convert rule values to display format (for example, expanding PHIDs
     // into tokens).
     foreach ($rule_data as $key => $rule) {
         $rule_data[$key]['value'] = $rules[$rule['rule']]->getValueForDisplay($viewer, $rule['value']);
     }
     $default_select = AphrontFormSelectControl::renderSelectTag($default_action, $action_options, array('name' => 'default'));
     if ($errors) {
         $errors = id(new PHUIInfoView())->setErrors($errors);
     }
     $form = id(new PHUIFormLayoutView())->appendChild($errors)->appendChild(javelin_tag('input', array('type' => 'hidden', 'name' => 'rules', 'sigil' => 'rules')))->appendChild(id(new PHUIFormInsetView())->setTitle(pht('Rules'))->setRightButton(javelin_tag('a', array('href' => '#', 'class' => 'button green', 'sigil' => 'create-rule', 'mustcapture' => true), pht('New Rule')))->setDescription(pht('These rules are processed in order.'))->setContent(javelin_tag('table', array('sigil' => 'rules', 'class' => 'policy-rules-table'), '')))->appendChild(id(new AphrontFormMarkupControl())->setLabel(pht('If No Rules Match'))->setValue(pht('%s all other users.', $default_select)));
     $form = phutil_tag('div', array('id' => $root_id), $form);
     $rule_options = mpull($rules, 'getRuleDescription');
     $type_map = mpull($rules, 'getValueControlType');
     $templates = mpull($rules, 'getValueControlTemplate');
     require_celerity_resource('policy-edit-css');
     Javelin::initBehavior('policy-rule-editor', array('rootID' => $root_id, 'actions' => $action_options, 'rules' => $rule_options, 'types' => $type_map, 'templates' => $templates, 'data' => $rule_data, 'defaultRule' => $default_rule));
     $title = pht('Custom Policy');
     $key = $request->getStr('capability');
     if ($key) {
         $capability = PhabricatorPolicyCapability::getCapabilityByKey($key);
         $title = pht('Custom "%s" Policy', $capability->getCapabilityName());
     }
     $dialog = id(new AphrontDialogView())->setWidth(AphrontDialogView::WIDTH_FULL)->setUser($viewer)->setTitle($title)->appendChild($form)->addSubmitButton(pht('Save Policy'))->addCancelButton('#');
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 public function testGetAllTypes()
 {
     PhabricatorPHIDType::getAllTypes();
     $this->assertTrue(true);
 }
 public static function getIndexableDocumentTypes(PhabricatorUser $viewer = null)
 {
     // TODO: This is inelegant and not very efficient, but gets us reasonable
     // results. It would be nice to do this more elegantly.
     $objects = id(new PhutilClassMapQuery())->setAncestorClass('PhabricatorFulltextInterface')->execute();
     $type_map = array();
     foreach ($objects as $object) {
         $phid_type = phid_get_type($object->generatePHID());
         $type_map[$phid_type] = $object;
     }
     if ($viewer) {
         $types = PhabricatorPHIDType::getAllInstalledTypes($viewer);
     } else {
         $types = PhabricatorPHIDType::getAllTypes();
     }
     $results = array();
     foreach ($types as $type) {
         $typeconst = $type->getTypeConstant();
         $object = idx($type_map, $typeconst);
         if ($object) {
             $results[$typeconst] = $type->getTypeName();
         }
     }
     asort($results);
     return $results;
 }
 protected function getPHIDType()
 {
     $types = PhabricatorPHIDType::getAllTypes();
     return idx($types, $this->getType());
 }
 public static function getIndexableDocumentTypes(PhabricatorUser $viewer = null)
 {
     // TODO: This is inelegant and not very efficient, but gets us reasonable
     // results. It would be nice to do this more elegantly.
     $indexers = id(new PhutilSymbolLoader())->setAncestorClass('PhabricatorSearchDocumentIndexer')->loadObjects();
     if ($viewer) {
         $types = PhabricatorPHIDType::getAllInstalledTypes($viewer);
     } else {
         $types = PhabricatorPHIDType::getAllTypes();
     }
     $results = array();
     foreach ($types as $type) {
         $typeconst = $type->getTypeConstant();
         foreach ($indexers as $indexer) {
             $fake_phid = 'PHID-' . $typeconst . '-fake';
             if ($indexer->shouldIndexDocumentByPHID($fake_phid)) {
                 $results[$typeconst] = $type->getTypeName();
             }
         }
     }
     asort($results);
     return $results;
 }