1: <?php
2: /**
3: * Sam_Driver_Base defines an API for implementing storage backends for Sam.
4: *
5: * @author Chris Bowlby <excalibur@hub.org>
6: * @author Max Kalika <max@gentoo.org>
7: * @author Jan Schneider <jan@horde.org>
8: * @package Sam
9: */
10: abstract class Sam_Driver_Base
11: {
12: /**
13: * The user's preferences.
14: *
15: * @var array
16: */
17: protected $_options = array();
18:
19: /**
20: * The defaults to use if user hasn't defined a value.
21: *
22: * @var array
23: */
24: protected $_defaults = array();
25:
26: /**
27: * The user name.
28: *
29: * @var string
30: */
31: protected $_user;
32:
33: /**
34: * Capabilities supported by the driver.
35: *
36: * @var array
37: */
38: protected $_capabilities = array();
39:
40: /**
41: * Parameter hash for the backend.
42: *
43: * @var array
44: */
45: protected $_params = array();
46:
47: /**
48: * Constructor.
49: *
50: * @param string $user A user name.
51: * @param array $params Backend specific class parameters.
52: */
53: public function __construct($user, $params = array())
54: {
55: $this->_user = $user;
56: $this->_params = $params;
57: }
58:
59: /**
60: * Retrieves user preferences and optionally default values from the
61: * backend.
62: *
63: * @throws Sam_Exception
64: */
65: abstract public function retrieve();
66:
67: /**
68: * Stores user preferences and optionally default values in the backend.
69: *
70: * @param boolean $defaults Whether to store the global defaults instead
71: * of user options.
72: *
73: * @throws Sam_Exception
74: */
75: abstract public function store($defaults = false);
76:
77: /**
78: * Check to see if the backend supports a particular capability.
79: *
80: * @param string $capability The name of the capability to check.
81: *
82: * @return boolean True if the backend is capable, false otherwise.
83: */
84: public function hasCapability($capability)
85: {
86: return in_array($capability, $this->_capabilities);
87: }
88:
89: /**
90: * Converts a boolean option to a backend specific value.
91: *
92: * @param boolean $boolean The value to convert.
93: *
94: * @return mixed 1 if true and 0 if false.
95: */
96: public function booleanToOption($boolean)
97: {
98: return (int)(bool)$boolean;
99: }
100:
101: /**
102: * Convert a backend specific boolean value to a PHP boolean.
103: *
104: * @param mixed $option The value to convert.
105: *
106: * @return boolean True if the backend-specific value is true,
107: * false otherwise.
108: */
109: public function optionToBoolean($option)
110: {
111: return $option === $this->booleanToOption(true);
112: }
113:
114: /**
115: * Returns a preference from user settings or global defaults.
116: *
117: * @param string $option The option to retrieve.
118: *
119: * @return mixed The requested option value.
120: */
121: public function getOption($option)
122: {
123: if (isset($this->_options[$option])) {
124: return $this->_options[$option];
125: }
126: if (isset($this->_defaults[$option])) {
127: return $this->_defaults[$option];
128: }
129: return null;
130: }
131:
132: /**
133: * Sets a preference value for the user or as global defaults, depending on
134: * the parameters.
135: *
136: * Does not automatically store options to the backend.
137: *
138: * @param string $option The option to set.
139: * @param string $value The new value.
140: * @param boolean $defaults Whether to set the global defaults instead of
141: * user options.
142: */
143: public function setOption($option, $value, $defaults = false)
144: {
145: if ($defaults) {
146: $this->_defaults[$option] = $value;
147: } else {
148: $this->_options[$option] = $value;
149: }
150: }
151:
152: /**
153: * Returns an internal address array as a new-line separated string.
154: *
155: * Useful for retrieving whitelists and blacklists.
156: *
157: * @param string $option The option to retrieve.
158: *
159: * @return string New-line separated list value.
160: *
161: */
162: public function getListOption($option)
163: {
164: $list = $this->getOption($option);
165: return is_array($list) ? implode("\n", array_unique($list)) : $list;
166: }
167:
168: /**
169: * Sets an internal address array.
170: *
171: * Useful for whitelists and blacklists. The passed data is split at
172: * whitespace. Does not automatically store options to the backend.
173: *
174: * @param string $option The option to set.
175: * @param string $value A string of data that will be converted to an
176: * array and stored for later storage to the
177: * backend.
178: * @param boolean $defaults Whether to set the global defaults instead of
179: * user options.
180: */
181: public function setListOption($option, $value, $defaults = false)
182: {
183: $list = preg_split('/\s+/', trim($value), -1, PREG_SPLIT_NO_EMPTY);
184: return $this->setOption($option, array_unique($list), $defaults);
185: }
186:
187: /**
188: * Sets an internal array of options which have multiple elements of data
189: * stored in their value.
190: *
191: * E.g. rewrite_header takes two elements, a header and a string, as in
192: * 'rewrite_header' => 'Subject ***SPAM***'.
193: *
194: * There can be multiple entries for these options, so they cannot be
195: * treated independently.
196: *
197: * Does not automatically store options to the backend.
198: *
199: * @param string $option The base option to set.
200: * Should only be 'rewrite_header' ATM.
201: * @param string $value A string of data that will be converted to an
202: * array and stored for later storage to the
203: * backend.
204: * @param boolean $defaults Whether to set the global defaults instead of
205: * user options.
206: */
207: public function setStackedOption($option, $value, $defaults = false)
208: {
209: $list = preg_split('/\n/', trim($value), -1, PREG_SPLIT_NO_EMPTY);
210: return $this->setOption($option, array_unique($list), $defaults);
211: }
212: }
213: