private function renderPolicyProperty(PhabricatorPolicyInterface $object)
 {
     $viewer = $this->getUser();
     $policies = PhabricatorPolicyQuery::loadPolicies($viewer, $object);
     $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
     $policy = idx($policies, $view_capability);
     if (!$policy) {
         return null;
     }
     // If an object is in a Space with a strictly stronger (more restrictive)
     // policy, we show the more restrictive policy. This better aligns the
     // UI hint with the actual behavior.
     // NOTE: We'll do this even if the viewer has access to only one space, and
     // show them information about the existence of spaces if they click
     // through.
     $use_space_policy = false;
     if ($object instanceof PhabricatorSpacesInterface) {
         $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object);
         $spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer);
         $space = idx($spaces, $space_phid);
         if ($space) {
             $space_policies = PhabricatorPolicyQuery::loadPolicies($viewer, $space);
             $space_policy = idx($space_policies, $view_capability);
             if ($space_policy) {
                 if ($space_policy->isStrongerThan($policy)) {
                     $policy = $space_policy;
                     $use_space_policy = true;
                 }
             }
         }
     }
     $container_classes = array();
     $container_classes[] = 'policy-header-callout';
     $phid = $object->getPHID();
     // If we're going to show the object policy, try to determine if the object
     // policy differs from the default policy. If it does, we'll call it out
     // as changed.
     if (!$use_space_policy) {
         $default_policy = PhabricatorPolicyQuery::getDefaultPolicyForObject($viewer, $object, $view_capability);
         if ($default_policy) {
             if ($default_policy->getPHID() != $policy->getPHID()) {
                 $container_classes[] = 'policy-adjusted';
                 if ($default_policy->isStrongerThan($policy)) {
                     // The policy has strictly been weakened. For example, the
                     // default might be "All Users" and the current policy is "Public".
                     $container_classes[] = 'policy-adjusted-weaker';
                 } else {
                     if ($policy->isStrongerThan($default_policy)) {
                         // The policy has strictly been strengthened, and is now more
                         // restrictive than the default. For example, "All Users" has
                         // been replaced with "No One".
                         $container_classes[] = 'policy-adjusted-stronger';
                     } else {
                         // The policy has been adjusted but not strictly strengthened
                         // or weakened. For example, "Members of X" has been replaced with
                         // "Members of Y".
                         $container_classes[] = 'policy-adjusted-different';
                     }
                 }
             }
         }
     }
     $policy_name = array($policy->getShortName());
     $policy_icon = $policy->getIcon() . ' bluegrey';
     if ($object instanceof PhabricatorPolicyCodexInterface) {
         $codex = PhabricatorPolicyCodex::newFromObject($object, $viewer);
         $codex_name = $codex->getPolicyShortName($policy, $view_capability);
         if ($codex_name !== null) {
             $policy_name = $codex_name;
         }
         $codex_icon = $codex->getPolicyIcon($policy, $view_capability);
         if ($codex_icon !== null) {
             $policy_icon = $codex_icon;
         }
         $codex_classes = $codex->getPolicyTagClasses($policy, $view_capability);
         foreach ($codex_classes as $codex_class) {
             $container_classes[] = $codex_class;
         }
     }
     if (!is_array($policy_name)) {
         $policy_name = (array) $policy_name;
     }
     $arrow = id(new PHUIIconView())->setIcon('fa-angle-right')->addClass('policy-tier-separator');
     $policy_name = phutil_implode_html($arrow, $policy_name);
     $icon = id(new PHUIIconView())->setIcon($policy_icon);
     $link = javelin_tag('a', array('class' => 'policy-link', 'href' => '/policy/explain/' . $phid . '/' . $view_capability . '/', 'sigil' => 'workflow'), $policy_name);
     return phutil_tag('span', array('class' => implode(' ', $container_classes)), array($icon, $link));
 }
 public static function getSpecialRules(PhabricatorPolicyInterface $object, PhabricatorUser $viewer, $capability, $active_only)
 {
     if ($object instanceof PhabricatorPolicyCodexInterface) {
         $codex = PhabricatorPolicyCodex::newFromObject($object, $viewer);
         $rules = $codex->getPolicySpecialRuleDescriptions();
         $exceptions = array();
         foreach ($rules as $rule) {
             $is_active = $rule->getIsActive();
             if ($is_active) {
                 $rule_capabilities = $rule->getCapabilities();
                 if ($rule_capabilities) {
                     if (!in_array($capability, $rule_capabilities)) {
                         $is_active = false;
                     }
                 }
             }
             if (!$is_active && $active_only) {
                 continue;
             }
             $description = $rule->getDescription();
             if (!$is_active) {
                 $description = phutil_tag('span', array('class' => 'phui-policy-section-view-inactive-rule'), $description);
             }
             $exceptions[] = $description;
         }
     } else {
         if (method_exists($object, 'describeAutomaticCapability')) {
             $exceptions = (array) $object->describeAutomaticCapability($capability);
             $exceptions = array_filter($exceptions);
         } else {
             $exceptions = array();
         }
     }
     return $exceptions;
 }