/** * Return search specs * * @param string $filename config file name * * @return array */ public function get($filename) { // Load data if it is not already in the object's cache: if (!isset($this->searchSpecs[$filename])) { // Connect to searchspecs cache: $cache = null !== $this->cacheManager ? $this->cacheManager->getCache('searchspecs') : false; // Determine full configuration file path: $fullpath = Locator::getBaseConfigPath($filename); $local = Locator::getLocalConfigPath($filename); // Generate cache key: $cacheKey = $filename . '-' . (file_exists($fullpath) ? filemtime($fullpath) : 0); if (!empty($local)) { $cacheKey .= '-local-' . filemtime($local); } $cacheKey = md5($cacheKey); // Generate data if not found in cache: if ($cache === false || !($results = $cache->getItem($cacheKey))) { $results = file_exists($fullpath) ? Yaml::parse(file_get_contents($fullpath)) : []; if (!empty($local)) { $localResults = Yaml::parse(file_get_contents($local)); foreach ($localResults as $key => $value) { $results[$key] = $value; } } if ($cache !== false) { $cache->setItem($cacheKey, $results); } } $this->searchSpecs[$filename] = $results; } return $this->searchSpecs[$filename]; }
/** * Return search specs * * @param string $filename config file name * * @return array */ public function get($filename) { // Load data if it is not already in the object's cache: if (!isset($this->searchSpecs[$filename])) { $this->searchSpecs[$filename] = $this->getFromPaths(Locator::getBaseConfigPath($filename), Locator::getLocalConfigPath($filename)); } return $this->searchSpecs[$filename]; }
/** * Load the specified configuration file. * * @param string $filename config file name * @param string $path path relative to VuFind base (optional; defaults * to config/vufind * * @return Config */ protected function loadConfigFile($filename, $path = 'config/vufind') { // If we don't have a local config file in config/vufind, check for it in // config/finna and load from there if found. $localConfig = Locator::getLocalConfigPath($filename, $path); if ($localConfig === null) { $localConfig = Locator::getLocalConfigPath($filename, 'config/finna'); if ($localConfig !== null) { return parent::loadConfigFile($filename, 'config/finna'); } } return parent::loadConfigFile($filename, $path); }
/** * Support action for config -- attempt to enable auto configuration. * * @return mixed */ public function enableautoconfigAction() { $configFile = \VuFind\Config\Locator::getConfigPath('config.ini'); $writer = new \VuFind\Config\Writer($configFile); $writer->set('System', 'autoConfigure', 1); if ($writer->save()) { $this->flashMessenger()->setNamespace('success')->addMessage('Auto-configuration enabled.'); // Reload config now that it has been edited (otherwise, old setting // will persist in cache): $this->getServiceLocator()->get('VuFind\\Config')->reload('config'); } else { $this->flashMessenger()->setNamespace('error')->addMessage('Could not enable auto-configuration; check permissions on ' . $configFile . '.'); } return $this->forwardTo('AdminConfig', 'Home'); }
/** * Standard setup method. * * @return void */ public static function setUpBeforeClass() { // Create test files: $parentPath = Locator::getLocalConfigPath('unit-test-parent.ini', null, true); $parent = "[Section1]\n" . "a=1\nb=2\nc=3\n" . "[Section2]\n" . "d=4\ne=5\nf=6\n" . "[Section3]\n" . "g=7\nh=8\ni=9\n"; $childPath = Locator::getLocalConfigPath('unit-test-child.ini', null, true); $child = "[Section1]\n" . "j=10\nk=11\nl=12\n" . "[Section2]\n" . "m=13\nn=14\no=15\n" . "[Parent_Config]\n" . "path=\"{$parentPath}\"\n" . "override_full_sections=Section1\n"; // Fail if we are unable to write files: if (null === $parentPath || null === $childPath || !file_put_contents($parentPath, $parent) || !file_put_contents($childPath, $child)) { self::$writeFailed = true; return; } // Mark for cleanup: self::$filesToDelete = [$parentPath, $childPath]; }
/** * Harvest OAI-PMH records. * * @return \Zend\Console\Response */ public function harvestoaiAction() { $this->checkLocalSetting(); // Get default options, add the default --ini setting if missing: $opts = HarvesterConsoleRunner::getDefaultOptions(); if (!$opts->getOption('ini')) { $ini = \VuFind\Config\Locator::getConfigPath('oai.ini', 'harvest'); $opts->addArguments(['--ini=' . $ini]); } // Get the default VuFind HTTP client: $client = $this->getServiceLocator()->get('VuFind\\Http')->createClient(); // Run the job! $runner = new HarvesterConsoleRunner($opts, $client, $this->getHarvestRoot()); return $runner->run() ? $this->getSuccessResponse() : $this->getFailureResponse(); }
/** * Load the specified configuration file. * * @param string $filename config file name * @param string $path path relative to VuFind base (optional; defaults * to config/vufind * * @return Config */ protected function loadConfigFile($filename, $path = 'config/vufind') { $configs = []; $fullpath = Locator::getConfigPath($filename, $path); // Return empty configuration if file does not exist: if (!file_exists($fullpath)) { return new Config([]); } // Retrieve and parse at least one configuration file, and possibly a whole // chain of them if the Parent_Config setting is used: do { $configs[] = new Config($this->iniReader->fromFile($fullpath), true); $i = count($configs) - 1; if (isset($configs[$i]->Parent_Config->path)) { $fullpath = $configs[$i]->Parent_Config->path; } elseif (isset($configs[$i]->Parent_Config->relative_path)) { $fullpath = pathinfo($fullpath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . $configs[$i]->Parent_Config->relative_path; } else { $fullpath = false; } } while ($fullpath); // The last element in the array will be the top of the inheritance tree. // Let's establish a baseline: $config = array_pop($configs); // Now we'll pull all the children down one at a time and override settings // as appropriate: while (!is_null($child = array_pop($configs))) { $overrideSections = isset($child->Parent_Config->override_full_sections) ? explode(',', str_replace(' ', '', $child->Parent_Config->override_full_sections)) : []; foreach ($child as $section => $contents) { // Omit Parent_Config from the returned configuration; it is only // needed during loading, and its presence will cause problems in // config files that iterate through all of the sections (e.g. // combined.ini, permissions.ini). if ($section === 'Parent_Config') { continue; } if (in_array($section, $overrideSections) || !isset($config->{$section})) { $config->{$section} = $child->{$section}; } else { foreach (array_keys($contents->toArray()) as $key) { $config->{$section}->{$key} = $child->{$section}->{$key}; } } } } $config->setReadOnly(); return $config; }
/** * Harvest OAI-PMH records. * * @return \Zend\Console\Response */ public function harvestoaiAction() { $this->checkLocalSetting(); // Parse switches: $this->consoleOpts->addRules(['from-s' => 'Harvest start date', 'until-s' => 'Harvest end date']); $from = $this->consoleOpts->getOption('from'); $until = $this->consoleOpts->getOption('until'); // Read Config files $configFile = \VuFind\Config\Locator::getConfigPath('oai.ini', 'harvest'); $oaiSettings = @parse_ini_file($configFile, true); if (empty($oaiSettings)) { Console::writeLine("Please add OAI-PMH settings to oai.ini."); return $this->getFailureResponse(); } // If first command line parameter is set, see if we can limit to just the // specified OAI harvester: $argv = $this->consoleOpts->getRemainingArgs(); if (isset($argv[0])) { if (isset($oaiSettings[$argv[0]])) { $oaiSettings = [$argv[0] => $oaiSettings[$argv[0]]]; } else { Console::writeLine("Could not load settings for {$argv[0]}."); return $this->getFailureResponse(); } } // Loop through all the settings and perform harvests: $processed = 0; foreach ($oaiSettings as $target => $settings) { if (!empty($target) && !empty($settings)) { Console::writeLine("Processing {$target}..."); try { $client = $this->getServiceLocator()->get('VuFind\\Http')->createClient(); $harvest = new OAI($target, $settings, $client, $from, $until); $harvest->launch(); } catch (\Exception $e) { Console::writeLine($e->getMessage()); return $this->getFailureResponse(); } $processed++; } } // All done. Console::writeLine("Completed without errors -- {$processed} source(s) processed."); return $this->getSuccessResponse(); }
/** * Transform $xmlFile using the provided $properties configuration. * * @param string $xmlFile XML file to transform. * @param string $properties Properties file. * * @throws \Exception * @return mixed Transformed XML. */ protected function generateXML($xmlFile, $properties) { // Load properties file: $properties = ConfigLocator::getConfigPath($properties, 'import'); if (!file_exists($properties)) { throw new \Exception("Cannot load properties file: {$properties}."); } $options = parse_ini_file($properties, true); // Make sure required parameter is set: if (!isset($options['General']['xslt'])) { throw new \Exception("Properties file ({$properties}) is missing General/xslt setting."); } $xslFile = ConfigLocator::getConfigPath($options['General']['xslt'], 'import/xsl'); // Initialize the XSL processor: $xsl = $this->initProcessor($options); // Load up the style sheet $style = new DOMDocument(); if (!$style->load($xslFile)) { throw new \Exception("Problem loading XSL file: {$xslFile}."); } $xsl->importStyleSheet($style); // Load up the XML document $xml = new DOMDocument(); if (!$xml->load($xmlFile)) { throw new \Exception("Problem loading XML file: {$xmlFile}."); } // Process and return the XML through the style sheet $result = $xsl->transformToXML($xml); if (!$result) { throw new \Exception("Problem transforming XML."); } return $result; }
/** * Disable auto-configuration. * * @return mixed */ public function doneAction() { $config = ConfigLocator::getLocalConfigPath('config.ini', null, true); $writer = new ConfigWriter($config); $writer->set('System', 'autoConfigure', 0); if (!$writer->save()) { return $this->forwardTo('Install', 'fixbasicconfig'); } return $this->createViewModel(['configDir' => dirname($config)]); }
/** * Initialize the driver. * * Validate configuration and perform all resource-intensive tasks needed to * make the driver active. * * @throws ILSException * @return void */ public function init() { if (empty($this->config)) { throw new ILSException('Configuration needs to be set.'); } if (isset($this->config['Catalog']['arena_member'])) { $this->arenaMember = $this->config['Catalog']['arena_member']; } else { throw new ILSException('arena_member configuration needs to be set.'); } if (isset($this->config['Catalog']['catalogue_wsdl'])) { $this->catalogue_wsdl = Locator::getConfigPath($this->config['Catalog']['catalogue_wsdl']); } else { throw new ILSException('catalogue_wsdl configuration needs to be set.'); } if (isset($this->config['Catalog']['patron_wsdl'])) { $this->patron_wsdl = Locator::getConfigPath($this->config['Catalog']['patron_wsdl']); } else { throw new ILSException('patron_wsdl configuration needs to be set.'); } if (isset($this->config['Catalog']['loans_wsdl'])) { $this->loans_wsdl = Locator::getConfigPath($this->config['Catalog']['loans_wsdl']); } else { throw new ILSException('loans_wsdl configuration needs to be set.'); } if (isset($this->config['Catalog']['payments_wsdl'])) { $this->payments_wsdl = Locator::getConfigPath($this->config['Catalog']['payments_wsdl']); } else { throw new ILSException('payments_wsdl configuration needs to be set.'); } if (isset($this->config['Catalog']['reservations_wsdl'])) { $this->reservations_wsdl = Locator::getConfigPath($this->config['Catalog']['reservations_wsdl']); } else { throw new ILSException('reservations_wsdl configuration needs to be set.'); } $this->defaultPickUpLocation = isset($this->config['Holds']['defaultPickUpLocation']) ? $this->config['Holds']['defaultPickUpLocation'] : false; if ($this->defaultPickUpLocation == '0') { $this->defaultPickUpLocation = false; } if (isset($this->config['Debug']['durationLogPrefix'])) { $this->durationLogPrefix = $this->config['Debug']['durationLogPrefix']; } if (isset($this->config['Debug']['verbose'])) { $this->verbose = $this->config['Debug']['verbose']; } if (isset($this->config['Debug']['log'])) { $this->logFile = $this->config['Debug']['log']; } $this->holdingsOrganisationOrder = isset($this->config['Holdings']['holdingsOrganisationOrder']) ? explode(":", $this->config['Holdings']['holdingsOrganisationOrder']) : []; $this->holdingsOrganisationOrder = array_flip($this->holdingsOrganisationOrder); $this->holdingsBranchOrder = isset($this->config['Holdings']['holdingsBranchOrder']) ? explode(":", $this->config['Holdings']['holdingsBranchOrder']) : []; $this->holdingsBranchOrder = array_flip($this->holdingsBranchOrder); // Establish a namespace in the session for persisting cached data $this->session = new SessionContainer('AxiellWebServices_' . $this->arenaMember); }
/** * Get path to a WSDL file taking inheritance into account * * @param string $wsdl WSDL file name * * @return string */ protected function getWsdlPath($wsdl) { $file = Locator::getConfigPath($wsdl); if (!file_exists($file)) { $file = Locator::getConfigPath($wsdl, 'config/finna'); } return $file; }
/** * Display summary of installation status * * @return mixed */ public function homeAction() { // If the cache is messed up, nothing is going to work right -- check that // first: $cache = $this->getServiceLocator()->get('VuFind\\CacheManager'); if ($cache->hasDirectoryCreationError()) { return $this->redirect()->toRoute('install-fixcache'); } // First find out which version we are upgrading: if (!isset($this->cookie->sourceDir) || !is_dir($this->cookie->sourceDir)) { return $this->forwardTo('Upgrade', 'GetSourceDir'); } // Next figure out which version(s) are involved: if (!isset($this->cookie->oldVersion) || !isset($this->cookie->newVersion)) { return $this->forwardTo('Upgrade', 'EstablishVersions'); } // Now make sure we have a configuration file ready: if (!isset($this->cookie->configOkay) || !$this->cookie->configOkay) { return $this->redirect()->toRoute('upgrade-fixconfig'); } // Now make sure the database is up to date: if (!isset($this->cookie->databaseOkay) || !$this->cookie->databaseOkay) { return $this->redirect()->toRoute('upgrade-fixdatabase'); } // Check for missing metadata in the resource table; note that we do a // redirect rather than a forward here so that a submit button clicked // in the database action doesn't cause the metadata action to also submit! if (!isset($this->cookie->metadataOkay) || !$this->cookie->metadataOkay) { return $this->redirect()->toRoute('upgrade-fixmetadata'); } // We're finally done -- display any warnings that we collected during // the process. $allWarnings = array_merge(isset($this->cookie->warnings) ? $this->cookie->warnings : [], (array) $this->session->warnings); foreach ($allWarnings as $warning) { $this->flashMessenger()->addMessage($warning, 'info'); } return $this->createViewModel(['configDir' => dirname(ConfigLocator::getLocalConfigPath('config.ini', null, true)), 'importDir' => LOCAL_OVERRIDE_DIR . '/import', 'oldVersion' => $this->cookie->oldVersion]); }
/** * Test @parent_yaml directive. * * @return void */ public function testParentYaml() { if (self::$writeFailed) { $this->markTestSkipped('Could not write test configurations.'); } $reader = new SearchSpecsReader(); $core = Locator::getLocalConfigPath('middle.yaml', null, true); $local = Locator::getLocalConfigPath('bottom.yaml', null, true); $this->assertEquals(['top' => 'foo', 'middle' => 'bar', 'bottom' => 'baz'], $this->callMethod($reader, 'getFromPaths', [$core, $local])); }
/** * Map string using a config file from the translation_maps folder. * * @param string $in string to map. * @param string $filename filename of map file * * @return string mapped text. */ public static function mapString($in, $filename) { // Load the translation map and send back the appropriate value. Note // that PHP's parse_ini_file() function is not compatible with SolrMarc's // style of properties map, so we are parsing this manually. $map = []; $mapFile = ConfigLocator::getConfigPath($filename, 'import/translation_maps'); foreach (file($mapFile) as $line) { $parts = explode('=', $line, 2); if (isset($parts[1])) { $key = trim($parts[0]); $map[$key] = trim($parts[1]); } } return isset($map[$in]) ? $map[$in] : $in; }
/** * Convert hash algorithms * Expected parameters: oldmethod:oldkey (or none) newmethod:newkey * * @return \Zend\Console\Response */ public function switchdbhashAction() { // Validate command line arguments: $argv = $this->consoleOpts->getRemainingArgs(); if (count($argv) < 1) { Console::writeLine('Expected parameters: newmethod [newkey]'); return $this->getFailureResponse(); } // Pull existing encryption settings from the configuration: $config = $this->getConfig(); if (!isset($config->Authentication->encrypt_ils_password) || !isset($config->Authentication->ils_encryption_key) || !$config->Authentication->encrypt_ils_password) { $oldhash = 'none'; $oldkey = null; } else { $oldhash = isset($config->Authentication->ils_encryption_algo) ? $config->Authentication->ils_encryption_algo : 'blowfish'; $oldkey = $config->Authentication->ils_encryption_key; } // Pull new encryption settings from arguments: $newhash = $argv[0]; $newkey = isset($argv[1]) ? $argv[1] : $oldkey; // No key specified AND no key on file = fatal error: if ($newkey === null) { Console::writeLine('Please specify a key as the second parameter.'); return $this->getFailureResponse(); } // If no changes were requested, abort early: if ($oldkey == $newkey && $oldhash == $newhash) { Console::writeLine('No changes requested -- no action needed.'); return $this->getSuccessResponse(); } // Initialize Mcrypt first, so we can catch any illegal algorithms before // making any changes: try { if ($oldhash != 'none') { $oldCrypt = new Mcrypt(['algorithm' => $oldhash]); } $newCrypt = new Mcrypt(['algorithm' => $newhash]); } catch (\Exception $e) { Console::writeLine($e->getMessage()); return $this->getFailureResponse(); } // Next update the config file, so if we are unable to write the file, // we don't go ahead and make unwanted changes to the database: $configPath = ConfigLocator::getLocalConfigPath('config.ini', null, true); Console::writeLine("\tUpdating {$configPath}..."); $writer = new ConfigWriter($configPath); $writer->set('Authentication', 'encrypt_ils_password', true); $writer->set('Authentication', 'ils_encryption_algo', $newhash); $writer->set('Authentication', 'ils_encryption_key', $newkey); if (!$writer->save()) { Console::writeLine("\tWrite failed!"); return $this->getFailureResponse(); } // Now do the database rewrite: $userTable = $this->getServiceLocator()->get('VuFind\\DbTablePluginManager')->get('User'); $users = $userTable->select(function ($select) { $select->where->isNotNull('cat_username'); }); Console::writeLine("\tConverting hashes for " . count($users) . ' user(s).'); foreach ($users as $row) { $pass = null; if ($oldhash != 'none' && isset($row['cat_pass_enc'])) { $oldcipher = new BlockCipher($oldCrypt); $oldcipher->setKey($oldkey); $pass = $oldcipher->decrypt($row['cat_pass_enc']); } else { $pass = $row['cat_password']; } $newcipher = new BlockCipher($newCrypt); $newcipher->setKey($newkey); $row['cat_password'] = null; $row['cat_pass_enc'] = $newcipher->encrypt($pass); $row->save(); } // If we got this far, all went well! Console::writeLine("\tFinished."); return $this->getSuccessResponse(); }
/** * Loads pickup location information from configuration file. * * @param string $filename File to load from * * @throws ILSException * @return void */ protected function loadPickupLocations($filename) { // Load pickup locations file: $pickupLocationsFile = ConfigLocator::getConfigPath($filename, 'config/vufind'); if (!file_exists($pickupLocationsFile)) { throw new ILSException("Cannot load pickup locations file: {$pickupLocationsFile}."); } if (($handle = fopen($pickupLocationsFile, "r")) !== false) { while (($data = fgetcsv($handle)) !== false) { $this->pickupLocations[$data[0]][] = ['locationID' => $data[1], 'locationDisplay' => $data[2]]; } fclose($handle); } }
/** * Construct the OpenUrl helper. * * @param ServiceManager $sm Service manager. * * @return OpenUrl */ public static function getOpenUrl(ServiceManager $sm) { $config = $sm->getServiceLocator()->get('VuFind\\Config')->get('config'); $openUrlRules = json_decode(file_get_contents(\VuFind\Config\Locator::getConfigPath('OpenUrlRules.json')), true); return new OpenUrl($sm->get('context'), $openUrlRules, isset($config->OpenURL) ? $config->OpenURL : null); }
/** * Restore configurations to the state they were in prior to a call to * changeConfig(). * * @return void */ protected function restoreConfigs() { foreach ($this->modifiedConfigs as $current) { $file = $current . '.ini'; $local = ConfigLocator::getLocalConfigPath($file, null, true); $backup = $local . '.bak'; // Do we have a backup? If so, restore from it; otherwise, just // delete the local file, as it did not previously exist: unlink($local); if (file_exists($backup)) { rename($backup, $local); } } }
/** * Get the map labels. * * @return array */ public function getMapLabels() { $labels = []; $mapLabelData = explode(':', $this->mapLabels); if ($mapLabelData[0] == 'driver') { $labels = $this->getRecordDriver()->tryMethod('getCoordinateLabels'); return $labels; } if ($mapLabelData[0] == 'file') { $coords = $this->getRecordDriver()->tryMethod('getDisplayCoordinates'); /* read lookup file into array */ $label_lookup = []; $file = \VuFind\Config\Locator::getConfigPath($mapLabelData[1]); if (file_exists($file)) { $fp = fopen($file, 'r'); while (($line = fgetcsv($fp, 0, "\t")) !== false) { if (count($line) > 1) { $label_lookup[$line[0]] = $line[1]; } } fclose($fp); } $labels = []; if (null !== $coords) { foreach ($coords as $val) { /* Collapse spaces to make combined coordinate string to match against lookup table coordinate */ $coordmatch = implode('', explode(' ', $val)); /* See if coordinate string matches lookup table coordinates and if so return label */ $labelname = isset($label_lookup[$coordmatch]) ? $label_lookup[$coordmatch] : ''; array_push($labels, $labelname); } } return $labels; } }