Ergebnis 1 bis 4 von 4

Thema: ModuleNews.php überschreiben / Benutzer-Gruppenverwaltung für Newsbeiträge

  1. #1
    Contao-Nutzer
    Registriert seit
    02.04.2020.
    Beiträge
    16

    Standard ModuleNews.php überschreiben / Benutzer-Gruppenverwaltung für Newsbeiträge

    Um Nachrichten-Beiträge nur ausgewählten Benutzergruppen anzuzeigen, muss die die Datei ModuleNews.php unter /news-bundle/src/Resources/contao/modules/ModuleNews.php überschreiben. Wie mache ich das am besten? Einfach die Ordnerstruktur 1zu1 kopieren und in root/contao einfügen?

  2. #2
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.126
    Partner-ID
    10107

    Standard

    Die Klasse kannst du nicht überschreiben. Aber eine alternative Lösung wäre folgende:
    PHP-Code:
    // contao/dca/tl_news.php
    use Contao\CoreBundle\DataContainer\PaletteManipulator;
    use 
    Doctrine\DBAL\Platforms\MySQLPlatform;

    $GLOBALS['TL_DCA']['tl_news']['fields']['protected'] = [
        
    'exclude' => true,
        
    'filter' => true,
        
    'inputType' => 'checkbox',
        
    'eval' => ['submitOnChange' => true],
        
    'sql' => ['type' => 'boolean''default' => false],
    ];

    $GLOBALS['TL_DCA']['tl_news']['fields']['groups'] = [
        
    'exclude' => true,
        
    'inputType' => 'checkbox',
        
    'foreignKey' => 'tl_member_group.name',
        
    'eval' => ['mandatory' => true'multiple' => true],
        
    'sql' => ['type' => 'blob''length' => MySQLPlatform::LENGTH_LIMIT_BLOB'notnull' => false],
        
    'relation' => ['type' => 'hasMany''load' => 'lazy'],
    ];

    $GLOBALS['TL_DCA']['tl_news']['palettes']['__selector__'][] = 'protected';
    $GLOBALS['TL_DCA']['tl_news']['subpalettes']['protected'] = 'groups';

    $pm PaletteManipulator::create()
        ->
    addLegend('protected_legend''publish_legend'PaletteManipulator::POSITION_BEFORE)
        ->
    addField('protected''protected_legend'PaletteManipulator::POSITION_APPEND)
    ;

    foreach (
    $GLOBALS['TL_DCA']['tl_news']['palettes'] as $name => $palette) {
        if (!\
    is_string($palette)) {
            continue;
        }

        
    $pm->applyToPalette($name'tl_news');

    PHP-Code:
    // src/EventListener/ProtectNewsEntryListener.php
    namespace App\EventListener;

    use 
    Contao\CoreBundle\DependencyInjection\Attribute\AsHook;
    use 
    Contao\CoreBundle\Exception\AccessDeniedException;
    use 
    Contao\CoreBundle\Exception\InsufficientAuthenticationException;
    use 
    Contao\FrontendTemplate;
    use 
    Contao\Module;
    use 
    Contao\StringUtil;
    use 
    Symfony\Component\Security\Core\Security;

    #[AsHook('parseArticles', priority: 10000)]
    class ProtectNewsEntryListener
    {
        public function 
    __construct(private readonly Security $security)
        {
        }

        public function 
    __invoke(FrontendTemplate $template, array $newsModule $module): void
        
    {
            if (
    'newsreader' !== $module->type || !$news['protected']) {
                return;
            }

            if (
    $this->security->isGranted(ContaoCorePermissions::MEMBER_IN_GROUPSStringUtil::deserialize($news['groups'], true))) {
                return;
            }

            if (
    $this->security->isGranted('ROLE_MEMBER')) {
                throw new 
    AccessDeniedException();
            } else {
                throw new 
    InsufficientAuthenticationException();
            }
        }

    (ungetestet)
    » sponsor me via GitHub or PayPal or Revolut

  3. #3
    Contao-Nutzer
    Registriert seit
    02.04.2020.
    Beiträge
    16

    Standard

    woah, danke Spooky. Auf die Lösung mit Hook bin ich inzwischen auch gekommen.
    Dein Code sieht aber richtig clean und viel besser aus.

    Hier mein Vorschlag:
    PHP-Code:
    <?php

    declare(strict_types=1);

    namespace 
    App\EventListener;

    use 
    Contao\CoreBundle\DependencyInjection\Attribute\AsHook;
    use 
    Contao\FrontendUser;
    use 
    Contao\MemberGroupModel;
    use 
    Contao\Model\Collection;
    use 
    Contao\Module;
    use 
    Contao\NewsModel;

    #[AsHook('newsListFetchItems')]
    class NewsListFetchItemsListener
    {
        public function 
    __invoke(array $newsArchives, ?bool $featuredOnlyint $limitint $offsetModule $module)
        {
            
    $membersGroup MemberGroupModel::findAll();
            
    $objUser FrontendUser::getInstance();

            if (
    $objUser instanceof FrontendUser && !empty($module->news_archives)) {
                
    // Query the database and return the records
                
    $resultNews = [];

                foreach (
    $module->news_archives as $archive) {
                    
    $allNewsFromArchive NewsModel::findByPid($archive);

                    if (!empty(
    $allNewsFromArchive)) {
                        
    /** @var NewsModel $newsItem */
                        
    foreach ($allNewsFromArchive as $newsItem) {
                            
    $groups = \StringUtil::deserialize($newsItem->groups);
                            
    $commonGroups array_intersect($groups$objUser->groups);

                            if (!empty(
    $commonGroups)) {
                                
    // Extend $resultNews with $newsItem
                                
    $resultNews[] = $newsItem;
                            }
                        }
                    }
                }

                return new 
    Collection($resultNews'tl_news');
            }

            return 
    false;
        }
    }
    tl_news.php wie bei dir im Beispiel.

    Erfolgreich getestet.

  4. #4
    Community-Moderator
    Wandelndes Contao-Lexikon
    Avatar von Spooky
    Registriert seit
    12.04.2012.
    Ort
    Scotland
    Beiträge
    34.126
    Partner-ID
    10107

    Standard

    Dein Hook entfernt auch News aus der Collection, die protected sind - das braucht man vielleicht zusätzlich (je nach dem wie man es haben möchte - also ob Protected News noch in der Liste aufscheinen sollen, aber der Click auf die Details würde zu einem Login führen, oder man will auch in der Newslist keine Protected Items haben). Ich würde aber auch in deinem Hook empfehlen isGranted zu nutzen.
    » sponsor me via GitHub or PayPal or Revolut

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Lesezeichen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •