nextcloud/lib/private/CapabilitiesManager.php
Roeland Jago Douma c044aa34fa
Make the capabilities manager more error proof
If an app registers an invalid capabilty we should not crash hard.
Instead we should catch the exception. Log it (error) and carry on.

* Added tests
2016-08-15 20:37:19 +02:00

79 lines
2.1 KiB
PHP

<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC;
use OCP\AppFramework\QueryException;
use OCP\Capabilities\ICapability;
use OCP\ILogger;
class CapabilitiesManager {
/** @var \Closure[] */
private $capabilities = array();
/** @var ILogger */
private $logger;
public function __construct(ILogger $logger) {
$this->logger = $logger;
}
/**
* Get an array of al the capabilities that are registered at this manager
*
* @throws \InvalidArgumentException
* @return array
*/
public function getCapabilities() {
$capabilities = [];
foreach($this->capabilities as $capability) {
try {
$c = $capability();
} catch (QueryException $e) {
$this->logger->error('CapabilitiesManager: {message}', ['app' => 'core', 'message' => $e->getMessage()]);
continue;
}
if ($c instanceof ICapability) {
$capabilities = array_replace_recursive($capabilities, $c->getCapabilities());
} else {
throw new \InvalidArgumentException('The given Capability (' . get_class($c) . ') does not implement the ICapability interface');
}
}
return $capabilities;
}
/**
* In order to improve lazy loading a closure can be registered which will be called in case
* capabilities are actually requested
*
* $callable has to return an instance of OCP\Capabilities\ICapability
*
* @param \Closure $callable
*/
public function registerCapability(\Closure $callable) {
array_push($this->capabilities, $callable);
}
}