From 33c696263dddc7b27d4e49edbf0633ede8eaffd5 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Thu, 19 Jul 2012 14:07:35 -0400
Subject: [PATCH] Added remaining missing controllers (not functional yet).

---
 module/VuFind/config/module.config.php        |   2 +
 .../VuFind/Controller/UpgradeController.php   | 476 ++++++++++++++++++
 .../src/VuFind/Controller/VudlController.php  | 274 ++++++++++
 3 files changed, 752 insertions(+)
 create mode 100644 module/VuFind/src/VuFind/Controller/UpgradeController.php
 create mode 100644 module/VuFind/src/VuFind/Controller/VudlController.php

diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 4c2696674de..05cb8bebac5 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -83,6 +83,8 @@ $config = array(
             'summon' => 'VuFind\Controller\SummonController',
             'summonrecord' => 'VuFind\Controller\SummonrecordController',
             'tag' => 'VuFind\Controller\TagController',
+            'upgrade' => 'VuFind\Controller\UpgradeController',
+            'vudl' => 'VuFind\Controller\VudlController',
             'worldcat' => 'VuFind\Controller\WorldcatController',
             'worldcatrecord' => 'VuFind\Controller\WorldcatrecordController',
         ),
diff --git a/module/VuFind/src/VuFind/Controller/UpgradeController.php b/module/VuFind/src/VuFind/Controller/UpgradeController.php
new file mode 100644
index 00000000000..03c007644c8
--- /dev/null
+++ b/module/VuFind/src/VuFind/Controller/UpgradeController.php
@@ -0,0 +1,476 @@
+<?php
+/**
+ * Upgrade Controller
+ *
+ * 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  Controller
+ * @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\Controller;
+
+/**
+ * Class controls VuFind upgrading.
+ *
+ * @category VuFind2
+ * @package  Controller
+ * @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 UpgradeController extends AbstractBase
+{
+    protected $cookie;
+    protected $session;
+
+    /**
+     * init
+     *
+     * @return void
+     */
+    public function init()
+    {
+        /* TODO
+        $this->view->flashMessenger = $this->_helper->flashMessenger;
+
+        // We want to use cookies for tracking the state of the upgrade, since the
+        // session is unreliable -- if the user upgrades a configuration that uses
+        // a different session handler than the default one, we'll lose track of our
+        // upgrade state in the middle of the process!
+        $this->cookie = new VF_Cookie_Namespace('vfup');
+
+        // ...however, once the configuration piece of the upgrade is done, we can
+        // safely use the session for storing some values.  We'll use this for the
+        // temporary storage of root database credentials, since it is unwise to
+        // send such sensitive values around as cookies!
+        $this->session = new Zend_Session_Namespace('upgrade');
+
+        // We should also use the session for storing warnings once we know it will
+        // be stable; this will prevent the cookies from getting too big.
+        if (!isset($this->session->warnings)) {
+            $this->session->warnings = array();
+        }
+         */
+    }
+
+    /**
+     * Support method -- given a directory, extract a version number from the
+     * build.xml file within that directory.
+     *
+     * @param string $dir Directory to search for build.xml
+     *
+     * @return string
+     */
+    protected function getVersion($dir)
+    {
+        $xml = simplexml_load_file($dir . '/build.xml');
+        if (!$xml) {
+            throw new \Exception('Cannot load ' . $dir . '/build.xml.');
+        }
+        $parts = $xml->xpath('/project/property[@name="version"]/@value');
+        return (string)$parts[0];
+    }
+
+    /**
+     * Display a fatal error message.
+     *
+     * @return void
+     */
+    public function errorAction()
+    {
+        // Just display template
+        return $this->createViewModel();
+    }
+
+    /**
+     * Figure out which version(s) are being used.
+     *
+     * @return void
+     */
+    public function establishversionsAction()
+    {
+        /* TODO
+        $this->cookie->oldVersion = $this->getVersion(
+            realpath(APPLICATION_PATH . '/..')
+        );
+        $this->cookie->newVersion = $this->getVersion(
+            $this->cookie->sourceDir
+        );
+
+        // Block upgrade when encountering common errors:
+        if (empty($this->cookie->oldVersion)) {
+            $this->_helper->flashMessenger->setNamespace('error')
+                ->addMessage('Cannot determine source version.');
+            unset($this->cookie->oldVersion);
+            return $this->_forward('Error');
+        }
+        if (empty($this->cookie->newVersion)) {
+            $this->_helper->flashMessenger->setNamespace('error')
+                ->addMessage('Cannot determine destination version.');
+            unset($this->cookie->newVersion);
+            return $this->_forward('Error');
+        }
+        if ($this->cookie->newVersion == $this->cookie->oldVersion) {
+            $this->_helper->flashMessenger->setNamespace('error')
+                ->addMessage('Cannot upgrade version to itself.');
+            unset($this->cookie->newVersion);
+            return $this->_forward('Error');
+        }
+
+        // If we got this far, everything is okay:
+        return $this->_forward('Home');
+         */
+    }
+
+    /**
+     * Upgrade the configuration files.
+     *
+     * @return void
+     */
+    public function fixconfigAction()
+    {
+        /* TODO
+        $upgrader = new VF_Config_Upgrade(
+            $this->cookie->oldVersion, $this->cookie->newVersion,
+            $this->cookie->sourceDir . '/web/conf',
+            APPLICATION_PATH . '/configs',
+            LOCAL_OVERRIDE_DIR . '/application/configs'
+        );
+        try {
+            $upgrader->run();
+            $this->cookie->warnings = $upgrader->getWarnings();
+            $this->cookie->configOkay = true;
+            return $this->_forward('Home');
+        } catch (Exception $e) {
+            $extra = is_a($e, 'VF_Exception_FileAccess')
+                ? '  Check file permissions.' : '';
+            $this->_helper->flashMessenger->setNamespace('error')
+                ->addMessage('Config upgrade failed: ' . $e->getMessage() . $extra);
+            return $this->_forward('Error');
+        }
+         */
+    }
+
+    /**
+     * Upgrade the database.
+     *
+     * @return void
+     */
+    public function fixdatabaseAction()
+    {
+        /* TODO
+        try {
+            // Set up the helper with information from our SQL file:
+            $this->_helper->dbUpgrade->loadSql(APPLICATION_PATH . '/sql/mysql.sql');
+
+            // Check for missing tables.  Note that we need to finish dealing with
+            // missing tables before we proceed to the missing columns check, or else
+            // the missing tables will cause fatal errors during the column test.
+            $missingTables = $this->_helper->dbUpgrade->getMissingTables();
+            if (!empty($missingTables)) {
+                if (!isset($this->session->dbRootUser)
+                    || !isset($this->session->dbRootPass)
+                ) {
+                    return $this->_forward('GetDbCredentials');
+                }
+                $db = VF_DB::connect(
+                    $this->session->dbRootUser, $this->session->dbRootPass
+                );
+                $this->_helper->dbUpgrade->createMissingTables($missingTables, $db);
+                $this->session->warnings[] = "Created missing table(s): "
+                    . implode(', ', $missingTables);
+            }
+
+            // Check for missing columns.
+            $missingCols = $this->_helper->dbUpgrade->getMissingColumns();
+            if (!empty($missingCols)) {
+                if (!isset($this->session->dbRootUser)
+                    || !isset($this->session->dbRootPass)
+                ) {
+                    return $this->_forward('GetDbCredentials');
+                }
+                if (!isset($db)) {  // connect to DB if not already connected
+                    $db = VF_DB::connect(
+                        $this->session->dbRootUser, $this->session->dbRootPass
+                    );
+                }
+                $this->_helper->dbUpgrade->createMissingColumns($missingCols, $db);
+                $this->session->warnings[] = "Added column(s) to table(s): "
+                    . implode(', ', array_keys($missingCols));
+            }
+
+            // Check for modified columns.
+            $modifiedCols = $this->_helper->dbUpgrade->getModifiedColumns();
+            if (!empty($modifiedCols)) {
+                if (!isset($this->session->dbRootUser)
+                    || !isset($this->session->dbRootPass)
+                ) {
+                    return $this->_forward('GetDbCredentials');
+                }
+                if (!isset($db)) {  // connect to DB if not already connected
+                    $db = VF_DB::connect(
+                        $this->session->dbRootUser, $this->session->dbRootPass
+                    );
+                }
+                $this->_helper->dbUpgrade->updateModifiedColumns($modifiedCols, $db);
+                $this->session->warnings[] = "Modified column(s) in table(s): "
+                    . implode(', ', array_keys($modifiedCols));
+            }
+
+            // Don't keep DB credentials in session longer than necessary:
+            unset($this->session->dbRootUser);
+            unset($this->session->dbRootPass);
+
+            // Check for legacy "anonymous tag" bug:
+            $anonymousTags = VuFind_Model_Db_Tags::getAnonymousCount();
+            if ($anonymousTags > 0 && !isset($this->cookie->skipAnonymousTags)) {
+                $this->view->anonymousCount = $anonymousTags;
+                return $this->_forward('FixAnonymousTags');
+            }
+        } catch (Exception $e) {
+            $this->_helper->flashMessenger->setNamespace('error')
+                ->addMessage('Database upgrade failed: ' . $e->getMessage());
+            return $this->_forward('Error');
+        }
+
+        $this->cookie->databaseOkay = true;
+        return $this->_forward('Home');
+         */
+    }
+
+    /**
+     * Prompt the user for database credentials.
+     *
+     * @return void
+     */
+    public function getdbcredentialsAction()
+    {
+        /* TODO
+        $this->view->dbrootuser = $this->_request->getParam('dbrootuser', 'root');
+
+        // Process form submission:
+        if (strlen($this->_request->getParam('submit', '')) > 0) {
+            $pass = $this->_request->getParam('dbrootpass');
+
+            // Test the connection:
+            try {
+                $db = VF_DB::connect($this->view->dbrootuser, $pass);
+                $db->query("SELECT * FROM user;");  // query a table known to exist
+                $this->session->dbRootUser = $this->view->dbrootuser;
+                $this->session->dbRootPass = $pass;
+                return $this->_forward('FixDatabase');
+            } catch (Exception $e) {
+                $this->_helper->flashMessenger->setNamespace('error')
+                    ->addMessage('Could not connect; please try again.');
+            }
+        }
+         */
+    }
+
+    /**
+     * Prompt the user about fixing anonymous tags.
+     *
+     * @return void
+     */
+    public function fixanonymoustagsAction()
+    {
+        /* TODO
+        // Handle skip action:
+        if (strlen($this->_request->getParam('skip', '')) > 0) {
+            $this->cookie->skipAnonymousTags = true;
+            return $this->_forward('FixDatabase');
+        }
+
+        // Handle submit action:
+        if (strlen($this->_request->getParam('submit', '')) > 0) {
+            $user = $this->_request->getParam('username');
+            if (empty($user)) {
+                $this->_helper->flashMessenger->setNamespace('error')
+                    ->addMessage('Username must not be empty.');
+            } else {
+                $user = VuFind_Model_Db_User::getByUsername($user, false);
+                if (empty($user) || !is_object($user) || !isset($user->id)) {
+                    $this->_helper->flashMessenger->setNamespace('error')
+                        ->addMessage("User {$user} not found.");
+                } else {
+                    $table = new VuFind_Model_Db_ResourceTags();
+                    $table->assignAnonymousTags($user->id);
+                    $this->session->warnings[]
+                        = "Assigned all anonymous tags to {$user->username}.";
+                    return $this->_forward('FixDatabase');
+                }
+            }
+        }
+         */
+    }
+
+    /**
+     * Fix missing metadata in the resource table.
+     *
+     * @return void
+     */
+    public function fixmetadataAction()
+    {
+        /* TODO
+        // User requested skipping this step?  No need to do further work:
+        if (strlen($this->_request->getParam('skip', '')) > 0) {
+            $this->cookie->metadataOkay = true;
+            return $this->_forward('Home');
+        }
+
+        // Check for problems:
+        $table = new VuFind_Model_Db_Resource();
+        $problems = $table->findMissingMetadata();
+
+        // No problems?  We're done here!
+        if (count($problems) == 0) {
+            $this->cookie->metadataOkay = true;
+            return $this->_forward('Home');
+        }
+
+        // Process submit button:
+        if (strlen($this->_request->getParam('submit', '')) > 0) {
+            foreach ($problems as $problem) {
+                try {
+                    $driver = VF_Record::load($problem->record_id, $problem->source);
+                    $problem->assignMetadata($driver)->save();
+                } catch (VF_Exception_RecordMissing $e) {
+                    $this->session->warnings[]
+                        = "Unable to load metadata for record "
+                        . "{$problem->source}:{$problem->record_id}";
+                }
+            }
+            $this->cookie->metadataOkay = true;
+            return $this->_forward('Home');
+        }
+         */
+    }
+
+    /**
+     * Prompt the user for a source directory.
+     *
+     * @return void
+     */
+    public function getsourcedirAction()
+    {
+        /* TODO
+        // Process form submission:
+        $dir = $this->_request->getParam('sourcedir');
+        if (!empty($dir)) {
+            $this->cookie->sourceDir = rtrim($dir, '\/');
+            // Clear out request to avoid infinite loop:
+            $this->_request->setParam('sourcedir', '');
+            return $this->_forward('Home');
+        }
+
+        // If a bad directory was provided, display an appropriate error:
+        if (isset($this->cookie->sourceDir)) {
+            if (!is_dir($this->cookie->sourceDir)) {
+                $this->_helper->flashMessenger->setNamespace('error')
+                    ->addMessage($this->cookie->sourceDir . ' does not exist.');
+            } else if (!file_exists($this->cookie->sourceDir . '/build.xml')) {
+                $this->_helper->flashMessenger->setNamespace('error')->addMessage(
+                    'Could not find build.xml in source directory;'
+                    . ' upgrade does not support VuFind versions prior to 1.1.'
+                );
+            }
+        }
+         */
+    }
+
+    /**
+     * Display summary of installation status
+     *
+     * @return void
+     */
+    public function homeAction()
+    {
+        /* TODO
+        // If the cache is messed up, nothing is going to work right -- check that
+        // first:
+        $cache = new VF_Cache_Manager();
+        if ($cache->hasDirectoryCreationError()) {
+            return $this->_redirect('/Install/fixcache');
+        }
+
+        // First find out which version we are upgrading:
+        if (!isset($this->cookie->sourceDir)
+            || !is_dir($this->cookie->sourceDir)
+        ) {
+            return $this->_forward('GetSourceDir');
+        }
+
+        // Next figure out which version(s) are involved:
+        if (!isset($this->cookie->oldVersion)
+            || !isset($this->cookie->newVersion)
+        ) {
+            return $this->_forward('EstablishVersions');
+        }
+
+        // Now make sure we have a configuration file ready:
+        if (!isset($this->cookie->configOkay)) {
+            return $this->_redirect('/Upgrade/FixConfig');
+        }
+
+        // Now make sure the database is up to date:
+        if (!isset($this->cookie->databaseOkay)) {
+            return $this->_redirect('/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)) {
+            return $this->_redirect('/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->_helper->flashMessenger->setNamespace('info')
+                ->addMessage($warning);
+        }
+         */
+    }
+
+    /**
+     * Start over with the upgrade process in case of an error.
+     *
+     * @return void
+     */
+    public function resetAction()
+    {
+        /* TODO
+        foreach ($this->cookie->getAllValues() as $k => $v) {
+            unset($this->cookie->$k);
+        }
+        foreach ($this->session as $k => $v) {
+            unset($this->session->$k);
+        }
+        return $this->_forward('Home');
+         */
+    }
+}
+
diff --git a/module/VuFind/src/VuFind/Controller/VudlController.php b/module/VuFind/src/VuFind/Controller/VudlController.php
new file mode 100644
index 00000000000..596491eb47e
--- /dev/null
+++ b/module/VuFind/src/VuFind/Controller/VudlController.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * VuDLController Module Controller
+ *
+ * PHP Version 5
+ *
+ * Copyright (C) Villanova University 2011.
+ *
+ * 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  Controller
+ * @author   Chris Hallberg <challber@villanova.edu>
+ * @author   David Lacy <david.lacy@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org   Main Site
+ */
+namespace VuFind\Controller;
+use VuFind\Search\Solr\Results as SolrResults;
+
+/**
+ * This controller is for the viewing of the digital library files.
+ *
+ * @category VuFind2
+ * @package  Controller
+ * @author   Chris Hallberg <challber@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     http://vufind.org   Main Site
+ */
+class VudlController extends AbstractBase
+{
+    /**
+     * Get the information from the XML
+     *
+     * Image srcs, document groups
+     *
+     * Data is later loaded and rendered with JS
+     *
+     * @return void
+     */
+    public function recordAction()
+    {
+        /* TODO
+        // TARGET ID
+        $id = $this->_request->getParam('id');
+        $this->view->id = $id;
+
+        // GET XML FILE NAME
+        $driver = SolrResults::getRecord($id);
+        if (!method_exists($driver, 'getFullRecord')) {
+            throw new Exception('Cannot obtain VuDL record');
+        }
+        $result = $driver->getFullRecord();
+        $url = isset($result->url) ? trim($result->url) : false;
+        if (empty($url)) {
+            throw new Exception('Not a VuDL Record: '.$id);
+        }
+
+        // LOAD FILE (this is the only time we pull the whole XML file
+        $xml = simplexml_load_file($url);
+        if (!$xml) {
+            //echo 'catch','<br>';
+            // DOUBLE ENCODING MADNESS - some of the records need to be encoded
+            $split = explode('/', $url);
+            // uri encode everything in url after 'VuDL'
+            for ($i=8;$i<count($split);$i++) {
+                //echo $split[$i],'<br>';
+                $split[$i] = rawurlencode($split[$i]);
+            }
+            $url = implode($split, '/');
+            $xml = simplexml_load_file($url);
+        }
+
+        // FILE INFORMATION / DESCRIPTION
+        $fileDetails = $this->getDocSummary($xml);
+        $this->view->details = $fileDetails;
+        $this->view->file = urlencode($url);
+
+        // GET IDS FOR ALL FILES
+        $files = $this->getAllFiles($xml);
+
+        // GET PAGE AND DOCUMENT STRUCTURE
+        $pages = array();
+        $docs = array();
+        foreach ($xml->xpath('//METS:structMap/METS:div/METS:div') as $div) {
+            foreach ($div->xpath('METS:div') as $item) {
+                $index = intval($item['ORDER']) - 1;
+                // Only the first five pages, the rest are loaded thru AJAX
+                if ($div['TYPE'] == 'page_level') {
+                    $pages[$index] = array(
+                        'label'=>(string) $item['LABEL'],
+                        'original' => ''
+                    );
+                    // Store image srcs under their use
+                    foreach ($item->xpath('METS:fptr') as $id) {
+                        $file = $files[(string) $id['FILEID']];
+                        $pages[$index][$file['use']] = $file['src'];
+                    }
+                } elseif ($div['TYPE'] == 'document_level') {
+                    $id = $item->xpath('METS:fptr');
+                    $id = $id[0];
+                    // Assuming only one document per... document
+                    $file = $files[(string) $id['FILEID']];
+                    $docs[$index] = array(
+                        'label' =>(string) $item['LABEL'],
+                        'src'   => $file['src']
+                    );
+                    // Set the right thumbnail
+                    if ($file['type'] == 'application/pdf') {
+                        $docs[$index]['img'] = 'pdf';
+                    } elseif ($file['type'] == 'application/msword') {
+                        $docs[$index]['img'] = 'doc';
+                    }
+                }
+            }
+        }
+
+        // SEND THE DATA FOR THE FIRST PAGES
+        // (Original, Large, Medium, Thumbnail srcs) and THE DOCUMENTS
+        $this->view->pages = $pages;
+        $this->view->docs = $docs;
+         */
+    }
+
+    /**
+     * In order to reduce initial load time the majority
+     * of the data is called here after document.ready
+     *
+     * @return string JSON encoded data with the urls of all the images
+     *                for each page associated with the document
+     */
+    public function pageDataAction()
+    {
+        /* TODO
+        // We don't want to use views or layouts in this controller since
+        // it is responsible for generating AJAX responses rather than HTML.
+        $this->_helper->viewRenderer->setNoRender();
+        $this->_helper->layout->disableLayout();
+
+        $url = $this->_request->getParam('file');
+        $xml = simplexml_load_file($url);
+
+        // GET IDS FOR ALL FILES
+        $files = $this->getAllFiles($xml);
+
+        // RETURN IMAGES BY use AND labels
+        foreach ($xml->xpath('//METS:structMap/METS:div/METS:div') as $div) {
+            error_reporting(0); // No notices in my JSON please!
+            foreach ($div->xpath('METS:div') as $item) {
+                if ($div['TYPE'] == 'page_level') {
+                    $index = intval($item['ORDER']) - 1;
+                    $pages[$index] = array(
+                        'label'=>(string) $item['LABEL'],
+                        'original' => ''
+                    );
+                    // Store image srcs under their use
+                    foreach ($item->xpath('METS:fptr') as $id) {
+                        $file = $files[(string) $id['FILEID']];
+                        $pages[$index][$file['use']] = $file['src'];
+                    }
+                }
+            }
+        }
+        echo json_encode($pages);
+        error_reporting(-1);
+         */
+    }
+
+    /**
+     * Parses the xml file for the section detailing the files
+     *
+     * @param SimpleXMLElement $xml - to be parsed
+     *
+     * @return  An array of file objects, string-indexed by ID
+     *          Object contains 'src','type','use'(size)
+     */
+    protected function getAllFiles($xml)
+    {
+        $files = array();
+        // really only one:
+        foreach ($xml->xpath('//METS:fileSec') as $fileSec) {
+            // for each group:
+            foreach ($fileSec->xpath('METS:fileGrp') as $i=>$group) {
+                // store by id:
+                foreach ($group->xpath('METS:file') as $j=>$file) {
+                    $src = $file->xpath('METS:FLocat');
+                    $src = $src[0]->attributes('xlink', true);
+                    $files[ $file['ID'].'' ] = array(
+                        'src'  => (string) $src['href'],
+                        'type' => (string) $file['MIMETYPE'],
+                        'use'  => strtolower((string) $group['USE'])
+                    );
+                }
+            }
+        }
+        return $files;
+    }
+
+    /**
+     * Pull the file details (title, date, etc) from the XML
+     *
+     * Data is string indexed by what type of information it is
+     *
+     * @param SimpleXMLElement $xml - to be parsed
+     *
+     * @return  title-indexed array of basic document data
+     *          'author' => 'Kevin Bacon', etc.
+     */
+    protected function getDocSummary($xml)
+    {
+        $data = array();
+        foreach ($xml->xpath('//METS:xmlData') as $xmlData) {
+            if (count($xmlData->children('oai_dc', true)) > 0) {
+                foreach ($xmlData->children('oai_dc', true) as $doc_data) {
+                    foreach ($doc_data->children('dc', true) as $detail) {
+                        $index = $detail->getName();
+                        $data[$index] =(string) $detail;
+                    }
+                }
+                return $data;
+            }
+        }
+    }
+
+    /**
+     * Used to AJAX information about a page that may not have been loaded yet.
+     *
+     * This is a hardly used fallback and may be a candid for deletion
+     *
+     * @return  JSON encoded array with information about the images
+     *          associated with the parameter-specified page.
+     *          Indexed by use (size)
+     */
+    public function pageTabsAction()
+    {
+        /* TODO
+        // We don't want to use views or layouts in this controller since
+        // it is responsible for generating AJAX responses rather than HTML.
+        $this->_helper->viewRenderer->setNoRender();
+        $this->_helper->layout->disableLayout();
+
+        $page = intval($this->_request->getParam('page'));
+        // TARGET ID
+        $id = $this->_request->getParam('id');
+        $xml = $this->getXMLRecord($id);
+
+        // GET FILE IDs AND SRCs
+        $files = $this->getAllFiles($xml);
+
+        // GET PAGES
+        $pages = $this->getPageStructure($xml);
+        if ($id >= count($pages)) {
+            echo '';
+        }
+
+        $re = array();
+        foreach ($pages[$page]['ids'] as $id) {
+            $re[strtolower($files[$id]['use'])] = $files[$id]['src'];
+        }
+        echo json_encode($re);
+         */
+    }
+}
-- 
GitLab