1
0

ServerContainer.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Joas Schilling <coding@schilljs.com>
  6. *
  7. * @license AGPL-3.0
  8. *
  9. * This code is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License, version 3,
  11. * as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU Affero General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License, version 3,
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>
  20. *
  21. */
  22. namespace OC;
  23. use OC\AppFramework\App;
  24. use OC\AppFramework\DependencyInjection\DIContainer;
  25. use OC\AppFramework\Utility\SimpleContainer;
  26. use OCP\AppFramework\QueryException;
  27. /**
  28. * Class ServerContainer
  29. *
  30. * @package OC
  31. */
  32. class ServerContainer extends SimpleContainer {
  33. /** @var DIContainer[] */
  34. protected $appContainers;
  35. /** @var string[] */
  36. protected $hasNoAppContainer;
  37. /** @var string[] */
  38. protected $namespaces;
  39. /**
  40. * ServerContainer constructor.
  41. */
  42. public function __construct() {
  43. parent::__construct();
  44. $this->appContainers = [];
  45. $this->namespaces = [];
  46. $this->hasNoAppContainer = [];
  47. }
  48. /**
  49. * @param string $appName
  50. * @param string $appNamespace
  51. */
  52. public function registerNamespace($appName, $appNamespace) {
  53. // Cut of OCA\ and lowercase
  54. $appNamespace = strtolower(substr($appNamespace, strrpos($appNamespace, '\\') + 1));
  55. $this->namespaces[$appNamespace] = $appName;
  56. }
  57. /**
  58. * @param string $appName
  59. * @param DIContainer $container
  60. */
  61. public function registerAppContainer($appName, DIContainer $container) {
  62. $this->appContainers[strtolower(App::buildAppNamespace($appName, ''))] = $container;
  63. }
  64. /**
  65. * @param string $namespace
  66. * @param string $sensitiveNamespace
  67. * @return DIContainer
  68. * @throws QueryException
  69. */
  70. protected function getAppContainer($namespace, $sensitiveNamespace) {
  71. if (isset($this->appContainers[$namespace])) {
  72. return $this->appContainers[$namespace];
  73. }
  74. if (isset($this->namespaces[$namespace])) {
  75. if (!isset($this->hasNoAppContainer[$namespace])) {
  76. $applicationClassName = 'OCA\\' . $sensitiveNamespace . '\\AppInfo\\Application';
  77. if (class_exists($applicationClassName)) {
  78. new $applicationClassName();
  79. if (isset($this->appContainers[$namespace])) {
  80. return $this->appContainers[$namespace];
  81. }
  82. }
  83. $this->hasNoAppContainer[$namespace] = true;
  84. }
  85. return new DIContainer($this->namespaces[$namespace]);
  86. }
  87. throw new QueryException();
  88. }
  89. /**
  90. * @param string $name name of the service to query for
  91. * @return mixed registered service for the given $name
  92. * @throws QueryException if the query could not be resolved
  93. */
  94. public function query($name) {
  95. $name = $this->sanitizeName($name);
  96. if (isset($this[$name])) {
  97. return $this[$name];
  98. }
  99. // In case the service starts with OCA\ we try to find the service in
  100. // the apps container first.
  101. if (strpos($name, 'OCA\\') === 0 && substr_count($name, '\\') >= 2) {
  102. $segments = explode('\\', $name);
  103. try {
  104. $appContainer = $this->getAppContainer(strtolower($segments[1]), $segments[1]);
  105. return $appContainer->queryNoFallback($name);
  106. } catch (QueryException $e) {
  107. // Didn't find the service or the respective app container,
  108. // ignore it and fall back to the core container.
  109. }
  110. } else if (strpos($name, 'OC\\Settings\\') === 0 && substr_count($name, '\\') >= 3) {
  111. $segments = explode('\\', $name);
  112. try {
  113. $appContainer = $this->getAppContainer(strtolower($segments[1]), $segments[1]);
  114. return $appContainer->queryNoFallback($name);
  115. } catch (QueryException $e) {
  116. // Didn't find the service or the respective app container,
  117. // ignore it and fall back to the core container.
  118. }
  119. }
  120. return parent::query($name);
  121. }
  122. }