diff --git a/module/VuFind/src/VuFind/Export.php b/module/VuFind/src/VuFind/Export.php new file mode 100644 index 0000000000000000000000000000000000000000..3ce6edfe4357cc8b3769de2be5b33f2d3065223e --- /dev/null +++ b/module/VuFind/src/VuFind/Export.php @@ -0,0 +1,229 @@ +<?php +/** + * Export support class + * + * 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 Support_Classes + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +namespace VuFind; +use VuFind\Config\Reader as ConfigReader; + +/** + * Export support class + * + * @category VuFind2 + * @package Support_Classes + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org Main Site + */ +class Export +{ + /** + * Get bulk export options. + * + * @return array + */ + public static function getBulkOptions() + { + static $options = false; + + if ($options === false) { + $options = array(); + $config = ConfigReader::getConfig(); + if (isset($config->BulkExport->enabled) + && isset($config->BulkExport->options) + && $config->BulkExport->enabled + ) { + foreach (explode(':', $config->BulkExport->options) as $option) { + if (isset($config->Export->$option) + && $config->Export->$option == true + ) { + $options[] = $option; + } + } + } + } + + return $options; + } + + /** + * Get the URL for bulk export. + * + * @param Zend_View $view View object (needed for URL generation) + * @param string $format Export format being used + * @param array $ids Array of IDs to export (in source|id format) + * + * @return string + */ + public static function getBulkUrl($view, $format, $ids) + { + $params = array(); + $params[] = 'f=' . urlencode($format); + foreach ($ids as $id) { + $params[] = urlencode('i[]') . '=' . urlencode($id); + } + $url = $view->fullUrl( + $view->url( + array('controller' => 'Cart', 'action' => 'doExport'), 'default', + true + ) + ); + $url .= '?' . implode('&', $params); + + return self::needsRedirect($format) + ? self::getRedirectUrl($format, $url) : $url; + } + + /** + * Build callback URL for export. + * + * @param string $format Export format being used + * @param string $callback Callback URL for retrieving record(s) + * + * @return string + */ + public static function getRedirectUrl($format, $callback) + { + // Grab configuration, since we may need it to fill in template: + $config = ConfigReader::getConfig(); + + // Fill in special tokens in template:/* + $exportConfig = ConfigReader::getConfig('export'); + $template = $exportConfig->$format->redirectUrl; + preg_match_all('/\{([^}]+)\}/', $template, $matches); + foreach ($matches[1] as $current) { + $parts = explode('|', $current); + switch ($parts[0]) { + + case 'config': + case 'encodedConfig': + if (isset($config->{$parts[1]}->{$parts[2]})) { + $value = $config->{$parts[1]}->{$parts[2]}; + } else { + $value = $parts[3]; + } + if ($parts[0] == 'encodedConfig') { + $value = urlencode($value); + } + $template = str_replace('{' . $current . '}', $value, $template); + break; + case 'encodedCallback': + $template = str_replace( + '{' . $current . '}', urlencode($callback), $template + ); + break; + } + } + return $template; + } + + /** + * Does the requested format require a redirect? + * + * @param string $format Format to check + * + * @return bool + */ + public static function needsRedirect($format) + { + $exportConfig = ConfigReader::getConfig('export'); + return isset($exportConfig->$format->redirectUrl); + } + + /** + * Convert an array of individual records into a single string for display. + * + * @param string $format Format of records to process + * @param array $parts Multiple records to process + * + * @return string + */ + public static function processGroup($format, $parts) + { + // Load export configuration: + $exportConfig = ConfigReader::getConfig('export'); + + // If we're in XML mode, we need to do some special processing: + if (isset($exportConfig->$format->combineXpath)) { + $ns = array(); + if (isset($exportConfig->$format->combineNamespaces)) { + foreach ($exportConfig->$format->combineNamespaces as $current) { + $ns[] = explode('|', $current, 2); + } + } + foreach ($parts as $part) { + // Convert text into XML object: + $current = simplexml_load_string($part); + + // The first record gets kept as-is; subsequent records get merged + // in based on the configured XPath (currently only one level is + // supported)... + if (!isset($retVal)) { + $retVal = $current; + } else { + foreach ($ns as $n) { + $current->registerXPathNamespace($n[0], $n[1]); + } + $matches = $current->xpath($exportConfig->$format->combineXpath); + foreach ($matches as $match) { + SimpleXML::appendElement($retVal, $match); + } + } + } + return $retVal->asXML(); + } else { + // Not in XML mode -- just concatenate everything together: + return implode('', $parts); + } + } + + /** + * Set headers for the requested format. + * + * @param string $format Selected export format + * @param Zend_Controller_Response_Abstract $response Response object to modify + * + * @return void + */ + public static function setHeaders($format, $response) + { + $exportConfig = ConfigReader::getConfig('export'); + if (isset($exportConfig->$format->headers)) { + $headerTypes = array(); + foreach ($exportConfig->$format->headers as $header) { + // Keep track of which header keys we have already seen -- we + // want to allow duplicate values, so if we've previously encountered + // a particular key, we should set the "replace" parameter of the + // setHeader() method to false: + $parts = explode(':', $header, 2); + $key = strtolower($parts[0]); + $response->setHeader( + trim($parts[0]), trim($parts[1]), !isset($headerTypes[$key]) + ); + $headerTypes[$key] = 1; + } + } + } +} diff --git a/module/VuFind/src/VuFind/SimpleXML.php b/module/VuFind/src/VuFind/SimpleXML.php new file mode 100644 index 0000000000000000000000000000000000000000..ec08ff176ed57d9610e18170f22c863580629eb5 --- /dev/null +++ b/module/VuFind/src/VuFind/SimpleXML.php @@ -0,0 +1,95 @@ +<?php +/** + * VuFind SimpleXML enhancement functionality + * + * PHP version 5 + * + * Copyright (C) Villanova University 2009. + * + * 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 Support_Classes + * @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/system_classes Wiki + */ +namespace VuFind; + +/** + * VuFind SimpleXML enhancement functionality + * + * @category VuFind2 + * @package Support_Classes + * @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/system_classes Wiki + */ +class SimpleXML +{ + /** + * Attach $child to $parent. Adapted from function defined in PHP docs here: + * http://www.php.net/manual/en/class.simplexmlelement.php#99071 + * + * @param SimpleXMLElement $parent Parent element to modify + * @param SimpleXMLElement $child Child element to attach + * + * @return void + */ + public static function appendElement($parent, $child) + { + // get all namespaces for document + $namespaces = $child->getNamespaces(true); + + // check if there is a default namespace for the current node + $currentNs = $child->getNamespaces(); + $defaultNs = count($currentNs) > 0 ? current($currentNs) : null; + $prefix = (count($currentNs) > 0) ? current(array_keys($currentNs)) : ''; + $childName = strlen($prefix) > 1 + ? $prefix . ':' . $child->getName() : $child->getName(); + + // check if the value is string value / data + if (trim((string) $child) == '') { + $element = $parent->addChild($childName, null, $defaultNs); + } else { + $element = $parent->addChild( + $childName, htmlspecialchars((string)$child), $defaultNs + ); + } + + foreach ($child->attributes() as $attKey => $attValue) { + $element->addAttribute($attKey, $attValue); + } + foreach ($namespaces as $nskey => $nsurl) { + foreach ($child->attributes($nsurl) as $attKey => $attValue) { + $element->addAttribute($nskey . ':' . $attKey, $attValue, $nsurl); + } + } + + // add children -- try with namespaces first, but default to all children + // if no namespaced children are found. + $children = 0; + foreach ($namespaces as $nskey => $nsurl) { + foreach ($child->children($nsurl) as $currChild) { + self::appendElement($element, $currChild); + $children++; + } + } + if ($children == 0) { + foreach ($child->children() as $currChild) { + self::appendElement($element, $currChild); + } + } + } +} \ No newline at end of file diff --git a/themes/blueprint/templates/ajax/export-favorites.phtml b/themes/blueprint/templates/ajax/export-favorites.phtml index 41f6aad941cf5480c67d543084a38f6745e8b020..cd5688f58ad699fbd98126ff4f637438239d8ec7 100644 --- a/themes/blueprint/templates/ajax/export-favorites.phtml +++ b/themes/blueprint/templates/ajax/export-favorites.phtml @@ -1,6 +1,6 @@ <p> - <a class="save" onclick="hideLightbox();" href="<?=$this->escapeHtml($this->url)?>"<?=VF_Export::needsRedirect($this->format) ? ' target="_blank"' : ''?>><?= - VF_Export::needsRedirect($this->format) + <a class="save" onclick="hideLightbox();" href="<?=$this->escapeHtml($this->url)?>"<?=\VuFind\Export::needsRedirect($this->format) ? ' target="_blank"' : ''?>><?= + \VuFind\Export::needsRedirect($this->format) ? $this->transEsc('export_redirect', array('%%service%%' => $this->translate($this->format))) : $this->transEsc('export_download') ?></a> diff --git a/themes/blueprint/templates/cart/cart.phtml b/themes/blueprint/templates/cart/cart.phtml index 1df2f20c9aa1833066b930b25c4d66e9f6d50c56..677393dfbbc3c9ef0acc064431386ab2cb73e731 100644 --- a/themes/blueprint/templates/cart/cart.phtml +++ b/themes/blueprint/templates/cart/cart.phtml @@ -13,7 +13,7 @@ <input type="checkbox" class="selectAllCheckboxes floatleft" name="selectAll" id="cartCheckboxSelectAll"/> <label for="cartCheckboxSelectAll" class="floatleft"><?=$this->transEsc('select_page')?></label> <input type="submit" class="fav floatleft button" name="saveCart" value="<?=$this->transEsc('bookbag_save_selected')?>" title="<?=$this->transEsc('bookbag_save')?>"/> <input type="submit" class="mail floatleft button" name="email" value="<?=$this->transEsc('bookbag_email_selected')?>" title="<?=$this->transEsc('bookbag_email')?>"/> - <? $exportOptions = VF_Export::getBulkOptions(); if (count($exportOptions) > 0): ?> + <? $exportOptions = \VuFind\Export::getBulkOptions(); if (count($exportOptions) > 0): ?> <input type="submit" class="export floatleft button" name="export" value="<?=$this->transEsc('bookbag_export_selected')?>" title="<?=$this->transEsc('bookbag_export')?>"/> <? endif; ?> <input type="submit" class="print floatleft button" name="print" value="<?=$this->transEsc('bookbag_print_selected')?>" title="<?=$this->transEsc('print_selected')?>"/> diff --git a/themes/blueprint/templates/myresearch/bulk-action-buttons.phtml b/themes/blueprint/templates/myresearch/bulk-action-buttons.phtml index bcc0a02337d836e4c37e1e416748e0483463a142..88d56a0449aacb6ffd2c095c505dd8d2b87427b3 100644 --- a/themes/blueprint/templates/myresearch/bulk-action-buttons.phtml +++ b/themes/blueprint/templates/myresearch/bulk-action-buttons.phtml @@ -6,7 +6,7 @@ <? if ((!is_null($this->list) && $this->list->editAllowed()) || is_null($this->list) && $this->layout()->account->isLoggedIn()): ?> <input id="<?=$this->idPrefix?>delete_list_items_<?=!is_null($this->list) ? $this->escapeHtml($this->list->id) : ''?>" type="submit" class="delete floatleft button" name="delete" value="<?=$this->transEsc('Delete')?>" title="<?=$this->transEsc('delete_selected')?>"/> <? endif; ?> - <? $exportOptions = VF_Export::getBulkOptions(); if (count($exportOptions) > 0): ?> + <? $exportOptions = \VuFind\Export::getBulkOptions(); if (count($exportOptions) > 0): ?> <input type="submit" class="export floatleft button" name="export" value="<?=$this->transEsc('Export')?>" title="<?=$this->transEsc('export_selected')?>"/> <? endif; ?> <input type="submit" class="print floatleft button" name="print" value="<?=$this->transEsc('Print')?>" title="<?=$this->transEsc('print_selected')?>"/> diff --git a/themes/blueprint/templates/record/view.phtml b/themes/blueprint/templates/record/view.phtml index f81b8b6be4c5d8001e8379db946f59d194d755b4..1b7122799b1966b171a0ad0e3cca5978c6b551e3 100644 --- a/themes/blueprint/templates/record/view.phtml +++ b/themes/blueprint/templates/record/view.phtml @@ -37,7 +37,7 @@ <a href="<?=$this->recordLink()->getUrl($this->driver, 'Export')?>" class="export exportMenu"><?=$this->transEsc('Export Record')?></a> <ul class="menu offscreen" id="exportMenu"> <? foreach ($exportFormats as $exportFormat): ?> - <li><a <? if (VF_Export::needsRedirect($exportFormat)): ?>target="<?=$this->escapeHtml($exportFormat)?>Main" <? endif; ?>href="<?=$this->recordLink()->getUrl($this->driver, 'Export')?>?style=<?=$this->escapeHtml($exportFormat)?>"><?=$this->transEsc('Export to')?> <?=$this->escapeHtml($exportFormat)?></a></li> + <li><a <? if (\VuFind\Export::needsRedirect($exportFormat)): ?>target="<?=$this->escapeHtml($exportFormat)?>Main" <? endif; ?>href="<?=$this->recordLink()->getUrl($this->driver, 'Export')?>?style=<?=$this->escapeHtml($exportFormat)?>"><?=$this->transEsc('Export to')?> <?=$this->escapeHtml($exportFormat)?></a></li> <? endforeach; ?> </ul> </li>