1: <?php
2: /**
3: * Copyright 2013-2014 Horde LLC (http://www.horde.org/)
4: *
5: * See the enclosed file COPYING for license information (GPL). If you
6: * did not receive this file, see http://www.horde.org/licenses/gpl.
7: *
8: * @category Horde
9: * @copyright 2013-2014 Horde LLC
10: * @license http://www.horde.org/licenses/gpl GPL
11: * @package IMP
12: */
13:
14: /**
15: * Abstract base class for attachment data storage.
16: *
17: * @author Michael Slusarz <slusarz@horde.org>
18: * @category Horde
19: * @copyright 2013-2014 Horde LLC
20: * @license http://www.horde.org/licenses/gpl GPL
21: * @package IMP
22: *
23: * @property-read boolean $linked Can this attachment be linked?
24: * @property-read Horde_Url $link_url The URL, if the attachment is linked.
25: */
26: abstract class IMP_Compose_Attachment_Storage
27: {
28: /**
29: * Attachment identifier.
30: *
31: * @var string
32: */
33: protected $_id;
34:
35: /**
36: * Temporary file location.
37: *
38: * @var string
39: */
40: protected $_tmpfile;
41:
42: /**
43: * Attachment owner.
44: *
45: * @var string
46: */
47: protected $_user;
48:
49: /**
50: * Constructor.
51: *
52: * @param string $user Attachment owner.
53: * @param string $id Attachment identifier.
54: */
55: public function __construct($user, $id = null)
56: {
57: $this->_user = $user;
58: $this->_id = $id;
59: }
60:
61: /**
62: */
63: public function __get($name)
64: {
65: switch ($name) {
66: case 'linked':
67: return ($this instanceof IMP_Compose_Attachment_Linked);
68:
69: case 'link_url':
70: return $this->linked
71: ? Horde::url(
72: 'attachment.php',
73: true,
74: array('append_session' => -1)
75: )->add(array(
76: 'id' => $this->_id,
77: 'u' => $this->_user
78: ))
79: : null;
80: }
81: }
82:
83: /**
84: * Read attachment data from storage.
85: *
86: * @return Horde_Stream Stream object containing data.
87: * @throws IMP_Compose_Exception
88: */
89: public function read()
90: {
91: return (isset($this->_tmpfile) && is_readable($this->_tmpfile))
92: ? new Horde_Stream_Existing(array('stream' => fopen($this->_tmpfile, 'r')))
93: : $this->_read();
94: }
95:
96: /**
97: * @see read()
98: */
99: abstract protected function _read();
100:
101: /**
102: * Write attachment to storage.
103: *
104: * @param string $filename Filename containing attachment data.
105: * @param Horde_Mime_Part $part Mime part object containing attachment
106: * metadata.
107: *
108: * @throws IMP_Compose_Exception
109: */
110: public function write($filename, Horde_Mime_Part $part)
111: {
112: $this->_tmpfile = $filename;
113: $this->_write($filename, $part);
114: }
115:
116: /**
117: * @see write()
118: */
119: abstract protected function _write($filename, Horde_Mime_Part $part);
120:
121: /**
122: * Writes attachment data to a temporary file.
123: *
124: * @return string Temporary file path.
125: *
126: * @throws IMP_Compose_Exception
127: */
128: public function getTempFile()
129: {
130: if (isset($this->_tmpfile)) {
131: return $this->_tmpfile;
132: }
133:
134: $stream = $this->read();
135:
136: $tmp = Horde::getTempFile('impatt');
137: $fd = fopen($tmp, 'w+');
138:
139: while (!$stream->eof()) {
140: fwrite($fd, $stream->substring(0, 8192));
141: }
142: fclose($fd);
143: $stream->close();
144:
145: return $tmp;
146: }
147:
148: /**
149: * Delete data from storage.
150: */
151: abstract public function delete();
152:
153: /**
154: * Does the attachment exist in the storage backend?
155: *
156: * @return boolean True if the file exists.
157: */
158: abstract public function exists();
159:
160: /**
161: * Return metadata about attachment.
162: *
163: * @return IMP_Compose_Linked_Metadata Metadata object.
164: */
165: public function getMetadata()
166: {
167: return new IMP_Compose_Linked_Metadata();
168: }
169:
170: /**
171: * Save attachment metadata.
172: *
173: * @param IMP_Compose_Linked_Metadata $md Metadata object. Null will
174: * clear all metadata.
175: */
176: public function saveMetadata($md = null)
177: {
178: }
179:
180: /**
181: * Garbage collection.
182: */
183: public function gc()
184: {
185: }
186:
187: }
188: