vendor/sulu/sulu/src/Sulu/Component/Webspace/Manager/WebspaceCollectionBuilder.php line 110

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Component\Webspace\Manager;
  11. use Sulu\Bundle\AdminBundle\Metadata\FormMetadata\TypedFormMetadata;
  12. use Sulu\Component\Localization\Localization;
  13. use Sulu\Component\Webspace\Analyzer\RequestAnalyzerInterface;
  14. use Sulu\Component\Webspace\Environment;
  15. use Sulu\Component\Webspace\Exception\InvalidTemplateException;
  16. use Sulu\Component\Webspace\Portal;
  17. use Sulu\Component\Webspace\PortalInformation;
  18. use Sulu\Component\Webspace\Url;
  19. use Sulu\Component\Webspace\Url\ReplacerInterface;
  20. use Sulu\Component\Webspace\Webspace;
  21. use Symfony\Component\Config\Loader\LoaderInterface;
  22. use Symfony\Component\Config\Resource\FileResource;
  23. use Symfony\Component\Finder\Finder;
  24. class WebspaceCollectionBuilder
  25. {
  26.     /**
  27.      * The loader for the xml config files.
  28.      *
  29.      * @var LoaderInterface
  30.      */
  31.     private $loader;
  32.     /**
  33.      * @var ReplacerInterface
  34.      */
  35.     private $urlReplacer;
  36.     /**
  37.      * The path to the xml config files.
  38.      *
  39.      * @var string
  40.      */
  41.     private $path;
  42.     /**
  43.      * The webspaces for the configured path.
  44.      *
  45.      * @var Webspace[]
  46.      */
  47.     private $webspaces;
  48.     /**
  49.      * The portals for the configured path.
  50.      *
  51.      * @var Portal[]
  52.      */
  53.     private $portals;
  54.     /**
  55.      * The portal informations for the configured path.
  56.      *
  57.      * @var PortalInformation[][]
  58.      */
  59.     private $portalInformations;
  60.     /**
  61.      * @var TypedFormMetadata
  62.      */
  63.     private $typedFormMetadata;
  64.     /**
  65.      * @var array
  66.      */
  67.     private $availableTemplates;
  68.     public function __construct(
  69.         LoaderInterface $loader,
  70.         ReplacerInterface $urlReplacer,
  71.         $path,
  72.         array $availableTemplates
  73.     ) {
  74.         $this->loader $loader;
  75.         $this->urlReplacer $urlReplacer;
  76.         $this->path $path;
  77.         $this->availableTemplates $availableTemplates;
  78.     }
  79.     public function build()
  80.     {
  81.         $finder = new Finder();
  82.         $finder->in($this->path)->files()->name('*.xml')->sortByName();
  83.         // Iterate over config files, and add a portal object for each config to the collection
  84.         $collection = new WebspaceCollection();
  85.         // reset arrays
  86.         $this->webspaces = [];
  87.         $this->portals = [];
  88.         $this->portalInformations = [];
  89.         foreach ($finder as $file) {
  90.             // add file resource for cache invalidation
  91.             $collection->addResource(new FileResource($file->getRealPath()));
  92.             /** @var Webspace $webspace */
  93.             $webspace $this->loader->load($file->getRealPath());
  94.             foreach ($webspace->getDefaultTemplates() as $defaultTemplate) {
  95.                 if (!\in_array($defaultTemplate$this->availableTemplates)) {
  96.                     throw new InvalidTemplateException($webspace$defaultTemplate);
  97.                 }
  98.                 if (\in_array($defaultTemplate$webspace->getExcludedTemplates())) {
  99.                     throw new InvalidTemplateException($webspace$defaultTemplate);
  100.                 }
  101.             }
  102.             $this->webspaces[$webspace->getKey()] = $webspace;
  103.             $this->buildPortals($webspace);
  104.         }
  105.         $environments \array_keys($this->portalInformations);
  106.         foreach ($environments as $environment) {
  107.             // sort all portal informations by length
  108.             \uksort(
  109.                 $this->portalInformations[$environment],
  110.                 function($a$b) {
  111.                     return \strlen($a) < \strlen($b) ? : -1;
  112.                 }
  113.             );
  114.         }
  115.         $collection->setWebspaces($this->webspaces);
  116.         $collection->setPortals($this->portals);
  117.         $collection->setPortalInformations($this->portalInformations);
  118.         return $collection;
  119.     }
  120.     private function buildPortals(Webspace $webspace)
  121.     {
  122.         foreach ($webspace->getPortals() as $portal) {
  123.             $this->portals[] = $portal;
  124.             $this->buildEnvironments($portal);
  125.         }
  126.     }
  127.     private function buildEnvironments(Portal $portal)
  128.     {
  129.         foreach ($portal->getEnvironments() as $environment) {
  130.             $this->buildEnvironment($portal$environment);
  131.         }
  132.     }
  133.     private function buildEnvironment(Portal $portalEnvironment $environment)
  134.     {
  135.         foreach ($environment->getUrls() as $url) {
  136.             $urlAddress $url->getUrl();
  137.             $urlRedirect $url->getRedirect();
  138.             if (null == $urlRedirect) {
  139.                 $this->buildUrls($portal$environment$url$urlAddress);
  140.             } else {
  141.                 // create the redirect
  142.                 $this->buildUrlRedirect(
  143.                     $portal->getWebspace(),
  144.                     $environment,
  145.                     $portal,
  146.                     $urlAddress,
  147.                     $urlRedirect,
  148.                     $url
  149.                 );
  150.             }
  151.         }
  152.         foreach ($environment->getCustomUrls() as $customUrl) {
  153.             $urlAddress $customUrl->getUrl();
  154.             $this->portalInformations[$environment->getType()][$urlAddress] = new PortalInformation(
  155.                 RequestAnalyzerInterface::MATCH_TYPE_WILDCARD,
  156.                 $portal->getWebspace(),
  157.                 $portal,
  158.                 null,
  159.                 $urlAddress,
  160.                 null,
  161.                 null,
  162.                 false,
  163.                 $urlAddress,
  164.                 1
  165.             );
  166.         }
  167.     }
  168.     /**
  169.      * @param string $urlAddress
  170.      * @param string $urlRedirect
  171.      */
  172.     private function buildUrlRedirect(
  173.         Webspace $webspace,
  174.         Environment $environment,
  175.         Portal $portal,
  176.         $urlAddress,
  177.         $urlRedirect,
  178.         Url $url
  179.     ) {
  180.         $this->portalInformations[$environment->getType()][$urlAddress] = new PortalInformation(
  181.             RequestAnalyzerInterface::MATCH_TYPE_REDIRECT,
  182.             $webspace,
  183.             $portal,
  184.             null,
  185.             $urlAddress,
  186.             null,
  187.             $urlRedirect,
  188.             $url->isMain(),
  189.             $url->getUrl(),
  190.             $this->urlReplacer->hasHostReplacer($urlAddress) ? 9
  191.         );
  192.     }
  193.     /**
  194.      * @param string[] $replacers
  195.      * @param string $urlAddress
  196.      */
  197.     private function buildUrlFullMatch(
  198.         Portal $portal,
  199.         Environment $environment,
  200.         $replacers,
  201.         $urlAddress,
  202.         Localization $localization,
  203.         Url $url
  204.     ) {
  205.         $urlResult $this->generateUrlAddress($urlAddress$replacers);
  206.         $this->portalInformations[$environment->getType()][$urlResult] = new PortalInformation(
  207.             RequestAnalyzerInterface::MATCH_TYPE_FULL,
  208.             $portal->getWebspace(),
  209.             $portal,
  210.             $localization,
  211.             $urlResult,
  212.             null,
  213.             null,
  214.             $url->isMain(),
  215.             $url->getUrl(),
  216.             $this->urlReplacer->hasHostReplacer($urlResult) ? 10
  217.         );
  218.     }
  219.     /**
  220.      * @param string $urlAddress
  221.      */
  222.     private function buildUrlPartialMatch(
  223.         Portal $portal,
  224.         Environment $environment,
  225.         $urlAddress,
  226.         Url $url
  227.     ) {
  228.         $replacers = [];
  229.         $urlResult $this->urlReplacer->cleanup(
  230.             $urlAddress,
  231.             [
  232.                 ReplacerInterface::REPLACER_LANGUAGE,
  233.                 ReplacerInterface::REPLACER_COUNTRY,
  234.                 ReplacerInterface::REPLACER_LOCALIZATION,
  235.                 ReplacerInterface::REPLACER_SEGMENT,
  236.             ]
  237.         );
  238.         $urlRedirect $this->generateUrlAddress($urlAddress$replacers);
  239.         if ($this->validateUrlPartialMatch($urlResult$environment)) {
  240.             $this->portalInformations[$environment->getType()][$urlResult] = new PortalInformation(
  241.                 RequestAnalyzerInterface::MATCH_TYPE_PARTIAL,
  242.                 $portal->getWebspace(),
  243.                 $portal,
  244.                 null,
  245.                 $urlResult,
  246.                 null,
  247.                 $urlRedirect,
  248.                 false// partial matches cannot be main
  249.                 $url->getUrl(),
  250.                 $this->urlReplacer->hasHostReplacer($urlResult) ? 9
  251.             );
  252.         }
  253.     }
  254.     /**
  255.      * Builds the URLs for the portal, which are not a redirect.
  256.      *
  257.      * @param string $urlAddress
  258.      */
  259.     private function buildUrls(
  260.         Portal $portal,
  261.         Environment $environment,
  262.         Url $url,
  263.         $urlAddress
  264.     ) {
  265.         if ($url->getLanguage()) {
  266.             $language $url->getLanguage();
  267.             $country $url->getCountry();
  268.             $locale $language . ($country '_' $country '');
  269.             $replacers = [
  270.                 ReplacerInterface::REPLACER_LANGUAGE => $language,
  271.                 ReplacerInterface::REPLACER_COUNTRY => $country,
  272.                 ReplacerInterface::REPLACER_LOCALIZATION => $locale,
  273.             ];
  274.             $this->buildUrlFullMatch(
  275.                 $portal,
  276.                 $environment,
  277.                 $replacers,
  278.                 $urlAddress,
  279.                 $portal->getLocalization($locale),
  280.                 $url
  281.             );
  282.         } else {
  283.             // create all the urls for every localization combination
  284.             foreach ($portal->getLocalizations() as $localization) {
  285.                 $language $url->getLanguage() ? $url->getLanguage() : $localization->getLanguage();
  286.                 $country $url->getCountry() ? $url->getCountry() : $localization->getCountry();
  287.                 $replacers = [
  288.                     ReplacerInterface::REPLACER_LANGUAGE => $language,
  289.                     ReplacerInterface::REPLACER_COUNTRY => $country,
  290.                     ReplacerInterface::REPLACER_LOCALIZATION => $localization->getLocale(Localization::DASH),
  291.                 ];
  292.                 $this->buildUrlFullMatch(
  293.                     $portal,
  294.                     $environment,
  295.                     $replacers,
  296.                     $urlAddress,
  297.                     $localization,
  298.                     $url
  299.                 );
  300.             }
  301.         }
  302.         $this->buildUrlPartialMatch(
  303.             $portal,
  304.             $environment,
  305.             $urlAddress,
  306.             $url
  307.         );
  308.     }
  309.     /**
  310.      * @param string $urlResult
  311.      *
  312.      * @return bool
  313.      */
  314.     private function validateUrlPartialMatch($urlResultEnvironment $environment)
  315.     {
  316.         return
  317.             // only valid if there is no full match already
  318.             !\array_key_exists($urlResult$this->portalInformations[$environment->getType()])
  319.             // check if last character is no dot
  320.             && '.' != \substr($urlResult, -1);
  321.     }
  322.     /**
  323.      * Replaces the given values in the pattern.
  324.      *
  325.      * @param string $pattern
  326.      * @param array $replacers
  327.      *
  328.      * @return string
  329.      */
  330.     private function generateUrlAddress($pattern$replacers)
  331.     {
  332.         foreach ($replacers as $replacer => $value) {
  333.             $pattern $this->urlReplacer->replace($pattern$replacer$value);
  334.         }
  335.         return $pattern;
  336.     }
  337. }