vendor/ezsystems/ezcommerce-shop/src/Silversolutions/Bundle/EshopBundle/Services/Mapping/XsltDocumentMappingService.php line 35

Open in your IDE?
  1. <?php
  2. /**
  3.  * @copyright Copyright (C) Ibexa AS. All rights reserved.
  4.  * @license For full copyright and license information view LICENSE file distributed with this source code.
  5.  */
  6. namespace Silversolutions\Bundle\EshopBundle\Services\Mapping;
  7. use eZ\Publish\Core\MVC\ConfigResolverInterface;
  8. use Monolog\Logger;
  9. use Silversolutions\Utilities\Xml\Converter;
  10. use Silversolutions\Utilities\Xslt\Processor;
  11. use Silversolutions\Utilities\Xslt\Reader;
  12. use Symfony\Component\Config\FileLocatorInterface;
  13. /**
  14.  * A mapping service, that uses an XSLT processor to perform the mapping.
  15.  *
  16.  * The XSL mapping files must be stored in a specific directory within one or
  17.  * more bundles. The bundles sub-directory is: Resources/mapping/[targetCode]/xsl,
  18.  * in which [targetCode] must be passed to this class in the constructor.
  19.  * The bundles, which contain mapping directories, must be set with
  20.  * setMappingBundles() or addMappingBundle(). The last passed bundle name is the
  21.  * one with highest priority to match XSL files.
  22.  *
  23.  * The files in these directories follow as specific naming scheme:
  24.  * request|response.[messageCode].xsl
  25.  * The first part determines the direction of the communication. The second part
  26.  * [messageCode] is passed to the map*() methods and defines, which massage is
  27.  * being mapped.
  28.  *
  29.  * The classes from the namespace Silversolutions\Utilies\Xslt are used as a not
  30.  * injected dependency.
  31.  */
  32. class XsltDocumentMappingService extends AbstractDocumentMappingService
  33. {
  34.     /**
  35.      * Injected dependency to a file locator implementation.
  36.      *
  37.      * @var FileLocatorInterface
  38.      */
  39.     protected $fileLocator;
  40.     /**
  41.      * @var string[]
  42.      */
  43.     private $mappingBundles = [];
  44.     /**
  45.      * @var string
  46.      */
  47.     private $mappingOffset;
  48.     /**
  49.      * @var Logger
  50.      */
  51.     protected $logger;
  52.     /** @var ConfigResolverInterface */
  53.     protected $configResolver;
  54.     /**
  55.      * @var bool
  56.      */
  57.     protected $debugMessages false;
  58.     /**
  59.      * @param FileLocatorInterface $fileLocator
  60.      * @param Logger $logger
  61.      * @param bool $debugMessages
  62.      * @param ConfigResolverInterface $configResolver
  63.      */
  64.     public function __construct(FileLocatorInterface $fileLocatorLogger $logger$debugMessagesConfigResolverInterface $configResolver)
  65.     {
  66.         $this->fileLocator $fileLocator;
  67.         $this->logger $logger;
  68.         $this->debugMessages = (bool)$debugMessages;
  69.         $this->configResolver $configResolver;
  70.     }
  71.     /**
  72.      * Sets properties.
  73.      */
  74.     public function setProperties()
  75.     {
  76.         $targetCode $this->configResolver->getParameter('target_code''siso_erp');
  77.         $this->mappingOffset '/Resources/mapping/' $targetCode '/xsl/';
  78.         //mappingBundles
  79.         $bundleNames $this->configResolver->getParameter('mapping_bundles''siso_erp');
  80.         $this->mappingBundles = [];
  81.         if (is_array($bundleNames)) {
  82.             foreach ($bundleNames as $bundleName) {
  83.                 $this->addMappingBundle($bundleName);
  84.             }
  85.         }
  86.     }
  87.     /**
  88.      * Config dependency.
  89.      *
  90.      * @param string $bundleName
  91.      */
  92.     final public function addMappingBundle($bundleName)
  93.     {
  94.         if (is_string($bundleName) && $bundleName !== '') {
  95.             if ($bundleName[0] != '@') {
  96.                 $bundleName '@' $bundleName;
  97.             }
  98.             array_unshift($this->mappingBundles$bundleName $this->mappingOffset);
  99.         }
  100.     }
  101.     /**
  102.      * Maps a request document. It must be given in form of an array.
  103.      *
  104.      * @param array $serializedDocument
  105.      * @param string $mappingIdentifier
  106.      *
  107.      * @return array
  108.      */
  109.     public function mapRequest($serializedDocument$mappingIdentifier)
  110.     {
  111.         return $this->process('request'$serializedDocument$mappingIdentifier);
  112.     }
  113.     /**
  114.      * Maps a response document. It must be given in form of an array.
  115.      *
  116.      * @param array $serializedDocument
  117.      * @param string $mappingIdentifier
  118.      *
  119.      * @return array
  120.      */
  121.     public function mapResponse($serializedDocument$mappingIdentifier)
  122.     {
  123.         return $this->process('response'$serializedDocument$mappingIdentifier);
  124.     }
  125.     /**
  126.      * Common implementation of the mapping.
  127.      *
  128.      * @param string $type
  129.      * @param string $serializedDocument
  130.      * @param string $mappingIdentifier
  131.      *
  132.      * @throws \RuntimeException May be thrown during XSLT/XML processing
  133.      * @throws \InvalidArgumentException If given parameters are invalid
  134.      *
  135.      * @return array
  136.      */
  137.     protected function process($type$serializedDocument$mappingIdentifier)
  138.     {
  139.         if (!is_array($serializedDocument) && !is_string($serializedDocument)) {
  140.             throw new \InvalidArgumentException(
  141.                 'Given document data for mapping must be a well formed XML string or XML convertible array'
  142.             );
  143.         }
  144.         if (!is_string($mappingIdentifier) || empty($mappingIdentifier)) {
  145.             throw new \InvalidArgumentException(
  146.                 'Given message code must be non empty string'
  147.             );
  148.         }
  149.         if (empty($this->mappingBundles)) {
  150.             throw new \RuntimeException('Mapping-Bundles must not be empty, please check your configuration!');
  151.         }
  152.         try {
  153.             $reader = new Reader($this->fileLocator);
  154.             $xslFilePath $reader->getFilePath($type$mappingIdentifier$this->mappingBundles);
  155.             $xslContent $reader->getFileContent($type$mappingIdentifier$this->mappingBundles);
  156.             $xslt = new Processor($serializedDocument$xslContent$xslFilePath);
  157.             $converter = new Converter($xslt->process('dom'));
  158.             $transformedXml $converter->getXml();
  159.             $this->debugMessage($serializedDocument$transformedXml$xslFilePath$type);
  160.             return $transformedXml;
  161.         } catch (\Exception $exception) {
  162.             throw new \RuntimeException(
  163.                 'An error occurred during XSLT processing: ' $exception->getMessage(),
  164.                 $exception->getCode(),
  165.                 $exception
  166.             );
  167.         }
  168.     }
  169.     /**
  170.      * @param string $xmlInput
  171.      * @param string $xmlOutput
  172.      * @param string $xslStylesheet
  173.      * @param string $mappingType
  174.      */
  175.     protected function debugMessage($xmlInput$xmlOutput$xslStylesheet$mappingType)
  176.     {
  177.         if ($this->debugMessages) {
  178.             $logMessage 'Transformed XML using: ' $xslStylesheet;
  179.             $mappingData = [
  180.                 'mapping_type' => $mappingType,
  181.                 'stylesheet' => $xslStylesheet,
  182.                 'input_xml' => $xmlInput,
  183.                 'output_xml' => $xmlOutput,
  184.             ];
  185.             $this->logger->debug($logMessage, ['mapping_data' => $mappingData]);
  186.         }
  187.     }
  188. }