flag_lists-4.0.x-dev/src/FlagListsFlagLinkBuilder.php
src/FlagListsFlagLinkBuilder.php
<?php
namespace Drupal\flag_lists;
use Drupal\flag\FlagLinkBuilderInterface;
use Drupal\flag\FlagLinkBuilder;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Url;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Security\TrustedCallbackInterface;
/**
* Provides a lazy builder for flag lists flag links.
*/
class FlagListsFlagLinkBuilder implements
FlagLinkBuilderInterface,
TrustedCallbackInterface {
/**
* The original flag link builder.
*
* @var \Drupal\flag\FlagLinkBuilder
*/
protected $flagLinkBuilder;
/**
* The flag lists service.
*
* @var \Drupal\flag_lists\FlagListsServiceInterface
*/
protected $flagListsService;
/**
* Constructor.
*
* @param \Drupal\flag\FlagLinkBuilderInterface $link_builder
* The original FlagLinkBuilder.
* @param \Drupal\flag_lists\FlagListsServiceInterface $flag_lists_service
* The Flag Lists Service.
*/
public function __construct(FlagLinkBuilderInterface $link_builder,
FlagListsServiceInterface $flag_lists_service) {
$this->flagLinkBuilder = $link_builder;
$this->flagListsService = $flag_lists_service;
}
/**
* {@inheritdoc}
*/
public static function trustedCallbacks() {
return ['build'];
}
/**
* {@inheritdoc}
*/
public function build($entity_type_id, $entity_id, $flag_id, $view_mode = NULL) {
// $entity_type_id = 'node' etc
// $entity_id 'node id' etc
// $flag_id 'flag' machine name
// $view_mode the selected 'view mode'
$templates = $this->flagListsService->getAllFlagForList();
$link = [];
foreach ($templates as $template) {
if ($template->id() == $flag_id) {
// Don't return a link to a template.
// (All flag lists are actually real flags.)
return $link;
}
}
$account = \Drupal::currentUser()->getAccount();
$allFlagLists =
$this->flagListsService->getAllFlaggingCollections();
// Build a link according to original scheme.
$link = $this->flagLinkBuilder->build($entity_type_id,
$entity_id, $flag_id, $view_mode);
// Walk through all flag lists.
// Update only links of flag lists.
foreach ($allFlagLists as $flagList) {
// If this is the specific we are looking for.
if ($flagList->getRelatedFlag() == NULL) {
// The Flag Lists database is broken!
return $link;
}
if ($flagList->getRelatedFlag()->id() == $flag_id) {
// Best to check for access and ownership.
// Access is crusial but ownership need to be check
// otherwise administrators with full access will get
// a cluttered page with all system collections.
if (($flagList->access('view', $account)) &&
($flagList->getOwnerId() == $account->id())) {
// Build a flag link with flag method to check the access.
$options = UrlHelper::parse($link['#attributes']['href']);
$uri = substr_replace($options['path'], 'internal:/', 0,
strlen(base_path())) . '/' . $flagList->id();
unset($options['path']);
// Remove CSRF token and regenerate it for the new path.
unset($options['query']['token']);
$rendered_url = Url::fromUri($uri, $options)->toString(TRUE);
$rendered_url->applyTo($link);
$link['#attributes']['href'] = $rendered_url->getGeneratedUrl();
// Substitute Drupal tokens.
$flc = $this->flagListsService->getFlaggingCollectionById($flagList->id());
$token_service = \Drupal::token();
$bubbleable_metadata =
BubbleableMetadata::createFromRenderArray($link);
$link['#title']['#markup'] =
$token_service->replace($link['#title']['#markup'],
['flagging_collection' => $flc], [], $bubbleable_metadata);
$link['#attributes']['title'] =
$token_service->replace($link['#attributes']['title'],
['flagging_collection' => $flc], [], $bubbleable_metadata);
$bubbleable_metadata
->applyTo($link);
// Make flagging collection available in the twig.
$link['#flagging_collection'] =
$flagList->id();
}
else {
$link = [];
}
}
}
return $link;
}
}
