1: <?php
2: /**
3: * This class provides an interface to all identities a user might have.
4: *
5: * Copyright 2001-2012 Horde LLC (http://www.horde.org/)
6: *
7: * See the enclosed file COPYING for license information (LGPL). If you
8: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
9: *
10: * @author Jan Schneider <jan@horde.org>
11: * @category Horde
12: * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
13: * @package Prefs
14: */
15: class Horde_Prefs_Identity
16: {
17: /**
18: * Array containing all the user's identities.
19: *
20: * @var array
21: */
22: protected $_identities = array();
23:
24: /**
25: * A pointer to the user's standard identity.
26: * This one is used by the methods returning values if no other one is
27: * specified.
28: *
29: * @var integer
30: */
31: protected $_default = 0;
32:
33: /**
34: * The user whose identities these are.
35: *
36: * @var string
37: */
38: protected $_user = null;
39:
40: /**
41: * Preference names.
42: *
43: * @var array
44: */
45: protected $_prefnames = array(
46: 'default_identity' => 'default_identity',
47: 'from_addr' => 'from_addr',
48: 'fullname' => 'fullname',
49: 'id' => 'id',
50: 'identities' => 'identities',
51: 'properties' => array('id', 'fullname', 'from_addr')
52: );
53:
54: /**
55: * The prefs object that this Identity points to.
56: *
57: * @var Horde_Prefs
58: */
59: protected $_prefs;
60:
61: /**
62: * Constructor.
63: *
64: * @param array $params Parameters:
65: * <pre>
66: * default_identity: (string) The preference name for the default
67: * identity.
68: * DEFAULT: 'default_identity'
69: * from_addr: (string) The preference name for the user's from e-mail
70: * address.
71: * DEFAULT: 'from_addr'
72: * fullname: (string) The preference name for the user's full name.
73: * DEFAULT: 'fullname'
74: * id: (string) The preference name for the identity name.
75: * DEFAULT: 'id'
76: * identities: (string) The preference name for the identity store.
77: * DEFAULT: 'identities'
78: * prefs: (Horde_Prefs) [REQUIRED] The prefs object to use.
79: * properties: (array) The list of properties for the identity.
80: * DEFAULT: array('from_addr', 'fullname', 'id')
81: * user: (string) [REQUIRED] The user whose prefs we are handling.
82: * </pre>
83: */
84: public function __construct($params = array())
85: {
86: foreach (array_keys($this->_prefnames) as $val) {
87: if (isset($params[$val])) {
88: $this->_prefnames[$val] = $params[$val];
89: }
90: }
91: $this->_prefs = $params['prefs'];
92: $this->_user = $params['user'];
93:
94: if (!($this->_identities = @unserialize($this->_prefs->getValue($this->_prefnames['identities'])))) {
95: $this->_identities = $this->_prefs->getDefault($this->_prefnames['identities']);
96: }
97:
98: $this->setDefault($this->_prefs->getValue($this->_prefnames['default_identity']));
99: }
100:
101: /**
102: * Creates a default identity if none exists yet and sets the preferences
103: * up if the identities are locked.
104: */
105: public function init()
106: {
107: if (!is_array($this->_identities) || (count($this->_identities) <= 0)) {
108: foreach (array_keys($this->_prefnames) as $key) {
109: $identity[$key] = $this->_prefs->getValue($key);
110: }
111: if (empty($identity['id'])) {
112: $identity['id'] = Horde_Prefs_Translation::t("Default Identity");
113: }
114:
115: $this->_identities = array($identity);
116: $this->verify(0);
117: }
118: }
119:
120: /**
121: * Saves all identities in the prefs backend.
122: */
123: public function save()
124: {
125: $this->_prefs->setValue($this->_prefnames['identities'], serialize($this->_identities));
126: $this->_prefs->setValue($this->_prefnames['default_identity'], $this->_default);
127: }
128:
129: /**
130: * Adds a new identity to the array of identities.
131: *
132: * @param array $identity An identity hash to add.
133: *
134: * @return integer The pointer to the created identity
135: */
136: public function add($identity = array())
137: {
138: $this->_identities[] = $identity;
139: return count($this->_identities) - 1;
140: }
141:
142: /**
143: * Returns a complete identity hash.
144: *
145: * @param integer $identity The identity to retrieve.
146: *
147: * @return array An identity hash.
148: */
149: public function get($identity = null)
150: {
151: if (is_null($identity) || !isset($this->_identities[$identity])) {
152: $identity = $this->_default;
153: }
154: return $this->_identities[$identity];
155: }
156:
157: /**
158: * Removes an identity from the array of identities.
159: *
160: * @param integer $identity The pointer to the identity to be removed
161: *
162: * @return array The removed identity.
163: */
164: public function delete($identity)
165: {
166: $deleted = array_splice($this->_identities, $identity, 1);
167: foreach (array_keys($this->_identities) as $id) {
168: if ($this->setDefault($id)) {
169: break;
170: }
171: }
172: $this->save();
173:
174: return $deleted;
175: }
176:
177: /**
178: * Returns a pointer to the current default identity.
179: *
180: * @return integer The pointer to the current default identity.
181: */
182: public function getDefault()
183: {
184: return $this->_default;
185: }
186:
187: /**
188: * Sets the current default identity.
189: * If the identity doesn't exist, the old default identity stays the same.
190: *
191: * @param integer $identity The pointer to the new default identity.
192: *
193: * @return boolean True on success, false on failure.
194: */
195: public function setDefault($identity)
196: {
197: if (isset($this->_identities[$identity])) {
198: $this->_default = $identity;
199: return true;
200: }
201:
202: return false;
203: }
204:
205: /**
206: * Returns a property from one of the identities. If this value doesn't
207: * exist or is locked, the property is retrieved from the prefs backend.
208: *
209: * @param string $key The property to retrieve.
210: * @param integer $identity The identity to retrieve the property from.
211: *
212: * @return mixed The value of the property.
213: */
214: public function getValue($key, $identity = null)
215: {
216: if (is_null($identity) || !isset($this->_identities[$identity])) {
217: $identity = $this->_default;
218: }
219:
220: return (!isset($this->_identities[$identity][$key]) || $this->_prefs->isLocked($key))
221: ? $this->_prefs->getValue($key)
222: : $this->_identities[$identity][$key];
223: }
224:
225: /**
226: * Returns an array with the specified property from all existing
227: * identities.
228: *
229: * @param string $key The property to retrieve.
230: *
231: * @return array The array with the values from all identities.
232: */
233: public function getAll($key)
234: {
235: $list = array();
236:
237: foreach (array_keys($this->_identities) as $identity) {
238: $list[$identity] = $this->getValue($key, $identity);
239: }
240:
241: return $list;
242: }
243:
244: /**
245: * Sets a property with a specified value.
246: *
247: * @param string $key The property to set.
248: * @param mixed $val The value to which the property should be
249: * set.
250: * @param integer $identity The identity to set the property in.
251: *
252: * @return boolean True on success, false on failure (property was
253: * locked).
254: */
255: public function setValue($key, $val, $identity = null)
256: {
257: if (is_null($identity)) {
258: $identity = $this->_default;
259: }
260:
261: if (!$this->_prefs->isLocked($key)) {
262: $this->_identities[$identity][$key] = $val;
263: return true;
264: }
265:
266: return false;
267: }
268:
269: /**
270: * Returns true if all properties are locked and therefore nothing in the
271: * identities can be changed.
272: *
273: * @return boolean True if all properties are locked, false otherwise.
274: */
275: public function isLocked()
276: {
277: foreach ($this->_prefnames['properties'] as $key) {
278: if (!$this->_prefs->isLocked($key)) {
279: return false;
280: }
281: }
282:
283: return true;
284: }
285:
286: /**
287: * Returns true if the given address belongs to one of the identities.
288: *
289: * @param string $key The identity key to search.
290: * @param string $value The value to search for in $key.
291: *
292: * @return boolean True if the $value was found in $key.
293: */
294: public function hasValue($key, $valueA)
295: {
296: $list = $this->getAll($key);
297:
298: foreach ($list as $valueB) {
299: if (!empty($valueB) &&
300: strpos(Horde_String::lower($valueA), Horde_String::lower($valueB)) !== false) {
301: return true;
302: }
303: }
304:
305: return false;
306: }
307:
308: /**
309: * Verifies and sanitizes all identity properties.
310: *
311: * @param integer $identity The identity to verify.
312: *
313: * @throws Horde_Prefs_Exception
314: */
315: public function verify($identity = null)
316: {
317: if (is_null($identity)) {
318: $identity = $this->_default;
319: }
320:
321: if (!$this->getValue('id', $identity)) {
322: $this->setValue('id', Horde_Prefs_Translation::t("Unnamed"), $identity);
323: }
324:
325: /* RFC 2822 [3.2.5] does not allow the '\' character to be used in the
326: * personal portion of an e-mail string. */
327: if (strpos($this->getValue($this->_prefnames['fullname'], $identity), '\\') !== false) {
328: throw new Horde_Prefs_Exception('You cannot have the \ character in your full name.');
329: }
330:
331: try {
332: Horde_Mime_Address::parseAddressList($this->getValue($this->_prefnames['from_addr'], $identity), array('validate' => true));
333: } catch (Horde_Mime_Exception $e) {
334: throw new Horde_Prefs_Exception(sprintf(Horde_Prefs_Translation::t("\"%s\" is not a valid email address."), $this->getValue($this->_prefnames['from_addr'], $identity)));
335: }
336: }
337:
338: /**
339: * Returns the user's full name.
340: *
341: * @param integer $ident The identity to retrieve the name from.
342: *
343: * @return string The user's full name, or the user name if it doesn't
344: * exist.
345: */
346: public function getName($ident = null)
347: {
348: if (isset($this->_names[$ident])) {
349: return $this->_names[$ident];
350: }
351:
352: $this->_names[$ident] = $this->getValue($this->_prefnames['fullname'], $ident);
353: if (!strlen($this->_names[$ident])) {
354: $this->_names[$ident] = $this->_user;
355: }
356:
357: return $this->_names[$ident];
358: }
359:
360: /**
361: * Generates the from address to use for the default identity.
362: *
363: * @param boolean $fullname Include the fullname information.
364: *
365: * @return string The default from address.
366: */
367: public function getDefaultFromAddress($fullname = false)
368: {
369: $from_addr = '';
370:
371: if ($fullname) {
372: $name = $this->getValue($this->_prefnames['fullname']);
373: if (!empty($name)) {
374: $from_addr = $name . ' ';
375: }
376: }
377:
378: $addr = $this->getValue($this->_prefnames['from_addr']);
379: if (empty($addr)) {
380: $addr = $this->_user;
381: }
382:
383: if (empty($from_addr)) {
384: return $addr;
385: }
386:
387: return $from_addr . '<' . $addr . '>';
388: }
389:
390: }
391: