Verified Commit 529c7932 authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #3349394 by plopesc, fjgarlin, hestenet, penyaskito, friera: Provide...

Issue #3349394 by plopesc, fjgarlin, hestenet, penyaskito, friera: Provide announcement feed as a block
parent d088a7b0
Loading
Loading
Loading
Loading
Loading
+4 −0
Changes for core/modules/announcements_feed/announcements_feed.services.yml: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -15,3 +15,7 @@ services:
    class: Drupal\announcements_feed\LazyBuilders
    arguments: [ '@plugin.manager.element_info']
  Drupal\announcements_feed\LazyBuilders: '@announcements_feed.lazy_builders'
  announcements_feed.renderer:
    class: Drupal\announcements_feed\AnnounceRenderer
    arguments: ['@announcements_feed.fetcher', '%announcements_feed.feed_link%']
  Drupal\announcements_feed\AnnounceRenderer: '@announcements_feed.renderer'
+84 −0
Changes for core/modules/announcements_feed/src/AnnounceRenderer.php: 84 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\announcements_feed;

use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Service to render announcements from the external feed.
 *
 * @internal
 */
final class AnnounceRenderer {

  use StringTranslationTrait;

  /**
   * Constructs an AnnouncementRenderer object.
   *
   * @param \Drupal\announcements_feed\AnnounceFetcher $announceFetcher
   *   The AnnounceFetcher service.
   * @param string $feedLink
   *   The feed url path.
   */
  public function __construct(
    protected AnnounceFetcher $announceFetcher,
    protected string $feedLink
  ) {
  }

  /**
   * Generates the announcements feed render array.
   *
   * @return array
   *   Render array containing the announcements feed.
   */
  public function render(): array {
    try {
      $announcements = $this->announceFetcher->fetch();
    }
    catch (\Exception $e) {
      return [
        '#theme' => 'status_messages',
        '#message_list' => [
          'error' => [
            $this->t('An error occurred while parsing the announcements feed, check the logs for more information.'),
          ],
        ],
        '#status_headings' => [
          'error' => $this->t('Error Message'),
        ],
      ];
    }

    $build = [];
    foreach ($announcements as $announcement) {
      $key = $announcement->featured ? '#featured' : '#standard';
      $build[$key][] = $announcement;
    }

    $build += [
      '#theme' => 'announcements_feed',
      '#count' => count($announcements),
      '#feed_link' => $this->feedLink,
      '#cache' => [
        'contexts' => [
          'url.query_args:_wrapper_format',
        ],
        'tags' => [
          'announcements_feed:feed',
        ],
      ],
      '#attached' => [
        'library' => [
          'announcements_feed/drupal.announcements_feed.dialog',
        ],
      ],
    ];

    return $build;
  }

}
+6 −50
Changes for core/modules/announcements_feed/src/Controller/AnnounceController.php: 6 added lines, 50 removed lines.
Original line number Diff line number Diff line
@@ -4,9 +4,9 @@

namespace Drupal\announcements_feed\Controller;

use Drupal\announcements_feed\AnnounceRenderer;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\announcements_feed\AnnounceFetcher;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

@@ -20,14 +20,11 @@ class AnnounceController extends ControllerBase implements ContainerInjectionInt
  /**
   * Constructs an AnnounceController object.
   *
   * @param \Drupal\announcements_feed\AnnounceFetcher $announceFetcher
   *   The AnnounceFetcher service.
   * @param string $feedLink
   *   The feed url path.
   * @param \Drupal\announcements_feed\AnnounceRenderer $announceRenderer
   *   The AnnounceRenderer service.
   */
  public function __construct(
    protected AnnounceFetcher $announceFetcher,
    protected string $feedLink
    protected AnnounceRenderer $announceRenderer,
  ) {
  }

