You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.5 KiB

3 years ago
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
  5. *
  6. * @author Julius Härtl <jus@bitgrid.net>
  7. *
  8. * @license GNU AGPL version 3 or any later version
  9. *
  10. * This program is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU Affero General Public License as
  12. * published by the Free Software Foundation, either version 3 of the
  13. * License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Affero General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. namespace OC\Dashboard;
  25. use InvalidArgumentException;
  26. use OCP\AppFramework\QueryException;
  27. use OCP\Dashboard\IManager;
  28. use OCP\Dashboard\IWidget;
  29. use OCP\ILogger;
  30. use OCP\IServerContainer;
  31. use Throwable;
  32. class Manager implements IManager {
  33. /** @var array */
  34. private $lazyWidgets = [];
  35. /** @var IWidget[] */
  36. private $widgets = [];
  37. /** @var IServerContainer */
  38. private $serverContainer;
  39. public function __construct(IServerContainer $serverContainer) {
  40. $this->serverContainer = $serverContainer;
  41. }
  42. private function registerWidget(IWidget $widget): void {
  43. if (array_key_exists($widget->getId(), $this->widgets)) {
  44. throw new InvalidArgumentException('Dashboard widget with this id has already been registered');
  45. }
  46. $this->widgets[$widget->getId()] = $widget;
  47. }
  48. public function lazyRegisterWidget(string $widgetClass): void {
  49. $this->lazyWidgets[] = $widgetClass;
  50. }
  51. public function loadLazyPanels(): void {
  52. $classes = $this->lazyWidgets;
  53. foreach ($classes as $class) {
  54. try {
  55. /** @var IWidget $widget */
  56. $widget = $this->serverContainer->query($class);
  57. } catch (QueryException $e) {
  58. /*
  59. * There is a circular dependency between the logger and the registry, so
  60. * we can not inject it. Thus the static call.
  61. */
  62. \OC::$server->getLogger()->logException($e, [
  63. 'message' => 'Could not load lazy dashbaord widget: ' . $e->getMessage(),
  64. 'level' => ILogger::FATAL,
  65. ]);
  66. }
  67. /**
  68. * Try to register the loaded reporter. Theoretically it could be of a wrong
  69. * type, so we might get a TypeError here that we should catch.
  70. */
  71. try {
  72. $this->registerWidget($widget);
  73. } catch (Throwable $e) {
  74. /*
  75. * There is a circular dependency between the logger and the registry, so
  76. * we can not inject it. Thus the static call.
  77. */
  78. \OC::$server->getLogger()->logException($e, [
  79. 'message' => 'Could not register lazy dashboard widget: ' . $e->getMessage(),
  80. 'level' => ILogger::FATAL,
  81. ]);
  82. }
  83. try {
  84. $startTime = microtime(true);
  85. $widget->load();
  86. $endTime = microtime(true);
  87. $duration = $endTime - $startTime;
  88. if ($duration > 1) {
  89. \OC::$server->getLogger()->error('Dashboard widget {widget} took {duration} seconds to load.', [
  90. 'widget' => $widget->getId(),
  91. 'duration' => round($duration, 2),
  92. ]);
  93. }
  94. } catch (Throwable $e) {
  95. \OC::$server->getLogger()->logException($e, [
  96. 'message' => 'Error during dashboard widget loading: ' . $e->getMessage(),
  97. 'level' => ILogger::FATAL,
  98. ]);
  99. }
  100. }
  101. $this->lazyWidgets = [];
  102. }
  103. public function getWidgets(): array {
  104. $this->loadLazyPanels();
  105. return $this->widgets;
  106. }
  107. }