@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 323 lines 8.3 kB view raw
1<?php 2 3final class PhrictionDocument extends PhrictionDAO 4 implements 5 PhabricatorPolicyInterface, 6 PhabricatorSubscribableInterface, 7 PhabricatorFlaggableInterface, 8 PhabricatorTokenReceiverInterface, 9 PhabricatorDestructibleInterface, 10 PhabricatorFulltextInterface, 11 PhabricatorFerretInterface, 12 PhabricatorProjectInterface, 13 PhabricatorApplicationTransactionInterface, 14 PhabricatorConduitResultInterface, 15 PhabricatorPolicyCodexInterface, 16 PhabricatorSpacesInterface { 17 18 protected $slug; 19 protected $depth; 20 protected $contentPHID; 21 protected $status; 22 protected $viewPolicy; 23 protected $editPolicy; 24 protected $spacePHID; 25 protected $editedEpoch; 26 protected $maxVersion; 27 28 private $contentObject = self::ATTACHABLE; 29 private $ancestors = array(); 30 31 protected function getConfiguration() { 32 return array( 33 self::CONFIG_AUX_PHID => true, 34 self::CONFIG_TIMESTAMPS => false, 35 self::CONFIG_COLUMN_SCHEMA => array( 36 'slug' => 'sort128', 37 'depth' => 'uint32', 38 'status' => 'text32', 39 'editedEpoch' => 'epoch', 40 'maxVersion' => 'uint32', 41 ), 42 self::CONFIG_KEY_SCHEMA => array( 43 'slug' => array( 44 'columns' => array('slug'), 45 'unique' => true, 46 ), 47 'depth' => array( 48 'columns' => array('depth', 'slug'), 49 'unique' => true, 50 ), 51 ), 52 ) + parent::getConfiguration(); 53 } 54 55 public function getPHIDType() { 56 return PhrictionDocumentPHIDType::TYPECONST; 57 } 58 59 public static function initializeNewDocument(PhabricatorUser $actor, $slug) { 60 $document = id(new self()) 61 ->setSlug($slug); 62 63 $content = id(new PhrictionContent()) 64 ->setSlug($slug); 65 66 $default_title = PhabricatorSlug::getDefaultTitle($slug); 67 $content->setTitle($default_title); 68 $document->attachContent($content); 69 70 $parent_doc = null; 71 $ancestral_slugs = PhabricatorSlug::getAncestry($slug); 72 if ($ancestral_slugs) { 73 $parent = end($ancestral_slugs); 74 $parent_doc = id(new PhrictionDocumentQuery()) 75 ->setViewer($actor) 76 ->withSlugs(array($parent)) 77 ->executeOne(); 78 } 79 80 if ($parent_doc) { 81 $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( 82 $parent_doc); 83 84 $document 85 ->setViewPolicy($parent_doc->getViewPolicy()) 86 ->setEditPolicy($parent_doc->getEditPolicy()) 87 ->setSpacePHID($space_phid); 88 } else { 89 $default_view_policy = PhabricatorPolicies::getMostOpenPolicy(); 90 $document 91 ->setViewPolicy($default_view_policy) 92 ->setEditPolicy(PhabricatorPolicies::POLICY_USER) 93 ->setSpacePHID($actor->getDefaultSpacePHID()); 94 } 95 96 $document->setEditedEpoch(PhabricatorTime::getNow()); 97 $document->setMaxVersion(0); 98 99 return $document; 100 } 101 102 public static function getSlugURI($slug, $type = 'document') { 103 static $types = array( 104 'document' => '/w/', 105 'history' => '/phriction/history/', 106 ); 107 108 if (empty($types[$type])) { 109 throw new Exception(pht("Unknown URI type '%s'!", $type)); 110 } 111 112 $prefix = $types[$type]; 113 114 if ($slug == '/') { 115 return $prefix; 116 } else { 117 // NOTE: The effect here is to escape non-latin characters, since modern 118 // browsers deal with escaped UTF8 characters in a reasonable way (showing 119 // the user a readable URI) but older programs may not. 120 $slug = phutil_escape_uri($slug); 121 return $prefix.$slug; 122 } 123 } 124 125 public function setSlug($slug) { 126 $this->slug = PhabricatorSlug::normalize($slug); 127 $this->depth = PhabricatorSlug::getDepth($slug); 128 return $this; 129 } 130 131 public function attachContent(PhrictionContent $content) { 132 $this->contentObject = $content; 133 return $this; 134 } 135 136 public function getContent() { 137 return $this->assertAttached($this->contentObject); 138 } 139 140 public function getAncestors() { 141 return $this->ancestors; 142 } 143 144 public function getAncestor($slug) { 145 return $this->assertAttachedKey($this->ancestors, $slug); 146 } 147 148 public function attachAncestor($slug, $ancestor) { 149 $this->ancestors[$slug] = $ancestor; 150 return $this; 151 } 152 153 public function getURI() { 154 return self::getSlugURI($this->getSlug()); 155 } 156 157/* -( Status )------------------------------------------------------------- */ 158 159 160 public function getStatusObject() { 161 return PhrictionDocumentStatus::newStatusObject($this->getStatus()); 162 } 163 164 public function getStatusIcon() { 165 return $this->getStatusObject()->getIcon(); 166 } 167 168 public function getStatusColor() { 169 return $this->getStatusObject()->getColor(); 170 } 171 172 public function getStatusDisplayName() { 173 return $this->getStatusObject()->getDisplayName(); 174 } 175 176 public function isActive() { 177 return $this->getStatusObject()->isActive(); 178 } 179 180 181/* -( PhabricatorPolicyInterface )----------------------------------------- */ 182 183 184 public function getCapabilities() { 185 return array( 186 PhabricatorPolicyCapability::CAN_VIEW, 187 PhabricatorPolicyCapability::CAN_EDIT, 188 ); 189 } 190 191 public function getPolicy($capability) { 192 switch ($capability) { 193 case PhabricatorPolicyCapability::CAN_VIEW: 194 return $this->getViewPolicy(); 195 case PhabricatorPolicyCapability::CAN_EDIT: 196 return $this->getEditPolicy(); 197 } 198 } 199 200 public function hasAutomaticCapability($capability, PhabricatorUser $user) { 201 return false; 202 } 203 204 205/* -( PhabricatorSpacesInterface )----------------------------------------- */ 206 207 208 public function getSpacePHID() { 209 return $this->spacePHID; 210 } 211 212 213 214/* -( PhabricatorSubscribableInterface )----------------------------------- */ 215 216 217 public function isAutomaticallySubscribed($phid) { 218 return false; 219 } 220 221 222/* -( PhabricatorApplicationTransactionInterface )------------------------- */ 223 224 225 public function getApplicationTransactionEditor() { 226 return new PhrictionTransactionEditor(); 227 } 228 229 public function getApplicationTransactionTemplate() { 230 return new PhrictionTransaction(); 231 } 232 233 234/* -( PhabricatorTokenReceiverInterface )---------------------------------- */ 235 236 237 public function getUsersToNotifyOfTokenGiven() { 238 return PhabricatorSubscribersQuery::loadSubscribersForPHID($this->phid); 239 } 240 241 242/* -( PhabricatorDestructibleInterface )----------------------------------- */ 243 244 245 public function destroyObjectPermanently( 246 PhabricatorDestructionEngine $engine) { 247 248 $this->openTransaction(); 249 250 $contents = id(new PhrictionContentQuery()) 251 ->setViewer($engine->getViewer()) 252 ->withDocumentPHIDs(array($this->getPHID())) 253 ->execute(); 254 foreach ($contents as $content) { 255 $engine->destroyObject($content); 256 } 257 258 $this->delete(); 259 260 $this->saveTransaction(); 261 } 262 263 264/* -( PhabricatorFulltextInterface )--------------------------------------- */ 265 266 267 public function newFulltextEngine() { 268 return new PhrictionDocumentFulltextEngine(); 269 } 270 271 272/* -( PhabricatorFerretInterface )----------------------------------------- */ 273 274 275 public function newFerretEngine() { 276 return new PhrictionDocumentFerretEngine(); 277 } 278 279 280/* -( PhabricatorConduitResultInterface )---------------------------------- */ 281 282 283 public function getFieldSpecificationsForConduit() { 284 return array( 285 id(new PhabricatorConduitSearchFieldSpecification()) 286 ->setKey('path') 287 ->setType('string') 288 ->setDescription(pht('The path to the document.')), 289 id(new PhabricatorConduitSearchFieldSpecification()) 290 ->setKey('status') 291 ->setType('map<string, wild>') 292 ->setDescription(pht('Status information about the document.')), 293 ); 294 } 295 296 public function getFieldValuesForConduit() { 297 $status = array( 298 'value' => $this->getStatus(), 299 'name' => $this->getStatusDisplayName(), 300 ); 301 302 return array( 303 'path' => $this->getSlug(), 304 'status' => $status, 305 ); 306 } 307 308 public function getConduitSearchAttachments() { 309 return array( 310 id(new PhrictionContentSearchEngineAttachment()) 311 ->setAttachmentKey('content'), 312 ); 313 } 314 315/* -( PhabricatorPolicyCodexInterface )------------------------------------ */ 316 317 318 public function newPolicyCodex() { 319 return new PhrictionDocumentPolicyCodex(); 320 } 321 322 323}