vendor/jackalope/jackalope/src/Jackalope/Repository.php line 155

Open in your IDE?
  1. <?php
  2. namespace Jackalope;
  3. use Jackalope\Transaction\UserTransaction;
  4. use ReflectionClass;
  5. use Jackalope\Transport\TransportInterface;
  6. use Jackalope\Transport\TransactionInterface;
  7. use PHPCR\CredentialsInterface;
  8. use PHPCR\RepositoryException;
  9. use PHPCR\RepositoryInterface;
  10. /**
  11. * {@inheritDoc}
  12. *
  13. * @license http://www.apache.org/licenses Apache License Version 2.0, January 2004
  14. * @license http://opensource.org/licenses/MIT MIT License
  15. *
  16. * @api
  17. */
  18. class Repository implements RepositoryInterface
  19. {
  20. /**
  21. * The descriptor key for the version of the specification that this repository implements.
  22. * For JCR 2.0 the value of this descriptor is the string "2.0".
  23. *
  24. * @api
  25. */
  26. const JACKALOPE_OPTION_STREAM_WRAPPER = 'jackalope.option.stream_wrapper';
  27. protected $jackalopeNotImplemented = [
  28. // https://github.com/jackalope/jackalope/issues/217
  29. 'jackalope.not_implemented.node.definition' => true,
  30. // https://github.com/jackalope/jackalope/issues/218
  31. 'jackalope.not_implemented.node.set_primary_type' => true,
  32. // https://github.com/jackalope/jackalope/issues/219
  33. 'jackalope.not_implemented.node.can_add_mixin' => true,
  34. // https://github.com/jackalope/jackalope/issues/220
  35. 'jackalope.not_implemented.node_type.unregister' => true,
  36. // https://github.com/jackalope/jackalope/issues/221
  37. 'jackalope.not_implemented.session.impersonate' => true,
  38. // https://github.com/jackalope/jackalope/issues/222
  39. 'jackalope.not_implemented.session.set_namespace_prefix' => true,
  40. // https://github.com/jackalope/jackalope/issues/54
  41. 'jackalope.not_implemented.version.version_labels' => true,
  42. // https://github.com/jackalope/jackalope/issues/55
  43. 'jackalope.not_implemented.version.merge' => true,
  44. // https://github.com/jackalope/jackalope/issues/224
  45. 'jackalope.not_implemented.version.configuration' => true,
  46. // https://github.com/jackalope/jackalope/issues/223
  47. 'jackalope.not_implemented.version.activity' => true,
  48. // https://github.com/jackalope/jackalope/issues/67
  49. 'jackalope.not_implemented.lock_token' => true,
  50. // https://github.com/jackalope/jackalope/issues/67
  51. 'jackalope.not_implemented.get_lock' => true,
  52. // https://github.com/jackalope/jackalope/issues/67
  53. 'jackalope.not_implemented.non_session_scoped_lock' => true,
  54. ];
  55. /**
  56. * flag to call stream_wrapper_register only once
  57. */
  58. protected static $binaryStreamWrapperRegistered;
  59. /**
  60. * The factory to instantiate objects
  61. *
  62. * @var FactoryInterface
  63. */
  64. protected $factory;
  65. /**
  66. * The transport to use
  67. *
  68. * @var TransportInterface
  69. */
  70. protected $transport;
  71. /**
  72. * List of supported options
  73. *
  74. * @var array
  75. */
  76. protected $options = [
  77. // this is OPTION_TRANSACTIONS_SUPPORTED
  78. 'transactions' => true,
  79. // this is JACKALOPE_OPTION_STREAM_WRAPPER
  80. 'stream_wrapper' => true,
  81. Session::OPTION_AUTO_LASTMODIFIED => true,
  82. ];
  83. /**
  84. * Cached array of repository descriptors. Each is either a string or an
  85. * array of strings.
  86. *
  87. * @var array
  88. */
  89. protected $descriptors;
  90. /**
  91. * Create repository with the option to overwrite the factory and bound to
  92. * a transport.
  93. *
  94. * Use RepositoryFactoryDoctrineDBAL or RepositoryFactoryJackrabbit to
  95. * instantiate this class.
  96. *
  97. * @param FactoryInterface $factory the object factory to use. If this is
  98. * null, the Jackalope\Factory is instantiated. Note that the
  99. * repository is the only class accepting null as factory.
  100. * @param TransportInterface $transport transport implementation
  101. * @param array $options defines optional features to enable/disable (see
  102. * $options property)
  103. */
  104. public function __construct(FactoryInterface $factory = null, TransportInterface $transport, array $options = null)
  105. {
  106. $this->factory = null === $factory ? new Factory() : $factory;
  107. $this->transport = $transport;
  108. $this->options = array_merge($this->options, (array) $options);
  109. $this->options['transactions'] = $this->options['transactions'] && $transport instanceof TransactionInterface;
  110. // register a stream wrapper to lazily load binary property values
  111. if (null === self::$binaryStreamWrapperRegistered) {
  112. self::$binaryStreamWrapperRegistered = $this->options['stream_wrapper'];
  113. if (self::$binaryStreamWrapperRegistered) {
  114. stream_wrapper_register('jackalope', BinaryStreamWrapper::class);
  115. }
  116. }
  117. }
  118. /**
  119. * {@inheritDoc}
  120. *
  121. * @throws \InvalidArgumentException
  122. *
  123. * @api
  124. */
  125. public function login(CredentialsInterface $credentials = null, $workspaceName = null)
  126. {
  127. if (! $workspaceName = $this->transport->login($credentials, $workspaceName)) {
  128. throw new RepositoryException('Transport failed to login without telling why');
  129. }
  130. /** @var $session Session */
  131. $session = $this->factory->get(Session::class, [$this, $workspaceName, $credentials, $this->transport]);
  132. $session->setSessionOption(Session::OPTION_AUTO_LASTMODIFIED, $this->options[Session::OPTION_AUTO_LASTMODIFIED]);
  133. if ($this->options['transactions']) {
  134. $utx = $this->factory->get(UserTransaction::class, [$this->transport, $session, $session->getObjectManager()]);
  135. $session->getWorkspace()->setTransactionManager($utx);
  136. }
  137. return $session;
  138. }
  139. /**
  140. * {@inheritDoc}
  141. *
  142. * @api
  143. */
  144. public function getDescriptorKeys()
  145. {
  146. if (null === $this->descriptors) {
  147. $this->loadDescriptors();
  148. }
  149. return array_keys($this->descriptors);
  150. }
  151. /**
  152. * {@inheritDoc}
  153. *
  154. * @api
  155. */
  156. public function isStandardDescriptor($key)
  157. {
  158. $ref = new ReflectionClass(RepositoryInterface::class);
  159. $consts = $ref->getConstants();
  160. return in_array($key, $consts);
  161. }
  162. /**
  163. * {@inheritDoc}
  164. *
  165. * @api
  166. */
  167. public function getDescriptor($key)
  168. {
  169. // handle some of the keys locally
  170. switch ($key) {
  171. case self::JACKALOPE_OPTION_STREAM_WRAPPER:
  172. return $this->options['stream_wrapper'];
  173. case self::OPTION_TRANSACTIONS_SUPPORTED:
  174. return $this->options['transactions'];
  175. case self::OPTION_LIFECYCLE_SUPPORTED:
  176. case self::OPTION_SHAREABLE_NODES_SUPPORTED:
  177. case self::OPTION_RETENTION_SUPPORTED:
  178. case self::OPTION_ACCESS_CONTROL_SUPPORTED:
  179. return false;
  180. }
  181. if (null === $this->descriptors) {
  182. $this->loadDescriptors();
  183. }
  184. return (isset($this->descriptors[$key])) ? $this->descriptors[$key] : null;
  185. }
  186. /**
  187. * Load the descriptors into $this->descriptors
  188. *
  189. * Most of them come from the transport to allow for non-feature complete
  190. * transports.
  191. *
  192. * @throws RepositoryException
  193. */
  194. protected function loadDescriptors()
  195. {
  196. $this->descriptors = array_merge(
  197. $this->jackalopeNotImplemented,
  198. $this->transport->getRepositoryDescriptors()
  199. );
  200. }
  201. }