public function testSpacesSeveralSpaces()
 {
     $this->destroyAllSpaces();
     // Try creating a few spaces, one of which is a default space. This should
     // work fine.
     $actor = $this->generateNewTestUser();
     $default = $this->newSpace($actor, pht('Default Space'), true);
     $this->newSpace($actor, pht('Alternate Space'), false);
     $this->assertEqual(2, count($this->loadAllSpaces()));
     $this->assertEqual(2, count(PhabricatorSpacesNamespaceQuery::getAllSpaces()));
     $cache_default = PhabricatorSpacesNamespaceQuery::getDefaultSpace();
     $this->assertEqual($default->getPHID(), $cache_default->getPHID());
 }
 public function render()
 {
     $object = $this->getObject();
     $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object);
     if (!$space_phid) {
         return null;
     }
     // If the viewer can't see spaces, pretend they don't exist.
     $viewer = $this->getUser();
     if (!PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) {
         return null;
     }
     // If this is the default space, don't show a space label.
     $default = PhabricatorSpacesNamespaceQuery::getDefaultSpace();
     if ($default) {
         if ($default->getPHID() == $space_phid) {
             return null;
         }
     }
     return phutil_tag('span', array('class' => 'spaces-name'), array($viewer->renderHandle($space_phid)->setUseShortName(true), ' | '));
 }
 private function canViewerSeeObjectsInSpace(PhabricatorUser $viewer, $space_phid)
 {
     $spaces = PhabricatorSpacesNamespaceQuery::getAllSpaces();
     // If there are no spaces, everything exists in an implicit default space
     // with no policy controls. This is the default state.
     if (!$spaces) {
         if ($space_phid !== null) {
             return false;
         } else {
             return true;
         }
     }
     if ($space_phid === null) {
         $space = PhabricatorSpacesNamespaceQuery::getDefaultSpace();
     } else {
         $space = idx($spaces, $space_phid);
     }
     if (!$space) {
         return false;
     }
     // This may be more involved later, but for now being able to see the
     // space is equivalent to being able to see everything in it.
     return self::hasCapability($viewer, $space, PhabricatorPolicyCapability::CAN_VIEW);
 }
 private function getTransactionOldValue(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     $type = $xaction->getTransactionType();
     $xtype = $this->getModularTransactionType($type);
     if ($xtype) {
         return $xtype->generateOldValue($object);
     }
     switch ($type) {
         case PhabricatorTransactions::TYPE_CREATE:
             return null;
         case PhabricatorTransactions::TYPE_SUBSCRIBERS:
             return array_values($this->subscribers);
         case PhabricatorTransactions::TYPE_VIEW_POLICY:
             if ($this->getIsNewObject()) {
                 return null;
             }
             return $object->getViewPolicy();
         case PhabricatorTransactions::TYPE_EDIT_POLICY:
             if ($this->getIsNewObject()) {
                 return null;
             }
             return $object->getEditPolicy();
         case PhabricatorTransactions::TYPE_JOIN_POLICY:
             if ($this->getIsNewObject()) {
                 return null;
             }
             return $object->getJoinPolicy();
         case PhabricatorTransactions::TYPE_SPACE:
             if ($this->getIsNewObject()) {
                 return null;
             }
             $space_phid = $object->getSpacePHID();
             if ($space_phid === null) {
                 $default_space = PhabricatorSpacesNamespaceQuery::getDefaultSpace();
                 if ($default_space) {
                     $space_phid = $default_space->getPHID();
                 }
             }
             return $space_phid;
         case PhabricatorTransactions::TYPE_EDGE:
             $edge_type = $xaction->getMetadataValue('edge:type');
             if (!$edge_type) {
                 throw new Exception(pht("Edge transaction has no '%s'!", 'edge:type'));
             }
             $old_edges = array();
             if ($object->getPHID()) {
                 $edge_src = $object->getPHID();
                 $old_edges = id(new PhabricatorEdgeQuery())->withSourcePHIDs(array($edge_src))->withEdgeTypes(array($edge_type))->needEdgeData(true)->execute();
                 $old_edges = $old_edges[$edge_src][$edge_type];
             }
             return $old_edges;
         case PhabricatorTransactions::TYPE_CUSTOMFIELD:
             // NOTE: Custom fields have their old value pre-populated when they are
             // built by PhabricatorCustomFieldList.
             return $xaction->getOldValue();
         case PhabricatorTransactions::TYPE_COMMENT:
             return null;
         default:
             return $this->getCustomTransactionOldValue($object, $xaction);
     }
 }
 /**
  * Constrain the query to include only results in valid Spaces.
  *
  * This method builds part of a WHERE clause which considers the spaces the
  * viewer has access to see with any explicit constraint on spaces added by
  * @{method:withSpacePHIDs}.
  *
  * @param AphrontDatabaseConnection Database connection.
  * @return string Part of a WHERE clause.
  * @task spaces
  */
 private function buildSpacesWhereClause(AphrontDatabaseConnection $conn)
 {
     $object = $this->newResultObject();
     if (!$object) {
         return null;
     }
     if (!$object instanceof PhabricatorSpacesInterface) {
         return null;
     }
     $viewer = $this->getViewer();
     // If we have an omnipotent viewer and no formal space constraints, don't
     // emit a clause. This primarily enables older migrations to run cleanly,
     // without fataling because they try to match a `spacePHID` column which
     // does not exist yet. See T8743, T8746.
     if ($viewer->isOmnipotent()) {
         if ($this->spaceIsArchived === null && $this->spacePHIDs === null) {
             return null;
         }
     }
     $space_phids = array();
     $include_null = false;
     $all = PhabricatorSpacesNamespaceQuery::getAllSpaces();
     if (!$all) {
         // If there are no spaces at all, implicitly give the viewer access to
         // the default space.
         $include_null = true;
     } else {
         // Otherwise, give them access to the spaces they have permission to
         // see.
         $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer);
         foreach ($viewer_spaces as $viewer_space) {
             if ($this->spaceIsArchived !== null) {
                 if ($viewer_space->getIsArchived() != $this->spaceIsArchived) {
                     continue;
                 }
             }
             $phid = $viewer_space->getPHID();
             $space_phids[$phid] = $phid;
             if ($viewer_space->getIsDefaultNamespace()) {
                 $include_null = true;
             }
         }
     }
     // If we have additional explicit constraints, evaluate them now.
     if ($this->spacePHIDs !== null) {
         $explicit = array();
         $explicit_null = false;
         foreach ($this->spacePHIDs as $phid) {
             if ($phid === null) {
                 $space = PhabricatorSpacesNamespaceQuery::getDefaultSpace();
             } else {
                 $space = idx($all, $phid);
             }
             if ($space) {
                 $phid = $space->getPHID();
                 $explicit[$phid] = $phid;
                 if ($space->getIsDefaultNamespace()) {
                     $explicit_null = true;
                 }
             }
         }
         // If the viewer can see the default space but it isn't on the explicit
         // list of spaces to query, don't match it.
         if ($include_null && !$explicit_null) {
             $include_null = false;
         }
         // Include only the spaces common to the viewer and the constraints.
         $space_phids = array_intersect_key($space_phids, $explicit);
     }
     if (!$space_phids && !$include_null) {
         if ($this->spacePHIDs === null) {
             throw new PhabricatorEmptyQueryException(pht('You do not have access to any spaces.'));
         } else {
             throw new PhabricatorEmptyQueryException(pht('You do not have access to any of the spaces this query ' . 'is constrained to.'));
         }
     }
     $alias = $this->getPrimaryTableAlias();
     if ($alias) {
         $col = qsprintf($conn, '%T.spacePHID', $alias);
     } else {
         $col = 'spacePHID';
     }
     if ($space_phids && $include_null) {
         return qsprintf($conn, '(%Q IN (%Ls) OR %Q IS NULL)', $col, $space_phids, $col);
     } else {
         if ($space_phids) {
             return qsprintf($conn, '%Q IN (%Ls)', $col, $space_phids);
         } else {
             return qsprintf($conn, '%Q IS NULL', $col);
         }
     }
 }