diff --git a/Build/Documentation/dbdocs/generate.php b/Build/Documentation/dbdocs/generate.php deleted file mode 100755 index bf6578cab5..0000000000 --- a/Build/Documentation/dbdocs/generate.php +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env php - - * - * 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. - */ - -$classLoader = require_once __DIR__ . '/../../../vendor/autoload.php'; - -$outputPath = $argv[1] ?? null; -if (empty($outputPath) || !is_writable(($outputPath))) { - echo 'Error: Output path not specified or not writable' . "\n"; - exit(1); -} - -putenv('TYPO3_PATH_ROOT=' . __DIR__ . '/public'); -putenv('TYPO3_PATH_APP=' . __DIR__); - -// For compatibility with TYPO v9 -define('PATH_thisScript', __FILE__); - -// For request types other than "FE", the configuration manager would try to access the database. -\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(1, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_FE); -\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader, false); - -$generator = new \Kitodo\DbDocs\Generator(); -$tables = $generator->collectTables(); -$page = $generator->generatePage($tables); -file_put_contents($outputPath, $page->render()); diff --git a/Build/Documentation/dbdocs/public/typo3 b/Build/Documentation/dbdocs/public/typo3 deleted file mode 120000 index e8b61495a1..0000000000 --- a/Build/Documentation/dbdocs/public/typo3 +++ /dev/null @@ -1 +0,0 @@ -../../../../public/typo3 \ No newline at end of file diff --git a/Build/Documentation/dbdocs/public/typo3conf/LocalConfiguration.php b/Build/Documentation/dbdocs/public/typo3conf/LocalConfiguration.php deleted file mode 100644 index 1134704633..0000000000 --- a/Build/Documentation/dbdocs/public/typo3conf/LocalConfiguration.php +++ /dev/null @@ -1,15 +0,0 @@ - [ - 'caching' => [ - 'cacheConfigurations' => [ - // When DataMapFactory checks the cache, it shouldn't try to access the database - 'extbase_datamapfactory_datamap' => [ - 'backend' => \TYPO3\CMS\Core\Cache\Backend\NullBackend::class, - ], - ], - ], - 'encryptionKey' => 'TYPO3 wants an encryption key here, but it should not be needed.', - ], -]; diff --git a/Build/Documentation/dbdocs/public/typo3conf/PackageStates.php b/Build/Documentation/dbdocs/public/typo3conf/PackageStates.php deleted file mode 100644 index 7f45da40a7..0000000000 --- a/Build/Documentation/dbdocs/public/typo3conf/PackageStates.php +++ /dev/null @@ -1,31 +0,0 @@ - [ - 'core' => [ - 'packagePath' => 'typo3/sysext/core/', - ], - 'recordlist' => [ - 'packagePath' => 'typo3/sysext/recordlist/', - ], - 'backend' => [ - 'packagePath' => 'typo3/sysext/backend/', - ], - 'extbase' => [ - 'packagePath' => 'typo3/sysext/extbase/', - ], - 'tstemplate' => [ - 'packagePath' => 'typo3/sysext/tstemplate/', - ], - 'dlf' => [ - 'packagePath' => 'typo3conf/ext/dlf/', - ], - ], - 'version' => 5, -]; diff --git a/Build/Documentation/dbdocs/public/typo3conf/ext/dlf b/Build/Documentation/dbdocs/public/typo3conf/ext/dlf deleted file mode 120000 index 305f2077ff..0000000000 --- a/Build/Documentation/dbdocs/public/typo3conf/ext/dlf +++ /dev/null @@ -1 +0,0 @@ -../../../../../.. \ No newline at end of file diff --git a/Build/Documentation/dbdocs/Generator.php b/Classes/Command/DbDocs/Generator.php similarity index 82% rename from Build/Documentation/dbdocs/Generator.php rename to Classes/Command/DbDocs/Generator.php index b42a016be9..2064293a5e 100644 --- a/Build/Documentation/dbdocs/Generator.php +++ b/Classes/Command/DbDocs/Generator.php @@ -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; /** @@ -53,14 +57,6 @@ class Generator */ protected $configurationManager; - /** - * @param LanguageService $languageService - */ - public function injectLanguageService(LanguageService $languageService) - { - $this->languageService = $languageService; - } - /** * @param DataMapper $dataMapper */ @@ -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; } @@ -87,7 +83,7 @@ public function injectConfigurationManager(ConfigurationManager $configurationMa public function __construct() { - + $this->languageService = GeneralUtility::makeInstance(LanguageService::class); } /** @@ -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; } @@ -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()); } } @@ -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) @@ -237,7 +254,7 @@ public function generatePage(array $tables) $page->addText(<<subsections[] = $section; return $section; } diff --git a/Classes/Command/DbDocsCommand.php b/Classes/Command/DbDocsCommand.php new file mode 100644 index 0000000000..55ad1339ae --- /dev/null +++ b/Classes/Command/DbDocsCommand.php @@ -0,0 +1,92 @@ + + * + * 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; + } +} diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 95812b25f7..d9bcc950a2 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -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 diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index e58dad0ceb..07fdf3bec6 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -119,7 +119,7 @@ Generate the database reference table: ```bash composer install -composer docs:db +typo3 kitodo:dbdocs ``` ### Troubleshooting diff --git a/Documentation/Developers/Database.rst b/Documentation/Developers/Database.rst index 4f7edaf6c7..24ee1996c1 100644 --- a/Documentation/Developers/Database.rst +++ b/Documentation/Developers/Database.rst @@ -4,7 +4,7 @@ Database Tables 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. tx_dlf_actionlog: Action protocol ================================= @@ -20,10 +20,10 @@ Extbase domain model: ``Kitodo\Dlf\Domain\Model\ActionLog`` :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: crdate  *integer* :description: @@ -63,10 +63,10 @@ Extbase domain model: ``Kitodo\Dlf\Domain\Model\Basket`` :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -86,6 +86,9 @@ Extbase domain model: ``Kitodo\Dlf\Domain\Model\Basket`` - :field: l18n_diffsource  *blob* :description: + - :field: l10n_state  *text* + :description: + - :field: label  *string* :description: *Basket* @@ -112,10 +115,10 @@ Domain model of the 'Collection'. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -144,6 +147,9 @@ Domain model of the 'Collection'. - :field: l18n_diffsource  *blob* :description: + - :field: l10n_state  *text* + :description: + - :field: hidden  *smallint* :description: *Hide* @@ -199,10 +205,10 @@ Domain model of the 'Document'. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: *Last Modified* @@ -338,10 +344,10 @@ For more information, see the documentation page on metadata. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -399,10 +405,10 @@ A library institution with the following use cases: :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -425,6 +431,9 @@ A library institution with the following use cases: - :field: l18n_diffsource  *blob* :description: + - :field: l10n_state  *text* + :description: + - :field: label  *string* :description: *Name* @@ -437,8 +446,7 @@ A library institution with the following use cases: - :field: contact  *string* :description: *Contact* - Contact email address of the library (used as ``adminEmail`` in responses - to OAI ``Identify`` requests). + Contact email address of the library (used as ``adminEmail`` in responses to OAI ``Identify`` requests). - :field: image  *string* :description: *Logo* @@ -448,8 +456,7 @@ A library institution with the following use cases: - :field: oai_label  *string* :description: *Open Archives Interface (OAI) Label* - The label that is used as ``repositoryName`` in responses to OAI - ``Identify`` requests. + The label that is used as ``repositoryName`` in responses to OAI ``Identify`` requests - :field: oai_base  *string* :description: *Open Archives Interface (OAI) Base URL* @@ -485,10 +492,10 @@ Extbase domain model: ``Kitodo\Dlf\Domain\Model\Mail`` :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: deleted  *smallint* :description: @@ -522,10 +529,10 @@ A metadata kind (title, year, ...) and its configuration for display and indexin :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -548,6 +555,9 @@ A metadata kind (title, year, ...) and its configuration for display and indexin - :field: l18n_diffsource  *blob* :description: + - :field: l10n_state  *text* + :description: + - :field: hidden  *smallint* :description: *Hide* @@ -563,7 +573,7 @@ A metadata kind (title, year, ...) and its configuration for display and indexin - :field: format  *integer* :description: *Data Format* - The formats that encode this metadatum (local IRRE field to ``tx_dlf_metadataformat``). + The formats that encode this metadata (local IRRE field to ``tx_dlf_metadataformat``). - :field: default_value  *string* :description: *Default Value* @@ -606,7 +616,7 @@ tx_dlf_metadataformat: Metadata Format Extbase domain model: ``Kitodo\Dlf\Domain\Model\MetadataFormat`` -This specifies a way how a metadatum (``tx_dlf_metadata``) may be encoded in a specific data format (``tx_dlf_format``). +This specifies a way how a metadata (``tx_dlf_metadata``) may be encoded in a specific data format (``tx_dlf_format``). For instance, the title of a document may be obtained from either the MODS title field, or from the TEIHDR caption. This is modeled as two ``tx_dlf_metadaformat`` @@ -621,10 +631,10 @@ This contains the xpath expressions on the model 'Metadata'. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -638,11 +648,8 @@ This contains the xpath expressions on the model 'Metadata'. - :field: deleted  *smallint* :description: - - :field: sys_language_uid  *integer* - :description: *Language* - - - :field: l18n_parent  *integer* - :description: *Transl.Orig* + - :field: l10n_state  *text* + :description: - :field: parent_id  *integer* :description: UID of the ``tx_dlf_metadata`` that is encoded by this metadata entry. @@ -655,17 +662,85 @@ This contains the xpath expressions on the model 'Metadata'. - :field: xpath  *string* :description: *XPath (relative to //dmdSec/mdWrap/xmlData/root and with namespace) or JSONPath (relative to resource JSON object)* - XPath/JSONPath expression to extract the metadatum (relative to the data format root). + XPath/JSONPath expression to extract the metadata (relative to the data format root). - :field: xpath_sorting  *string* :description: *XPath / JSONPath for sorting (optional)* - XPath/JSONPath expression to extract sorting variant (suffixed ``_sorting``) of the metadatum. + XPath/JSONPath expression to extract sorting variant (suffixed ``_sorting``) of the metadata. + + - :field: subentries  *integer* + :description: - :field: mandatory  *smallint* :description: *Mandatory field?* - - Whether or not the field is mandatory. Not used at the moment (originally planned to be used in METS validator). + + + + +tx_dlf_metadatasubentries: Metadata +=================================== + +Extbase domain model: ``Kitodo\Dlf\Domain\Model\MetadataSubentry`` + +This specifies a way how a metadatum (``tx_dlf_metadata``) may be encoded in a specific data format (``tx_dlf_format``). + +For instance, the title of a document may be obtained from either the MODS +title field, or from the TEIHDR caption. This is modeled as two ``tx_dlf_metadaformat`` +that refer to the same ``tx_dlf_metadata`` but different ``tx_dlf_format``. + +This contains the xpath expressions on the model 'Metadata'. + +.. t3-field-list-table:: + :header-rows: 1 + + - :field: Field + :description: Description + + - :field: **uid**  *integer* + :description: The uid of the record. The uid is only unique in the context of the database table. + + - :field: pid  *integer* + :description: The id of the page the record is "stored". + + - :field: parent_id  *integer* + :description: + + - :field: tstamp  *integer* + :description: + + - :field: crdate  *integer* + :description: + + - :field: cruser_id  *integer* + :description: + + - :field: deleted  *smallint* + :description: + + - :field: sys_language_uid  *integer* + :description: + + - :field: l18n_parent  *integer* + :description: + + - :field: l18n_diffsource  *blob* + :description: + + - :field: label  *string* + :description: *Display Label* + + - :field: index_name  *string* + :description: *Index Name* + + - :field: xpath  *string* + :description: *XPath (relative to //dmdSec/mdWrap/xmlData/root and with namespace) or JSONPath (relative to resource JSON object)* + + - :field: default_value  *string* + :description: *Default Value* + + - :field: wrap  *text* + :description: *TypoScript-Wrap* @@ -684,10 +759,10 @@ Extbase domain model: ``Kitodo\Dlf\Domain\Model\Printer`` :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: deleted  *smallint* :description: @@ -752,7 +827,7 @@ In particular, this holds the index name of the used Solr core. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* :description: @@ -796,10 +871,10 @@ Domain model of 'Structure'. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: @@ -822,6 +897,9 @@ Domain model of 'Structure'. - :field: l18n_diffsource  *blob* :description: + - :field: l10n_state  *text* + :description: + - :field: hidden  *smallint* :description: *Hide* @@ -846,8 +924,8 @@ Domain model of 'Structure'. -tx_dlf_tokens -============= +tx_dlf_tokens: Tokens +===================== Extbase domain model: ``Kitodo\Dlf\Domain\Model\Token`` @@ -860,10 +938,10 @@ Resumption tokens for OAI-PMH interface. :description: Description - :field: **uid**  *integer* - :description: + :description: The uid of the record. The uid is only unique in the context of the database table. - :field: pid  *integer* - :description: + :description: The id of the page the record is "stored". - :field: tstamp  *integer* :description: Timestamp of the token used to determine if it has expired. diff --git a/composer.json b/composer.json index 4a75953177..1458d46451 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,6 @@ }, "autoload-dev": { "psr-4": { - "Kitodo\\DbDocs\\": "Build/Documentation/dbdocs", "Kitodo\\Dlf\\Tests\\": "Tests/" } }, @@ -101,9 +100,6 @@ "test:func:watch": [ "@test:func -w" ], - "docs:db": [ - "./Build/Documentation/dbdocs/generate.php ./Documentation/Developers/Database.rst" - ], "docs:build": [ "rm -Rf ./Documentation-GENERATED-temp", "docker run --user=$(id -u):$(id -g) --rm -v ./:/project -it ghcr.io/typo3-documentation/render-guides:latest --config ./Documentation",