]> git.mxchange.org Git - friendica.git/blob - src/Model/Attach.php
102e7b1a1d2f708575fc95af981b49c72c1848cd
[friendica.git] / src / Model / Attach.php
1 <?php
2
3 /**
4  * @file src/Model/Attach.php
5  * @brief This file contains the Attach class for database interface
6  */
7 namespace Friendica\Model;
8
9 use Friendica\Core\StorageManager;
10 use Friendica\Core\System;
11 use Friendica\Database\DBA;
12 use Friendica\Database\DBStructure;
13 use Friendica\DI;
14 use Friendica\Model\Storage\IStorage;
15 use Friendica\Object\Image;
16 use Friendica\Util\DateTimeFormat;
17 use Friendica\Util\Mimetype;
18 use Friendica\Util\Security;
19
20 /**
21  * Class to handle attach dabatase table
22  */
23 class Attach
24 {
25
26         /**
27          * @brief Return a list of fields that are associated with the attach table
28          *
29          * @return array field list
30          * @throws \Exception
31          */
32         private static function getFields()
33         {
34                 $allfields = DBStructure::definition(DI::app()->getBasePath(), false);
35                 $fields = array_keys($allfields['attach']['fields']);
36                 array_splice($fields, array_search('data', $fields), 1);
37                 return $fields;
38         }
39
40         /**
41          * @brief Select rows from the attach table and return them as array
42          *
43          * @param array $fields     Array of selected fields, empty for all
44          * @param array $conditions Array of fields for conditions
45          * @param array $params     Array of several parameters
46          *
47          * @return array
48          *
49          * @throws \Exception
50          * @see   \Friendica\Database\DBA::selectToArray
51          */
52         public static function selectToArray(array $fields = [], array $conditions = [], array $params = [])
53         {
54                 if (empty($fields)) {
55                         $fields = self::getFields();
56                 }
57
58                 return DBA::selectToArray('attach', $fields, $conditions, $params);
59         }
60
61         /**
62          * @brief Retrieve a single record from the attach table
63          *
64          * @param array $fields     Array of selected fields, empty for all
65          * @param array $conditions Array of fields for conditions
66          * @param array $params     Array of several parameters
67          *
68          * @return bool|array
69          *
70          * @throws \Exception
71          * @see   \Friendica\Database\DBA::select
72          */
73         public static function selectFirst(array $fields = [], array $conditions = [], array $params = [])
74         {
75                 if (empty($fields)) {
76                         $fields = self::getFields();
77                 }
78
79                 return DBA::selectFirst('attach', $fields, $conditions, $params);
80         }
81
82         /**
83          * @brief Check if attachment with given conditions exists
84          *
85          * @param array $conditions Array of extra conditions
86          *
87          * @return boolean
88          * @throws \Exception
89          */
90         public static function exists(array $conditions)
91         {
92                 return DBA::exists('attach', $conditions);
93         }
94
95         /**
96          * @brief Retrive a single record given the ID
97          *
98          * @param int $id Row id of the record
99          *
100          * @return bool|array
101          *
102          * @throws \Exception
103          * @see   \Friendica\Database\DBA::select
104          */
105         public static function getById($id)
106         {
107                 return self::selectFirst([], ['id' => $id]);
108         }
109
110         /**
111          * @brief Retrive a single record given the ID
112          *
113          * @param int $id Row id of the record
114          *
115          * @return bool|array
116          *
117          * @throws \Exception
118          * @see   \Friendica\Database\DBA::select
119          */
120         public static function getByIdWithPermission($id)
121         {
122                 $r = self::selectFirst(['uid'], ['id' => $id]);
123                 if ($r === false) {
124                         return false;
125                 }
126
127                 $sql_acl = Security::getPermissionsSQLByUserId($r['uid']);
128
129                 $conditions = [
130                         '`id` = ?' . $sql_acl,
131                         $id
132                 ];
133
134                 $item = self::selectFirst([], $conditions);
135
136                 return $item;
137         }
138
139         /**
140          * @brief Get file data for given row id. null if row id does not exist
141          *
142          * @param array $item Attachment data. Needs at least 'id', 'backend-class', 'backend-ref'
143          *
144          * @return string  file data
145          * @throws \Exception
146          */
147         public static function getData($item)
148         {
149                 if ($item['backend-class'] == '') {
150                         // legacy data storage in 'data' column
151                         $i = self::selectFirst(['data'], ['id' => $item['id']]);
152                         if ($i === false) {
153                                 return null;
154                         }
155                         return $i['data'];
156                 } else {
157                         $backendClass = $item['backend-class'];
158                         $backendRef = $item['backend-ref'];
159                         return $backendClass::get($backendRef);
160                 }
161         }
162
163         /**
164          * @brief Store new file metadata in db and binary in default backend
165          *
166          * @param string  $data      Binary data
167          * @param integer $uid       User ID
168          * @param string  $filename  Filename
169          * @param string  $filetype  Mimetype. optional, default = ''
170          * @param integer $filesize  File size in bytes. optional, default = null
171          * @param string  $allow_cid Permissions, allowed contacts. optional, default = ''
172          * @param string  $allow_gid Permissions, allowed groups. optional, default = ''
173          * @param string  $deny_cid  Permissions, denied contacts.optional, default = ''
174          * @param string  $deny_gid  Permissions, denied greoup.optional, default = ''
175          *
176          * @return boolean/integer Row id on success, False on errors
177          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
178          */
179         public static function store($data, $uid, $filename, $filetype = '' , $filesize = null, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '')
180         {
181                 if ($filetype === '') {
182                         $filetype = Mimetype::getContentType($filename);
183                 }
184
185                 if (is_null($filesize)) {
186                         $filesize = strlen($data);
187                 }
188
189                 $backend_ref = DI::storage()->put($data);
190                 $data = '';
191
192                 $hash = System::createGUID(64);
193                 $created = DateTimeFormat::utcNow();
194
195                 $fields = [
196                         'uid' => $uid,
197                         'hash' => $hash,
198                         'filename' => $filename,
199                         'filetype' => $filetype,
200                         'filesize' => $filesize,
201                         'data' => $data,
202                         'created' => $created,
203                         'edited' => $created,
204                         'allow_cid' => $allow_cid,
205                         'allow_gid' => $allow_gid,
206                         'deny_cid' => $deny_cid,
207                         'deny_gid' => $deny_gid,
208                         'backend-class' => (string)DI::storage(),
209                         'backend-ref' => $backend_ref
210                 ];
211
212                 $r = DBA::insert('attach', $fields);
213                 if ($r === true) {
214                         return DBA::lastInsertId();
215                 }
216                 return $r;
217         }
218
219         /**
220          * @brief Store new file metadata in db and binary in default backend from existing file
221          *
222          * @param        $src
223          * @param        $uid
224          * @param string $filename
225          * @param string $allow_cid
226          * @param string $allow_gid
227          * @param string $deny_cid
228          * @param string $deny_gid
229          * @return boolean True on success
230          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
231          */
232         public static function storeFile($src, $uid, $filename = '', $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '')
233         {
234                 if ($filename === '') {
235                         $filename = basename($src);
236                 }
237
238                 $data = @file_get_contents($src);
239
240                 return self::store($data, $uid, $filename, '', null, $allow_cid, $allow_gid,  $deny_cid, $deny_gid);
241         }
242
243
244         /**
245          * @brief Update an attached file
246          *
247          * @param array         $fields     Contains the fields that are updated
248          * @param array         $conditions Condition array with the key values
249          * @param Image         $img        Image data to update. Optional, default null.
250          * @param array|boolean $old_fields Array with the old field values that are about to be replaced (true = update on duplicate)
251          *
252          * @return boolean  Was the update successful?
253          *
254          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
255          * @see   \Friendica\Database\DBA::update
256          */
257         public static function update($fields, $conditions, Image $img = null, array $old_fields = [])
258         {
259                 if (!is_null($img)) {
260                         // get items to update
261                         $items = self::selectToArray(['backend-class','backend-ref'], $conditions);
262
263                         foreach($items as $item) {
264                                 /** @var IStorage $backend_class */
265                                 $backend_class = (string)$item['backend-class'];
266                                 if ($backend_class !== '') {
267                                         $fields['backend-ref'] = $backend_class::put($img->asString(), $item['backend-ref']);
268                                 } else {
269                                         $fields['data'] = $img->asString();
270                                 }
271                         }
272                 }
273
274                 $fields['edited'] = DateTimeFormat::utcNow();
275
276                 return DBA::update('attach', $fields, $conditions, $old_fields);
277         }
278
279
280         /**
281          * @brief Delete info from table and data from storage
282          *
283          * @param array $conditions Field condition(s)
284          * @param array $options    Options array, Optional
285          *
286          * @return boolean
287          *
288          * @throws \Exception
289          * @see   \Friendica\Database\DBA::delete
290          */
291         public static function delete(array $conditions, array $options = [])
292         {
293                 // get items to delete data info
294                 $items = self::selectToArray(['backend-class','backend-ref'], $conditions);
295
296                 foreach($items as $item) {
297                         /** @var IStorage $backend_class */
298                         $backend_class = (string)$item['backend-class'];
299                         if ($backend_class !== '') {
300                                 $backend_class::delete($item['backend-ref']);
301                         }
302                 }
303
304                 return DBA::delete('attach', $conditions, $options);
305         }
306 }