From 9a895c852bb17bfa7801a5ade2edcf21833ed913 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Fri, 22 Feb 2013 11:36:51 -0500
Subject: [PATCH] Made XSLT importer custom class handling more flexible (and
 made the nasty class truncation logic optional, so we can start to move away
 from it).  Updated comments in configuration files to match.

---
 import/doaj.properties                     | 14 ++++++++++----
 import/dspace.properties                   | 14 ++++++++++----
 import/gsdl.properties                     | 14 ++++++++++----
 import/ndltd.properties                    | 14 ++++++++++----
 import/nlm_ojs.properties                  | 14 ++++++++++----
 import/ojs.properties                      | 14 ++++++++++----
 import/vudl.properties                     | 14 ++++++++++----
 module/VuFind/src/VuFind/XSLT/Importer.php | 17 ++++++++++++++---
 8 files changed, 84 insertions(+), 31 deletions(-)

diff --git a/import/doaj.properties b/import/doaj.properties
index 6b2641bbe6f..cc7cdf6e32c 100644
--- a/import/doaj.properties
+++ b/import/doaj.properties
@@ -8,11 +8,17 @@ xslt = doaj.xsl
 ; this line to register multiple PHP functions.
 ;php_function[] = str_replace
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/import/dspace.properties b/import/dspace.properties
index c5b0421dbb0..445ede1b384 100644
--- a/import/dspace.properties
+++ b/import/dspace.properties
@@ -7,11 +7,17 @@ xslt = dspace.xsl
 ; this line to register multiple PHP functions.
 ;php_function[] = str_replace
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/import/gsdl.properties b/import/gsdl.properties
index f81c22c9ccc..59d0a0a0b88 100644
--- a/import/gsdl.properties
+++ b/import/gsdl.properties
@@ -7,11 +7,17 @@ xslt = gsdl.xsl
 ; this line to register multiple PHP functions.
 ;php_function[] = str_replace
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/import/ndltd.properties b/import/ndltd.properties
index e76b8454c6d..b962661fdd7 100644
--- a/import/ndltd.properties
+++ b/import/ndltd.properties
@@ -7,11 +7,17 @@ xslt = ndltd.xsl
 ; this line to register multiple PHP functions.
 ;php_function[] = strtolower
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/import/nlm_ojs.properties b/import/nlm_ojs.properties
index 574cbb685a1..bc4821750ce 100644
--- a/import/nlm_ojs.properties
+++ b/import/nlm_ojs.properties
@@ -7,11 +7,17 @@ xslt = nlm_ojs.xsl
 ; this line to register multiple PHP functions.
 php_function[] = strtolower
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/import/ojs.properties b/import/ojs.properties
index d9263314467..0e62e1b660f 100644
--- a/import/ojs.properties
+++ b/import/ojs.properties
@@ -7,11 +7,17 @@ xslt = ojs.xsl
 ; this line to register multiple PHP functions.
 ;php_function[] = str_replace
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/import/vudl.properties b/import/vudl.properties
index a7af5e56dc9..5525a42d187 100644
--- a/import/vudl.properties
+++ b/import/vudl.properties
@@ -7,11 +7,17 @@ xslt = vudl.xsl
 ; this line to register multiple PHP functions.
 ;php_function[] = str_replace
 ; OPTIONAL: PHP class filled with public static functions for use by the XSLT file.
-; The class will be autoloaded using a prefix of VF_XSLT_Import_ (i.e. you need to
-; define VF_XSLT_Import_VuFind in your library directory); the short name will be
-; used from within the XSLT code.  You may repeat this line to load multiple custom
-; classes.
+; The class must live within a PHP namespace.  You may specify a fully-qualified
+; name; if you do not include a namespace, the class will automatically be assumed
+; to live in the \VuFind\XSLT\Import namespace.
 custom_class[] = VuFind
+; OPTIONAL: If true, all custom_class settings above will be passed to the XSLT with
+; their namespaces stripped off; for example, \VuFind\XSLT\Import\VuFind would be
+; treated as \VuFind in XSLT files.  This allows more compact syntax within XSLT
+; files, but it can lead to name conflicts if used carelessly.  If set to false, you
+; must use fully-qualified names in your XSLT.  The false setting is recommended, but
+; the current default is "true" for compatibility with legacy configurations.
+truncate_custom_class = true
 
 ; XSLT parameters -- any key/value pairs set here will be passed as parameters to
 ; the XSLT file, allowing local values to be set without modifying XSLT code.
diff --git a/module/VuFind/src/VuFind/XSLT/Importer.php b/module/VuFind/src/VuFind/XSLT/Importer.php
index f0c3dd5da8e..1549c4d6fa8 100644
--- a/module/VuFind/src/VuFind/XSLT/Importer.php
+++ b/module/VuFind/src/VuFind/XSLT/Importer.php
@@ -157,10 +157,21 @@ class Importer implements ServiceLocatorAwareInterface
             $classes = is_array($options['General']['custom_class'])
                 ? $options['General']['custom_class']
                 : array($options['General']['custom_class']);
+            $truncate = isset($options['General']['truncate_custom_class'])
+                ? $options['General']['truncate_custom_class'] : true;
             foreach ($classes as $class) {
-                // Dynamically generate the requested class:
-                $class = preg_replace('/[^A-Za-z0-9_]/', '', $class);
-                eval("class $class extends \\VuFind\\XSLT\\Import\\$class { }");
+                // Add a default namespace if none was provided:
+                if (false === strpos($class, '\\')) {
+                    $class = 'VuFind\XSLT\Import\\' . $class;
+                }
+                // If necessary, dynamically generate the truncated version of the
+                // requested class:
+                if ($truncate) {
+                    $parts = explode('\\', $class);
+                    $class = preg_replace('/[^A-Za-z0-9_]/', '', array_pop($parts));
+                    $ns = implode('\\', $parts);
+                    eval("class $class extends \\$ns\\$class { }");
+                }
                 $methods = get_class_methods($class);
                 if (method_exists($class, 'setServiceLocator')) {
                     $class::setServiceLocator($this->getServiceLocator());
-- 
GitLab