true, self::CONFIG_SERIALIZATION => array( 'subprojectPHIDs' => self::SERIALIZATION_JSON, ), ) + parent::getConfiguration(); } public function generatePHID() { return PhabricatorPHID::generateNewPHID( PhabricatorPHIDConstants::PHID_TYPE_PROJ); } public function loadProfile() { $profile = id(new PhabricatorProjectProfile())->loadOneWhere( 'projectPHID = %s', $this->getPHID()); return $profile; } public function attachMemberPHIDs(array $phids) { $this->memberPHIDs = $phids; return $this; } public function getMemberPHIDs() { if ($this->memberPHIDs === null) { throw new Exception("Call attachMemberPHIDs() first!"); } return $this->memberPHIDs; } public function loadMemberPHIDs() { if (!$this->getPHID()) { return array(); } return PhabricatorEdgeQuery::loadDestinationPHIDs( $this->getPHID(), PhabricatorEdgeConfig::TYPE_PROJ_MEMBER); } public function setPhrictionSlug($slug) { // NOTE: We're doing a little magic here and stripping out '/' so that // project pages always appear at top level under projects/ even if the // display name is "Hack / Slash" or similar (it will become // 'hack_slash' instead of 'hack/slash'). $slug = str_replace('/', ' ', $slug); $slug = PhabricatorSlug::normalize($slug); $this->phrictionSlug = $slug; return $this; } }