diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index a43dc88f4100dd4310f3d78fa7548d9e69eb5966..6aa0d939510973efb20ea739860be418309efcb6 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -138,6 +138,31 @@ $config = array( 'result-scroller' => 'VuFind\Controller\Plugin\ResultScroller', ) ), + 'ils_driver_plugin_manager' => array( + 'abstract_factories' => array('VuFind\ILS\Driver\PluginFactory'), + 'invokables' => array( + 'aleph' => 'VuFind\ILS\Driver\Aleph', + 'amicus' => 'VuFind\ILS\Driver\Amicus', + 'daia' => 'VuFind\ILS\Driver\DAIA', + 'demo' => 'VuFind\ILS\Driver\Demo', + 'evergreen' => 'VuFind\ILS\Driver\Evergreen', + 'horizon' => 'VuFind\ILS\Driver\Horizon', + 'horizonxmlapi' => 'VuFind\ILS\Driver\HorizonXMLAPI', + 'innovative' => 'VuFind\ILS\Driver\Innovative', + 'koha' => 'VuFind\ILS\Driver\Koha', + 'newgenlib' => 'VuFind\ILS\Driver\NewGenLib', + 'noils' => 'VuFind\ILS\Driver\NoILS', + 'pica' => 'VuFind\ILS\Driver\PICA', + 'sample' => 'VuFind\ILS\Driver\Sample', + 'symphony' => 'VuFind\ILS\Driver\Symphony', + 'unicorn' => 'VuFind\ILS\Driver\Unicorn', + 'virtua' => 'VuFind\ILS\Driver\Virtua', + 'voyager' => 'VuFind\ILS\Driver\Voyager', + 'voyagerrestful' => 'VuFind\ILS\Driver\VoyagerRestful', + 'xcncip' => 'VuFind\ILS\Driver\XCNCIP', + 'xcncip2' => 'VuFind\ILS\Driver\XCNCIP2', + ), + ), 'recommend_plugin_manager' => array( 'abstract_factories' => array('VuFind\Recommend\PluginFactory'), 'invokables' => array( diff --git a/module/VuFind/src/VuFind/Bootstrap.php b/module/VuFind/src/VuFind/Bootstrap.php index 99b1257c46d87d746fd01b81e6e3a2a77000ea5f..0f1a5135b42299a3f8febf07a828def83dfb059d 100644 --- a/module/VuFind/src/VuFind/Bootstrap.php +++ b/module/VuFind/src/VuFind/Bootstrap.php @@ -90,11 +90,13 @@ class Bootstrap $config = $app->getConfig(); // Use naming conventions to set up a bunch of services based on namespace: - $namespaces = array('Auth', 'Autocomplete', 'Recommend', 'Session'); + $namespaces = array( + 'Auth', 'Autocomplete', 'ILS\Driver', 'Recommend', 'Session' + ); foreach ($namespaces as $ns) { - $serviceName = $ns . 'PluginManager'; + $serviceName = str_replace('\\', '', $ns) . 'PluginManager'; $className = 'VuFind\\' . $ns . '\PluginManager'; - $configKey = strtolower($ns) . '_plugin_manager'; + $configKey = strtolower(str_replace('\\', '_', $ns)) . '_plugin_manager'; $service = new $className( new ServiceManagerConfig($config[$configKey]) ); @@ -109,6 +111,9 @@ class Bootstrap $manager = new \VuFind\Search\Manager($config['search_manager']); $manager->setServiceLocator($serviceManager); $serviceManager->setService('SearchManager', $manager); + + // TODO: factor out static connection manager. + \VuFind\Connection\Manager::setServiceLocator($serviceManager); } /** diff --git a/module/VuFind/src/VuFind/Connection/Manager.php b/module/VuFind/src/VuFind/Connection/Manager.php index ff8231da477aa65883e9185c2ea77ab53a649192..cdd6d0b3559e1f505b56f5a20e39b270cbf80dc1 100644 --- a/module/VuFind/src/VuFind/Connection/Manager.php +++ b/module/VuFind/src/VuFind/Connection/Manager.php @@ -27,7 +27,8 @@ */ namespace VuFind\Connection; -use VuFind\Config\Reader as ConfigReader, VuFind\ILS\Connection as ILSConnection; +use VuFind\Config\Reader as ConfigReader, VuFind\ILS\Connection as ILSConnection, + Zend\ServiceManager\ServiceLocatorInterface; /** * Central class for connecting to resources used by VuFind. @@ -40,6 +41,20 @@ use VuFind\Config\Reader as ConfigReader, VuFind\ILS\Connection as ILSConnection */ class Manager { + protected static $serviceLocator; + + /** + * Set the service locator. + * + * @param ServiceLocatorInterface $serviceLocator Locator to register + * + * @return void + */ + public static function setServiceLocator(ServiceLocatorInterface $serviceLocator) + { + self::$serviceLocator = $serviceLocator; + } + /** * Connect to the catalog. * @@ -52,7 +67,10 @@ class Manager // remember the old connection and return that instead of starting over. static $catalog = false; if ($catalog === false) { + $config = ConfigReader::getConfig(); $catalog = new ILSConnection(); + $catalog->setServiceLocator(self::$serviceLocator); + $catalog->setConfig($config->Catalog); } return $catalog; diff --git a/module/VuFind/src/VuFind/ILS/Connection.php b/module/VuFind/src/VuFind/ILS/Connection.php index adec157af0f6e7c943a9cc3cc69ad55fffb77513..0ffca7c867ba415281ffbcded37c05efdc2e983d 100644 --- a/module/VuFind/src/VuFind/ILS/Connection.php +++ b/module/VuFind/src/VuFind/ILS/Connection.php @@ -30,7 +30,9 @@ * @link http://vufind.org/wiki/building_an_ils_driver Wiki */ namespace VuFind\ILS; -use VuFind\Config\Reader as ConfigReader, VuFind\Exception\ILS as ILSException; +use VuFind\Config\Reader as ConfigReader, VuFind\Exception\ILS as ILSException, + Zend\ServiceManager\ServiceLocatorAwareInterface, + Zend\ServiceManager\ServiceLocatorInterface; /** * Catalog Connection Class @@ -48,52 +50,78 @@ use VuFind\Config\Reader as ConfigReader, VuFind\Exception\ILS as ILSException; class Connection { /** - * The class of the appropriate driver. + * Has the driver been initialized yet? * - * @var string + * @var bool */ - protected $driverClass; + protected $driverInitialized = false; /** * The object of the appropriate driver. * * @var object */ - protected $driver = false; + protected $driver; /** - * Constructor + * The service locator * - * @throws ILSException + * @var ServiceLocatorInterface + */ + protected $serviceLocator; + + /** + * ILS configuration + * + * @var \Zend\Config\Config */ - public function __construct() + protected $config; + + /** + * Set the configuration of the connection. + * + * @param \Zend\Config\Config $config Configuration representing the [Catalog] + * section of config.ini + * + * @return void + */ + public function setConfig($config) { - $config = ConfigReader::getConfig(); - if (!isset($config->Catalog->driver)) { + $this->config = $config; + + if (!isset($config->driver)) { throw new ILSException('ILS driver setting missing.'); } - $class = 'VuFind\ILS\Driver\\' . $config->Catalog->driver; - if (!class_exists($class)) { + $driverManager = $this->getServiceLocator()->get('ILSDriverPluginManager'); + $service = $config->driver; + if (!$driverManager->has($service)) { // Don't throw ILSException here -- we don't want this to be // treated as a login problem; it's more serious than that! - throw new \Exception('ILS driver missing: ' . $class); + throw new \Exception('ILS driver missing: ' . $service); } - $this->driverClass = $class; + $this->driver = $driverManager->get($service); // If we're configured to fail over to the NoILS driver, we need // to test if the main driver is working. - if (isset($config->Catalog->loadNoILSOnFailure) - && $config->Catalog->loadNoILSOnFailure - ) { + if (isset($config->loadNoILSOnFailure) && $config->loadNoILSOnFailure) { try { $this->getDriver(); } catch (\Exception $e) { - $this->driver = false; - $this->driverClass = 'VuFind\ILS\Driver\NoILS'; + $this->driver = $driverManager->get('NoILS'); } } } + /** + * Get class name of the driver object. + * + * @return string + */ + public function getDriverClass() + { + return get_class($this->driver); + } + /** * Get access to the driver object. * @@ -102,10 +130,10 @@ class Connection */ public function getDriver() { - if (!$this->driver) { - $this->driver = new $this->driverClass; + if (!$this->driverInitialized) { $this->driver->setConfig($this->getDriverConfig()); $this->driver->init(); + $this->driverInitialized = true; } return $this->driver; } @@ -120,7 +148,7 @@ class Connection public function getDriverConfig() { // Determine config file name based on class name: - $parts = explode('\\', $this->driverClass); + $parts = explode('\\', $this->getDriverClass()); $configFile = end($parts) . '.ini'; $configFilePath = ConfigReader::getConfigPath($configFile); return file_exists($configFilePath) @@ -141,7 +169,7 @@ class Connection public function checkFunction($function) { // Extract the configuration from the driver if available: - $functionConfig = method_exists($this->driverClass, 'getConfig') + $functionConfig = method_exists($this->getDriverClass(), 'getConfig') ? $this->getDriver()->getConfig($function) : false; // See if we have a corresponding check method to analyze the response: @@ -170,7 +198,7 @@ class Connection $response = false; if ($this->getHoldsMode() != "none" - && method_exists($this->driverClass, 'placeHold') + && method_exists($this->getDriverClass(), 'placeHold') && isset($functionConfig['HMACKeys']) ) { $response = array('function' => "placeHold"); @@ -182,7 +210,7 @@ class Connection if (isset($functionConfig['extraHoldFields'])) { $response['extraHoldFields'] = $functionConfig['extraHoldFields']; } - } else if (method_exists($this->driverClass, 'getHoldLink')) { + } else if (method_exists($this->getDriverClass(), 'getHoldLink')) { $response = array('function' => "getHoldLink"); } return $response; @@ -203,14 +231,13 @@ class Connection protected function checkMethodcancelHolds($functionConfig) { $response = false; - $config = ConfigReader::getConfig(); - if ($config->Catalog->cancel_holds_enabled == true - && method_exists($this->driverClass, 'cancelHolds') + if ($this->config->cancel_holds_enabled == true + && method_exists($this->getDriverClass(), 'cancelHolds') ) { $response = array('function' => "cancelHolds"); - } else if ($config->Catalog->cancel_holds_enabled == true - && method_exists($this->driverClass, 'getCancelHoldLink') + } else if ($this->config->cancel_holds_enabled == true + && method_exists($this->getDriverClass(), 'getCancelHoldLink') ) { $response = array('function' => "getCancelHoldLink"); } @@ -231,14 +258,13 @@ class Connection protected function checkMethodRenewals($functionConfig) { $response = false; - $config = ConfigReader::getConfig(); - if ($config->Catalog->renewals_enabled == true - && method_exists($this->driverClass, 'renewMyItems') + if ($this->config->renewals_enabled == true + && method_exists($this->getDriverClass(), 'renewMyItems') ) { $response = array('function' => "renewMyItems"); - } else if ($config->Catalog->renewals_enabled == true - && method_exists($this->driverClass, 'renewMyItemsLink') + } else if ($this->config->renewals_enabled == true + && method_exists($this->getDriverClass(), 'renewMyItemsLink') ) { $response = array('function' => "renewMyItemsLink"); } @@ -259,7 +285,7 @@ class Connection */ public function checkRequestIsValid($id, $data, $patron) { - $method = array($this->driverClass, 'checkRequestIsValid'); + $method = array($this->getDriverClass(), 'checkRequestIsValid'); if (is_callable($method)) { return $this->getDriver()->checkRequestIsValid($id, $data, $patron); } @@ -294,8 +320,8 @@ class Connection public function getOfflineMode() { // Graceful degradation -- return false if no method supported. - return method_exists($this->driverClass, 'getOfflineMode') ? - $this->getDriver()->getOfflineMode() : false; + return method_exists($this->getDriverClass(), 'getOfflineMode') + ? $this->getDriver()->getOfflineMode() : false; } /** @@ -324,8 +350,8 @@ class Connection public function hasHoldings($id) { // Graceful degradation -- return true if no method supported. - return method_exists($this->driverClass, 'hasHoldings') ? - $this->getDriver()->hasHoldings($id) : true; + return method_exists($this->getDriverClass(), 'hasHoldings') + ? $this->getDriver()->hasHoldings($id) : true; } /** @@ -338,8 +364,8 @@ class Connection public function loginIsHidden() { // Graceful degradation -- return false if no method supported. - return method_exists($this->driverClass, 'loginIsHidden') ? - $this->getDriver()->loginIsHidden() : false; + return method_exists($this->getDriverClass(), 'loginIsHidden') + ? $this->getDriver()->loginIsHidden() : false; } /** @@ -354,11 +380,34 @@ class Connection */ public function __call($methodName, $params) { - if (is_callable(array($this->driverClass, $methodName))) { + if (is_callable(array($this->getDriverClass(), $methodName))) { return call_user_func_array( array($this->getDriver(), $methodName), $params ); } throw new ILSException('Cannot call method: ' . $methodName); } + + /** + * Set the service locator. + * + * @param ServiceLocatorInterface $serviceLocator Locator to register + * + * @return Connection + */ + public function setServiceLocator(ServiceLocatorInterface $serviceLocator) + { + $this->serviceLocator = $serviceLocator; + return $this; + } + + /** + * Get the service locator. + * + * @return \Zend\ServiceManager\ServiceLocatorInterface + */ + public function getServiceLocator() + { + return $this->serviceLocator; + } } diff --git a/module/VuFind/src/VuFind/ILS/Driver/PluginFactory.php b/module/VuFind/src/VuFind/ILS/Driver/PluginFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..a92408cda50fa63d6ca8f84ab4ace266c3d10819 --- /dev/null +++ b/module/VuFind/src/VuFind/ILS/Driver/PluginFactory.php @@ -0,0 +1,48 @@ +<?php +/** + * ILS driver plugin factory + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package ILS_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/creating_a_session_handler Wiki + */ +namespace VuFind\ILS\Driver; + +/** + * ILS driver plugin factory + * + * @category VuFind2 + * @package ILS_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/creating_a_session_handler Wiki + */ +class PluginFactory extends \VuFind\ServiceManager\AbstractPluginFactory +{ + /** + * Constructor + */ + public function __construct() + { + $this->defaultNamespace = 'VuFind\ILS\Driver'; + } +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/ILS/Driver/PluginManager.php b/module/VuFind/src/VuFind/ILS/Driver/PluginManager.php new file mode 100644 index 0000000000000000000000000000000000000000..ac27f6cb1628f200910b8a5b4be892d9ff58044e --- /dev/null +++ b/module/VuFind/src/VuFind/ILS/Driver/PluginManager.php @@ -0,0 +1,51 @@ +<?php +/** + * ILS driver plugin manager + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package ILS_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/creating_a_session_handler Wiki + */ +namespace VuFind\ILS\Driver; + +/** + * ILS driver plugin manager + * + * @category VuFind2 + * @package ILS_Drivers + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/creating_a_session_handler Wiki + */ +class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager +{ + /** + * Return the name of the base class or interface that plug-ins must conform + * to. + * + * @return string + */ + protected function getExpectedInterface() + { + return 'VuFind\ILS\Driver\DriverInterface'; + } +} \ No newline at end of file