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

heimrichhannot / contao-utils-bundle / 13950027063

19 Mar 2025 03:11PM UTC coverage: 77.891% (+4.1%) from 73.745%
13950027063

Pull #93

github

koertho
add more test coverage
Pull Request #93: Forwardport #87

116 of 170 new or added lines in 6 files covered. (68.24%)

2 existing lines in 1 file now uncovered.

1071 of 1375 relevant lines covered (77.89%)

3.28 hits per line

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

14.58
/src/EntityFinder/EntityFinderHelper.php
1
<?php
2

3
/*
4
 * Copyright (c) 2022 Heimrich & Hannot GmbH
5
 *
6
 * @license LGPL-3.0-or-later
7
 */
8

9
namespace HeimrichHannot\UtilsBundle\EntityFinder;
10

11
use Contao\ContentModel;
12
use Contao\CoreBundle\Framework\ContaoFramework;
13
use Contao\Database;
14
use Contao\Model;
15
use Contao\Model\Collection;
16
use Contao\ModuleModel;
17
use Contao\Validator;
18
use Doctrine\DBAL\Connection;
19
use HeimrichHannot\MailDrumBundle\Backend\Content;
20
use HeimrichHannot\UtilsBundle\Util\Utils;
21

22
class EntityFinderHelper
23
{
24
    public function __construct(
25
        private readonly Utils           $utils,
26
        private readonly ContaoFramework $framework,
27
        private readonly Connection      $connection,
28
    )
29
    {
30
    }
1✔
31

32
    /**
33
     * Search within serialized array fields of the model entity.
34
     *
35
     * @param string $type   Module type
36
     * @param string $field  Field with serialized data
37
     * @param array  $values Values to search for in serialized data field
38
     *
39
     * @throws \Exception
40
     */
41
    public function findModulesByTypeAndSerializedValue(string $type, string $field, array $values): ?Collection
42
    {
43
        $blobQuery = $this->utils->database()->createWhereForSerializedBlob(ModuleModel::getTable().'.'.$field, $values);
1✔
44
        $columns = [$blobQuery->createOrWhere()];
1✔
45
        $values = $blobQuery->values;
1✔
46

47
        $columns[] = ModuleModel::getTable().'.type=?';
1✔
48
        $values[] = $type;
1✔
49

50
        return $this->framework->getAdapter(ModuleModel::class)->findBy($columns, $values);
1✔
51
    }
52

53
        /**
54
     * Find frontend modules by insert inserttags like insert_module oder insert_article.
55
     *
56
     * @param string $type The module type
57
     * @param string $field The tl_module field
58
     * @param string $inserttag The inserttag to search for, for example insert_module
59
     * @param int $id The element id to search for, for example the module id (as used in {{insert_module::1}}, would be 1 in this case)
60
     * @return array The found module ids
61
     * @throws \Exception
62
     */
63
    public function findModulesByInserttag(string $type, string $field, string $inserttag, int $id): array
64
    {
65
        if (!Validator::isAlias($field)) {
×
66
            throw new \Exception('Invalid field name '.$field.'given.');
×
67
        }
68
        if (!Validator::isAlias($inserttag)) {
×
69
            throw new \Exception('Invalid inserttag '.$inserttag.'given.');
×
70
        }
71
        $result = Database::getInstance()
×
72
            ->prepare("SELECT id FROM tl_module
×
73
                        WHERE type=?
74
                        AND (
75
                            $field LIKE '%{{".$inserttag."::".$id."}}%'
×
76
                            OR $field LIKE '%{{".$inserttag."::".$id."::%')")
×
77
            ->execute($type);
×
78

79
        return $result->fetchEach('id');
×
80
    }
81

82

83
    /**
84
     * Find content elements by insert inserttags like insert_module oder insert_article.
85
     *
86
     * @param string $type The element type
87
     * @param string $field The tl_content field
88
     * @param string $inserttag The inserttag to search for, for example insert_module
89
     * @param int $id The element id to search for, for example the module id (as used in {{insert_module::1}}, would be 1 in this case)
90
     * @return array<ContentModel> The found content element ids
91
     * @throws \Exception
92
     */
93
    public function findContentElementByInserttag(string $type, string $field, string $inserttag, int $id): array
94
    {
95
        if (!Validator::isAlias($field)) {
×
96
            throw new \Exception('Invalid field name '.$field.'given.');
×
97
        }
98
        if (!Validator::isAlias($inserttag)) {
×
99
            throw new \Exception('Invalid inserttag '.$inserttag.'given.');
×
100
        }
101
        $result = Database::getInstance()
×
102
            ->prepare("SELECT id FROM tl_content
×
103
                        WHERE type=?
104
                        AND (
105
                            $field LIKE '%{{".$inserttag."::".$id."}}%'
×
106
                            OR $field LIKE '%{{".$inserttag."::".$id."::%')")
×
107
            ->execute($type);
×
108

109
        return $result->fetchEach('id');
×
110
    }
111

112
    /**
113
     * @throws \Doctrine\DBAL\Exception
114
     */
115
    public function fetchModelOrData(string $table, int|string $idOrAlias): ?Model
116
    {
117
        /** @var class-string<Model> $modelClass */
NEW
118
        $modelClass = Model::getClassFromTable($table);
×
119

NEW
120
        if (!$modelClass || !class_exists($modelClass)) {
×
NEW
121
            if (!$this->connection->createSchemaManager()->tablesExist([$table])) {
×
NEW
122
                return null;
×
123
            }
NEW
124
            if (is_string($idOrAlias)) {
×
NEW
125
                $result = $this->connection->executeQuery("SELECT * FROM $table WHERE alias=?", [$idOrAlias]);
×
NEW
126
                if ($result->rowCount() === 0) {
×
NEW
127
                    return null;
×
128
                }
NEW
129
                return $this->anonymousModel($table, $result->fetchAssociative());
×
130
            }
NEW
131
            if (is_numeric($idOrAlias)) {
×
NEW
132
                if ($idOrAlias != (int) $idOrAlias) {
×
NEW
133
                    return null;
×
134
                }
135

NEW
136
                $result = $this->connection->executeQuery("SELECT * FROM $table WHERE id=?", [(int)$idOrAlias]);
×
NEW
137
                if ($result->rowCount() === 0) {
×
NEW
138
                    return null;
×
139
                }
NEW
140
                return $this->anonymousModel($table, $result->fetchAssociative());
×
141
            }
142
        }
143

NEW
144
        return $modelClass::findByIdOrAlias($idOrAlias);
×
145
    }
146

147
    private function anonymousModel(string $table, array $data): Model
148
    {
NEW
149
        return new class($table, $data) extends Model {
×
150

151
            protected $blnPreventSaving = true;
152

153
            public function __construct(string $table, array $data = [])
154
            {
NEW
155
                $this->strTable = $table;
×
NEW
156
                $this->setRow($data);
×
157
            }
NEW
158
        };
×
159
    }
160
}
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