1: <?php
2: 3: 4: 5: 6: 7: 8: 9:
10: class Turba_Object
11: {
12: 13: 14: 15: 16:
17: public $driver;
18:
19: 20: 21: 22: 23:
24: public $attributes;
25:
26: 27: 28: 29: 30:
31: protected $_vfs;
32:
33: 34: 35: 36: 37:
38: public $sortValue = array();
39:
40: 41: 42: 43: 44: 45:
46: public function __construct(Turba_Driver $driver, array $attributes = array())
47: {
48: $this->driver = $driver;
49: $this->attributes = $attributes;
50: $this->attributes['__type'] = 'Object';
51: }
52:
53: 54: 55: 56: 57:
58: public function getAttributes()
59: {
60: return $this->attributes;
61: }
62:
63: 64: 65:
66: public function getSource()
67: {
68: return $this->driver->getName();
69: }
70:
71: 72: 73: 74: 75: 76: 77:
78: public function getGuid($delimiter = ':')
79: {
80: return 'turba' . $delimiter . $this->getSource() . $delimiter . $this->getValue('__uid');
81: }
82:
83: 84: 85: 86: 87: 88: 89: 90:
91: public function getValue($attribute)
92: {
93: if (isset($this->attributes[$attribute]) &&
94: Horde::hookExists('decode_attribute', 'turba')) {
95: try {
96: return Horde::callHook('decode_attribute', array($attribute, $this->attributes[$attribute], $this), 'turba');
97: } catch (Turba_Exception $e) {}
98: }
99: if (isset($this->driver->map[$attribute]) &&
100: is_array($this->driver->map[$attribute])) {
101: $args = array();
102: foreach ($this->driver->map[$attribute]['fields'] as $field) {
103: $args[] = $this->getValue($field);
104: }
105: return Turba::formatCompositeField($this->driver->map[$attribute]['format'], $args);
106: } elseif (!isset($this->attributes[$attribute])) {
107: return null;
108: } elseif (isset($GLOBALS['attributes'][$attribute]) &&
109: ($GLOBALS['attributes'][$attribute]['type'] == 'image')) {
110: return empty($this->attributes[$attribute])
111: ? null
112: : array(
113: 'load' => array(
114: 'data' => $this->attributes[$attribute],
115: 'file' => basename(Horde::getTempFile('horde_form_', false, '', false, true))
116: )
117: );
118: }
119:
120: return $this->attributes[$attribute];
121: }
122:
123: 124: 125: 126: 127: 128:
129: public function setValue($attribute, $value)
130: {
131: if (Horde::hookExists('encode_attribute', 'turba')) {
132: try {
133: $value = Horde::callHook('encode_attribute', array($attribute, $value, isset($this->attributes[$attribute]) ? $this->attributes[$attribute] : null, $this), 'turba');
134: } catch (Turba_Exception $e) {}
135: }
136: if (isset($this->driver->map[$attribute]) &&
137: is_array($this->driver->map[$attribute]) &&
138: !isset($this->driver->map[$attribute]['attribute'])) {
139: return;
140: }
141:
142: $this->attributes[$attribute] = $value;
143: return;
144: }
145:
146: 147: 148: 149: 150: 151: 152: 153:
154: public function hasValue($attribute)
155: {
156: if (isset($this->driver->map[$attribute]) &&
157: is_array($this->driver->map[$attribute])) {
158: foreach ($this->driver->map[$attribute]['fields'] as $field) {
159: if ($this->hasValue($field)) {
160: return true;
161: }
162: }
163: return false;
164: } else {
165: return !is_null($this->getValue($attribute));
166: }
167: }
168:
169: 170: 171: 172: 173: 174: 175:
176: public function lastModification()
177: {
178: $time = $this->getValue('__modified');
179: if (!is_null($time)) {
180: return $time;
181: }
182: if (!$this->getValue('__uid')) {
183: $this->setValue('__modified', 0);
184: return 0;
185: }
186: $time = 0;
187: try {
188: $log = $GLOBALS['injector']
189: ->getInstance('Horde_History')
190: ->getHistory($this->getGuid());
191: foreach ($log as $entry) {
192: if ($entry['action'] == 'add' || $entry['action'] == 'modify') {
193:
194: $time = max($time, $entry['ts']);
195: }
196: }
197: } catch (Exception $e) {}
198: $this->setValue('__modified', $time);
199:
200: return $time;
201: }
202:
203: 204: 205: 206: 207: 208:
209: public function merge(Turba_Object $contact)
210: {
211: foreach (array_keys($contact->attributes) as $attribute) {
212: if (!$this->hasValue($attribute) && $contact->hasValue($attribute)) {
213: $this->setValue($attribute, $contact->getValue($attribute));
214: }
215: }
216: }
217:
218: 219: 220: 221: 222: 223:
224: public function getHistory()
225: {
226: if (!$this->getValue('__uid')) {
227: return array();
228: }
229: $history = array();
230: try {
231: $log = $GLOBALS['injector']
232: ->getInstance('Horde_History')
233: ->getHistory($this->getGuid());
234: foreach ($log as $entry) {
235: if ($entry['action'] == 'add' || $entry['action'] == 'modify') {
236: if ($GLOBALS['registry']->getAuth() != $entry['who']) {
237: $by = sprintf(_("by %s"), Turba::getUserName($entry['who']));
238: } else {
239: $by = _("by me");
240: }
241: $history[$entry['action'] == 'add' ? 'created' : 'modified']
242: = strftime($GLOBALS['prefs']->getValue('date_format'), $entry['ts'])
243: . ' '
244: . date($GLOBALS['prefs']->getValue('twentyFour') ? 'G:i' : 'g:i a', $entry['ts'])
245: . ' '
246: . htmlspecialchars($by);
247: }
248: }
249: } catch (Exception $e) {
250: return array();
251: }
252:
253: return $history;
254: }
255:
256: 257: 258: 259: 260:
261: public function isGroup()
262: {
263: return false;
264: }
265:
266: 267: 268: 269: 270:
271: public function isEditable()
272: {
273: return $this->driver->hasPermission(Horde_Perms::EDIT);
274: }
275:
276: 277: 278: 279: 280: 281: 282:
283: public function hasPermission($perm)
284: {
285: return $this->driver->hasPermission($perm);
286: }
287:
288: 289: 290: 291: 292: 293: 294: 295:
296: public function url($view = null, $full = false)
297: {
298: $url = Horde::url('contact.php', $full)->add(array(
299: 'source' => $this->driver->getName(),
300: 'key' => $this->getValue('__key')
301: ));
302:
303: if (!is_null($view)) {
304: $url->add('view', $view);
305: }
306:
307: return $url;
308: }
309:
310: 311: 312: 313: 314: 315: 316:
317: public function addFile(array $info)
318: {
319: if (!$this->getValue('__uid')) {
320: throw new Turba_Exception('VFS not supported for this object.');
321: }
322: $this->_vfsInit();
323: $dir = Turba::VFS_PATH . '/' . $this->getValue('__uid');
324: $file = $info['name'];
325: while ($this->_vfs->exists($dir, $file)) {
326: if (preg_match('/(.*)\[(\d+)\](\.[^.]*)?$/', $file, $match)) {
327: $file = $match[1] . '[' . ++$match[2] . ']' . $match[3];
328: } else {
329: $dot = strrpos($file, '.');
330: if ($dot === false) {
331: $file .= '[1]';
332: } else {
333: $file = substr($file, 0, $dot) . '[1]' . substr($file, $dot);
334: }
335: }
336: }
337: try {
338: $this->_vfs->write($dir, $file, $info['tmp_name'], true);
339: } catch (Horde_Vfs_Exception $e) {
340: throw new Turba_Exception($e);
341: }
342: }
343:
344: 345: 346: 347: 348: 349:
350: public function deleteFile($file)
351: {
352: if (!$this->getValue('__uid')) {
353: throw new Turba_Exception('VFS not supported for this object.');
354: }
355: $this->_vfsInit();
356: try {
357: $this->_vfs->deleteFile(Turba::VFS_PATH . '/' . $this->getValue('__uid'), $file);
358: } catch (Horde_Vfs_Exception $e) {
359: throw new Turba_Exception($e);
360: }
361: }
362:
363: 364: 365: 366: 367:
368: public function deleteFiles()
369: {
370: if (!$this->getValue('__uid')) {
371: throw new Turba_Exception('VFS not supported for this object.');
372: }
373: $this->_vfsInit();
374: if ($this->_vfs->exists(Turba::VFS_PATH, $this->getValue('__uid'))) {
375: try {
376: $this->_vfs->deleteFolder(Turba::VFS_PATH, $this->getValue('__uid'), true);
377: } catch (Horde_Vfs_Exception $e) {
378: throw new Turba_Exception($e);
379: }
380: }
381: }
382:
383: 384: 385: 386: 387:
388: public function listFiles()
389: {
390: if (!$this->getValue('__uid')) {
391: return array();
392: }
393: try {
394: $this->_vfsInit();
395: if ($this->_vfs->exists(Turba::VFS_PATH, $this->getValue('__uid'))) {
396: return $this->_vfs->listFolder(Turba::VFS_PATH . '/' . $this->getValue('__uid'));
397: }
398: } catch (Turba_Exception $e) {}
399:
400: return array();
401: }
402:
403: 404: 405: 406: 407: 408: 409: 410:
411: public function vfsDisplayUrl($file)
412: {
413: global $registry, $mime_drivers_map, $mime_drivers;
414:
415: $mime_part = new Horde_Mime_Part();
416: $mime_part->setType(Horde_Mime_Magic::extToMime($file['type']));
417: $viewer = $GLOBALS['injector']->getInstance('Horde_Core_Factory_MimeViewer')->create($mime_part);
418:
419:
420: $url_params = array('actionID' => 'download_file',
421: 'file' => $file['name'],
422: 'type' => $file['type'],
423: 'source' => $this->driver->getName(),
424: 'key' => $this->getValue('__key'));
425: $dl = Horde::link(Horde::downloadUrl($file['name'], $url_params), $file['name']) . Horde::img('download.png', _("Download")) . '</a>';
426:
427:
428: if ($viewer && !($viewer instanceof Horde_Mime_Viewer_Default)) {
429: $url = Horde::url('view.php')
430: ->add($url_params)
431: ->add('actionID', 'view_file');
432: $link = Horde::link($url, $file['name'], null, '_blank') . $file['name'] . '</a>';
433: } else {
434: $link = $file['name'];
435: }
436:
437: return $link . ' ' . $dl;
438: }
439:
440: 441: 442: 443: 444: 445: 446: 447:
448: public function vfsEditUrl($file)
449: {
450: $delform = '<form action="' .
451: Horde::url('deletefile.php') .
452: '" style="display:inline" method="post">' .
453: Horde_Util::formInput() .
454: '<input type="hidden" name="file" value="' . htmlspecialchars($file['name']) . '" />' .
455: '<input type="hidden" name="source" value="' . htmlspecialchars($this->driver->getName()) . '" />' .
456: '<input type="hidden" name="key" value="' . htmlspecialchars($this->getValue('__key')) . '" />' .
457: '<input type="image" class="img" src="' . Horde_Themes::img('delete.png') . '" />' .
458: '</form>';
459:
460: return $this->vfsDisplayUrl($file) . ' ' . $delform;
461: }
462:
463: 464: 465: 466: 467:
468: public function store()
469: {
470: return $this->setValue('__key', $this->driver->save($this));
471: }
472:
473: 474: 475: 476: 477:
478: protected function _vfsInit()
479: {
480: if (!isset($this->_vfs)) {
481: try {
482: $this->_vfs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Vfs')->create('documents');
483: } catch (Horde_Exception $e) {
484: throw new Turba_Exception($e);
485: }
486: }
487: }
488:
489: }
490: