1<?php
2/**
3 * A bsaic object representation.
4 *
5 * PHP version 5
6 *
7 * @category Kolab
8 * @package  Kolab_Server
9 * @author   Gunnar Wrobel <wrobel@pardus.de>
10 * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
11 * @link     http://pear.horde.org/index.php?package=Kolab_Server
12 */
13
14/**
15 * This class provides basic methods common to all Kolab server objects.
16 *
17 * Copyright 2008-2016 Horde LLC (http://www.horde.org/)
18 *
19 * See the enclosed file COPYING for license information (LGPL). If you
20 * did not receive this file, see http://www.horde.org/licenses/lgpl21.
21 *
22 * @category Kolab
23 * @package  Kolab_Server
24 * @author   Gunnar Wrobel <wrobel@pardus.de>
25 * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
26 * @link     http://pear.horde.org/index.php?package=Kolab_Server
27 */
28class Horde_Kolab_Server_Object_Inetorgperson extends Horde_Kolab_Server_Object_Organizationalperson
29{
30    /** The specific object class of this object type */
31    const OBJECTCLASS_INETORGPERSON = 'inetOrgPerson';
32
33    /**
34     * The attributes defined for this class.
35     *
36     * @var array
37     */
38    public static $attributes = array(
39        'uid', 'mail','Firstnamelastname',
40/*         'Organization', 'Businesscategory', 'Homephone', 'Mobile', */
41/*         'Photo', 'Jpegphoto', 'Givenname', 'Middlenames', */
42/*         'Homepostaladdress', 'Labeleduri', 'Lastnamefirstname', */
43/*         'Usersmimecertificate' */
44    );
45
46    /**
47     * A structure to initialize the attribute structure for this class.
48     *
49     * @var array
50     */
51/*     public static $init_attributes = array( */
52/*         'defined' => array( */
53/*             self::ATTRIBUTE_SID, */
54/*             self::ATTRIBUTE_GIVENNAME, */
55/*             self::ATTRIBUTE_LABELEDURI, */
56/*             self::ATTRIBUTE_HOMEPOSTALADDRESS, */
57/*             self::ATTRIBUTE_ORGANIZATION, */
58/*             self::ATTRIBUTE_BUSINESSCATEGORY, */
59/*             self::ATTRIBUTE_HOMEPHONE, */
60/*             self::ATTRIBUTE_MOBILE, */
61/*             self::ATTRIBUTE_PHOTO, */
62/*             self::ATTRIBUTE_JPEGPHOTO, */
63/*             self::ATTRIBUTE_SMIMECERTIFICATE, */
64/*         ), */
65/*         'derived' => array( */
66/*             self::ATTRARRAY_HOMEPOSTALADDRESS => array( */
67/*                 'base' => array( */
68/*                     self::ATTRIBUTE_HOMEPOSTALADDRESS, */
69/*                     self::ATTRIBUTE_GIVENNAME, */
70/*                     self::ATTRIBUTE_SN */
71/*                 ), */
72/*                 'method' => 'getHomePostalAddressHash', */
73/*             ), */
74/*             self::ATTRARRAY_LABELEDURI => array( */
75/*                 'base' => array( */
76/*                     self::ATTRIBUTE_LABELEDURI, */
77/*                 ), */
78/*                 'method' => 'getLabeledUriHash', */
79/*             ), */
80/*             self::ATTRIBUTE_GIVENNAME => array( */
81/*                 'base' => array( */
82/*                     self::ATTRIBUTE_GIVENNAME, */
83/*                 ), */
84/*                 'method' => 'getField', */
85/*                 'args' => array( */
86/*                     self::ATTRIBUTE_GIVENNAME, */
87/*                     0, */
88/*                     ' ' */
89/*                 ), */
90/*             ), */
91/*             self::ATTRIBUTE_MIDDLENAMES => array( */
92/*                 'base' => array( */
93/*                     self::ATTRIBUTE_GIVENNAME, */
94/*                 ), */
95/*                 'method' => 'getField', */
96/*                 'args' => array( */
97/*                     self::ATTRIBUTE_GIVENNAME, */
98/*                     1, */
99/*                     ' ', */
100/*                     2 */
101/*                 ), */
102/*             ), */
103/*             self::ATTRIBUTE_FNLN => array( */
104/*                 'base' => array( */
105/*                     self::ATTRIBUTE_GIVENNAME, */
106/*                     self::ATTRIBUTE_SN */
107/*                 ), */
108/*                 'method' => 'getFnLn', */
109/*             ), */
110/*             self::ATTRIBUTE_LNFN => array( */
111/*                 'base' => array( */
112/*                     self::ATTRIBUTE_GIVENNAME, */
113/*                     self::ATTRIBUTE_SN */
114/*                 ), */
115/*                 'method' => 'getLnFn', */
116/*             ), */
117/*         ), */
118/*         'collapsed' => array( */
119/*             self::ATTRIBUTE_GIVENNAME => array( */
120/*                 'base' => array( */
121/*                     self::ATTRIBUTE_GIVENNAME, */
122/*                     self::ATTRIBUTE_MIDDLENAMES, */
123/*                 ), */
124/*                 'method' => 'setField', */
125/*                 'args' => array( */
126/*                     ' ', */
127/*                 ), */
128/*             ), */
129/*             self::ATTRIBUTE_LABELEDURI => array( */
130/*                 'base' => array( */
131/*                     self::ATTRARRAY_LABELEDURI, */
132/*                 ), */
133/*                 'method' => 'setLabeledUriHash', */
134/*             ), */
135/*             self::ATTRIBUTE_HOMEPOSTALADDRESS => array( */
136/*                 'base' => array( */
137/*                     self::ATTRARRAY_HOMEPOSTALADDRESS, */
138/*                 ), */
139/*                 'method' => 'setHomePostalAddressHash', */
140/*             ), */
141/*         ), */
142/*         'locked' => array( */
143/*             self::ATTRIBUTE_MAIL, */
144/*         ), */
145/*         'object_classes' => array( */
146/*             self::OBJECTCLASS_INETORGPERSON, */
147/*         ), */
148/*     ); */
149
150    /**
151     * Return the filter string to retrieve this object type.
152     *
153     * @static
154     *
155     * @return string The filter to retrieve this object type from the server
156     *                database.
157     */
158    public static function getFilter()
159    {
160        $criteria = array('AND' => array(array('field' => self::ATTRIBUTE_OC,
161                                               'op'    => '=',
162                                               'test'  => self::OBJECTCLASS_INETORGPERSON),
163                          ),
164        );
165        return $criteria;
166    }
167
168    /**
169     * Get the name of this Object as "Firstname Lastname".
170     *
171     * @return string The name.
172     */
173    protected function getFnLn()
174    {
175        $gn = $this->get(self::ATTRIBUTE_GIVENNAME, true);
176        $sn = $this->get(self::ATTRIBUTE_SN, true);
177        return sprintf('%s %s', $gn, $sn);
178    }
179
180    /**
181     * Get the name of this Object as "Lastname, Firstname".
182     *
183     * @return string The name.
184     */
185    protected function getLnFn()
186    {
187        $gn = $this->get(self::ATTRIBUTE_GIVENNAME, true);
188        $sn = $this->get(self::ATTRIBUTE_SN, true);
189        return sprintf('%s, %s', $sn, $gn);
190    }
191
192    /**
193     * Return a hash of URIs. The keys of the hash are the labels.
194     *
195     * @return array The URIs.
196     */
197    protected function getLabeledUriHash()
198    {
199        $result = array();
200        $uris   = $this->get(self::ATTRIBUTE_LABELEDURI, false);
201        if (empty($uris)) {
202            return array();
203        }
204        if (!is_array($uris)) {
205            $uris = array($uris);
206        }
207        foreach ($uris as $uri) {
208            list($address, $label) = explode(' ', $uri, 2);
209            if (!isset($result[$label])) {
210                $result[$label] = array($address);
211            } else {
212                $result[$label][] = $address;
213            }
214        }
215        return $result;
216    }
217
218    /**
219     * Store a hash of URIs. The keys of the hash are the labels.
220     *
221     * @param string $key        The attribute to collapse into.
222     * @param array  $attributes The attributes to collapse.
223     * @param array  &$info      The information currently working on.
224     *
225     * @return NULL
226     */
227    protected function setLabeledUriHash($key, $attributes, &$info)
228    {
229        $result = array();
230        $uris   = $info[self::ATTRARRAY_LABELEDURI];
231        foreach ($uris as $label => $addresses) {
232            if (!is_array($addresses)) {
233                $addresses = array($addresses);
234            }
235            foreach ($addresses as $address) {
236                $result[] = $address . ' ' . $label;
237            }
238        }
239        $info[self::ATTRIBUTE_LABELEDURI] = $result;
240        unset($info[self::ATTRARRAY_LABELEDURI]);
241    }
242
243    /**
244     * Get home postal addresses as an array.
245     *
246     * @return array The home addressses.
247     */
248    protected function getHomePostalAddressHash()
249    {
250        $result    = array();
251        $addresses = $this->get(self::ATTRIBUTE_HOMEPOSTALADDRESS);
252        if (empty($addresses)) {
253            return $addresses;
254        }
255        if (!is_array($addresses)) {
256            $addresses = array($addresses);
257        }
258        foreach ($addresses as $address) {
259            list($name_segment, $street_segment,
260                 $postal_address, $postal_code, $city) = sscanf('%s$%s$%s$%s %s', $address);
261            if ($name_segment == "Post office box") {
262                $result[] = array(
263                    self::ATTRIBUTE_POSTOFFICEBOX => $street_segment,
264                    self::ATTRIBUTE_POSTALADDRESS => $postal_address,
265                    self::ATTRIBUTE_POSTALCODE => $postal_code,
266                    self::ATTRIBUTE_CITY => $city
267                );
268            } else {
269                $result[] = array(
270                    self::ATTRIBUTE_STREET => $street_segment,
271                    self::ATTRIBUTE_POSTALADDRESS => $postal_address,
272                    self::ATTRIBUTE_POSTALCODE => $postal_code,
273                    self::ATTRIBUTE_CITY => $city
274                );
275            }
276        }
277        return $result;
278    }
279
280    /**
281     * Store home postal addresses provided as array.
282     *
283     * @param string $key        The attribute to collapse into.
284     * @param array  $attributes The attributes to collapse.
285     * @param array  &$info      The information currently working on.
286     *
287     * @return NULL
288     */
289    protected function setHomePostalAddressHash($key, $attributes, &$info)
290    {
291        $result         = array();
292        $db_postal_data = array();
293        $db_elements    = array(self::ATTRIBUTE_GIVENNAME,
294                                self::ATTRIBUTE_SN);
295        foreach ($db_elements as $attribute) {
296            if (!empty($info[$attribute])) {
297                if (is_array($info[$attribute])) {
298                    $new = $info[$attribute][0];
299                } else {
300                    $new = $info[$attribute];
301                }
302                $db_postal_data[$attribute] = $this->quote($new);
303            } else {
304                $old = $this->_get($attribute, true);
305                if (!empty($old)) {
306                    $db_postal_data[$attribute] = $this->quote($old);
307                } else {
308                    $db_postal_data[$attribute] = '';
309                }
310            }
311        }
312        $elements = array(self::ATTRIBUTE_STREET,
313                          self::ATTRIBUTE_POSTOFFICEBOX,
314                          self::ATTRIBUTE_POSTALADDRESS,
315                          self::ATTRIBUTE_POSTALCODE,
316                          self::ATTRIBUTE_CITY);
317        if (!empty($info[self::ATTRARRAY_HOMEPOSTALADDRESS])) {
318            $addresses = $info[self::ATTRARRAY_HOMEPOSTALADDRESS];
319        } else {
320            $addresses = $this->get(self::ATTRARRAY_HOMEPOSTALADDRESS);
321        }
322        foreach ($addresses as $address) {
323            $postal_data = array();
324            foreach ($elements as $element) {
325                if (isset($address[$element])) {
326                    $postal_data[$element] = $this->quote($address[$element]);
327                } else {
328                    $postal_data[$element] = '';
329                }
330            }
331            if (!empty($postal_data[self::ATTRIBUTE_STREET])) {
332                $postal_data['street_segment'] = $postal_data[self::ATTRIBUTE_STREET];
333                $postal_data['name_segment']   = $db_postal_data[self::ATTRIBUTE_GIVENNAME] . ' ' . $db_postal_data[self::ATTRIBUTE_SN];
334            } else {
335                $postal_data['street_segment'] = $postal_data[self::ATTRIBUTE_POSTOFFICEBOX];
336                $postal_data['name_segment']   = "Post office box";
337            }
338            $result[] = sprintf('%s$%s$%s$%s %s',
339                                $postal_data['name_segment'],
340                                $postal_data['street_segment'],
341                                $postal_data[self::ATTRIBUTE_POSTALADDRESS],
342                                $postal_data[self::ATTRIBUTE_POSTALCODE],
343                                $postal_data[self::ATTRIBUTE_CITY]);
344        }
345        $info[self::ATTRIBUTE_HOMEPOSTALADDRESS] = $result;
346        unset($info[self::ATTRARRAY_HOMEPOSTALADDRESS]);
347    }
348
349    /**
350     * Generates an ID for the given information.
351     *
352     * @param array $info The data of the object.
353     *
354     * @static
355     *
356     * @return string|PEAR_Error The ID.
357     */
358    public function generateId(array &$info)
359    {
360        if ($this->exists()) {
361            if (!isset($info[self::ATTRIBUTE_GIVENNAME])
362                && !isset($info[self::ATTRIBUTE_SN])) {
363                return false;
364            }
365            if (!isset($info[self::ATTRIBUTE_GIVENNAME])) {
366                $info[self::ATTRIBUTE_GIVENNAME] = $this->get(self::ATTRIBUTE_GIVENNAME);
367            }
368            if (!isset($info[self::ATTRIBUTE_SN])) {
369                $info[self::ATTRIBUTE_SN] = $this->get(self::ATTRIBUTE_SN);
370            }
371        }
372
373        $id_mapfields = array(self::ATTRIBUTE_GIVENNAME,
374                              self::ATTRIBUTE_SN);
375        $id_format    = self::ATTRIBUTE_CN . '=' . '%s %s';
376
377        $fieldarray = array();
378        foreach ($id_mapfields as $mapfield) {
379            if (isset($info[$mapfield])) {
380                $id = $info[$mapfield];
381                if (is_array($id)) {
382                    $id = $id[0];
383                }
384                $fieldarray[] = $this->server->structure->quoteForUid($id);
385            } else {
386                $fieldarray[] = '';
387            }
388        }
389
390        return trim(vsprintf($id_format, $fieldarray), " \t\n\r\0\x0B,");
391    }
392
393}