Completed
Pull Request — master (#233)
by
unknown
07:16
created

VirtualLib::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 11
ccs 0
cts 8
cp 0
rs 9.4286
cc 1
eloc 7
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 * COPS (Calibre OPDS PHP Server) class file
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 * @author     Klaus Broelemann <[email protected]>
7
 */
8
9
require_once('base.php');
10
11
/**
12
 * Read and filter virtual libraries
13
 */
14
class VirtualLib {
15
	const SQL_VL_KEY = "virtual_libraries";  // Key for the virtual library entries.
16
	
17
	const FILTER_TYPE_TEXT = 0;   // Filter by search text
18
	const FILTER_TYPE_NUM  = 1;   // Filter by number
19
	const FILTER_TYPE_BOOL = 2;   // Filter by existence
20
	
21
	private $db_id = null;   // Database Index for the virtual lib
22
	private $vl_id = null;   // Library Index
23
	private $filter = null;  // structured representation of the current filter 
24
	
25
	private static $currentVL = null;  // Singleton: current virtual lib
26
	
27
	/**
28
	 * The constructor parses the calibre search string and creates a array-based representation out of it.
29
	 * 
30
	 * @param int $database The database id of the new object.
31
	 * @param int $virtualLib The virtual library id of the new object.
32
	 */
33
	private function __construct($database = null, $virtualLib = null) {
34
		$this->db_id  = $database;
35
		$this->vl_id  = $virtualLib;
36
		
37
		// Get the current search string
38
		$vlList = self::getVLList($database);
39
		$vlList = array_values($vlList);
40
		$searchStr = $vlList[$virtualLib];
41
		
42
		$this->filter = self::parseFilter($searchStr);
43
	}
44
	
45
	/**
46
	 * Get the current VirtualLib object. 
47
	 *  
48
	 * @param int $database The current database id.
49
	 * @param int $virtualLib The current virtual library id.
50
	 * @return VirtualLib The corresponding VirtualLib object.
51
	 */
52
	public static function getVL($database = null, $virtualLib = null) {
53
		if ( is_null(self::$currentVL) || self::$currentVL->db_id != $database || self::$currentVL->vl_id != $virtualLib ) {
54
			self::$currentVL = new VirtualLib($database, $virtualLib);
55
		}
56
		return self::$currentVL;
57
	}
58
	
59
	/**
60
	 * Converts the calibre search string into an internal format
61
	 * 
62
	 * @param string $searchStr The calibre string
63
	 * @return string The internal, array-based representation
64
	 */
65
	private static function parseFilter($searchStr) {
66
		// deal with empty strings
67
		if (strlen($searchStr) == 0)
68
			return null;
69
		
70
		// Simple search string pattern. It recognizes search string of the form
71
		//     [name]:[value]
72
		// and their negation
73
		//     not [name]:[value]
74
		// where value is either a number, a boolean or a string in double quote.
75
		// In the latter case, the string starts with an operator (= or ~), followed by the search text.
76
		// TODO: deal with more complex search terms that can contain "and", "or" and brackets
77
		$pattern = '#(?P<neg>not)?\s*(?P<name>\w+):(?P<value>"(?P<op>=|~)(?P<text>.*)"|true|false|\d+)#i';
78
		preg_match($pattern, $searchStr, $match);
79
		
80
		// Extract the actual value, operator and type
81
		$value    = $match["value"];
82
		$operator = "=";
83
		if (substr($value, 0, 1) == '"') {
84
			$value = $match["text"];
85
			$operator = $match["op"];
86
			$type = self::FILTER_TYPE_TEXT;
87
		} elseif (preg_match("#\d+", $value)) {
88
			$value = intval($value);
89
			$type = self::FILTER_TYPE_NUM;
90
		} else {
91
			$value = (strcasecmp($value, "true") == 0);
92
			$type = self::FILTER_TYPE_BOOL;
93
		}
94
		
95
		// Put together filter data
96
		$filter = array(
97
				"name"  => $match["name"],
98
				"neg"   => (strlen($match["neg"]) > 0)?true:false,
99
				"op"    => $operator,
100
				"value" => $value,
101
				"type"  => $type
102
		);
103
		
104
		return $filter;
105
	}
106
	
107
	/**
108
	 * Checks if the support for virtual libraries is enabled in the settings.
109
	 * 
110
	 * @return boolean true, if virtual libraries are enabled.
111
	 */
112 41
	public static function isVLEnabled() {
113 41
		global $config;
114 41
		return ($config['enable_virtual_libraries'] == 1);
115
	}
116
	
117
	/**
118
	 * Gets a list of all virtual libraries in a database.
119
	 * 
120
	 * @param int $database id of the database
121
	 * @return array An array of virtual libraries with the names as keys and the filter strings as values.  
122
	 */
123 22
	public static function getVLList($database = NULL) {
124
		// Load list from Database
125 22
		$vLibs = json_decode(Base::getCalibreSetting(self::SQL_VL_KEY, $database), true);
126
		// Add "All Books" at the beginning
127 22
		if (is_null($vLibs))
128 22
			return array(localize ("allbooks.title") => "");
129
		else
130
			return array_merge(array(localize ("allbooks.title") => ""), $vLibs);
131
	}
132
	
133
	/**
134
	 * Gets a list of all virtual libraries in a database.
135
	 *
136
	 * @param int $database id of the database
137
	 * @return array An array of virtual libraries with the names as keys and the filter strings as values.
138
	 */
139 22
	public static function getVLNameList($database = NULL) {
140 22
		return array_keys(self::getVLList($database));
141
	}
142
	
143
	/**
144
	 * Combines the database and virtual lib names into a merged name.
145
	 * 
146
	 * The resulting name has the form "{$dbName} - {$vlName}". If one of these parameters is empty, the dash will also be removed.
147
	 * If the support for virtual libraries is not enabled, this function simply returns the database name.
148
	 * 
149
	 * @param string $dbName The Database Name
150
	 * @param string $vlName The Name of the virtual library
151
	 */
152 1
	public static function getDisplayName($dbName, $vlName) {
153 1
		if (self::isVLEnabled())
154 1
			return trim(str_format('{0} - {1}', $dbName, $vlName), ' -');
155
		else
156 1
			return $dbName;
157
	}
158
}