Fix Bug #985492: faceted search feature
This commit is contained in:
commit
d222dd6040
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2012 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -106,13 +106,13 @@ class tx_dlf_cli extends t3lib_cli {
|
|||
|
||||
// Set basic information about the script.
|
||||
$this->cli_help = array (
|
||||
'name' => 'Command Line Interface for Goobi.Presentation',
|
||||
'synopsis' => '###OPTIONS###',
|
||||
'description' => 'Currently the only task available is "index".'.LF.'Try "/PATH/TO/TYPO3/cli_dispatch.phpsh dlf index" to view more options.',
|
||||
'examples' => '/PATH/TO/TYPO3/cli_dispatch.phpsh dlf TASK -ARG1=VALUE1 -ARG2=VALUE2',
|
||||
'options' => '',
|
||||
'license' => 'GNU GPL - free software!',
|
||||
'author' => 'Sebastian Meyer <sebastian.meyer@slub-dresden.de>',
|
||||
'name' => 'Command Line Interface for Goobi.Presentation',
|
||||
'synopsis' => '###OPTIONS###',
|
||||
'description' => 'Currently the only task available is "index".'.LF.'Try "/PATH/TO/TYPO3/cli_dispatch.phpsh dlf index" to view more options.',
|
||||
'examples' => '/PATH/TO/TYPO3/cli_dispatch.phpsh dlf TASK -ARG1=VALUE1 -ARG2=VALUE2',
|
||||
'options' => '',
|
||||
'license' => 'GNU GPL - free software!',
|
||||
'author' => 'Sebastian Meyer <sebastian.meyer@slub-dresden.de>',
|
||||
);
|
||||
|
||||
// Run parent constructor.
|
||||
|
|
|
@ -180,7 +180,7 @@ final class tx_dlf_document {
|
|||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $parentid = 0;
|
||||
protected $parentId = 0;
|
||||
|
||||
/**
|
||||
* This holds the physical pages
|
||||
|
@ -229,7 +229,7 @@ final class tx_dlf_document {
|
|||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $recordid;
|
||||
protected $recordId;
|
||||
|
||||
/**
|
||||
* This holds the singleton object of each document with its UID as array key
|
||||
|
@ -658,9 +658,28 @@ final class tx_dlf_document {
|
|||
$this->_getDmdSec();
|
||||
|
||||
// Is this metadata format supported?
|
||||
if (!empty($this->formats[$this->dmdSec[$dmdId]['type']]['class'])) {
|
||||
if (!empty($this->formats[$this->dmdSec[$dmdId]['type']])) {
|
||||
|
||||
$class = $this->formats[$this->dmdSec[$dmdId]['type']]['class'];
|
||||
if (!empty($this->formats[$this->dmdSec[$dmdId]['type']]['class'])) {
|
||||
|
||||
$class = $this->formats[$this->dmdSec[$dmdId]['type']]['class'];
|
||||
|
||||
// Get the metadata from class.
|
||||
if (class_exists($class) && ($obj = t3lib_div::makeInstance($class)) instanceof tx_dlf_format) {
|
||||
|
||||
$obj->extractMetadata($this->dmdSec[$dmdId]['xml'], $metadata);
|
||||
|
||||
} else {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_document->getMetadata('.$id.', '.$_cPid.')] Invalid class/method "'.$class.'->extractMetadata()" for metadata format "'.$this->dmdSec[$dmdId]['type'].'"', $this->extKey, SYSLOG_SEVERITY_WARNING);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -674,23 +693,6 @@ final class tx_dlf_document {
|
|||
|
||||
}
|
||||
|
||||
// Get the metadata from class.
|
||||
if (class_exists($class) && ($obj = t3lib_div::makeInstance($class)) instanceof tx_dlf_format) {
|
||||
|
||||
$obj->extractMetadata($this->dmdSec[$dmdId]['xml'], $metadata);
|
||||
|
||||
} else {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_document->getMetadata('.$id.', '.$_cPid.')] Invalid class/method "'.$class.'->extractMetadata()" for metadata format "'.$this->dmdSec[$dmdId]['type'].'"', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return array ();
|
||||
|
||||
}
|
||||
|
||||
// Get the structure's type.
|
||||
if (!empty($this->logicalUnits[$id])) {
|
||||
|
||||
|
@ -880,7 +882,7 @@ final class tx_dlf_document {
|
|||
$titledata = $this->getMetadata($this->_getToplevelId(), $cPid);
|
||||
|
||||
// Set record identifier for METS file.
|
||||
array_unshift($titledata['record_id'], $this->recordid);
|
||||
array_unshift($titledata['record_id'], $this->recordId);
|
||||
|
||||
return $titledata;
|
||||
|
||||
|
@ -1432,7 +1434,7 @@ final class tx_dlf_document {
|
|||
|
||||
$this->pid = $pid;
|
||||
|
||||
$this->parentid = $partof;
|
||||
$this->parentId = $partof;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1606,15 +1608,15 @@ final class tx_dlf_document {
|
|||
}
|
||||
|
||||
/**
|
||||
* This returns $this->parentid via __get()
|
||||
* This returns $this->parentId via __get()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return integer The UID of the parent document or zero if not applicable
|
||||
*/
|
||||
protected function _getParentid() {
|
||||
protected function _getParentId() {
|
||||
|
||||
return $this->parentid;
|
||||
return $this->parentId;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1775,15 +1777,15 @@ final class tx_dlf_document {
|
|||
}
|
||||
|
||||
/**
|
||||
* This returns $this->recordid via __get()
|
||||
* This returns $this->recordId via __get()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return mixed The METS file's record identifier
|
||||
*/
|
||||
protected function _getRecordid() {
|
||||
protected function _getRecordId() {
|
||||
|
||||
return $this->recordid;
|
||||
return $this->recordId;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1963,7 +1965,7 @@ final class tx_dlf_document {
|
|||
|
||||
if (!empty($objId[0]['OBJID'])) {
|
||||
|
||||
$this->recordid = (string) $objId[0]['OBJID'];
|
||||
$this->recordId = (string) $objId[0]['OBJID'];
|
||||
|
||||
}
|
||||
|
||||
|
@ -1974,7 +1976,7 @@ final class tx_dlf_document {
|
|||
|
||||
if (method_exists($hookObj, 'construct_postProcessRecordId')) {
|
||||
|
||||
$this->recordid = $hookObj->construct_postProcessRecordId($xml, $this->recordid);
|
||||
$this->recordId = $hookObj->construct_postProcessRecordId($xml, $this->recordId);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1982,9 +1984,9 @@ final class tx_dlf_document {
|
|||
|
||||
}
|
||||
|
||||
if (!empty($this->recordid)) {
|
||||
if (!empty($this->recordId)) {
|
||||
|
||||
$whereClause = 'tx_dlf_documents.record_id='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->recordid, 'tx_dlf_documents').tx_dlf_helper::whereClause('tx_dlf_documents');
|
||||
$whereClause = 'tx_dlf_documents.record_id='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->recordId, 'tx_dlf_documents').tx_dlf_helper::whereClause('tx_dlf_documents');
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -2014,7 +2016,7 @@ final class tx_dlf_document {
|
|||
|
||||
if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
|
||||
|
||||
list ($this->uid, $this->pid, $this->recordid, $this->parentid, $location) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
|
||||
list ($this->uid, $this->pid, $this->recordId, $this->parentId, $location) = $GLOBALS['TYPO3_DB']->sql_fetch_row($result);
|
||||
|
||||
// Load XML file...
|
||||
if ($this->load($location)) {
|
||||
|
@ -2122,7 +2124,7 @@ final class tx_dlf_document {
|
|||
// SimpleXMLElement objects can't be serialized, thus save the XML as string for serialization
|
||||
$this->asXML = $this->xml->asXML();
|
||||
|
||||
return array ('uid', 'pid', 'parentid', 'asXML');
|
||||
return array ('uid', 'pid', 'parentId', 'asXML');
|
||||
|
||||
}
|
||||
|
||||
|
@ -2187,7 +2189,7 @@ final class tx_dlf_document {
|
|||
|
||||
}
|
||||
|
||||
/* No xclasses allowed for this class!
|
||||
/* No xclasses allowed for final classes!
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_document.php']) {
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_document.php']);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -28,14 +28,14 @@
|
|||
|
||||
/**
|
||||
* Interface 'tx_dlf_format' for the 'dlf' extension.
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
interface tx_dlf_format {
|
||||
|
||||
/**
|
||||
|
@ -53,8 +53,8 @@ interface tx_dlf_format {
|
|||
}
|
||||
|
||||
/* No xclasses for interfaces!
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_format.php']) {
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_format.php']);
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_format.php']) {
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_format.php']);
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -46,22 +46,12 @@ class tx_dlf_helper {
|
|||
public static $extKey = 'dlf';
|
||||
|
||||
/**
|
||||
* The encryption key
|
||||
* @see encrypt() / decrypt()
|
||||
* The locallang array for common use
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
private static $ENCRYPTION_KEY = 'b8b311560d3e6f8dea0aa445995b1b2b';
|
||||
|
||||
/**
|
||||
* The initialization vector for encryption
|
||||
* @see encrypt() / decrypt()
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
private static $ENCRYPTION_IV = '381416de30a5c970f8f486aa6d5cc932';
|
||||
protected static $locallang = array ();
|
||||
|
||||
/**
|
||||
* Searches the array recursively for a given value and returns the corresponding key if successful
|
||||
|
@ -253,9 +243,21 @@ class tx_dlf_helper {
|
|||
|
||||
}
|
||||
|
||||
$iv = substr(self::$ENCRYPTION_IV, 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CFB));
|
||||
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
|
||||
|
||||
$decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, self::$ENCRYPTION_KEY, base64_decode($encrypted), MCRYPT_MODE_CFB, $iv);
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_helper->decrypt('.$encrypted.', '.$hash.')] No encryption key set in TYPO3 configuration', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
$iv = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CFB));
|
||||
|
||||
$decrypted = mcrypt_decrypt(MCRYPT_BLOWFISH, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], base64_decode($encrypted), MCRYPT_MODE_CFB, $iv);
|
||||
|
||||
$salt = substr($hash, 0, 10);
|
||||
|
||||
|
@ -302,9 +304,21 @@ class tx_dlf_helper {
|
|||
|
||||
}
|
||||
|
||||
$iv = substr(self::$ENCRYPTION_IV, 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CFB));
|
||||
if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
|
||||
|
||||
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, self::$ENCRYPTION_KEY, $string, MCRYPT_MODE_CFB, $iv));
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_helper->encrypt('.$string.')] No encryption key set in TYPO3 configuration', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
$iv = substr(md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']), 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CFB));
|
||||
|
||||
$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $string, MCRYPT_MODE_CFB, $iv));
|
||||
|
||||
$salt = substr(md5(uniqid(rand(), TRUE)), 0, 10);
|
||||
|
||||
|
@ -330,7 +344,7 @@ class tx_dlf_helper {
|
|||
|
||||
return $GLOBALS['BE_USER'];
|
||||
|
||||
} elseif (!isset($_COOKIE['be_typo_user'])) {
|
||||
} elseif (!isset($_COOKIE['be_typo_user'])) { // TODO: Since TYPO3 4.6 the cookie name is configurable in $TYPO3_CONF_VARS['BE']['cookieName']
|
||||
|
||||
// Initialize backend session with CLI user's rights.
|
||||
$userObj = t3lib_div::makeInstance('t3lib_beUserAuth');
|
||||
|
@ -530,6 +544,71 @@ class tx_dlf_helper {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper function for getting localizations in frontend and backend
|
||||
*
|
||||
* @param string $key: The locallang key to translate
|
||||
* @param string $default: Default return value if no translation is available
|
||||
* @param boolean $hsc: Should the result be htmlspecialchar()'ed?
|
||||
*
|
||||
* @return string The translated string or the given key on failure
|
||||
*/
|
||||
public static function getLL($key, $default = '', $hsc = FALSE) {
|
||||
|
||||
// Set initial output to default value.
|
||||
$translated = (string) $default;
|
||||
|
||||
// Load common locallang file.
|
||||
if (empty(self::$locallang)) {
|
||||
|
||||
$file = t3lib_extMgm::extPath(self::$extKey, 'common/locallang.xml');
|
||||
|
||||
if (TYPO3_MODE === 'FE') {
|
||||
|
||||
self::$locallang = $GLOBALS['TSFE']->readLLfile($file);
|
||||
|
||||
} elseif (TYPO3_MODE === 'BE') {
|
||||
|
||||
self::$locallang = $GLOBALS['LANG']->includeLLFile($file, FALSE, TRUE);
|
||||
|
||||
} elseif (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_helper->getLL('.$key.', '.$default.', ['.($hsc ? 'TRUE' : 'FALSE').'])] Unexpected TYPO3_MODE "'.TYPO3_MODE.'"', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Get translation.
|
||||
if (!empty(self::$locallang['default'][$key])) {
|
||||
|
||||
if (TYPO3_MODE === 'FE') {
|
||||
|
||||
$translated = $GLOBALS['TSFE']->getLLL($key, self::$locallang);
|
||||
|
||||
} elseif (TYPO3_MODE === 'BE') {
|
||||
|
||||
$translated = $GLOBALS['LANG']->getLLL($key, self::$locallang, FALSE);
|
||||
|
||||
} elseif (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_helper->getLL('.$key.', '.$default.', ['.($hsc ? 'TRUE' : 'FALSE').'])] Unexpected TYPO3_MODE "'.TYPO3_MODE.'"', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Escape HTML characters if applicable.
|
||||
if ($hsc) {
|
||||
|
||||
$translated = htmlspecialchars($translated);
|
||||
|
||||
}
|
||||
|
||||
return $translated;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URN of an object
|
||||
* @see http://www.persistent-identifier.de/?link=316
|
||||
|
|
|
@ -150,7 +150,7 @@ class tx_dlf_indexing {
|
|||
|
||||
}
|
||||
|
||||
self::$solr->commit();
|
||||
self::$solr->service->commit();
|
||||
|
||||
// Get document title from database.
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
|
@ -271,9 +271,9 @@ class tx_dlf_indexing {
|
|||
try {
|
||||
|
||||
// Delete Solr document.
|
||||
self::$solr->deleteByQuery('uid:'.$uid);
|
||||
self::$solr->service->deleteByQuery('uid:'.$uid);
|
||||
|
||||
self::$solr->commit();
|
||||
self::$solr->service->commit();
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
|
@ -539,7 +539,7 @@ class tx_dlf_indexing {
|
|||
|
||||
try {
|
||||
|
||||
self::$solr->addDocument($solrDoc);
|
||||
self::$solr->service->addDocument($solrDoc);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
|
@ -602,7 +602,7 @@ class tx_dlf_indexing {
|
|||
if (!self::$solr) {
|
||||
|
||||
// Connect to Solr server.
|
||||
if (self::$solr = tx_dlf_solr::solrConnect($core)) {
|
||||
if (self::$solr = tx_dlf_solr::getInstance($core)) {
|
||||
|
||||
// Load indexing configuration if needed.
|
||||
if ($pid) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -28,13 +28,13 @@
|
|||
|
||||
/**
|
||||
* Metadata format class 'tx_dlf_mods' for the 'dlf' extension.
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
*/
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
*/
|
||||
class tx_dlf_mods implements tx_dlf_format {
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -28,14 +28,14 @@
|
|||
|
||||
/**
|
||||
* Base class 'tx_dlf_module' for the 'dlf' extension.
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract class tx_dlf_module extends t3lib_SCbase {
|
||||
|
||||
public $extKey = 'dlf';
|
||||
|
@ -232,7 +232,7 @@ abstract class tx_dlf_module extends t3lib_SCbase {
|
|||
|
||||
/* No xclasses for abstract classes!
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_module.php']) {
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_module.php']);
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_module.php']);
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -28,14 +28,14 @@
|
|||
|
||||
/**
|
||||
* Base class 'tx_dlf_plugin' for the 'dlf' extension.
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract class tx_dlf_plugin extends tslib_pibase {
|
||||
|
||||
public $extKey = 'dlf';
|
||||
|
@ -317,7 +317,7 @@ abstract class tx_dlf_plugin extends tslib_pibase {
|
|||
|
||||
/* No xclasses for abstract classes!
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_plugin.php']) {
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_plugin.php']);
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_plugin.php']);
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -24,27 +24,158 @@
|
|||
// TODO: Clean up and reduce code duplication. Consider switching to Solarium.
|
||||
/**
|
||||
* [CLASS/FUNCTION INDEX of SCRIPT]
|
||||
*/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Solr class 'tx_dlf_solr' for the 'dlf' extension.
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @author Henrik Lochmann <dev@mentalmotive.com>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
*/
|
||||
*
|
||||
* @author Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* @author Henrik Lochmann <dev@mentalmotive.com>
|
||||
* @copyright Copyright (c) 2011, Sebastian Meyer, SLUB Dresden
|
||||
* @package TYPO3
|
||||
* @subpackage tx_dlf
|
||||
* @access public
|
||||
*/
|
||||
class tx_dlf_solr {
|
||||
|
||||
/**
|
||||
* This holds the core name
|
||||
*
|
||||
* @var string
|
||||
* @access protected
|
||||
*/
|
||||
protected $core = '';
|
||||
|
||||
/**
|
||||
* This holds the PID for the configuration
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $cPid = 0;
|
||||
|
||||
/**
|
||||
* The extension key
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public static $extKey = 'dlf';
|
||||
public $extKey = 'dlf';
|
||||
|
||||
/**
|
||||
* This holds the filter query
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
protected $filter = array ();
|
||||
|
||||
/**
|
||||
* This holds the max results
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $limit = 50000;
|
||||
|
||||
/**
|
||||
* This holds the number of hits for last search
|
||||
*
|
||||
* @var integer
|
||||
* @access protected
|
||||
*/
|
||||
protected $numberOfHits = 0;
|
||||
|
||||
/**
|
||||
* Is the search instantiated successfully?
|
||||
*
|
||||
* @var boolean
|
||||
* @access protected
|
||||
*/
|
||||
protected $ready = FALSE;
|
||||
|
||||
/**
|
||||
* This holds the singleton search objects with their core as array key
|
||||
*
|
||||
* @var array(tx_dlf_solr)
|
||||
* @access protected
|
||||
*/
|
||||
protected static $registry = array ();
|
||||
|
||||
/**
|
||||
* This holds the Solr service object
|
||||
*
|
||||
* @var Apache_Solr_Service
|
||||
* @access protected
|
||||
*/
|
||||
protected $service;
|
||||
|
||||
/**
|
||||
* This is a singleton class, thus instances must be created by this method
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $core: Name or UID of the core to load
|
||||
*
|
||||
* @return tx_dlf_solr Instance of this class
|
||||
*/
|
||||
public static function getInstance($core) {
|
||||
|
||||
// Save parameter for logging purposes.
|
||||
$_core = $core;
|
||||
|
||||
// Get core name if UID is given.
|
||||
if (t3lib_div::testInt($core)) {
|
||||
|
||||
$core = tx_dlf_helper::getIndexName($core, 'tx_dlf_solrcores');
|
||||
|
||||
}
|
||||
|
||||
// Check if core is set.
|
||||
if (empty($core)) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_solr->getInstance('.$_core.')] Invalid core name "'.$core.'" for Apache Solr', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Check if there is an instance in the registry already.
|
||||
if (is_object(self::$registry[$core]) && self::$registry[$core] instanceof self) {
|
||||
|
||||
// Return singleton instance if available.
|
||||
return self::$registry[$core];
|
||||
|
||||
}
|
||||
|
||||
// Create new instance...
|
||||
$instance = new self($core);
|
||||
|
||||
// ...and save it to registry.
|
||||
if ($instance->ready) {
|
||||
|
||||
self::$registry[$core] = $instance;
|
||||
|
||||
// Return new instance.
|
||||
return $instance;
|
||||
|
||||
} else {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_solr->getInstance('.$_core.')] Could not connect to Apache Solr server', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request URL for a specific Solr core
|
||||
|
@ -82,19 +213,428 @@ class tx_dlf_solr {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get SolrPhpClient service object and establish connection to Solr server
|
||||
* @see EXT:dlf/lib/SolrPhpClient/Apache/Solr/Service.php
|
||||
* Get next unused Solr core number
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param mixed $core: Name or UID of the core to load
|
||||
* @param integer $start: Number to start with
|
||||
*
|
||||
* @return mixed Instance of Apache_Solr_Service or NULL on failure
|
||||
* @return integer First unused core number found
|
||||
*/
|
||||
public static function solrConnect($core = 0) {
|
||||
public static function solrGetCoreNumber($start = 0) {
|
||||
|
||||
// Save parameter for logging purposes.
|
||||
$_core = $core;
|
||||
$start = max(intval($start), 0);
|
||||
|
||||
// Check if core already exists.
|
||||
if (self::getInstance('dlfCore'.$start) === NULL) {
|
||||
|
||||
return $start;
|
||||
|
||||
} else {
|
||||
|
||||
return self::solrGetCoreNumber($start + 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a search request.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $query: The search query
|
||||
*
|
||||
* @return tx_dlf_list The result list
|
||||
*/
|
||||
public function search($query = '*') {
|
||||
|
||||
// Sanitize query string.
|
||||
$query = (string) $query;
|
||||
|
||||
if (empty($query)) {
|
||||
|
||||
$query = '*';
|
||||
|
||||
}
|
||||
|
||||
// Perform search.
|
||||
$query = $this->service->search($query, 0, $this->limit, $this->filter);
|
||||
|
||||
$this->numberOfHits = count($query->response->docs);
|
||||
|
||||
$toplevel = array ();
|
||||
|
||||
$checks = array ();
|
||||
|
||||
// Get metadata configuration.
|
||||
if ($numHits) {
|
||||
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
'tx_dlf_metadata.index_name AS index_name,tx_dlf_metadata.tokenized AS tokenized,tx_dlf_metadata.indexed AS indexed,tx_dlf_metadata.is_listed AS is_listed,tx_dlf_metadata.is_sortable AS is_sortable',
|
||||
'tx_dlf_metadata',
|
||||
'(tx_dlf_metadata.is_listed=1 OR tx_dlf_metadata.is_sortable=1) AND tx_dlf_metadata.pid='.intval($this->cPid).tx_dlf_helper::whereClause('tx_dlf_metadata'),
|
||||
'',
|
||||
'tx_dlf_metadata.sorting ASC',
|
||||
''
|
||||
);
|
||||
|
||||
$metadata = array ();
|
||||
|
||||
$sorting = array ();
|
||||
|
||||
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
|
||||
|
||||
if ($resArray['is_listed']) {
|
||||
|
||||
$metadata[$resArray['index_name']] = $resArray['index_name'].'_'.($resArray['tokenized'] ? 't' : 'u').'s'.($resArray['indexed'] ? 'i' : 'u');
|
||||
|
||||
}
|
||||
|
||||
if ($resArray['is_sortable']) {
|
||||
|
||||
$sorting[$resArray['index_name']] = $resArray['index_name'].'_sorting';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Keep track of relevance.
|
||||
$i = 0;
|
||||
|
||||
// Process results.
|
||||
foreach ($query->response->docs as $doc) {
|
||||
|
||||
// Prepate document's metadata.
|
||||
$docMeta = array ();
|
||||
|
||||
foreach ($metadata as $index_name => $solr_name) {
|
||||
|
||||
if (!empty($doc->$solr_name)) {
|
||||
|
||||
$docMeta[$index_name] = (is_array($doc->$solr_name) ? $doc->$solr_name : array ($doc->$solr_name));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Prepate document's metadata for sorting.
|
||||
$docSorting = array ();
|
||||
|
||||
foreach ($sorting as $index_name => $solr_name) {
|
||||
|
||||
if (!empty($doc->$solr_name)) {
|
||||
|
||||
$docSorting[$index_name] = (is_array($doc->$solr_name) ? $doc->$solr_name[0] : $doc->$solr_name);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add relevance to sorting values.
|
||||
$docSorting['relevance'] = str_pad($i, 6, '0', STR_PAD_LEFT);
|
||||
|
||||
// Split toplevel documents from subparts.
|
||||
if ($doc->toplevel == 1) {
|
||||
|
||||
$toplevel[$doc->uid] = array (
|
||||
'uid' => $doc->uid,
|
||||
'page' => $doc->page,
|
||||
'metadata' => $docMeta,
|
||||
'sorting' => $docSorting,
|
||||
'subparts' => (!empty($toplevel[$doc->uid]['subparts']) ? $toplevel[$doc->uid]['subparts'] : array ())
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
$toplevel[$doc->uid]['subparts'][] = array (
|
||||
'uid' => $doc->uid,
|
||||
'page' => $doc->page,
|
||||
'metadata' => $docMeta,
|
||||
'sorting' => $docSorting
|
||||
);
|
||||
|
||||
if (!in_array($doc->uid, $check)) {
|
||||
|
||||
$checks[] = $doc->uid;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
}
|
||||
|
||||
// Check if the toplevel documents have metadata.
|
||||
foreach ($checks as $check) {
|
||||
|
||||
if (empty($toplevel[$check]['uid'])) {
|
||||
|
||||
// Get information for toplevel document.
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
'tx_dlf_documents.uid AS uid,tx_dlf_documents.metadata AS metadata,tx_dlf_documents.metadata_sorting AS metadata_sorting',
|
||||
'tx_dlf_documents',
|
||||
'tx_dlf_documents.uid='.intval($check).tx_dlf_helper::whereClause('tx_dlf_documents'),
|
||||
'',
|
||||
'',
|
||||
'1'
|
||||
);
|
||||
|
||||
// Process results.
|
||||
if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
|
||||
|
||||
$resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
|
||||
|
||||
// Prepare document's metadata.
|
||||
$metadata = unserialize($resArray['metadata']);
|
||||
|
||||
if (!empty($metadata['type'][0]) && t3lib_div::testInt($metadata['type'][0])) {
|
||||
|
||||
$metadata['type'][0] = tx_dlf_helper::getIndexName($metadata['type'][0], 'tx_dlf_structures', $this->cPid);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($metadata['owner'][0]) && t3lib_div::testInt($metadata['owner'][0])) {
|
||||
|
||||
$metadata['owner'][0] = tx_dlf_helper::getIndexName($metadata['owner'][0], 'tx_dlf_libraries', $this->cPid);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($metadata['collection']) && is_array($metadata['collection'])) {
|
||||
|
||||
foreach ($metadata['collection'] as $i => $collection) {
|
||||
|
||||
if (t3lib_div::testInt($collection)) {
|
||||
|
||||
$metadata['collection'][$i] = tx_dlf_helper::getIndexName($metadata['collection'][$i], 'tx_dlf_collections', $this->cPid);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Prepare document's metadata for sorting.
|
||||
$sorting = unserialize($resArray['metadata_sorting']);
|
||||
|
||||
if (!empty($sorting['type']) && t3lib_div::testInt($sorting['type'])) {
|
||||
|
||||
$sorting['type'] = tx_dlf_helper::getIndexName($sorting['type'], 'tx_dlf_structures', $this->cPid);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($sorting['owner']) && t3lib_div::testInt($sorting['owner'])) {
|
||||
|
||||
$sorting['owner'] = tx_dlf_helper::getIndexName($sorting['owner'], 'tx_dlf_libraries', $this->cPid);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($sorting['collection']) && t3lib_div::testInt($sorting['collection'])) {
|
||||
|
||||
$sorting['collection'] = tx_dlf_helper::getIndexName($sorting['collection'], 'tx_dlf_collections', $this->cPid);
|
||||
|
||||
}
|
||||
|
||||
$toplevel[$check] = array (
|
||||
'uid' => $resArray['uid'],
|
||||
'page' => 1,
|
||||
'metadata' => $metadata,
|
||||
'sorting' => $sorting,
|
||||
'subparts' => $toplevel[$check]['subparts']
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
// Clear entry if there is no (accessible) toplevel document.
|
||||
unset ($toplevel[$check]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Save list of documents.
|
||||
$list = t3lib_div::makeInstance('tx_dlf_list');
|
||||
|
||||
$list->reset();
|
||||
|
||||
$list->add(array_values($toplevel));
|
||||
|
||||
// Set metadata for search.
|
||||
$list->metadata = array (
|
||||
'label' => '',
|
||||
'description' => '',
|
||||
'options' => array (
|
||||
'source' => 'search',
|
||||
'select' => $query,
|
||||
'filter' => $this->filter,
|
||||
'order' => 'relevance'
|
||||
)
|
||||
);
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns $this->numberOfHits via __get()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return integer Total number of hits for last search
|
||||
*/
|
||||
protected function _getNumberOfHits() {
|
||||
|
||||
return $this->numberOfHits;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns $this->ready via __get()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return boolean Is the search instantiated successfully?
|
||||
*/
|
||||
protected function _getReady() {
|
||||
|
||||
return $this->ready;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns $this->service via __get()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return Apache_Solr_Service Apache Solr service object
|
||||
*/
|
||||
protected function _getService() {
|
||||
|
||||
return $this->service;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets $this->cPid via __set()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @param integer $value: The new PID for the metadata definitions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setCPid($value) {
|
||||
|
||||
$this->cPid = max(intval($value), 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets $this->filter via __set()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @param array $value: The filter query
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setFilter(array $value) {
|
||||
|
||||
$this->filter = $value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets $this->limit via __set()
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @param integer $value: The max number of results
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _setLimit($value) {
|
||||
|
||||
$this->limit = max(intval($value), 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This magic method is called each time an invisible property is referenced from the object
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $var: Name of variable to get
|
||||
*
|
||||
* @return mixed Value of $this->$var
|
||||
*/
|
||||
public function __get($var) {
|
||||
|
||||
$method = '_get'.ucfirst($var);
|
||||
|
||||
if (!property_exists($this, $var) || !method_exists($this, $method)) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_solr->__get('.$var.')] There is no getter function for property "'.$var.'"', $this->extKey, SYSLOG_SEVERITY_WARNING);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
return $this->$method();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This magic method is called each time an invisible property is referenced from the object
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $var: Name of variable to set
|
||||
* @param mixed $value: New value of variable
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __set($var, $value) {
|
||||
|
||||
$method = '_set'.ucfirst($var);
|
||||
|
||||
if (!property_exists($this, $var) || !method_exists($this, $method)) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_solr->__set('.$var.', '.$value.')] There is no setter function for property "'.$var.'"', $this->extKey, SYSLOG_SEVERITY_WARNING);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$this->$method($value);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a singleton class, thus the constructor should be private/protected
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @param string $core: The name of the core to use
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function __construct($core) {
|
||||
|
||||
// Load class.
|
||||
if (!class_exists('Apache_Solr_Service')) {
|
||||
|
@ -118,92 +658,33 @@ class tx_dlf_solr {
|
|||
// Set port if not set.
|
||||
$port = t3lib_div::intInRange($conf['solrPort'], 1, 65535, 8180);
|
||||
|
||||
// Get core name if UID is given.
|
||||
if (t3lib_div::testInt($core)) {
|
||||
|
||||
$core = tx_dlf_helper::getIndexName($core, 'tx_dlf_solrcores');
|
||||
|
||||
if (empty($core)) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_solr->solrConnect('.$_core.')] Invalid UID "'.$_core.'" for Apache Solr core', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Append core name to path.
|
||||
$path = trim($conf['solrPath'], '/').'/'.$core;
|
||||
|
||||
// Instantiate Apache_Solr_Service class.
|
||||
$solr = t3lib_div::makeInstance('Apache_Solr_Service', $host, $port, $path);
|
||||
$this->service = t3lib_div::makeInstance('Apache_Solr_Service', $host, $port, $path);
|
||||
|
||||
// Check if connection is established.
|
||||
if ($solr->ping() !== FALSE) {
|
||||
if ($this->service->ping() !== FALSE) {
|
||||
|
||||
// Do not collapse single value arrays.
|
||||
$solr->setCollapseSingleValueArrays = FALSE;
|
||||
$this->service->setCollapseSingleValueArrays = FALSE;
|
||||
|
||||
return $solr;
|
||||
// Set core name.
|
||||
$this->core = $core;
|
||||
|
||||
} else {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_solr->solrConnect('.$_core.')] Could not connect to Apache Solr server with core "'.$core.'"', $this->extKey, SYSLOG_SEVERITY_ERROR);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
// Instantiation successful!
|
||||
$this->ready = TRUE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next unused Solr core number
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param integer $start: Number to start with
|
||||
*
|
||||
* @return integer First unused core number found
|
||||
*/
|
||||
public static function solrGetCoreNumber($start = 0) {
|
||||
|
||||
$start = max(intval($start), 0);
|
||||
|
||||
// Check if core already exists.
|
||||
if (self::solrConnect('dlfCore'.$start) === NULL) {
|
||||
|
||||
return $start;
|
||||
|
||||
} else {
|
||||
|
||||
return self::solrGetCoreNumber($start + 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a static class, thus no instances should be created
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function __construct() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* No xclasses for static classes!
|
||||
/* No xclasses allowed for singleton classes!
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_solr.php']) {
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_solr.php']);
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/common/class.tx_dlf_solr.php']);
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<T3locallang>
|
||||
<meta type="array">
|
||||
<type>module</type>
|
||||
<description>Common language labels for extension 'dlf'</description>
|
||||
</meta>
|
||||
<data type="array">
|
||||
<languageKey index="default" type="array">
|
||||
<label index="demo">demo</label>
|
||||
</languageKey>
|
||||
<languageKey index="de" type="array">
|
||||
<label index="demo">demo</label>
|
||||
</languageKey>
|
||||
</data>
|
||||
</T3locallang>
|
|
@ -197,7 +197,7 @@ $TCA['tx_dlf_libraries'] = array (
|
|||
);
|
||||
|
||||
// Register static typoscript.
|
||||
t3lib_extMgm::addStaticFile($_EXTKEY, 'typoscript/', 'DLF (Base Configuration)');
|
||||
t3lib_extMgm::addStaticFile($_EXTKEY, 'typoscript/', 'Basic Configuration');
|
||||
|
||||
// Register plugins.
|
||||
t3lib_div::loadTCA('tt_content');
|
||||
|
@ -272,6 +272,8 @@ $TCA['tt_content']['types']['list']['subtypes_addlist'][$_EXTKEY.'_search'] = 'p
|
|||
|
||||
t3lib_extMgm::addPlugin(array('LLL:EXT:dlf/locallang.xml:tt_content.dlf_search', $_EXTKEY.'_search'), 'list_type');
|
||||
|
||||
t3lib_extMgm::addStaticFile($_EXTKEY, 'plugins/search/', 'Search Facets');
|
||||
|
||||
t3lib_extMgm::addPiFlexFormValue($_EXTKEY.'_search', 'FILE:EXT:'.$_EXTKEY.'/plugins/search/flexform.xml');
|
||||
|
||||
// Plugin "statistics".
|
||||
|
|
|
@ -92,6 +92,61 @@ class tx_dlf_tceforms {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get flexform's items array for plugin "tx_dlf_search"
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param array &$params: An array with parameters
|
||||
* @param t3lib_TCEforms &$pObj: The parent object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function itemsProcFunc_facetsList(&$params, &$pObj) {
|
||||
|
||||
if ($params['row']['pi_flexform']) {
|
||||
|
||||
$pi_flexform = t3lib_div::xml2array($params['row']['pi_flexform']);
|
||||
|
||||
$pages = $pi_flexform['data']['sDEF']['lDEF']['pages']['vDEF'];
|
||||
|
||||
// There is a strange behavior where the uid from the flexform is prepended by the table's name and appended by its title.
|
||||
// i.e. instead of "18" it reads "pages_18|Title"
|
||||
if (!t3lib_div::testInt($pages)) {
|
||||
|
||||
$_parts = explode('|', $pages);
|
||||
|
||||
$pages = array_pop(explode('_', $_parts[0]));
|
||||
|
||||
}
|
||||
|
||||
if ($pages > 0) {
|
||||
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
'label,index_name',
|
||||
'tx_dlf_metadata',
|
||||
'is_facet=1 AND pid='.intval($pages).' AND (sys_language_uid IN (-1,0) OR l18n_parent=0)'.tx_dlf_helper::whereClause('tx_dlf_metadata'),
|
||||
'',
|
||||
'sorting',
|
||||
''
|
||||
);
|
||||
|
||||
if ($GLOBALS['TYPO3_DB']->sql_num_rows($result) > 0) {
|
||||
|
||||
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_row($result)) {
|
||||
|
||||
$params['items'][] = $resArray;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get flexform's items array for plugin "tx_dlf_oai"
|
||||
*
|
||||
|
|
|
@ -263,12 +263,12 @@ class tx_dlf_tcemain {
|
|||
if ($fieldArray['hidden']) {
|
||||
|
||||
// Establish Solr connection.
|
||||
if ($solr = tx_dlf_solr::solrConnect($core)) {
|
||||
if ($solr = tx_dlf_solr::getInstance($core)) {
|
||||
|
||||
// Delete Solr document.
|
||||
$solr->deleteByQuery('uid:'.$id);
|
||||
$solr->service->deleteByQuery('uid:'.$id);
|
||||
|
||||
$solr->commit();
|
||||
$solr->service->commit();
|
||||
|
||||
}
|
||||
|
||||
|
@ -345,9 +345,9 @@ class tx_dlf_tcemain {
|
|||
if ($solr = tx_dlf_solr::solrConnect($core)) {
|
||||
|
||||
// Delete Solr document.
|
||||
$solr->deleteByQuery('uid:'.$id);
|
||||
$solr->service->deleteByQuery('uid:'.$id);
|
||||
|
||||
$solr->commit();
|
||||
$solr->service->commit();
|
||||
|
||||
if ($command == 'delete') {
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ class tx_dlf_collection extends tx_dlf_plugin {
|
|||
|
||||
// Get all documents in collection.
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
|
||||
'tx_dlf_collections.label AS collLabel,tx_dlf_collections.description AS collDesc,tx_dlf_documents.uid AS uid,tx_dlf_documents.metadata AS metadata,tx_dlf_documents.metadata_sorting AS metadata_sorting,tx_dlf_documents.volume_sorting AS volume_sorting,tx_dlf_documents.partof AS partof',
|
||||
'tx_dlf_collections.index_name AS index_name,tx_dlf_collections.label AS collLabel,tx_dlf_collections.description AS collDesc,tx_dlf_documents.uid AS uid,tx_dlf_documents.metadata AS metadata,tx_dlf_documents.metadata_sorting AS metadata_sorting,tx_dlf_documents.volume_sorting AS volume_sorting,tx_dlf_documents.partof AS partof',
|
||||
'tx_dlf_documents',
|
||||
'tx_dlf_relations',
|
||||
'tx_dlf_collections',
|
||||
|
@ -283,6 +283,7 @@ class tx_dlf_collection extends tx_dlf_plugin {
|
|||
'options' => array (
|
||||
'source' => 'collection',
|
||||
'select' => $id,
|
||||
'filter' => array ('collection_faceting:"'.$resArray['index_name'].'"'),
|
||||
'order' => 'title'
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2011 Sebastian Meyer <sebastian.meyer@slub-dresden.de>
|
||||
* All rights reserved
|
||||
|
@ -79,14 +79,12 @@ class tx_dlf_search extends tx_dlf_plugin {
|
|||
*
|
||||
* @access protected
|
||||
*
|
||||
* @param integer $core: UID of the core
|
||||
*
|
||||
* @return string HTML input fields with encrypted core name and hash
|
||||
*/
|
||||
protected function addEncryptedCoreName($core) {
|
||||
protected function addEncryptedCoreName() {
|
||||
|
||||
// Get core name.
|
||||
$name = tx_dlf_helper::getIndexName($core, 'tx_dlf_solrcores');
|
||||
$name = tx_dlf_helper::getIndexName($this->conf['solrcore'], 'tx_dlf_solrcores');
|
||||
|
||||
// Encrypt core name.
|
||||
if (!empty($name)) {
|
||||
|
@ -108,6 +106,129 @@ class tx_dlf_search extends tx_dlf_plugin {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the facets menu to the search form
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return string HTML output of facets menu
|
||||
*/
|
||||
protected function addFacetsMenu() {
|
||||
|
||||
// Check for typoscript configuration to prevent fatal error.
|
||||
if (empty($this->conf['facetsConf.'])) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_search->addFacetsMenu()] Incomplete plugin configuration', $this->extKey, SYSLOG_SEVERITY_WARNING);
|
||||
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
// Quit without doing anything if no facets are selected.
|
||||
if (empty($this->conf['facets'])) {
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
// Get facets from plugin configuration.
|
||||
$facets = array ();
|
||||
|
||||
foreach (t3lib_div::trimExplode(',', $this->conf['facets'], TRUE) as $facet) {
|
||||
|
||||
$facets[$facet] = tx_dlf_helper::translate($facet, 'tx_dlf_metadata', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
// Render facets menu.
|
||||
$TSconfig = array ();
|
||||
|
||||
$TSconfig['special'] = 'userfunction';
|
||||
|
||||
$TSconfig['special.']['userFunc'] = 'tx_dlf_search->makeFacetsMenuArray';
|
||||
|
||||
$TSconfig['special.']['facets'] = $facets;
|
||||
|
||||
$TSconfig = t3lib_div::array_merge_recursive_overrule($this->conf['facetsConf.'], $TSconfig);
|
||||
|
||||
return $this->cObj->HMENU($TSconfig);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array for a HMENU entry of a facet value.
|
||||
*
|
||||
* @param string $field: The facet's index_name
|
||||
* @param string $value: The facet's value
|
||||
* @param integer $count: Number of hits for this facet
|
||||
* @param array $search: The parameters of the current search query
|
||||
* @param string &$state: The state of the parent item
|
||||
*
|
||||
* @return array The array for the facet's menu entry
|
||||
*/
|
||||
protected function getFacetsMenuEntry($field, $value, $count, $search, &$state) {
|
||||
|
||||
$entryArray = array();
|
||||
|
||||
// Translate value.
|
||||
if ($field == 'owner_faceting') {
|
||||
|
||||
// Translate name of holding library.
|
||||
$entryArray['title'] = tx_dlf_helper::translate($value, 'tx_dlf_libraries', $this->conf['pages']);
|
||||
|
||||
} elseif ($field == 'type_faceting') {
|
||||
|
||||
// Translate document type.
|
||||
$entryArray['title'] = tx_dlf_helper::translate($value, 'tx_dlf_structures', $this->conf['pages']);
|
||||
|
||||
} elseif ($field == 'language_faceting') {
|
||||
|
||||
// Translate ISO 639 language code.
|
||||
$entryArray['title'] = tx_dlf_helper::getLanguageName($value);
|
||||
|
||||
} else {
|
||||
|
||||
$entryArray['title'] = $value;
|
||||
|
||||
}
|
||||
|
||||
$entryArray['count'] = $count;
|
||||
|
||||
$entryArray['doNotLinkIt'] = 0;
|
||||
|
||||
// Check if facet is already selected.
|
||||
$index = array_search($field.':"'.$value.'"', $search['fq']);
|
||||
|
||||
if ($index !== FALSE) {
|
||||
|
||||
// Facet is selected, thus remove it from filter.
|
||||
unset($search['fq'][$index]);
|
||||
|
||||
$search['fq'] = array_values($search['fq']);
|
||||
|
||||
$entryArray['ITEM_STATE'] = 'CUR';
|
||||
|
||||
$state = 'ACTIFSUB';
|
||||
|
||||
} else {
|
||||
|
||||
// Facet is not selected, thus add it to filter.
|
||||
$search['fq'][] = $field.':"'.$value.'"';
|
||||
|
||||
$entryArray['ITEM_STATE'] = 'NO';
|
||||
|
||||
}
|
||||
|
||||
$entryArray['_OVERRIDE_HREF'] = $this->pi_linkTP_keepPIvars_url(array ('query' => $search['query'], 'fq' => $search['fq']));
|
||||
|
||||
return $entryArray;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method of the PlugIn
|
||||
*
|
||||
|
@ -138,7 +259,7 @@ class tx_dlf_search extends tx_dlf_plugin {
|
|||
|
||||
}
|
||||
|
||||
if (empty($this->piVars['query'])) {
|
||||
if (!isset($this->piVars['query'])) {
|
||||
|
||||
// Add javascript for autocompletion if available.
|
||||
$autocomplete = $this->addAutocompleteJS();
|
||||
|
@ -172,241 +293,53 @@ class tx_dlf_search extends tx_dlf_plugin {
|
|||
'###LABEL_SUBMIT###' => $this->pi_getLL('label.submit'),
|
||||
'###FIELD_QUERY###' => $this->prefixId.'[query]',
|
||||
'###QUERY###' => htmlspecialchars($lastQuery),
|
||||
'###ADDITIONAL_INPUTS###' => '',
|
||||
'###ADDITIONAL_INPUTS###' => $this->addEncryptedCoreName(),
|
||||
'###FACETS_MENU###' => $this->addFacetsMenu()
|
||||
);
|
||||
|
||||
// Encrypt Solr core name and add as hidden input field to the search form.
|
||||
if ($autocomplete) {
|
||||
|
||||
$markerArray['###ADDITIONAL_INPUTS###'] = $this->addEncryptedCoreName($this->conf['solrcore']);
|
||||
|
||||
}
|
||||
|
||||
// Display search form.
|
||||
$content .= $this->cObj->substituteMarkerArray($this->template, $markerArray);
|
||||
|
||||
return $this->pi_wrapInBaseClass($content);
|
||||
|
||||
} elseif (($solr = tx_dlf_solr::solrConnect($this->conf['solrcore'])) !== NULL) {
|
||||
} else {
|
||||
|
||||
// Instantiate search object.
|
||||
$solr = tx_dlf_solr::getInstance($this->conf['solrcore']);
|
||||
|
||||
if (!$solr->ready) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_search->main('.$content.', [data])] Apache Solr not available', $this->extKey, SYSLOG_SEVERITY_ERROR, $conf);
|
||||
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
// Set search parameters.
|
||||
$solr->limit = $this->conf['limit'];
|
||||
|
||||
$solr->cPid = $this->conf['pages'];
|
||||
|
||||
if (!empty($this->piVars['fq'])) {
|
||||
|
||||
$solr->filter = $this->piVars['fq'];
|
||||
|
||||
}
|
||||
|
||||
// Perform search.
|
||||
$query = $solr->search($this->piVars['query'], 0, $this->conf['limit'], array ());
|
||||
$results = $solr->search($this->piVars['query']);
|
||||
|
||||
$numHits = count($query->response->docs);
|
||||
|
||||
$toplevel = array ();
|
||||
|
||||
$checks = array ();
|
||||
|
||||
// Get metadata configuration.
|
||||
if ($numHits) {
|
||||
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
'tx_dlf_metadata.index_name AS index_name,tx_dlf_metadata.tokenized AS tokenized,tx_dlf_metadata.indexed AS indexed,tx_dlf_metadata.is_listed AS is_listed,tx_dlf_metadata.is_sortable AS is_sortable',
|
||||
'tx_dlf_metadata',
|
||||
'(tx_dlf_metadata.is_listed=1 OR tx_dlf_metadata.is_sortable=1) AND tx_dlf_metadata.pid='.intval($this->conf['pages']).tx_dlf_helper::whereClause('tx_dlf_metadata'),
|
||||
'',
|
||||
'tx_dlf_metadata.sorting ASC',
|
||||
''
|
||||
);
|
||||
|
||||
$metadata = array ();
|
||||
|
||||
$sorting = array ();
|
||||
|
||||
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
|
||||
|
||||
if ($resArray['is_listed']) {
|
||||
|
||||
$metadata[$resArray['index_name']] = $resArray['index_name'].'_'.($resArray['tokenized'] ? 't' : 'u').'s'.($resArray['indexed'] ? 'i' : 'u');
|
||||
|
||||
}
|
||||
|
||||
if ($resArray['is_sortable']) {
|
||||
|
||||
$sorting[$resArray['index_name']] = $resArray['index_name'].'_sorting';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Keep track of relevance.
|
||||
$i = 0;
|
||||
|
||||
// Process results.
|
||||
foreach ($query->response->docs as $doc) {
|
||||
|
||||
// Prepate document's metadata.
|
||||
$docMeta = array ();
|
||||
|
||||
foreach ($metadata as $index_name => $solr_name) {
|
||||
|
||||
if (!empty($doc->$solr_name)) {
|
||||
|
||||
$docMeta[$index_name] = (is_array($doc->$solr_name) ? $doc->$solr_name : array ($doc->$solr_name));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Prepate document's metadata for sorting.
|
||||
$docSorting = array ();
|
||||
|
||||
foreach ($sorting as $index_name => $solr_name) {
|
||||
|
||||
if (!empty($doc->$solr_name)) {
|
||||
|
||||
$docSorting[$index_name] = (is_array($doc->$solr_name) ? $doc->$solr_name[0] : $doc->$solr_name);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add relevance to sorting values.
|
||||
$docSorting['relevance'] = str_pad($i, 6, '0', STR_PAD_LEFT);
|
||||
|
||||
// Split toplevel documents from subparts.
|
||||
if ($doc->toplevel == 1) {
|
||||
|
||||
$toplevel[$doc->uid] = array (
|
||||
'uid' => $doc->uid,
|
||||
'page' => $doc->page,
|
||||
'metadata' => $docMeta,
|
||||
'sorting' => $docSorting,
|
||||
'subparts' => (!empty($toplevel[$doc->uid]['subparts']) ? $toplevel[$doc->uid]['subparts'] : array ())
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
$toplevel[$doc->uid]['subparts'][] = array (
|
||||
'uid' => $doc->uid,
|
||||
'page' => $doc->page,
|
||||
'metadata' => $docMeta,
|
||||
'sorting' => $docSorting
|
||||
);
|
||||
|
||||
if (!in_array($doc->uid, $check)) {
|
||||
|
||||
$checks[] = $doc->uid;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$i++;
|
||||
|
||||
}
|
||||
|
||||
// Check if the toplevel documents have metadata.
|
||||
foreach ($checks as $check) {
|
||||
|
||||
if (empty($toplevel[$check]['uid'])) {
|
||||
|
||||
// Get information for toplevel document.
|
||||
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
|
||||
'tx_dlf_documents.uid AS uid,tx_dlf_documents.metadata AS metadata,tx_dlf_documents.metadata_sorting AS metadata_sorting',
|
||||
'tx_dlf_documents',
|
||||
'tx_dlf_documents.uid='.intval($check).tx_dlf_helper::whereClause('tx_dlf_documents'),
|
||||
'',
|
||||
'',
|
||||
'1'
|
||||
);
|
||||
|
||||
// Process results.
|
||||
if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) {
|
||||
|
||||
$resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result);
|
||||
|
||||
// Prepare document's metadata.
|
||||
$metadata = unserialize($resArray['metadata']);
|
||||
|
||||
if (!empty($metadata['type'][0]) && t3lib_div::testInt($metadata['type'][0])) {
|
||||
|
||||
$metadata['type'][0] = tx_dlf_helper::getIndexName($metadata['type'][0], 'tx_dlf_structures', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($metadata['owner'][0]) && t3lib_div::testInt($metadata['owner'][0])) {
|
||||
|
||||
$metadata['owner'][0] = tx_dlf_helper::getIndexName($metadata['owner'][0], 'tx_dlf_libraries', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($metadata['collection']) && is_array($metadata['collection'])) {
|
||||
|
||||
foreach ($metadata['collection'] as $i => $collection) {
|
||||
|
||||
if (t3lib_div::testInt($collection)) {
|
||||
|
||||
$metadata['collection'][$i] = tx_dlf_helper::getIndexName($metadata['collection'][$i], 'tx_dlf_collections', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Prepare document's metadata for sorting.
|
||||
$sorting = unserialize($resArray['metadata_sorting']);
|
||||
|
||||
if (!empty($sorting['type']) && t3lib_div::testInt($sorting['type'])) {
|
||||
|
||||
$sorting['type'] = tx_dlf_helper::getIndexName($sorting['type'], 'tx_dlf_structures', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($sorting['owner']) && t3lib_div::testInt($sorting['owner'])) {
|
||||
|
||||
$sorting['owner'] = tx_dlf_helper::getIndexName($sorting['owner'], 'tx_dlf_libraries', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
if (!empty($sorting['collection']) && t3lib_div::testInt($sorting['collection'])) {
|
||||
|
||||
$sorting['collection'] = tx_dlf_helper::getIndexName($sorting['collection'], 'tx_dlf_collections', $this->conf['pages']);
|
||||
|
||||
}
|
||||
|
||||
$toplevel[$check] = array (
|
||||
'uid' => $resArray['uid'],
|
||||
'page' => 1,
|
||||
'metadata' => $metadata,
|
||||
'sorting' => $sorting,
|
||||
'subparts' => $toplevel[$check]['subparts']
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
// Clear entry if there is no (accessible) toplevel document.
|
||||
unset ($toplevel[$check]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Save list of documents.
|
||||
$list = t3lib_div::makeInstance('tx_dlf_list');
|
||||
|
||||
$list->reset();
|
||||
|
||||
$list->add(array_values($toplevel));
|
||||
|
||||
// Set metadata for search.
|
||||
$list->metadata = array (
|
||||
$results->metadata = array (
|
||||
'label' => htmlspecialchars(sprintf($this->pi_getLL('searchfor', ''), $this->piVars['query'])),
|
||||
'description' => '<p class="tx-dlf-search-numHits">'.htmlspecialchars(sprintf($this->pi_getLL('hits', ''), $numHits, count($toplevel))).'</p>',
|
||||
'options' => array (
|
||||
'source' => 'search',
|
||||
'select' => $this->piVars['query'],
|
||||
'order' => 'relevance'
|
||||
)
|
||||
'description' => '<p class="tx-dlf-search-numHits">'.htmlspecialchars(sprintf($this->pi_getLL('hits', ''), $solr->numHits, $results->count)).'</p>',
|
||||
'options' => $results->metadata['options']
|
||||
);
|
||||
|
||||
$list->save();
|
||||
$results->save();
|
||||
|
||||
// Clean output buffer.
|
||||
t3lib_div::cleanOutputBuffers();
|
||||
|
@ -423,6 +356,127 @@ class tx_dlf_search extends tx_dlf_plugin {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* This builds a menu array for HMENU
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $content: The PlugIn content
|
||||
* @param array $conf: The PlugIn configuration
|
||||
*
|
||||
* @return array HMENU array
|
||||
*/
|
||||
public function makeFacetsMenuArray($content, $conf) {
|
||||
|
||||
$this->init($conf);
|
||||
|
||||
$menuArray = array ();
|
||||
|
||||
// Set default values for facet search.
|
||||
$search = array (
|
||||
'query' => '*',
|
||||
'fq' => array ()
|
||||
);
|
||||
|
||||
// Extract query and filter from last search.
|
||||
$list = t3lib_div::makeInstance('tx_dlf_list');
|
||||
|
||||
if (!empty($list->metadata['options']['source'])) {
|
||||
|
||||
if ($list->metadata['options']['source'] == 'search') {
|
||||
|
||||
$search['query'] = $list->metadata['options']['select'];
|
||||
|
||||
}
|
||||
|
||||
$search['fq'] = $list->metadata['options']['filter'];
|
||||
|
||||
}
|
||||
|
||||
// Get applicable facets.
|
||||
$solr = tx_dlf_solr::getInstance($this->conf['solrcore']);
|
||||
|
||||
if (!$solr->ready) {
|
||||
|
||||
if (TYPO3_DLOG) {
|
||||
|
||||
t3lib_div::devLog('[tx_dlf_search->makeFacetsMenuArray('.$content.', [data])] Apache Solr not available', $this->extKey, SYSLOG_SEVERITY_ERROR, $conf);
|
||||
|
||||
}
|
||||
|
||||
return array ();
|
||||
|
||||
}
|
||||
|
||||
$params = array (
|
||||
'facet' => 'true',
|
||||
'fq' => $search['fq'],
|
||||
'facet.field' => array ()
|
||||
);
|
||||
|
||||
foreach ($this->conf['facets'] as $field => $label) {
|
||||
|
||||
$params['facet.field'][] = $field.'_faceting';
|
||||
|
||||
}
|
||||
|
||||
// Perform search.
|
||||
$results = $solr->service->search($search['query'], 0, $this->conf['limit'], $params);
|
||||
|
||||
// Process results.
|
||||
foreach ($results->facet_counts->facet_fields as $field => $values) {
|
||||
|
||||
$hasValue = FALSE;
|
||||
|
||||
$entryArray = array ();
|
||||
|
||||
$entryArray['title'] = $this->conf['facets'][$field];
|
||||
|
||||
$entryArray['count'] = 0;
|
||||
|
||||
$entryArray['_OVERRIDE_HREF'] = '';
|
||||
|
||||
$entryArray['doNotLinkIt'] = 1;
|
||||
|
||||
$entryArray['ITEM_STATE'] = 'NO';
|
||||
|
||||
foreach ($values as $value => $count) {
|
||||
|
||||
if ($count > 0) {
|
||||
|
||||
$hasValue = TRUE;
|
||||
|
||||
$entryArray['count']++;
|
||||
|
||||
$entryArray['ITEM_STATE'] = 'IFSUB';
|
||||
|
||||
$entryArray['_SUB_MENU'][] = $this->getFacetsMenuEntry($field, $value, $count, $search, $entryArray['ITEM_STATE']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!$hasValue) {
|
||||
|
||||
$entryArray['_SUB_MENU'][] = array (
|
||||
'title' => $this->pi_getLL('noFacets', ''),
|
||||
'count' => 0,
|
||||
'_OVERRIDE_HREF' => '',
|
||||
'doNotLinkIt' => 1,
|
||||
'ITEM_STATE' => 'NO'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
$menuArray[] = $entryArray;
|
||||
|
||||
}
|
||||
|
||||
return $menuArray;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dlf/plugins/search/class.tx_dlf_search.php']) {
|
||||
|
|
|
@ -53,6 +53,22 @@
|
|||
</config>
|
||||
</TCEforms>
|
||||
</limit>
|
||||
<facets>
|
||||
<TCEforms>
|
||||
<displayCond>FIELD:pages:REQ:true</displayCond>
|
||||
<exclude>1</exclude>
|
||||
<label>LLL:EXT:dlf/plugins/search/locallang.xml:tt_content.pi_flexform.facets</label>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<items type="array"></items>
|
||||
<itemsProcFunc>tx_dlf_tceforms->itemsProcFunc_facetsList</itemsProcFunc>
|
||||
<size>5</size>
|
||||
<autoSizeMax>15</autoSizeMax>
|
||||
<maxitems>1024</maxitems>
|
||||
<minitems>0</minitems>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</facets>
|
||||
<targetPid>
|
||||
<TCEforms>
|
||||
<exclude>1</exclude>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<label index="tt_content.pi_flexform.sheet_general">Options</label>
|
||||
<label index="tt_content.pi_flexform.solrcore">Solr Core</label>
|
||||
<label index="tt_content.pi_flexform.limit">Maximum results</label>
|
||||
<label index="tt_content.pi_flexform.facets">Show these facets</label>
|
||||
<label index="tt_content.pi_flexform.targetPid">Target page (with "DLF: List View" plugin)</label>
|
||||
<label index="tt_content.pi_flexform.separator">Separator for metadata in TS array</label>
|
||||
<label index="tt_content.pi_flexform.templateFile">Template file</label>
|
||||
|
@ -16,11 +17,13 @@
|
|||
<label index="label.submit">Search</label>
|
||||
<label index="searchfor">Search for: "%s"</label>
|
||||
<label index="hits">%d hits found in %d documents.</label>
|
||||
<label index="noFacets">no facets</label>
|
||||
</languageKey>
|
||||
<languageKey index="de" type="array">
|
||||
<label index="tt_content.pi_flexform.sheet_general">Einstellungen</label>
|
||||
<label index="tt_content.pi_flexform.solrcore">Solr Kern</label>
|
||||
<label index="tt_content.pi_flexform.limit">Maximale Ergebnismenge</label>
|
||||
<label index="tt_content.pi_flexform.facets">Diese Facetten anzeigen</label>
|
||||
<label index="tt_content.pi_flexform.targetPid">Zielseite (mit Plugin "DLF: Listenansicht")</label>
|
||||
<label index="tt_content.pi_flexform.separator">Trennzeichen für Metadaten im TS-Array</label>
|
||||
<label index="tt_content.pi_flexform.templateFile">HTML-Template</label>
|
||||
|
@ -28,6 +31,7 @@
|
|||
<label index="label.submit">Suchen</label>
|
||||
<label index="searchfor">Suche nach: "%s"</label>
|
||||
<label index="hits">Die Suche ergab %d Treffer in %d Dokumenten.</label>
|
||||
<label index="noFacets">keine Einträge</label>
|
||||
</languageKey>
|
||||
</data>
|
||||
</T3locallang>
|
|
@ -0,0 +1,28 @@
|
|||
plugin.tx_dlf_search.facetsConf {
|
||||
expAll = 0
|
||||
1 = TMENU
|
||||
1 {
|
||||
noBlur = 1
|
||||
wrap = <ul>|</ul>
|
||||
NO = 1
|
||||
NO {
|
||||
stdWrap {
|
||||
wrap = <h2>|</h2>
|
||||
crop = 55 | ... | 1
|
||||
append.fieldRequired = count
|
||||
append = TEXT
|
||||
append.field = count
|
||||
append.wrap = (|)
|
||||
}
|
||||
doNotLinkIt.field = doNotLinkIt
|
||||
wrapItemAndSub = <li>|</li>
|
||||
}
|
||||
ACT < .NO
|
||||
ACT.wrapItemAndSub = <li class="tx-dlf-search-act">|</li>
|
||||
}
|
||||
2 < .1
|
||||
2 {
|
||||
NO.stdWrap.wrap >
|
||||
ACT.stdWrap.wrap >
|
||||
}
|
||||
}
|
|
@ -4,5 +4,6 @@
|
|||
<input type="text" id="###FIELD_QUERY###" name="###FIELD_QUERY###" value="###QUERY###" class="tx-dlf-search-query" autocomplete="off" role="textbox" aria-autocomplete="list" aria-haspopup="true">
|
||||
<input type="submit" value="###LABEL_SUBMIT###" />
|
||||
###ADDITIONAL_INPUTS###
|
||||
###FACETS_MENU###
|
||||
</form>
|
||||
<!-- ###TEMPLATE### -->
|
|
@ -1,29 +1,37 @@
|
|||
plugin.tx_dlf_toc.menuConf {
|
||||
expAll = 0
|
||||
1 = TMENU
|
||||
1.noBlur = 1
|
||||
1.wrap = <ul>|</ul>
|
||||
1.NO = 1
|
||||
1.NO.stdWrap.crop = 55 | ... | 1
|
||||
1.NO.stdWrap.ifEmpty.field = type
|
||||
1.NO.stdWrap.ifEmpty.append.fieldRequired = volume
|
||||
1.NO.stdWrap.ifEmpty.append = TEXT
|
||||
1.NO.stdWrap.ifEmpty.append.field = volume
|
||||
1.NO.stdWrap.ifEmpty.append.wrap = |
|
||||
1.NO.stdWrap.dataWrap = <span class="tx-dlf-toc-title">|</span> <span class="tx-dlf-toc-pagination">{field:pagination}</span>
|
||||
1.NO.doNotLinkIt.field = doNotLinkIt
|
||||
1.NO.ATagTitle.field = type
|
||||
1.NO.wrapItemAndSub = <li class="tx-dlf-toc-no">|</li>
|
||||
1.IFSUB < .1.NO
|
||||
1.IFSUB.wrapItemAndSub = <li class="tx-dlf-toc-no tx-dlf-toc-ifsub">|</li>
|
||||
1.CUR < .1.NO
|
||||
1.CUR.wrapItemAndSub = <li class="tx-dlf-toc-cur">|</li>
|
||||
1.CURIFSUB < .1.NO
|
||||
1.CURIFSUB.wrapItemAndSub = <li class="tx-dlf-toc-cur tx-dlf-toc-ifsub">|</li>
|
||||
1.ACT < .1.NO
|
||||
1.ACT.wrapItemAndSub = <li class="tx-dlf-toc-act">|</li>
|
||||
1.ACTIFSUB < .1.NO
|
||||
1.ACTIFSUB.wrapItemAndSub = <li class="tx-dlf-toc-act tx-dlf-toc-ifsub">|</li>
|
||||
1 {
|
||||
noBlur = 1
|
||||
wrap = <ul>|</ul>
|
||||
NO = 1
|
||||
NO {
|
||||
stdWrap {
|
||||
crop = 55 | ... | 1
|
||||
ifEmpty {
|
||||
field = type
|
||||
append.fieldRequired = volume
|
||||
append = TEXT
|
||||
append.field = volume
|
||||
append.wrap = |
|
||||
}
|
||||
dataWrap = <span class="tx-dlf-toc-title">|</span> <span class="tx-dlf-toc-pagination">{field:pagination}</span>
|
||||
}
|
||||
doNotLinkIt.field = doNotLinkIt
|
||||
ATagTitle.field = type
|
||||
wrapItemAndSub = <li class="tx-dlf-toc-no">|</li>
|
||||
}
|
||||
IFSUB < .NO
|
||||
IFSUB.wrapItemAndSub = <li class="tx-dlf-toc-no tx-dlf-toc-ifsub">|</li>
|
||||
CUR < .NO
|
||||
CUR.wrapItemAndSub = <li class="tx-dlf-toc-cur">|</li>
|
||||
CURIFSUB < .NO
|
||||
CURIFSUB.wrapItemAndSub = <li class="tx-dlf-toc-cur tx-dlf-toc-ifsub">|</li>
|
||||
ACT < .NO
|
||||
ACT.wrapItemAndSub = <li class="tx-dlf-toc-act">|</li>
|
||||
ACTIFSUB < .NO
|
||||
ACTIFSUB.wrapItemAndSub = <li class="tx-dlf-toc-act tx-dlf-toc-ifsub">|</li>
|
||||
}
|
||||
2 < .1
|
||||
3 < .2
|
||||
4 < .3
|
||||
|
|
|
@ -681,7 +681,7 @@ $TCA['tx_dlf_formats'] = array (
|
|||
'type' => 'input',
|
||||
'size' => 30,
|
||||
'max' => 1024,
|
||||
'eval' => 'required,nospace,alphanum_x,unique',
|
||||
'eval' => 'nospace,alphanum_x,unique',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue