mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +01:00
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
This commit is contained in:
parent
1cc04fb83c
commit
89778dc9e6
4 changed files with 114 additions and 31 deletions
|
@ -13,6 +13,45 @@ final class PhabricatorCustomLogoConfigType
|
||||||
return idx($logo, 'wordmarkText');
|
return idx($logo, 'wordmarkText');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the full URI of the Phorge logo
|
||||||
|
* @param PhabricatorUser Current viewer
|
||||||
|
* @return string Full URI of the Phorge logo
|
||||||
|
*/
|
||||||
|
public static function getLogoURI(PhabricatorUser $viewer) {
|
||||||
|
$logo_uri = null;
|
||||||
|
|
||||||
|
$custom_header = self::getLogoImagePHID();
|
||||||
|
if ($custom_header) {
|
||||||
|
$cache = PhabricatorCaches::getImmutableCache();
|
||||||
|
$cache_key_logo = 'ui.custom-header.logo-phid.v3.'.$custom_header;
|
||||||
|
$logo_uri = $cache->getKey($cache_key_logo);
|
||||||
|
|
||||||
|
if (!$logo_uri) {
|
||||||
|
// NOTE: If the file policy has been changed to be restrictive, we'll
|
||||||
|
// miss here and just show the default logo. The cache will fill later
|
||||||
|
// when someone who can see the file loads the page. This might be a
|
||||||
|
// little spooky, see T11982.
|
||||||
|
$files = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($custom_header))
|
||||||
|
->execute();
|
||||||
|
$file = head($files);
|
||||||
|
if ($file) {
|
||||||
|
$logo_uri = $file->getViewURI();
|
||||||
|
$cache->setKey($cache_key_logo, $logo_uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$logo_uri) {
|
||||||
|
$logo_uri =
|
||||||
|
celerity_get_resource_uri('/rsrc/image/logo/project-logo.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $logo_uri;
|
||||||
|
}
|
||||||
|
|
||||||
public function validateOption(PhabricatorConfigOption $option, $value) {
|
public function validateOption(PhabricatorConfigOption $option, $value) {
|
||||||
if (!is_array($value)) {
|
if (!is_array($value)) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
|
|
@ -203,8 +203,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||||
->addPropertySection(pht('Description'), $description)
|
->addPropertySection(pht('Description'), $description)
|
||||||
->addPropertySection(pht('Details'), $details);
|
->addPropertySection(pht('Details'), $details);
|
||||||
|
|
||||||
|
$page = $this->newPage()
|
||||||
return $this->newPage()
|
|
||||||
->setTitle($title)
|
->setTitle($title)
|
||||||
->setCrumbs($crumbs)
|
->setCrumbs($crumbs)
|
||||||
->setPageObjectPHIDs(
|
->setPageObjectPHIDs(
|
||||||
|
@ -213,6 +212,74 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||||
))
|
))
|
||||||
->appendChild($view);
|
->appendChild($view);
|
||||||
|
|
||||||
|
if ($this->getIncludeOpenGraphMetadata($viewer, $task)) {
|
||||||
|
$page = $this->addOpenGraphProtocolMetadataTags($page, $task);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the page should include Open Graph metadata tags
|
||||||
|
* @param PhabricatorUser $viewer Viewer of the object
|
||||||
|
* @param object $object
|
||||||
|
* @return bool True if the page should serve Open Graph metadata tags
|
||||||
|
*/
|
||||||
|
private function getIncludeOpenGraphMetadata(PhabricatorUser $viewer,
|
||||||
|
$object) {
|
||||||
|
// Don't waste time adding OpenGraph metadata for logged-in users
|
||||||
|
if ($viewer->getIsStandardUser()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Include OpenGraph tags only for public objects
|
||||||
|
return $object->getViewPolicy() === PhabricatorPolicies::POLICY_PUBLIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Open Graph Protocol metadata values
|
||||||
|
* @param ManiphestTask $task
|
||||||
|
* @return array Map of Open Graph property => value
|
||||||
|
*/
|
||||||
|
private function getOpenGraphProtocolMetadataValues($task) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$v = [];
|
||||||
|
$v['og:site_name'] = PlatformSymbols::getPlatformServerName();
|
||||||
|
$v['og:type'] = 'object';
|
||||||
|
$v['og:url'] = PhabricatorEnv::getProductionURI($task->getURI());
|
||||||
|
$v['og:title'] = $task->getMonogram().' '.$task->getTitle();
|
||||||
|
|
||||||
|
$desc = $task->getDescription();
|
||||||
|
if (phutil_nonempty_string($desc)) {
|
||||||
|
$v['og:description'] =
|
||||||
|
PhabricatorMarkupEngine::summarizeSentence($desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
$v['og:image'] =
|
||||||
|
PhabricatorCustomLogoConfigType::getLogoURI($viewer);
|
||||||
|
|
||||||
|
$v['og:image:height'] = 64;
|
||||||
|
$v['og:image:width'] = 64;
|
||||||
|
|
||||||
|
return $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Open Graph Protocol metadata tags to Maniphest task page
|
||||||
|
* @param PhabricatorStandardPageView $page
|
||||||
|
* @param ManiphestTask $task
|
||||||
|
* @return $page with additional OGP <meta> tags
|
||||||
|
*/
|
||||||
|
private function addOpenGraphProtocolMetadataTags($page, $task) {
|
||||||
|
foreach ($this->getOpenGraphProtocolMetadataValues($task) as $k => $v) {
|
||||||
|
$page->addHeadItem(phutil_tag(
|
||||||
|
'meta',
|
||||||
|
array(
|
||||||
|
'property' => $k,
|
||||||
|
'content' => $v,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
return $page;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildHeaderView(ManiphestTask $task) {
|
private function buildHeaderView(ManiphestTask $task) {
|
||||||
|
|
|
@ -378,7 +378,6 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a HTML element into <head> of the page to render.
|
* Insert a HTML element into <head> of the page to render.
|
||||||
* Used by PhameBlogViewController.
|
|
||||||
*
|
*
|
||||||
* @param PhutilSafeHTML HTML header to add
|
* @param PhutilSafeHTML HTML header to add
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -293,36 +293,15 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function renderPhabricatorLogo() {
|
private function renderPhabricatorLogo() {
|
||||||
$custom_header = PhabricatorCustomLogoConfigType::getLogoImagePHID();
|
|
||||||
|
|
||||||
$logo_style = array();
|
$logo_style = array();
|
||||||
|
$custom_header = PhabricatorCustomLogoConfigType::getLogoImagePHID();
|
||||||
if ($custom_header) {
|
if ($custom_header) {
|
||||||
$cache = PhabricatorCaches::getImmutableCache();
|
$viewer = $this->getViewer();
|
||||||
$cache_key_logo = 'ui.custom-header.logo-phid.v3.'.$custom_header;
|
$logo_uri = PhabricatorCustomLogoConfigType::getLogoURI($viewer);
|
||||||
|
|
||||||
$logo_uri = $cache->getKey($cache_key_logo);
|
|
||||||
if (!$logo_uri) {
|
|
||||||
// NOTE: If the file policy has been changed to be restrictive, we'll
|
|
||||||
// miss here and just show the default logo. The cache will fill later
|
|
||||||
// when someone who can see the file loads the page. This might be a
|
|
||||||
// little spooky, see T11982.
|
|
||||||
$files = id(new PhabricatorFileQuery())
|
|
||||||
->setViewer($this->getViewer())
|
|
||||||
->withPHIDs(array($custom_header))
|
|
||||||
->execute();
|
|
||||||
$file = head($files);
|
|
||||||
if ($file) {
|
|
||||||
$logo_uri = $file->getViewURI();
|
|
||||||
$cache->setKey($cache_key_logo, $logo_uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($logo_uri) {
|
|
||||||
$logo_style[] = 'background-size: 40px 40px;';
|
$logo_style[] = 'background-size: 40px 40px;';
|
||||||
$logo_style[] = 'background-position: 0 0;';
|
$logo_style[] = 'background-position: 0 0;';
|
||||||
$logo_style[] = 'background-image: url('.$logo_uri.')';
|
$logo_style[] = 'background-image: url('.$logo_uri.')';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$logo_node = phutil_tag(
|
$logo_node = phutil_tag(
|
||||||
'span',
|
'span',
|
||||||
|
@ -331,7 +310,6 @@ final class PhabricatorMainMenuView extends AphrontView {
|
||||||
'style' => implode(' ', $logo_style),
|
'style' => implode(' ', $logo_style),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
$wordmark_text = PhabricatorCustomLogoConfigType::getLogoWordmark();
|
$wordmark_text = PhabricatorCustomLogoConfigType::getLogoWordmark();
|
||||||
if (!phutil_nonempty_string($wordmark_text)) {
|
if (!phutil_nonempty_string($wordmark_text)) {
|
||||||
$wordmark_text = PlatformSymbols::getPlatformServerName();
|
$wordmark_text = PlatformSymbols::getPlatformServerName();
|
||||||
|
|
Loading…
Reference in a new issue