@@ -36,8 +33,7 @@ public function __construct(
   */
  public static function create(ContainerInterface $container): AnnounceController {
    return new static(
      $container->get('announcements_feed.fetcher'),
      $container->getParameter('announcements_feed.feed_link')
      $container->get('announcements_feed.renderer'),
    );
  }

@@ -51,47 +47,7 @@ public static function create(ContainerInterface $container): AnnounceController
   *   A build array with announcements.
   */
  public function getAnnouncements(Request $request): array {
    try {
      $announcements = $this->announceFetcher->fetch();
    }
    catch (\Exception $e) {
      return [
        '#theme' => 'status_messages',
        '#message_list' => [
          'error' => [
            $this->t('An error occurred while parsing the announcements feed, check the logs for more information.'),
          ],
        ],
        '#status_headings' => [
          'error' => $this->t('Error Message'),
        ],
      ];
    }

    $build = [];
    foreach ($announcements as $announcement) {
      $key = $announcement->featured ? '#featured' : '#standard';
      $build[$key][] = $announcement;
    }

    $build += [
      '#theme' => 'announcements_feed',
      '#count' => count($announcements),
      '#feed_link' => $this->feedLink,
      '#cache' => [
        'contexts' => [
          'url.query_args:_wrapper_format',
        ],
        'tags' => [
          'announcements_feed:feed',
        ],
      ],
      '#attached' => [
        'library' => [
          'announcements_feed/drupal.announcements_feed.dialog',
        ],
      ],
    ];
    $build = $this->announceRenderer->render();
    if ($request->query->get('_wrapper_format') != 'drupal_dialog.off_canvas') {
      $build['#theme'] = 'announcements_feed_admin';
      $build['#attached'] = [];
+71 −0
Changes for core/modules/announcements_feed/src/Plugin/Block/AnnounceBlock.php: 71 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\announcements_feed\Plugin\Block;

use Drupal\announcements_feed\AnnounceRenderer;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides an 'Announcements Feed' block.
 *
 * @Block(
 *   id = "announce_block",
 *   admin_label = @Translation("Announcements Feed"),
 * )
 *
 * @internal
 */
class AnnounceBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * Constructs a new AnnouncementsFeedBlock instance.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\announcements_feed\AnnounceRenderer $announceRenderer
   *   The AnnounceRenderer service.
   * @param \Drupal\Core\Session\AccountInterface $currentUser
   *   The current user.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, protected AnnounceRenderer $announceRenderer, protected AccountInterface $currentUser) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('announcements_feed.renderer'),
      $container->get('current_user')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account, $return_as_object = FALSE) {
    return AccessResult::allowedIfHasPermission($this->currentUser, 'access announcements');
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    return $this->announceRenderer->render();
  }

}
+70 −0
Changes for core/modules/announcements_feed/tests/src/FunctionalJavascript/AnnounceBlockTest.php: 70 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\announcements_feed\FunctionalJavascript;

use Drupal\announce_feed_test\AnnounceTestHttpClientMiddleware;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;

/**
 * Test the announcement block test visibility.
 *
 * @group announcements_feed
 */
class AnnounceBlockTest extends WebDriverTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'announcements_feed',
    'block',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * The announce block instance.
   *
   * @var \Drupal\block\Entity\Block
   */
  protected $announceBlock;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    AnnounceTestHttpClientMiddleware::setAnnounceTestEndpoint('/announce-feed-json/community-feeds');
    $this->announceBlock = $this->placeBlock('announce_block', [
      'label' => 'Announcements Feed',
    ]);
  }

  /**
   * Testing announce feed block visibility.
   */
  public function testAnnounceWithoutPermission() {
    // User with "access announcements" permission.
    $account = $this->drupalCreateUser([
      'access announcements',
    ]);
    $this->drupalLogin($account);
    $this->drupalGet('<front>');

    $assert_session = $this->assertSession();

    // Block should be visible for the user.
    $assert_session->pageTextContains('Announcements Feed');

    // Block is not accessible without permission.
    $this->drupalLogout();
    $assert_session->pageTextNotContains('Announcements Feed');

  }

}
Loading