Commit 4805aceb authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Module StepStar : amorce de changement de stratégie pour la transformation XSL...

Module StepStar : amorce de changement de stratégie pour la transformation XSL : utilisation de l'outil en ligne de commande 'transform'
parent f869a470
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ use StepStar\Service\Tef\TefService;
use StepStar\Service\Tef\TefServiceFactory;
use StepStar\Service\Xml\XmlService;
use StepStar\Service\Xml\XmlServiceFactory;
use StepStar\Service\Xsl\XslService;
use StepStar\Service\Xsl\XslServiceFactory;
use StepStar\Service\Xslt\XsltService;
use StepStar\Service\Xslt\XsltServiceFactory;
use StepStar\Service\Zip\ZipService;
@@ -83,7 +85,7 @@ return [
                'autoriteSudoc_etabSoutenance' => '123456789',
                'thesesRootTag' => 'THESES',
                'theseTag' => 'THESE',
                'resultDocumentHref' => '{$ETABLISSEMENT}_{THESE_ID}_{CODE_ETAB_SOUT}_{CODE_ETUDIANT}.xml',
//                'resultDocumentHref' => '{$ETABLISSEMENT}_{THESE_ID}_{CODE_ETAB_SOUT}_{CODE_ETUDIANT}.tef.xml',
            ],
        ],
        'api' => [
@@ -408,6 +410,7 @@ return [
            EnvoiFacade::class => EnvoiFacadeFactory::class,

            XmlService::class => XmlServiceFactory::class,
            XslService::class => XslServiceFactory::class,
            XsltService::class => XsltServiceFactory::class,
            TefService::class => TefServiceFactory::class,
            ApiService::class => ApiServiceFactory::class,
+5 −5
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ que ces méta sont saisies dans les formulaires STAR. C'est au choix.
                    ID="{$ETABLISSEMENT}_{THESE_ID}_{CODE_ETAB_SOUT}_{CODE_ETUDIANT}"
                    OBJID="{THESE_ID}_{CODE_ETAB_SOUT}_{CODE_ETUDIANT}">
                <!-- Création du bloc de md desciptives de la thèse -->
                <mets:dmdSec ID="{generate-id()}_desc_these">
                <mets:dmdSec ID="these_{CODE_ETAB_SOUT}_{THESE_ID}">
                    <mets:mdWrap MDTYPE="OTHER" OTHERMDTYPE="tef_desc_these">
                        <mets:xmlData>
                            <tef:thesisRecord>
@@ -113,7 +113,7 @@ que ces méta sont saisies dans les formulaires STAR. C'est au choix.
                <!-- Pas de md descriptives de l'édition -->
                <!-- Création du bloc de md administratives de la thèse -->
                <mets:amdSec>
                    <mets:techMD ID="{generate-id()}_admin">
                    <mets:techMD ID="these_{CODE_ETAB_SOUT}_{THESE_ID}_admin">
                        <mets:mdWrap MDTYPE="OTHER" OTHERMDTYPE="tef_admin_these">
                            <mets:xmlData>
                                <tef:thesisAdmin>
@@ -456,7 +456,7 @@ que ces méta sont saisies dans les formulaires STAR. C'est au choix.

                    <!--Déclaration des droits-->
                    <!--Déclaration de l'autorisation du chef d'établissement-->
                    <mets:rightsMD ID="{generate-id()}_etab">
                    <mets:rightsMD ID="these_{CODE_ETAB_SOUT}_{THESE_ID}_etab">
                        <mets:mdWrap MDTYPE="OTHER" OTHERMDTYPE="tef_droits_etablissement_these">
                            <mets:xmlData>
                                <metsRights:RightsDeclarationMD>
@@ -597,8 +597,8 @@ que ces méta sont saisies dans les formulaires STAR. C'est au choix.
                <mets:structMap TYPE="logical">
                    <mets:div
                            TYPE="THESE"
                            ADMID="{generate-id()}_admin {generate-id()}_etab"
                            DMDID="{generate-id()}_desc_these"
                            ADMID="these_{CODE_ETAB_SOUT}_{THESE_ID}_admin these_{CODE_ETAB_SOUT}_{THESE_ID}_etab"
                            DMDID="these_{CODE_ETAB_SOUT}_{THESE_ID}_desc_these"
                            CONTENTIDS="info:fides/STAR/{$ETABLISSEMENT}/{CODE_ETUDIANT}">
                    </mets:div>
                </mets:structMap>
+60 −0
Original line number Diff line number Diff line
<?php

namespace StepStar\Command;

use Application\Command\ShellCommand;

/**
 * Transformation XSL utilisant l'utilitaire en ligne de commande 'transform' de SaxonC,
 * utilitaire qui doit être buildée et dispo dans le PATH du serveur.
 *
 * @see https://www.saxonica.com/saxon-c/documentation11/index.html#!starting/running (Command line interface)
 */
class TransformShellCommand extends ShellCommand
{
    protected string $executable = 'transform';
    protected bool $verbose = false;
    protected string $xslFilePath;

    /**
     * @param string $xslFilePath
     * @return self
     */
    public function setXslFilePath(string $xslFilePath): self
    {
        $this->xslFilePath = $xslFilePath;
        return $this;
    }

    /**
     * @param bool $verbose
     * @return self
     */
    public function setVerbose(bool $verbose = true): self
    {
        $this->verbose = $verbose;
        return $this;
    }

    /**
     * @inheritDoc
     */
    public function getName(): string
    {
        return 'transform';
    }

    /**
     * @inheritDoc
     */
    public function generateCommandLine()
    {
        $parts = [
            $this->executable,
            $this->verbose ? '-t' : null,
            sprintf("-s:'%s' -xsl:'%s' -o:'%s'", $this->inputFilePath, $this->xslFilePath, $this->outputFilePath),
        ];

        $this->commandLine = implode(' ', array_filter($parts));
    }
}
 No newline at end of file
+70 −11
Original line number Diff line number Diff line
@@ -15,18 +15,22 @@ use StepStar\Service\Api\ApiServiceAwareTrait;
use StepStar\Service\Log\LogServiceAwareTrait;
use StepStar\Service\Tef\TefServiceAwareTrait;
use StepStar\Service\Xml\XmlServiceAwareTrait;
use StepStar\Service\Xsl\XslServiceAwareTrait;

class EnvoiFacade
{
    use LogServiceAwareTrait;
    use XslServiceAwareTrait;
    use XmlServiceAwareTrait;
    use TefServiceAwareTrait;
    use ApiServiceAwareTrait;

    use LoggerAwareTrait;

    private string $tefResultDocumentHref = '{$ETABLISSEMENT}_{THESE_ID}_{CODE_ETAB_SOUT}_{CODE_ETUDIANT}.xml';
    private string $tefResultDocumentHrefTheseIdPregMatchPattern = '/^.+_(.+)_.+_.+\.xml$/U';
    // ATTENTION, la partie extension doit exprimer "la même chose" dans les 3 propriétés suivantes :
    private string $tefResultDocumentHref = '{$ETABLISSEMENT}_{THESE_ID}_{CODE_ETAB_SOUT}_{CODE_ETUDIANT}.tef.xml';
    private string $tefResultDocumentHrefTheseIdPregMatchPattern = '/^.+_(.+)_.+_.+\.tef\.xml$/U';
    private string $listXmlFilesInDirectoryGlobPattern = '*.tef.xml';

    private bool $saveLog;

@@ -48,8 +52,8 @@ class EnvoiFacade
     */
    public function envoyerTheses(array $theses, bool $force, string $command): Generator
    {
        $xmlFilePath = tempnam(sys_get_temp_dir(), 'sygal_xml_') . '.xml';
        $outputDir = sys_get_temp_dir() . '/' . uniqid('out_');
        $inputDir = sys_get_temp_dir() . '/' . uniqid('sygal_xml_input_');
        $outputDir = sys_get_temp_dir() . '/' . uniqid('sygal_xml_output_');

        /**
         * Generation du fichier XML intermediaire (1 pour N theses) & des fichiers TEF (1 par these).
@@ -59,8 +63,8 @@ class EnvoiFacade
        $this->newLog($operation, $command);
        $success = true;
        try {
            $this->genererXmlForTheses($theses, $xmlFilePath);
            $this->genererTef($outputDir, $xmlFilePath);
            $this->genererXmlForThesesInDir($theses, $inputDir);
            $this->generateTefFromDir($inputDir, $outputDir);
        } catch (Exception $e) {
            $this->appendExceptionToLog($e);
            $success = false;
@@ -150,9 +154,33 @@ class EnvoiFacade
    }

    /**
     * @param array $theses Thèses à exporter au format XML.
     * @param string $outputDirPath Répertoire destination dans lequel générer le fichier XML
     * @return string Chemin du fichier XML généré
     * @throws \Exception
     */
    private function genererXmlForTheses(array $theses, string $xmlFilePath)
    private function genererXmlForThesesInDir(array $theses, string $outputDirPath): string
    {
        if (!is_dir($outputDirPath)) {
            $ok = mkdir($outputDirPath);
            if (!$ok) {
                throw new Exception("Impossible de créer le répertoire '$outputDirPath'.");
            }
        }

        $xmlFilePath = $outputDirPath . '/' . uniqid('sygal_xml_') . '.xml';

        $this->generateXmlForThesesInFile($theses, $xmlFilePath);

        return $xmlFilePath;
    }

    /**
     * @param array $theses Thèses à exporter au format XML.
     * @param string $xmlFilePath Chemin du fichier XML à générer
     * @throws \Exception
     */
    private function generateXmlForThesesInFile(array $theses, string $xmlFilePath)
    {
        $theseIds = implode(',', array_map(fn($these) => $these['id'], $theses));

@@ -188,7 +216,7 @@ class EnvoiFacade
    /**
     * @throws \Exception
     */
    private function genererXmlForThese(array $these, string $xmlFilePath)
    private function generateXmlForThese(array $these, string $xmlFilePath)
    {
        $theseId = $these['id'];
        $this->appendToLog("Generation du fichier XML contenant la these $theseId dans $xmlFilePath");
@@ -211,7 +239,37 @@ class EnvoiFacade
    /**
     * @throws \Exception
     */
    private function genererTef(string $outputDir, string $xmlInputFilePath)
    private function generateTefFromDir(string $inputDirPath, string $outputDir)
    {
        $this->appendToLog(sprintf(
            "Generation des fichiers TEF (1 par these) dans %s, a partir du repertoire %s :",
            $outputDir, $inputDirPath
        ));

//        $this->xslService->setOutputDir($inputDirPath);
        try {
            $xslFilePath = $this->xslService->generateXslFile($this->tefResultDocumentHref);
        } catch (TefServiceException $e) {
            throw new Exception("Une erreur est survenue pendant la generation du fichier XSL.", null, $e);
        }

        $this->tefService->setOutputDir($outputDir);
        try {
            $this->tefService->generateTefFilesFromDir($inputDirPath, $xslFilePath);
        } catch (TefServiceException $e) {
            throw new Exception("Une erreur est survenue pendant la generation des fichiers TEF.", null, $e);
        }

        $paths = $this->listXmlFilesInDirectory($outputDir);
        foreach ($paths as $path) {
            $this->appendToLog("> " . realpath($path));
        }
    }

    /**
     * @throws \Exception
     */
    private function generateTefFromFile(string $xmlInputFilePath, string $outputDir)
    {
        $this->appendToLog(sprintf(
            "Generation des fichiers TEF (1 par these) dans %s, a partir du fichier XML intermediaire %s :",
@@ -220,7 +278,8 @@ class EnvoiFacade

        $this->tefService->setOutputDir($outputDir);
        try {
            $this->tefService->generateTefFilesFromXml($xmlInputFilePath, $this->tefResultDocumentHref);
            $xslFilePath = $this->xslService->generateXslFile($this->tefResultDocumentHref);
            $this->tefService->generateTefFilesFromFile($xmlInputFilePath, $xslFilePath);
        } catch (TefServiceException $e) {
            throw new Exception("Une erreur est survenue pendant la generation des fichiers TEF.", null, $e);
        }
@@ -254,6 +313,6 @@ class EnvoiFacade
     */
    private function listXmlFilesInDirectory(string $dir): array
    {
        return Glob::glob($dir . '/*.xml', Glob::GLOB_BRACE);
        return Glob::glob($dir . '/' . $this->listXmlFilesInDirectoryGlobPattern, Glob::GLOB_BRACE);
    }
}
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ use StepStar\Service\Api\ApiService;
use StepStar\Service\Log\LogService;
use StepStar\Service\Tef\TefService;
use StepStar\Service\Xml\XmlService;
use StepStar\Service\Xsl\XslService;

class EnvoiFacadeFactory
{
@@ -24,6 +25,12 @@ class EnvoiFacadeFactory
        $xmlService = $container->get(XmlService::class);
        $facade->setXmlService($xmlService);

        /**
         * @var \StepStar\Service\Xsl\XslService $xslService
         */
        $xslService = $container->get(XslService::class);
        $facade->setXslService($xslService);

        /**
         * @var \StepStar\Service\Tef\TefService $tefService
         */
Loading