Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — dev-extbase-fluid (#771)
by
unknown
03:20
created

Generator::parseDocComment()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 21
rs 10
1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\DbDocs;
14
15
use Doctrine\DBAL\Schema\Table;
16
use Kitodo\Dlf\Common\Helper;
17
use ReflectionClass;
18
use TYPO3\CMS\Core\Database\Schema\Parser\Parser;
19
use TYPO3\CMS\Core\Database\Schema\SqlReader;
20
use TYPO3\CMS\Core\Localization\LanguageService;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
23
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
24
use TYPO3\CMS\Extbase\Object\ObjectManager;
25
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
26
27
/**
28
 * Aggregates information about database tables and generates an .rst reference page.
29
 *
30
 * @author Kajetan Dvoracek <[email protected]>
31
 * @package TYPO3
32
 * @subpackage dlf
33
 * @access public
34
 */
35
class Generator
36
{
37
    /**
38
     * @var ObjectManager
39
     */
40
    protected $objectManager;
41
42
    /**
43
     * @var LanguageService
44
     */
45
    protected $languageService;
46
47
    /**
48
     * @var DataMapper
49
     */
50
    protected $dataMapper;
51
52
    public function __construct()
53
    {
54
        $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
55
        $this->languageService = $this->objectManager->get(LanguageService::class);
56
        $this->dataMapper = $this->objectManager->get(DataMapper::class);
57
    }
58
59
    /**
60
     * Collect information about relevant tables from `ext_tables.sql` and the
61
     * Extbase classmap.
62
     */
63
    public function collectTables(): array
64
    {
65
        $sqlReader = $this->objectManager->get(SqlReader::class);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated: since TYPO3 10.4, will be removed in version 12.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

65
        $sqlReader = /** @scrutinizer ignore-deprecated */ $this->objectManager->get(SqlReader::class);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
66
        $sqlCode = $sqlReader->getTablesDefinitionString(true);
67
        $createTableStatements = $sqlReader->getCreateTableStatementArray($sqlCode);
68
69
        $tableToClassName = $this->getTableClassMap();
70
71
        $result = [];
72
73
        foreach ($createTableStatements as $statement) {
74
            $parser = new Parser($statement);
75
            list($table) = $parser->parse();
76
77
            $tableName = $table->getName();
78
            if (!str_starts_with($tableName, 'tx_dlf_')) {
79
                continue;
80
            }
81
82
            $className = $tableToClassName[$tableName] ?? null;
83
84
            $result[] = $this->getTableInfo($table, $className);
85
        }
86
87
        return $result;
88
    }
89
90
    /**
91
     * Get a map from database table names to their domain model class names.
92
     */
93
    public function getTableClassMap(): array
94
    {
95
        Helper::polyfillExtbaseClassesForTYPO3v9();
0 ignored issues
show
Deprecated Code introduced by
The function Kitodo\Dlf\Common\Helper...baseClassesForTYPO3v9() has been deprecated: Remove once we drop support for TYPO3v9 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

95
        /** @scrutinizer ignore-deprecated */ Helper::polyfillExtbaseClassesForTYPO3v9();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
96
97
        $configurationManager = $this->objectManager->get(ConfigurationManager::class);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated: since TYPO3 10.4, will be removed in version 12.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

97
        $configurationManager = /** @scrutinizer ignore-deprecated */ $this->objectManager->get(ConfigurationManager::class);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
98
        $frameworkConfiguration = $configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
99
100
        $result = [];
101
102
        foreach ($frameworkConfiguration['persistence']['classes'] as $className => $tableConf) {
103
            $tableName = $tableConf['mapping']['tableName'];
104
            $result[$tableName] = $className;
105
        }
106
107
        return $result;
108
    }
109
110
    /**
111
     * Collect information about a single table.
112
     *
113
     * @param Table $table The table to be analyzed
114
     * @param string|null $className Fully qualified name of the domain model class
115
     */
116
    protected function getTableInfo(Table $table, ?string $className): object
117
    {
118
        $tableName = $table->getName();
119
120
        $isPrimary = [];
121
        if (!is_null($primaryKey = $table->getPrimaryKey())) {
122
            foreach ($primaryKey->getUnquotedColumns() as $primaryColumn) {
123
                $isPrimary[$primaryColumn] = true;
124
            }
125
        }
126
127
        $columns = [];
128
        foreach ($table->getColumns() as $column) {
129
            $columnName = $column->getName();
130
131
            $columns[$columnName] = (object) [
132
                'name' => $columnName,
133
                'type' => $column->getType(),
134
                'isPrimary' => isset($isPrimary[$columnName]),
135
                'sqlComment' => $column->getComment() ?? '',
136
                'fieldComment' => '',
137
                'feComment' => $this->languageService->sL($GLOBALS['TCA'][$tableName]['columns'][$columnName]['label'] ?? ''),
138
            ];
139
        }
140
141
        $result = (object) [
142
            'name' => $tableName,
143
            'columns' => $columns,
144
            'modelClass' => null,
145
            'sqlComment' => $table->getComment() ?? '',
146
            'classComment' => '',
147
            'feComment' => $this->languageService->sL($GLOBALS['TCA'][$tableName]['ctrl']['title'] ?? ''),
148
        ];
149
150
        // Integrate doc-comments from model class and its fields
151
        if ($className !== null) {
152
            $reflection = new ReflectionClass($className);
153
154
            $dataMap = $this->dataMapper->getDataMap($className);
155
156
            foreach ($reflection->getProperties() as $property) {
157
                $column = $dataMap->getColumnMap($property->getName());
158
                if ($column !== null) {
159
                    $result->columns[$column->getColumnName()]->fieldComment = $this->parseDocComment($property->getDocComment());
160
                }
161
            }
162
163
            $result->modelClass = $className;
164
            $result->classComment = $this->parseDocComment($reflection->getDocComment());
165
        }
166
167
        return $result;
168
    }
169
170
    protected function parseDocComment($docComment)
171
    {
172
        // TODO: Consider using phpDocumentor (though that splits the docblock into summary and description)
173
174
        // Adopted from DocCommentParser in TYPO3 v9
175
        // https://github.com/TYPO3/typo3/blob/57944c8c5add00f0e8a1a5e1d07f30a8f20a8201/typo3/sysext/extbase/Classes/Reflection/DocCommentParser.php
176
        $text = '';
177
        $lines = explode("\n", $docComment);
178
        foreach ($lines as $line) {
179
            // Stop parsing at first tag
180
            if ($line !== '' && strpos($line, '@') !== false) {
181
                break;
182
            }
183
184
            // There may be a single non-signifying space after the doc-comment asterisk,
185
            // which is not included.
186
            $text .= preg_replace('#\\s*/?[*/]*\\s?(.*)$#', '$1', $line) . "\n";
187
        }
188
        $text = trim($text);
189
190
        return $text;
191
    }
192
193
    /**
194
     * Transform table structure into .rst page.
195
     */
196
    public function generatePage(array $tables)
197
    {
198
        $page = new RstSection();
199
        $page->setHeader('Database Tables');
200
        $page->addText(<<<RST
201
This is a reference of all database tables defined by Kitodo.Presentation.
202
203
.. tip:: This page is auto-generated. If you would like to edit it, please use doc-comments in the model class, COMMENT fields in ``ext_tables.sql`` if the table does not have one, or TCA labels. Then, you may re-generate the page by running ``composer docs:db`` inside the Kitodo.Presentation base folder.
204
RST);
205
206
        // Sort tables alphabetically
207
        usort($tables, function ($lhs, $rhs) {
208
            return $lhs->name <=> $rhs->name;
209
        });
210
211
        foreach ($tables as $tableInfo) {
212
            $section = $page->subsection();
213
214
            // Set header
215
            $header = $tableInfo->name;
216
            if (!empty($tableInfo->feComment)) {
217
                $header .= ': ' . $tableInfo->feComment;
218
            }
219
            $section->setHeader($header);
220
221
            // Set introductory text of subsection
222
            if ($tableInfo->modelClass) {
223
                $section->addText('Extbase domain model: ``' . $tableInfo->modelClass . '``');
224
            }
225
            $section->addText($tableInfo->classComment);
226
            $section->addText($tableInfo->sqlComment);
227
228
            // Generate main table
229
            $header = [[
230
                'field' => 'Field',
231
                'description' => 'Description',
232
            ]];
233
234
            $rows = array_map(function ($column) use ($page) {
235
                return [
236
                    'field' => (
237
                        $page->format($column->name, ['bold' => $column->isPrimary])
238
                        . "\u{00a0}\u{00a0}"
239
                        . $page->format($column->type->getName(), ['italic' => true])
240
                    ),
241
242
                    'description' => $page->paragraphs([
243
                        $page->format($column->feComment, ['italic' => true]),
244
                        $column->fieldComment,
245
                        $column->sqlComment,
246
                    ]),
247
                ];
248
            }, $tableInfo->columns);
249
250
            $section->addTable($rows, $header);
251
        }
252
253
        return $page;
254
    }
255
}
256