OCMProvider.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\OCM\Model;
  8. use OCP\EventDispatcher\IEventDispatcher;
  9. use OCP\OCM\Events\ResourceTypeRegisterEvent;
  10. use OCP\OCM\Exceptions\OCMArgumentException;
  11. use OCP\OCM\Exceptions\OCMProviderException;
  12. use OCP\OCM\IOCMProvider;
  13. use OCP\OCM\IOCMResource;
  14. /**
  15. * @since 28.0.0
  16. */
  17. class OCMProvider implements IOCMProvider {
  18. private bool $enabled = false;
  19. private string $apiVersion = '';
  20. private string $endPoint = '';
  21. /** @var IOCMResource[] */
  22. private array $resourceTypes = [];
  23. private bool $emittedEvent = false;
  24. public function __construct(
  25. protected IEventDispatcher $dispatcher,
  26. ) {
  27. }
  28. /**
  29. * @param bool $enabled
  30. *
  31. * @return $this
  32. */
  33. public function setEnabled(bool $enabled): static {
  34. $this->enabled = $enabled;
  35. return $this;
  36. }
  37. /**
  38. * @return bool
  39. */
  40. public function isEnabled(): bool {
  41. return $this->enabled;
  42. }
  43. /**
  44. * @param string $apiVersion
  45. *
  46. * @return $this
  47. */
  48. public function setApiVersion(string $apiVersion): static {
  49. $this->apiVersion = $apiVersion;
  50. return $this;
  51. }
  52. /**
  53. * @return string
  54. */
  55. public function getApiVersion(): string {
  56. return $this->apiVersion;
  57. }
  58. /**
  59. * @param string $endPoint
  60. *
  61. * @return $this
  62. */
  63. public function setEndPoint(string $endPoint): static {
  64. $this->endPoint = $endPoint;
  65. return $this;
  66. }
  67. /**
  68. * @return string
  69. */
  70. public function getEndPoint(): string {
  71. return $this->endPoint;
  72. }
  73. /**
  74. * create a new resource to later add it with {@see IOCMProvider::addResourceType()}
  75. * @return IOCMResource
  76. */
  77. public function createNewResourceType(): IOCMResource {
  78. return new OCMResource();
  79. }
  80. /**
  81. * @param IOCMResource $resource
  82. *
  83. * @return $this
  84. */
  85. public function addResourceType(IOCMResource $resource): static {
  86. $this->resourceTypes[] = $resource;
  87. return $this;
  88. }
  89. /**
  90. * @param IOCMResource[] $resourceTypes
  91. *
  92. * @return $this
  93. */
  94. public function setResourceTypes(array $resourceTypes): static {
  95. $this->resourceTypes = $resourceTypes;
  96. return $this;
  97. }
  98. /**
  99. * @return IOCMResource[]
  100. */
  101. public function getResourceTypes(): array {
  102. if (!$this->emittedEvent) {
  103. $this->emittedEvent = true;
  104. $event = new ResourceTypeRegisterEvent($this);
  105. $this->dispatcher->dispatchTyped($event);
  106. }
  107. return $this->resourceTypes;
  108. }
  109. /**
  110. * @param string $resourceName
  111. * @param string $protocol
  112. *
  113. * @return string
  114. * @throws OCMArgumentException
  115. */
  116. public function extractProtocolEntry(string $resourceName, string $protocol): string {
  117. foreach ($this->getResourceTypes() as $resource) {
  118. if ($resource->getName() === $resourceName) {
  119. $entry = $resource->getProtocols()[$protocol] ?? null;
  120. if (is_null($entry)) {
  121. throw new OCMArgumentException('protocol not found');
  122. }
  123. return (string)$entry;
  124. }
  125. }
  126. throw new OCMArgumentException('resource not found');
  127. }
  128. /**
  129. * import data from an array
  130. *
  131. * @param array $data
  132. *
  133. * @return $this
  134. * @throws OCMProviderException in case a descent provider cannot be generated from data
  135. * @see self::jsonSerialize()
  136. */
  137. public function import(array $data): static {
  138. $this->setEnabled(is_bool($data['enabled'] ?? '') ? $data['enabled'] : false)
  139. ->setApiVersion((string)($data['apiVersion'] ?? ''))
  140. ->setEndPoint($data['endPoint'] ?? '');
  141. $resources = [];
  142. foreach (($data['resourceTypes'] ?? []) as $resourceData) {
  143. $resource = new OCMResource();
  144. $resources[] = $resource->import($resourceData);
  145. }
  146. $this->setResourceTypes($resources);
  147. if (!$this->looksValid()) {
  148. throw new OCMProviderException('remote provider does not look valid');
  149. }
  150. return $this;
  151. }
  152. /**
  153. * @return bool
  154. */
  155. private function looksValid(): bool {
  156. return ($this->getApiVersion() !== '' && $this->getEndPoint() !== '');
  157. }
  158. /**
  159. * @return array{
  160. * enabled: bool,
  161. * apiVersion: string,
  162. * endPoint: string,
  163. * resourceTypes: array{
  164. * name: string,
  165. * shareTypes: string[],
  166. * protocols: array<string, string>
  167. * }[]
  168. * }
  169. */
  170. public function jsonSerialize(): array {
  171. $resourceTypes = [];
  172. foreach ($this->getResourceTypes() as $res) {
  173. $resourceTypes[] = $res->jsonSerialize();
  174. }
  175. return [
  176. 'enabled' => $this->isEnabled(),
  177. 'apiVersion' => $this->getApiVersion(),
  178. 'endPoint' => $this->getEndPoint(),
  179. 'resourceTypes' => $resourceTypes
  180. ];
  181. }
  182. }