vendor/jackalope/jackalope/src/Jackalope/NamespaceRegistry.php line 220

Open in your IDE?
  1. <?php
  2. namespace Jackalope;
  3. use Iterator;
  4. use ArrayIterator;
  5. use IteratorAggregate;
  6. use PHPCR\UnsupportedRepositoryOperationException;
  7. use PHPCR\ItemNotFoundException;
  8. use PHPCR\NamespaceRegistryInterface;
  9. use PHPCR\NamespaceException;
  10. use Jackalope\Transport\TransportInterface;
  11. use Jackalope\Transport\WritingInterface;
  12. /**
  13.  * {@inheritDoc}
  14.  *
  15.  * @license http://www.apache.org/licenses Apache License Version 2.0, January 2004
  16.  * @license http://opensource.org/licenses/MIT MIT License
  17.  */
  18. class NamespaceRegistry implements IteratorAggregateNamespaceRegistryInterface
  19. {
  20.     /**
  21.      * Instance of an implementation of the TransportInterface
  22.      * @var WritingInterface
  23.      */
  24.     protected $transport;
  25.     /**
  26.      * The factory to instantiate objects
  27.      * @var FactoryInterface
  28.      */
  29.     protected $factory;
  30.     /**
  31.      * List of predefined namespaces.
  32.      *
  33.      * @var array
  34.      */
  35.     protected $defaultNamespaces = [
  36.         self::PREFIX_JCR   => self::NAMESPACE_JCR,
  37.         self::PREFIX_SV    => self::NAMESPACE_SV,
  38.         self::PREFIX_NT    => self::NAMESPACE_NT,
  39.         self::PREFIX_MIX   => self::NAMESPACE_MIX,
  40.         self::PREFIX_XML   => self::NAMESPACE_XML,
  41.         self::PREFIX_EMPTY => self::NAMESPACE_EMPTY,
  42.     ];
  43.     /**
  44.      * Set of namespaces registered by the user.
  45.      *
  46.      * @var array
  47.      */
  48.     protected $userNamespaces null;
  49.     /**
  50.      * Initializes the created object.
  51.      *
  52.      * @param FactoryInterface   $factory
  53.      * @param TransportInterface $transport
  54.      *
  55.      * @throws ItemNotFoundException If property not found
  56.      */
  57.     public function __construct(FactoryInterface $factoryTransportInterface $transport)
  58.     {
  59.         $this->factory $factory;
  60.         $this->transport $transport;
  61.     }
  62.     /**
  63.      * Makes sure the namespaces are available.
  64.      *
  65.      * We are lazy and only load the namespaces when they are needed for the
  66.      * first time. This method has to be called by all methods that need to
  67.      * do something with user defined namespaces.
  68.      */
  69.     protected function lazyLoadNamespaces()
  70.     {
  71.         if ($this->userNamespaces === null) {
  72.             $namespaces $this->transport->getNamespaces();
  73.             $this->userNamespaces = [];
  74.             foreach ($namespaces as $prefix => $uri) {
  75.                 if (! array_key_exists($prefix$this->defaultNamespaces)) {
  76.                     $this->userNamespaces[$prefix] = $uri;
  77.                 }
  78.             }
  79.         }
  80.     }
  81.     /**
  82.      * {@inheritDoc}
  83.      *
  84.      * @api
  85.      */
  86.     public function registerNamespace($prefix$uri)
  87.     {
  88.         if (! $this->transport instanceof WritingInterface) {
  89.             throw new UnsupportedRepositoryOperationException('Transport does not support writing');
  90.         }
  91.         // prevent default namespace prefixes to be overridden.
  92.         $this->checkPrefix($prefix);
  93.         // prevent default namespace uris to be overridden
  94.         if (false !== array_search($uri$this->defaultNamespaces)) {
  95.             throw new NamespaceException("Can not change default namespace $prefix = $uri");
  96.         }
  97.         $this->lazyLoadNamespaces();
  98.         //first try putting the stuff in backend, and only afterwards update local info
  99.         // this has no impact on running sessions, go directly to storage
  100.         $this->transport->registerNamespace($prefix$uri);
  101.         // update local info
  102.         if (false !== $oldpref array_search($uri$this->userNamespaces)) {
  103.             // the backend takes care of storing this, but we have to update frontend info
  104.             unset($this->userNamespaces[$oldpref]);
  105.         }
  106.         $this->userNamespaces[$prefix] = $uri;
  107.     }
  108.     /**
  109.      * {@inheritDoc}
  110.      *
  111.      * @api
  112.      */
  113.     public function unregisterNamespaceByURI($uri)
  114.     {
  115.         if (! $this->transport instanceof WritingInterface) {
  116.             throw new UnsupportedRepositoryOperationException('Transport does not support writing');
  117.         }
  118.         $this->lazyLoadNamespaces();
  119.         $prefix array_search($uri$this->userNamespaces);
  120.         if ($prefix === false) {
  121.             throw new NamespaceException("Namespace '$uri' is not currently registered");
  122.         }
  123.         // now check whether this is a prefix out of the defaultNamespaces in checkPrefix
  124.         $this->checkPrefix($prefix);
  125.         $this->transport->unregisterNamespace($prefix);
  126.         //remove the prefix from the local userNamespaces array
  127.         unset($this->userNamespaces[$prefix]);
  128.     }
  129.     /**
  130.      * {@inheritDoc}
  131.      *
  132.      * @api
  133.      */
  134.     public function getPrefixes()
  135.     {
  136.         $this->lazyLoadNamespaces();
  137.         return array_merge(
  138.             array_keys($this->defaultNamespaces),
  139.             array_keys($this->userNamespaces)
  140.         );
  141.     }
  142.     /**
  143.      * {@inheritDoc}
  144.      *
  145.      * @api
  146.      */
  147.     public function getURIs()
  148.     {
  149.         $this->lazyLoadNamespaces();
  150.         return array_merge(
  151.             array_values($this->defaultNamespaces),
  152.             array_values($this->userNamespaces)
  153.         );
  154.     }
  155.     /**
  156.      * {@inheritDoc}
  157.      *
  158.      * @api
  159.      */
  160.     public function getURI($prefix)
  161.     {
  162.         $this->lazyLoadNamespaces();
  163.         if (isset($this->defaultNamespaces[$prefix])) {
  164.             return $this->defaultNamespaces[$prefix];
  165.         } elseif (isset($this->userNamespaces[$prefix])) {
  166.             $this->lazyLoadNamespaces();
  167.             return $this->userNamespaces[$prefix];
  168.         }
  169.         throw new NamespaceException("Mapping for '$prefix' is not defined");
  170.     }
  171.     /**
  172.      * {@inheritDoc}
  173.      *
  174.      * @api
  175.      */
  176.     public function getPrefix($uri)
  177.     {
  178.         $prefix array_search($uri$this->defaultNamespaces);
  179.         if ($prefix === false) {
  180.             $this->lazyLoadNamespaces();
  181.             $prefix array_search($uri$this->userNamespaces);
  182.             if ($prefix === false) {
  183.                 throw new NamespaceException("URI '$uri' is not defined in registry");
  184.             }
  185.         }
  186.         return $prefix;
  187.     }
  188.     /**
  189.      * Provide Traversable interface: iterator over all namespaces
  190.      *
  191.      * @return Iterator over all namespaces, with prefix as key and url as value
  192.      */
  193.     public function getIterator()
  194.     {
  195.         $this->lazyLoadNamespaces();
  196.         return new ArrayIterator(array_merge($this->defaultNamespaces$this->userNamespaces));
  197.     }
  198.     /**
  199.      * Implement verification if this is a valid prefix
  200.      *
  201.      * Throws the NamespaceException if trying to use one of the
  202.      * built-in prefixes or a prefix that begins with the characters "xml"
  203.      * (in any combination of case)
  204.      *
  205.      * @param string $prefix the prefix name to check
  206.      *
  207.      * @throws NamespaceException if re-assign built-in prefix or prefix starting with xml
  208.      *
  209.      * @private
  210.      * TODO: can we refactor Session::setNamespacePrefix to not need to directly access this?
  211.      */
  212.     public function checkPrefix($prefix)
  213.     {
  214.         if (! strncasecmp('xml'$prefix3)) {
  215.             throw new NamespaceException("Do not use xml in prefixes for namespace changes: '$prefix'");
  216.         }
  217.         if (array_key_exists($prefix$this->defaultNamespaces)) {
  218.             throw new NamespaceException("Do not change the predefined prefixes: '$prefix'");
  219.         }
  220.         if (false !== strpos($prefix' ') || false !== strpos($prefix':')) {
  221.             throw new NamespaceException("Not a valid namespace prefix '$prefix'");
  222.         }
  223.     }
  224.     /**
  225.      * Get all defined namespaces
  226.      *
  227.      * @private
  228.      */
  229.     public function getNamespaces()
  230.     {
  231.         $this->lazyLoadNamespaces();
  232.         return array_merge($this->defaultNamespaces$this->userNamespaces);
  233.     }
  234. }