@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.

Add Open Graph protocol meta tags to Maniphest task pages

Summary:
Add OGP <meta> tags to Maniphest task pages when the task is publicly accessible and anonymously accessed. See https://ogp.me/

Based on rP2c72c2b924ffa3f8a49dbec636a2cdca3bae004f reverted in rP49b57eae7df52c189aef1d973823c697fc97fd4b.

Closes T15472

Test Plan:
* Use the default Phorge logo, open a Maniphest task, look at the headers in its HTML.
* Set a custom Phorge logo via `config/edit/ui.logo/`.
* Access a task with "View Policy: All Users" while logged in: No OGP headers included.
* Access a task with "View Policy: Public" while logged in: No OGP headers included.
* Access a task with "View Policy: All Users" while logged out: No OGP headers included; "Access Denied: Restricted Maniphest Task" displayed.
* Access a task with "View Policy: Public" while logged out: OGP headers included.
* Access a task with "View Policy: Public" while logged out with a task description and a task without a task description: OGP headers included.

Reviewers: O1 Blessed Committers, valerio.bozzolan

Reviewed By: O1 Blessed Committers, valerio.bozzolan

Subscribers: avivey, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno

Maniphest Tasks: T15472

Differential Revision: https://we.phorge.it/D25668

+114 -31
+39
src/applications/config/custom/PhabricatorCustomLogoConfigType.php
··· 13 13 return idx($logo, 'wordmarkText'); 14 14 } 15 15 16 + /** 17 + * Return the full URI of the Phorge logo 18 + * @param PhabricatorUser Current viewer 19 + * @return string Full URI of the Phorge logo 20 + */ 21 + public static function getLogoURI(PhabricatorUser $viewer) { 22 + $logo_uri = null; 23 + 24 + $custom_header = self::getLogoImagePHID(); 25 + if ($custom_header) { 26 + $cache = PhabricatorCaches::getImmutableCache(); 27 + $cache_key_logo = 'ui.custom-header.logo-phid.v3.'.$custom_header; 28 + $logo_uri = $cache->getKey($cache_key_logo); 29 + 30 + if (!$logo_uri) { 31 + // NOTE: If the file policy has been changed to be restrictive, we'll 32 + // miss here and just show the default logo. The cache will fill later 33 + // when someone who can see the file loads the page. This might be a 34 + // little spooky, see T11982. 35 + $files = id(new PhabricatorFileQuery()) 36 + ->setViewer($viewer) 37 + ->withPHIDs(array($custom_header)) 38 + ->execute(); 39 + $file = head($files); 40 + if ($file) { 41 + $logo_uri = $file->getViewURI(); 42 + $cache->setKey($cache_key_logo, $logo_uri); 43 + } 44 + } 45 + } 46 + 47 + if (!$logo_uri) { 48 + $logo_uri = 49 + celerity_get_resource_uri('/rsrc/image/logo/project-logo.png'); 50 + } 51 + 52 + return $logo_uri; 53 + } 54 + 16 55 public function validateOption(PhabricatorConfigOption $option, $value) { 17 56 if (!is_array($value)) { 18 57 throw new Exception(
+69 -2
src/applications/maniphest/controller/ManiphestTaskDetailController.php
··· 203 203 ->addPropertySection(pht('Description'), $description) 204 204 ->addPropertySection(pht('Details'), $details); 205 205 206 - 207 - return $this->newPage() 206 + $page = $this->newPage() 208 207 ->setTitle($title) 209 208 ->setCrumbs($crumbs) 210 209 ->setPageObjectPHIDs( ··· 213 212 )) 214 213 ->appendChild($view); 215 214 215 + if ($this->getIncludeOpenGraphMetadata($viewer, $task)) { 216 + $page = $this->addOpenGraphProtocolMetadataTags($page, $task); 217 + } 218 + 219 + return $page; 220 + } 221 + 222 + /** 223 + * Whether the page should include Open Graph metadata tags 224 + * @param PhabricatorUser $viewer Viewer of the object 225 + * @param object $object 226 + * @return bool True if the page should serve Open Graph metadata tags 227 + */ 228 + private function getIncludeOpenGraphMetadata(PhabricatorUser $viewer, 229 + $object) { 230 + // Don't waste time adding OpenGraph metadata for logged-in users 231 + if ($viewer->getIsStandardUser()) { 232 + return false; 233 + } 234 + // Include OpenGraph tags only for public objects 235 + return $object->getViewPolicy() === PhabricatorPolicies::POLICY_PUBLIC; 236 + } 237 + 238 + /** 239 + * Get Open Graph Protocol metadata values 240 + * @param ManiphestTask $task 241 + * @return array Map of Open Graph property => value 242 + */ 243 + private function getOpenGraphProtocolMetadataValues($task) { 244 + $viewer = $this->getViewer(); 245 + 246 + $v = []; 247 + $v['og:site_name'] = PlatformSymbols::getPlatformServerName(); 248 + $v['og:type'] = 'object'; 249 + $v['og:url'] = PhabricatorEnv::getProductionURI($task->getURI()); 250 + $v['og:title'] = $task->getMonogram().' '.$task->getTitle(); 251 + 252 + $desc = $task->getDescription(); 253 + if (phutil_nonempty_string($desc)) { 254 + $v['og:description'] = 255 + PhabricatorMarkupEngine::summarizeSentence($desc); 256 + } 257 + 258 + $v['og:image'] = 259 + PhabricatorCustomLogoConfigType::getLogoURI($viewer); 260 + 261 + $v['og:image:height'] = 64; 262 + $v['og:image:width'] = 64; 263 + 264 + return $v; 265 + } 266 + 267 + /** 268 + * Add Open Graph Protocol metadata tags to Maniphest task page 269 + * @param PhabricatorStandardPageView $page 270 + * @param ManiphestTask $task 271 + * @return $page with additional OGP <meta> tags 272 + */ 273 + private function addOpenGraphProtocolMetadataTags($page, $task) { 274 + foreach ($this->getOpenGraphProtocolMetadataValues($task) as $k => $v) { 275 + $page->addHeadItem(phutil_tag( 276 + 'meta', 277 + array( 278 + 'property' => $k, 279 + 'content' => $v, 280 + ))); 281 + } 282 + return $page; 216 283 } 217 284 218 285 private function buildHeaderView(ManiphestTask $task) {
-1
src/view/page/PhabricatorStandardPageView.php
··· 378 378 379 379 /** 380 380 * Insert a HTML element into <head> of the page to render. 381 - * Used by PhameBlogViewController. 382 381 * 383 382 * @param PhutilSafeHTML HTML header to add 384 383 */
+6 -28
src/view/page/menu/PhabricatorMainMenuView.php
··· 293 293 } 294 294 295 295 private function renderPhabricatorLogo() { 296 + $logo_style = array(); 296 297 $custom_header = PhabricatorCustomLogoConfigType::getLogoImagePHID(); 297 - 298 - $logo_style = array(); 299 298 if ($custom_header) { 300 - $cache = PhabricatorCaches::getImmutableCache(); 301 - $cache_key_logo = 'ui.custom-header.logo-phid.v3.'.$custom_header; 302 - 303 - $logo_uri = $cache->getKey($cache_key_logo); 304 - if (!$logo_uri) { 305 - // NOTE: If the file policy has been changed to be restrictive, we'll 306 - // miss here and just show the default logo. The cache will fill later 307 - // when someone who can see the file loads the page. This might be a 308 - // little spooky, see T11982. 309 - $files = id(new PhabricatorFileQuery()) 310 - ->setViewer($this->getViewer()) 311 - ->withPHIDs(array($custom_header)) 312 - ->execute(); 313 - $file = head($files); 314 - if ($file) { 315 - $logo_uri = $file->getViewURI(); 316 - $cache->setKey($cache_key_logo, $logo_uri); 317 - } 318 - } 319 - 320 - if ($logo_uri) { 321 - $logo_style[] = 'background-size: 40px 40px;'; 322 - $logo_style[] = 'background-position: 0 0;'; 323 - $logo_style[] = 'background-image: url('.$logo_uri.')'; 324 - } 299 + $viewer = $this->getViewer(); 300 + $logo_uri = PhabricatorCustomLogoConfigType::getLogoURI($viewer); 301 + $logo_style[] = 'background-size: 40px 40px;'; 302 + $logo_style[] = 'background-position: 0 0;'; 303 + $logo_style[] = 'background-image: url('.$logo_uri.')'; 325 304 } 326 305 327 306 $logo_node = phutil_tag( ··· 330 309 'class' => 'phabricator-main-menu-project-logo', 331 310 'style' => implode(' ', $logo_style), 332 311 )); 333 - 334 312 335 313 $wordmark_text = PhabricatorCustomLogoConfigType::getLogoWordmark(); 336 314 if (!phutil_nonempty_string($wordmark_text)) {