• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

heimrichhannot / contao-utils-bundle / 18185911694

02 Oct 2025 07:05AM UTC coverage: 79.355% (-0.4%) from 79.752%
18185911694

push

github

koertho
moved author field default value to a oncreate callback

7 of 21 new or added lines in 1 file covered. (33.33%)

1157 of 1458 relevant lines covered (79.36%)

3.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.19
/src/EventListener/DcaField/DcaAuthorListener.php
1
<?php
2

3
namespace HeimrichHannot\UtilsBundle\EventListener\DcaField;
4

5
use Contao\BackendUser;
6
use Contao\CoreBundle\DependencyInjection\Attribute\AsHook;
7
use Contao\DataContainer;
8
use Contao\FrontendUser;
9
use Contao\Model;
10
use HeimrichHannot\UtilsBundle\Dca\AuthorField;
11
use HeimrichHannot\UtilsBundle\Dca\AuthorFieldConfiguration;
12
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
13
use Symfony\Component\Security\Core\User\UserInterface;
14

15
class DcaAuthorListener extends AbstractDcaFieldListener
16
{
17
    #[AsHook("loadDataContainer")]
18
    public function onLoadDataContainer(string $table): void
19
    {
20
        if (!isset(AuthorField::getRegistrations()[$table])) {
1✔
21
            return;
1✔
22
        }
23

24
        $options = AuthorField::getRegistrations()[$table];
1✔
25
        $authorFieldName = $this->getAuthorFieldName($options);
1✔
26
        $authorField = $this->createAuthorField($options);
1✔
27

28
        $GLOBALS['TL_DCA'][$table]['fields'][$authorFieldName] = $authorField;
1✔
29
        $GLOBALS['TL_DCA'][$table]['config']['oncreate_callback'][] = [self::class, 'onConfigCreateCallback'];
1✔
30
        $GLOBALS['TL_DCA'][$table]['config']['oncopy_callback'][] = [self::class, 'onConfigCopyCallback'];
1✔
31
    }
32

33
    public function onConfigCreateCallback(string $table, int $id, array $row, DataContainer $dc): void
34
    {
NEW
35
        $option = AuthorField::getRegistrations()[$dc->table] ?? null;
×
NEW
36
        $model = $this->getModelInstance($table, $id);
×
NEW
37
        if (!$model || !$option) {
×
NEW
38
            return;
×
39
        }
40

41
        /** @var TokenStorageInterface $tokenStorage */
NEW
42
        $tokenStorage = $this->container->get('token_storage');
×
NEW
43
        $user = $tokenStorage->getToken()?->getUser();
×
NEW
44
        if (!$user) {
×
NEW
45
            return;
×
46
        }
47

NEW
48
        $this->setAuthor($option, $user, $model);
×
NEW
49
        $model->save();
×
50
    }
51
    public function onConfigCopyCallback(int $insertId, DataContainer $dc): void
52
    {
53
        $options = AuthorField::getRegistrations()[$dc->table];
1✔
54
        $model = $this->getModelInstance($dc->table, $insertId);
1✔
55
        if (!$model || !$options) {
1✔
56
            return;
×
57
        }
58

59
        /** @var TokenStorageInterface $tokenStorage */
60
        $tokenStorage = $this->container->get('token_storage');
1✔
61
        $user = $tokenStorage->getToken()?->getUser();
1✔
62

63
        $this->setAuthor($options, $user, $model);
1✔
64
        $model->save();
1✔
65
    }
66

67
    /**
68
     * @param AuthorFieldConfiguration $options
69
     * @return string
70
     */
71
    protected function getAuthorFieldName(AuthorFieldConfiguration $options): string
72
    {
73
        if (!$options->hasFieldNamePrefix()) {
2✔
74
            return 'author';
2✔
75
        }
76
        if (str_ends_with($options->getFieldNamePrefix(), '_')) {
1✔
77
            return $options->getFieldNamePrefix() . 'author';
1✔
78
        } else {
79
            return $options->getFieldNamePrefix() . 'Author';
1✔
80
        }
81
    }
82

83
    public static function getSubscribedServices(): array
84
    {
85
        $services = parent::getSubscribedServices();
×
86
        $services['token_storage'] = TokenStorageInterface::class;
×
87
        return $services;
×
88
    }
89

90
    public function createAuthorField(AuthorFieldConfiguration $options): array
91
    {
92
        $authorField = [
1✔
93
            'inputType' => 'select',
1✔
94
            'eval' => [
1✔
95
                'doNotCopy' => true,
1✔
96
                'mandatory' => true,
1✔
97
                'chosen' => true,
1✔
98
                'includeBlankOption' => true,
1✔
99
                'tl_class' => 'w50'
1✔
100
            ],
1✔
101
            'sql' => "int(10) unsigned NOT NULL default 0",
1✔
102
        ];
1✔
103

104
        $this->applyDefaultFieldAdjustments($authorField, $options);
1✔
105

106
        if ($options->isUseDefaultLabel()) {
1✔
107
            $authorField['label'] = &$GLOBALS['TL_LANG']['MSC']['utilsBundle']['author'];
1✔
108
        }
109

110
        $authorField['default'] = 0;
1✔
111
        if (AuthorField::TYPE_USER === $options->getType()) {
1✔
112
            $authorField['foreignKey'] = 'tl_user.name';
1✔
113
            $authorField['relation'] = ['type' => 'hasOne', 'load' => 'lazy'];
1✔
114
        } elseif (AuthorField::TYPE_MEMBER === $options->getType()) {
×
115
            $authorField['foreignKey'] = "tl_member.CONCAT(firstname,' ',lastname)";
×
116
            $authorField['relation'] = ['type' => 'hasOne', 'load' => 'lazy'];
×
117
        }
118
        return $authorField;
1✔
119
    }
120

121
    private function setAuthor(AuthorFieldConfiguration $options, ?UserInterface $user, Model $model): void
122
    {
123
        $authorFieldName = $this->getAuthorFieldName($options);
1✔
124
        $model->{$authorFieldName} = 0;
1✔
125
        if (AuthorField::TYPE_USER === $options->getType()) {
1✔
126
            if ($user instanceof BackendUser) {
1✔
NEW
127
                $model->{$authorFieldName} = $user->id;
×
128
            }
NEW
129
        } elseif (AuthorField::TYPE_MEMBER === $options->getType()) {
×
NEW
130
            if ($user instanceof FrontendUser) {
×
NEW
131
                $model->{$authorFieldName} = $user->id;
×
132
            }
133
        }
134
    }
135
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc