@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 406 lines 11 kB view raw
1<?php 2 3final class PhameBlog extends PhameDAO 4 implements 5 PhabricatorPolicyInterface, 6 PhabricatorMarkupInterface, 7 PhabricatorSubscribableInterface, 8 PhabricatorFlaggableInterface, 9 PhabricatorProjectInterface, 10 PhabricatorDestructibleInterface, 11 PhabricatorApplicationTransactionInterface, 12 PhabricatorConduitResultInterface, 13 PhabricatorFulltextInterface, 14 PhabricatorFerretInterface { 15 16 protected $name; 17 protected $subtitle; 18 protected $description; 19 protected $domain; 20 protected $domainFullURI; 21 protected $parentSite; 22 protected $parentDomain; 23 protected $configData; 24 protected $creatorPHID; 25 protected $viewPolicy; 26 protected $editPolicy; 27 protected $interactPolicy; 28 protected $status; 29 protected $mailKey; 30 protected $profileImagePHID; 31 protected $headerImagePHID; 32 33 private $profileImageFile = self::ATTACHABLE; 34 private $headerImageFile = self::ATTACHABLE; 35 36 const STATUS_ACTIVE = 'active'; 37 const STATUS_ARCHIVED = 'archived'; 38 39 protected function getConfiguration() { 40 return array( 41 self::CONFIG_AUX_PHID => true, 42 self::CONFIG_SERIALIZATION => array( 43 'configData' => self::SERIALIZATION_JSON, 44 ), 45 self::CONFIG_COLUMN_SCHEMA => array( 46 'name' => 'text64', 47 'subtitle' => 'text64', 48 'description' => 'text', 49 'domain' => 'text128?', 50 'domainFullURI' => 'text128?', 51 'parentSite' => 'text128?', 52 'parentDomain' => 'text128?', 53 'status' => 'text32', 54 'mailKey' => 'bytes20', 55 'profileImagePHID' => 'phid?', 56 'headerImagePHID' => 'phid?', 57 58 'editPolicy' => 'policy', 59 'viewPolicy' => 'policy', 60 'interactPolicy' => 'policy', 61 ), 62 self::CONFIG_KEY_SCHEMA => array( 63 'key_phid' => null, 64 'phid' => array( 65 'columns' => array('phid'), 66 'unique' => true, 67 ), 68 'domain' => array( 69 'columns' => array('domain'), 70 'unique' => true, 71 ), 72 ), 73 ) + parent::getConfiguration(); 74 } 75 76 public function save() { 77 if (!$this->getMailKey()) { 78 $this->setMailKey(Filesystem::readRandomCharacters(20)); 79 } 80 return parent::save(); 81 } 82 83 public function generatePHID() { 84 return PhabricatorPHID::generateNewPHID( 85 PhabricatorPhameBlogPHIDType::TYPECONST); 86 } 87 88 public static function initializeNewBlog(PhabricatorUser $actor) { 89 $blog = id(new PhameBlog()) 90 ->setCreatorPHID($actor->getPHID()) 91 ->setStatus(self::STATUS_ACTIVE) 92 ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy()) 93 ->setEditPolicy(PhabricatorPolicies::POLICY_USER) 94 ->setInteractPolicy(PhabricatorPolicies::POLICY_USER); 95 96 return $blog; 97 } 98 99 public function isArchived() { 100 return ($this->getStatus() == self::STATUS_ARCHIVED); 101 } 102 103 public static function getStatusNameMap() { 104 return array( 105 self::STATUS_ACTIVE => pht('Active'), 106 self::STATUS_ARCHIVED => pht('Archived'), 107 ); 108 } 109 110 /** 111 * Makes sure a given custom blog uri is properly configured in DNS 112 * to point at this Phabricator instance. If there is an error in 113 * the configuration, return a string describing the error and how 114 * to fix it. If there is no error, return null. 115 * 116 * @return string|null 117 */ 118 public function validateCustomDomain($domain_full_uri) { 119 $example_domain = 'http://blog.example.com/'; 120 $label = pht('Invalid'); 121 122 // note this "uri" should be pretty busted given the desired input 123 // so just use it to test if there's a protocol specified 124 $uri = new PhutilURI($domain_full_uri); 125 $domain = $uri->getDomain(); 126 $protocol = $uri->getProtocol(); 127 $path = $uri->getPath(); 128 $supported_protocols = array('http', 'https'); 129 130 if (!in_array($protocol, $supported_protocols)) { 131 return pht( 132 'The custom domain should include a valid protocol in the URI '. 133 '(for example, "%s"). Valid protocols are "http" or "https".', 134 $example_domain); 135 } 136 137 if (strlen($path) && $path != '/') { 138 return pht( 139 'The custom domain should not specify a path (hosting a Phame '. 140 'blog at a path is currently not supported). Instead, just provide '. 141 'the bare domain name (for example, "%s").', 142 $example_domain); 143 } 144 145 if (strpos($domain, '.') === false) { 146 return pht( 147 'The custom domain should contain at least one dot (.) because '. 148 'some browsers fail to set cookies on domains without a dot. '. 149 'Instead, use a normal looking domain name like "%s".', 150 $example_domain); 151 } 152 153 if (!PhabricatorEnv::getEnvConfig('policy.allow-public')) { 154 $href = PhabricatorEnv::getProductionURI( 155 '/config/edit/policy.allow-public/'); 156 return pht( 157 'For custom domains to work, this server must be '. 158 'configured to allow the public access policy. Configure this '. 159 'setting %s, or ask an administrator to configure this setting. '. 160 'The domain can be specified later once this setting has been '. 161 'changed.', 162 phutil_tag( 163 'a', 164 array('href' => $href), 165 pht('here'))); 166 } 167 168 return null; 169 } 170 171 public function getLiveURI() { 172 if (phutil_nonempty_string($this->getDomain())) { 173 return $this->getExternalLiveURI(); 174 } else { 175 return $this->getInternalLiveURI(); 176 } 177 } 178 179 public function getExternalLiveURI() { 180 $uri = new PhutilURI($this->getDomainFullURI()); 181 PhabricatorEnv::requireValidRemoteURIForLink($uri); 182 return (string)$uri; 183 } 184 185 public function getExternalParentURI() { 186 $uri = $this->getParentDomain(); 187 PhabricatorEnv::requireValidRemoteURIForLink($uri); 188 return (string)$uri; 189 } 190 191 public function getInternalLiveURI() { 192 return '/phame/live/'.$this->getID().'/'; 193 } 194 195 public function getViewURI() { 196 return '/phame/blog/view/'.$this->getID().'/'; 197 } 198 199 public function getManageURI() { 200 return '/phame/blog/manage/'.$this->getID().'/'; 201 } 202 203 /** 204 * Get relative URI of Phame blog feed. 205 * 206 * @return string Relative URI of Phame blog feed 207 */ 208 public function getFeedURI() { 209 return '/phame/blog/feed/'.$this->getID().'/'; 210 } 211 212 public function getProfileImageURI() { 213 return $this->getProfileImageFile()->getBestURI(); 214 } 215 216 public function attachProfileImageFile(PhabricatorFile $file) { 217 $this->profileImageFile = $file; 218 return $this; 219 } 220 221 public function getProfileImageFile() { 222 return $this->assertAttached($this->profileImageFile); 223 } 224 225 public function getHeaderImageURI() { 226 return $this->getHeaderImageFile()->getBestURI(); 227 } 228 229 public function attachHeaderImageFile(PhabricatorFile $file) { 230 $this->headerImageFile = $file; 231 return $this; 232 } 233 234 public function getHeaderImageFile() { 235 return $this->assertAttached($this->headerImageFile); 236 } 237 238 239/* -( PhabricatorPolicyInterface Implementation )-------------------------- */ 240 241 242 public function getCapabilities() { 243 return array( 244 PhabricatorPolicyCapability::CAN_VIEW, 245 PhabricatorPolicyCapability::CAN_INTERACT, 246 PhabricatorPolicyCapability::CAN_EDIT, 247 ); 248 } 249 250 251 public function getPolicy($capability) { 252 switch ($capability) { 253 case PhabricatorPolicyCapability::CAN_VIEW: 254 return $this->getViewPolicy(); 255 case PhabricatorPolicyCapability::CAN_INTERACT: 256 return $this->getInteractPolicy(); 257 case PhabricatorPolicyCapability::CAN_EDIT: 258 return $this->getEditPolicy(); 259 } 260 } 261 262 public function hasAutomaticCapability($capability, PhabricatorUser $user) { 263 $can_edit = PhabricatorPolicyCapability::CAN_EDIT; 264 265 switch ($capability) { 266 case PhabricatorPolicyCapability::CAN_VIEW: 267 // Users who can edit or post to a blog can always view it. 268 if (PhabricatorPolicyFilter::hasCapability($user, $this, $can_edit)) { 269 return true; 270 } 271 break; 272 } 273 274 return false; 275 } 276 277 278 public function describeAutomaticCapability($capability) { 279 switch ($capability) { 280 case PhabricatorPolicyCapability::CAN_VIEW: 281 return pht( 282 'Users who can edit a blog can always view it.'); 283 } 284 285 return null; 286 } 287 288 289/* -( PhabricatorMarkupInterface Implementation )-------------------------- */ 290 291 292 public function getMarkupFieldKey($field) { 293 $content = $this->getMarkupText($field); 294 return PhabricatorMarkupEngine::digestRemarkupContent($this, $content); 295 } 296 297 298 public function newMarkupEngine($field) { 299 return PhabricatorMarkupEngine::newPhameMarkupEngine(); 300 } 301 302 303 public function getMarkupText($field) { 304 return $this->getDescription(); 305 } 306 307 308 public function didMarkupText( 309 $field, 310 $output, 311 PhutilMarkupEngine $engine) { 312 return $output; 313 } 314 315 public function shouldUseMarkupCache($field) { 316 return (bool)$this->getPHID(); 317 } 318 319/* -( PhabricatorDestructibleInterface )----------------------------------- */ 320 321 public function destroyObjectPermanently( 322 PhabricatorDestructionEngine $engine) { 323 324 $this->openTransaction(); 325 326 $posts = id(new PhamePostQuery()) 327 ->setViewer($engine->getViewer()) 328 ->withBlogPHIDs(array($this->getPHID())) 329 ->execute(); 330 foreach ($posts as $post) { 331 $engine->destroyObject($post); 332 } 333 $this->delete(); 334 335 $this->saveTransaction(); 336 } 337 338 339/* -( PhabricatorApplicationTransactionInterface )------------------------- */ 340 341 342 public function getApplicationTransactionEditor() { 343 return new PhameBlogEditor(); 344 } 345 346 public function getApplicationTransactionTemplate() { 347 return new PhameBlogTransaction(); 348 } 349 350 351/* -( PhabricatorSubscribableInterface Implementation )-------------------- */ 352 353 354 public function isAutomaticallySubscribed($phid) { 355 return false; 356 } 357 358 359/* -( PhabricatorConduitResultInterface )---------------------------------- */ 360 361 362 public function getFieldSpecificationsForConduit() { 363 return array( 364 id(new PhabricatorConduitSearchFieldSpecification()) 365 ->setKey('name') 366 ->setType('string') 367 ->setDescription(pht('The name of the blog.')), 368 id(new PhabricatorConduitSearchFieldSpecification()) 369 ->setKey('description') 370 ->setType('string') 371 ->setDescription(pht('Blog description.')), 372 id(new PhabricatorConduitSearchFieldSpecification()) 373 ->setKey('status') 374 ->setType('string') 375 ->setDescription(pht('Archived or active status.')), 376 ); 377 } 378 379 public function getFieldValuesForConduit() { 380 return array( 381 'name' => $this->getName(), 382 'description' => $this->getDescription(), 383 'status' => $this->getStatus(), 384 ); 385 } 386 387 public function getConduitSearchAttachments() { 388 return array(); 389 } 390 391 392/* -( PhabricatorFulltextInterface )--------------------------------------- */ 393 394 public function newFulltextEngine() { 395 return new PhameBlogFulltextEngine(); 396 } 397 398 399/* -( PhabricatorFerretInterface )----------------------------------------- */ 400 401 402 public function newFerretEngine() { 403 return new PhameBlogFerretEngine(); 404 } 405 406}