1<?php
2
3declare(strict_types=1);
4
5/**
6 * @copyright 2017 Christoph Wurst <christoph@winzerhof-wurst.at>
7 *
8 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
9 * @author Roeland Jago Douma <roeland@famdouma.nl>
10 *
11 * @license GNU AGPL version 3 or any later version
12 *
13 * This program is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Affero General Public License as
15 * published by the Free Software Foundation, either version 3 of the
16 * License, or (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Affero General Public License for more details.
22 *
23 * You should have received a copy of the GNU Affero General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 *
26 */
27
28namespace OC\Contacts\ContactsMenu;
29
30use Exception;
31use OC\App\AppManager;
32use OC\Contacts\ContactsMenu\Providers\EMailProvider;
33use OC\Contacts\ContactsMenu\Providers\ProfileProvider;
34use OCP\AppFramework\QueryException;
35use OCP\Contacts\ContactsMenu\IProvider;
36use OCP\IServerContainer;
37use OCP\IUser;
38use Psr\Log\LoggerInterface;
39
40class ActionProviderStore {
41
42	/** @var IServerContainer */
43	private $serverContainer;
44
45	/** @var AppManager */
46	private $appManager;
47
48	/** @var LoggerInterface */
49	private $logger;
50
51	public function __construct(IServerContainer $serverContainer, AppManager $appManager, LoggerInterface $logger) {
52		$this->serverContainer = $serverContainer;
53		$this->appManager = $appManager;
54		$this->logger = $logger;
55	}
56
57	/**
58	 * @param IUser $user
59	 * @return IProvider[]
60	 * @throws Exception
61	 */
62	public function getProviders(IUser $user): array {
63		$appClasses = $this->getAppProviderClasses($user);
64		$providerClasses = $this->getServerProviderClasses();
65		$allClasses = array_merge($providerClasses, $appClasses);
66		$providers = [];
67
68		foreach ($allClasses as $class) {
69			try {
70				$providers[] = $this->serverContainer->query($class);
71			} catch (QueryException $ex) {
72				$this->logger->error(
73					'Could not load contacts menu action provider ' . $class,
74					[
75						'app' => 'core',
76						'exception' => $ex,
77					]
78				);
79				throw new Exception('Could not load contacts menu action provider');
80			}
81		}
82
83		return $providers;
84	}
85
86	/**
87	 * @return string[]
88	 */
89	private function getServerProviderClasses(): array {
90		return [
91			ProfileProvider::class,
92			EMailProvider::class,
93		];
94	}
95
96	/**
97	 * @param IUser $user
98	 * @return string[]
99	 */
100	private function getAppProviderClasses(IUser $user): array {
101		return array_reduce($this->appManager->getEnabledAppsForUser($user), function ($all, $appId) {
102			$info = $this->appManager->getAppInfo($appId);
103
104			if (!isset($info['contactsmenu'])) {
105				// Nothing to add
106				return $all;
107			}
108
109			$providers = array_reduce($info['contactsmenu'], function ($all, $provider) {
110				return array_merge($all, [$provider]);
111			}, []);
112
113			return array_merge($all, $providers);
114		}, []);
115	}
116}
117