Skip to content

Commit

Permalink
[BUGFIX] Generate database documentation via typo3 command (#1486)
Browse files Browse the repository at this point in the history
Co-authored-by: Sebastian Meyer <[email protected]>
  • Loading branch information
thomaslow and sebastian-meyer authored Mar 5, 2025
1 parent da8c199 commit 16796f5
Show file tree
Hide file tree
Showing 12 changed files with 255 additions and 150 deletions.
35 changes: 0 additions & 35 deletions Build/Documentation/dbdocs/generate.php

This file was deleted.

1 change: 0 additions & 1 deletion Build/Documentation/dbdocs/public/typo3

This file was deleted.

15 changes: 0 additions & 15 deletions Build/Documentation/dbdocs/public/typo3conf/LocalConfiguration.php

This file was deleted.

31 changes: 0 additions & 31 deletions Build/Documentation/dbdocs/public/typo3conf/PackageStates.php

This file was deleted.

1 change: 0 additions & 1 deletion Build/Documentation/dbdocs/public/typo3conf/ext/dlf

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@
* LICENSE.txt file that was distributed with this source code.
*/

namespace Kitodo\DbDocs;
namespace Kitodo\Dlf\Command\DbDocs;

use Doctrine\DBAL\Schema\Table;
use Kitodo\Dlf\Common\Helper;
use ReflectionClass;
use ReflectionProperty;
use TYPO3\CMS\Core\Database\Schema\Parser\Parser;
use TYPO3\CMS\Core\Database\Schema\SqlReader;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Persistence\ClassesConfiguration;
use TYPO3\CMS\Extbase\Persistence\ClassesConfigurationFactory;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;

/**
Expand Down Expand Up @@ -53,14 +57,6 @@ class Generator
*/
protected $configurationManager;

/**
* @param LanguageService $languageService
*/
public function injectLanguageService(LanguageService $languageService)
{
$this->languageService = $languageService;
}

/**
* @param DataMapper $dataMapper
*/
Expand All @@ -72,7 +68,7 @@ public function injectDataMapper(DataMapper $dataMapper)
/**
* @param SqlReader $sqlReader
*/
public function injectSqlReader(DataMapper $sqlReader)
public function injectSqlReader(SqlReader $sqlReader)
{
$this->sqlReader = $sqlReader;
}
Expand All @@ -87,7 +83,7 @@ public function injectConfigurationManager(ConfigurationManager $configurationMa

public function __construct()
{

$this->languageService = GeneralUtility::makeInstance(LanguageService::class);
}

/**
Expand Down Expand Up @@ -125,12 +121,19 @@ public function collectTables(): array
*/
public function getTableClassMap(): array
{
$frameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
$dataMapFactory = GeneralUtility::makeInstance(DataMapFactory::class);

$result = [];
// access classes configuration through reflection, which is otherwise not available?
$reflectionProperty = new ReflectionProperty(DataMapFactory::class, 'classesConfiguration');
$reflectionProperty->setAccessible(true);
$classesConfiguration = $reflectionProperty->getValue($dataMapFactory);
$reflectionProperty = new ReflectionProperty(ClassesConfiguration::class, 'configuration');
$reflectionProperty->setAccessible(true);
$configuration = $reflectionProperty->getValue($classesConfiguration);

foreach ($frameworkConfiguration['persistence']['classes'] as $className => $tableConf) {
$tableName = $tableConf['mapping']['tableName'];
$result = [];
foreach ($configuration as $className => $tableConf) {
$tableName = $tableConf['tableName'];
$result[$tableName] = $className;
}

Expand Down Expand Up @@ -193,7 +196,7 @@ protected function getTableInfo(Table $table, ?string $className): object
: $column->getColumnName();

if (isset($result->columns[$columnName])) {
$result->columns[$columnName]->fieldComment = $this->parseDocComment($property->getDocComment());
$result->columns[$columnName]->fieldComment = $this->parsePropertyDocComment($property->getDocComment());
}
}

Expand All @@ -204,6 +207,20 @@ protected function getTableInfo(Table $table, ?string $className): object
return $result;
}

protected function parsePropertyDocComment($docComment)
{
$lines = explode("\n", $docComment);
foreach ($lines as $line) {
// extract text from @var line
if ($line !== '' && strpos($line, '@var') !== false) {
$text = preg_replace('#\\s*/?[*/]*\\s?(.*)$#', '$1', $line) . "\n";
$text = preg_replace('/@var [^ ]+ ?/', '', $text);
return trim($text);
}
}
return '';
}

protected function parseDocComment($docComment)
{
// TODO: Consider using phpDocumentor (though that splits the docblock into summary and description)
Expand Down Expand Up @@ -237,7 +254,7 @@ public function generatePage(array $tables)
$page->addText(<<<RST
This is a reference of all database tables defined by Kitodo.Presentation.
.. 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.
.. 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 ``typo3 kitodo:dbdocs`` inside the Kitodo.Presentation base folder.
RST);

// Sort tables alphabetically
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* LICENSE.txt file that was distributed with this source code.
*/

namespace Kitodo\DbDocs;
namespace Kitodo\Dlf\Command\DbDocs;

/**
* Simple utility to write .rst (reStructuredText).
Expand Down Expand Up @@ -55,7 +55,7 @@ public static function paragraphs(array $paragraphs)

public function subsection()
{
$section = new static();
$section = new self();
$this->subsections[] = $section;
return $section;
}
Expand Down
92 changes: 92 additions & 0 deletions Classes/Command/DbDocsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/**
* (c) Kitodo. Key to digital objects e.V. <[email protected]>
*
* This file is part of the Kitodo and TYPO3 projects.
*
* @license GNU General Public License version 3 or later.
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/

namespace Kitodo\Dlf\Command;

use Kitodo\Dlf\Common\AbstractDocument;
use Kitodo\Dlf\Common\Indexer;
use Kitodo\Dlf\Command\DbDocs\Generator;
use Kitodo\Dlf\Domain\Model\Document;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;

/**
* CLI Command for generating the reStructuredText file containing documentation
* about the database schema.
*
* @package TYPO3
* @subpackage dlf
*
* @access public
*/
class DbDocsCommand extends Command
{

protected Generator $generator;

public function __construct(Generator $generator)
{
parent::__construct();

$this->generator = $generator;
}

/**
* Configure the command by defining the name, options and arguments
*
* @access public
*
* @return void
*/
public function configure(): void
{
$this
->setDescription('Generate database rst file.')
->setHelp('')
->addArgument('outputPath', InputArgument::OPTIONAL, 'the path to the output rst file');
}

/**
* Executes the command to generate the documentation.
*
* @access protected
*
* @param InputInterface $input The input parameters
* @param OutputInterface $output The Symfony interface for outputs on console
*
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title($this->getDescription());

$outputPath = "kitodo-presentation/Documentation/Developers/Database.rst";
if ($input->getArgument('outputPath')) {
$outputPath = $input->getArgument('outputPath');
}

$tables = $this->generator->collectTables();
$page = $this->generator->generatePage($tables);

GeneralUtility::writeFile($outputPath, $page->render());

$io->write("Database documentation written to output file:\n" . $outputPath . "\n");
return Command::SUCCESS;
}
}
5 changes: 5 additions & 0 deletions Configuration/Services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ services:
Kitodo\Dlf\:
resource: '../Classes/*'

Kitodo\Dlf\Command\DbDocsCommand:
tags:
- name: console.command
command: 'kitodo:dbdocs'

Kitodo\Dlf\Command\DeleteCommand:
tags:
- name: console.command
Expand Down
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Generate the database reference table:

```bash
composer install
composer docs:db
typo3 kitodo:dbdocs
```

### Troubleshooting
Expand Down
Loading

0 comments on commit 16796f5

Please sign in to comment.