]> git.mxchange.org Git - friendica.git/blob - src/Model/FileTag.php
Update function calls
[friendica.git] / src / Model / FileTag.php
1 <?php
2 /**
3  * @file src/Model/FileTag.php
4  */
5
6 namespace Friendica\Model;
7
8 use Friendica\Core\L10n;
9 use Friendica\Core\PConfig;
10 use Friendica\Database\DBA;
11 use Friendica\Model\Item;
12
13 /**
14  * @brief This class handles FileTag related functions
15  */
16 class FileTag
17 {
18     // post categories and "save to file" use the same item.file table for storage.
19     // We will differentiate the different uses by wrapping categories in angle brackets
20     // and save to file categories in square brackets.
21     // To do this we need to escape these characters if they appear in our tag.
22
23     /**
24      * @brief URL encode &lt, &gt, left and right brackets
25      */
26     public static function encode($s)
27     {
28         return str_replace(['<', '>', '[', ']'], ['%3c', '%3e', '%5b', '%5d'], $s);
29     }
30
31     /**
32      * @brief URL decode &lt, &gt, left and right brackets
33      */
34     public static function decode($s)
35     {
36         return str_replace(['%3c', '%3e', '%5b', '%5d'], ['<', '>', '[', ']'], $s);
37     }
38
39     /**
40      * @brief Query files for tag
41      */
42     public static function fileQuery($table, $s, $type = 'file')
43     {
44         if ($type == 'file') {
45             $str = preg_quote('[' . str_replace('%', '%%', self::encode($s)) . ']');
46         } else {
47             $str = preg_quote('<' . str_replace('%', '%%', self::encode($s)) . '>');
48         }
49
50         return " AND " . (($table) ? DBA::escape($table) . '.' : '') . "file regexp '" . DBA::escape($str) . "' ";
51     }
52
53     /**
54      * @brief Get file tags from list
55      * 
56      * ex. given music,video return <music><video> or [music][video]
57      */
58     public static function listToFile($list, $type = 'file')
59     {
60         $tag_list = '';
61         if (strlen($list)) {
62             $list_array = explode(",", $list);
63             if ($type == 'file') {
64                 $lbracket = '[';
65                 $rbracket = ']';
66             } else {
67                 $lbracket = '<';
68                 $rbracket = '>';
69             }
70
71             foreach ($list_array as $item)
72             {
73                 if (strlen($item))
74                 {
75                     $tag_list .= $lbracket . self::encode(trim($item))  . $rbracket;
76                 }
77             }
78         }
79
80         return $tag_list;
81     }
82
83     /**
84      * @brief Get list from file tags
85      * 
86      * ex. given <music><video>[friends], return music,video or friends
87      */
88     public static function fileToList($file, $type = 'file')
89     {
90         $matches = false;
91         $list = '';
92         if ($type == 'file') {
93             $cnt = preg_match_all('/\[(.*?)\]/', $file, $matches, PREG_SET_ORDER);
94         } else {
95             $cnt = preg_match_all('/<(.*?)>/', $file, $matches, PREG_SET_ORDER);
96         }
97         if ($cnt) {
98             foreach ($matches as $mtch) {
99                 if (strlen($list)) {
100                     $list .= ',';
101                 }
102                 $list .= self::decode($mtch[1]);
103             }
104         }
105
106         return $list;
107     }
108
109     /**
110      * @brief Update file tags in PConfig
111      */
112     public static function updatePconfig($uid, $file_old, $file_new, $type = 'file')
113     {
114         // $file_old - categories previously associated with an item
115         // $file_new - new list of categories for an item
116
117         if (!intval($uid)) {
118             return false;
119         } elseif ($file_old == $file_new) {
120             return true;
121         }
122
123         $saved = PConfig::get($uid, 'system', 'filetags');
124
125         if (strlen($saved))
126         {
127             if ($type == 'file') {
128                 $lbracket = '[';
129                 $rbracket = ']';
130                 $termtype = TERM_FILE;
131             } else {
132                 $lbracket = '<';
133                 $rbracket = '>';
134                 $termtype = TERM_CATEGORY;
135             }
136
137             $filetags_updated = $saved;
138
139             // check for new tags to be added as filetags in pconfig
140             $new_tags = [];
141             $check_new_tags = explode(",", self::fileToList($file_new, $type));
142
143             foreach ($check_new_tags as $tag)
144             {
145                 if (!stristr($saved,$lbracket . self::encode($tag) . $rbracket)) {
146                     $new_tags[] = $tag;
147                 }
148             }
149
150             $filetags_updated .= self::listToFile(implode(",", $new_tags), $type);
151
152             // check for deleted tags to be removed from filetags in pconfig
153             $deleted_tags = [];
154             $check_deleted_tags = explode(",", self::fileToList($file_old, $type));
155
156             foreach ($check_deleted_tags as $tag)
157             {
158                 if (!stristr($file_new,$lbracket . self::encode($tag) . $rbracket)) {
159                     $deleted_tags[] = $tag;
160                 }
161             }
162
163             foreach ($deleted_tags as $key => $tag)
164             {
165                 $r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
166                     DBA::escape($tag),
167                     intval(TERM_OBJ_POST),
168                     intval($termtype),
169                     intval($uid));
170
171                 if (DBA::isResult($r)) {
172                     unset($deleted_tags[$key]);
173                 } else {
174                     $filetags_updated = str_replace($lbracket . self::encode($tag) . $rbracket, '', $filetags_updated);
175                 }
176             }
177
178             if ($saved != $filetags_updated)
179             {
180                 PConfig::set($uid, 'system', 'filetags', $filetags_updated);
181             }
182
183             return true;
184         } elseif (strlen($file_new)) {
185             PConfig::set($uid, 'system', 'filetags', $file_new);
186         }
187
188         return true;
189     }
190
191     /**
192      * @brief Add tag to file
193      */
194     public static function saveFile($uid, $item_id, $file)
195     {
196         if (!intval($uid))
197         {
198             return false;
199         }
200
201         $item = Item::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
202         if (DBA::isResult($item))
203         {
204             if (!stristr($item['file'], '[' . self::encode($file) . ']'))
205             {
206                 $fields = ['file' => $item['file'] . '[' . self::encode($file) . ']'];
207                 Item::update($fields, ['id' => $item_id]);
208             }
209
210             $saved = PConfig::get($uid, 'system', 'filetags');
211
212             if (!strlen($saved) || !stristr($saved, '[' . self::encode($file) . ']'))
213             {
214                 PConfig::set($uid, 'system', 'filetags', $saved . '[' . self::encode($file) . ']');
215             }
216
217             info(L10n::t('Item filed'));
218         }
219
220         return true;
221     }
222
223     /**
224      * @brief Remove tag from file
225      */
226     public static function unsaveFile($uid, $item_id, $file, $cat = false)
227     {
228         if (!intval($uid))
229         {
230             return false;
231         }
232
233         if ($cat == true) {
234             $pattern = '<' . self::encode($file) . '>' ;
235             $termtype = TERM_CATEGORY;
236         } else {
237             $pattern = '[' . self::encode($file) . ']' ;
238             $termtype = TERM_FILE;
239         }
240
241         $item = Item::selectFirst(['file'], ['id' => $item_id, 'uid' => $uid]);
242
243         if (!DBA::isResult($item))
244         {
245             return false;
246         }
247
248         $fields = ['file' => str_replace($pattern, '', $item['file'])];
249         Item::update($fields, ['id' => $item_id]);
250
251         $r = q("SELECT `oid` FROM `term` WHERE `term` = '%s' AND `otype` = %d AND `type` = %d AND `uid` = %d",
252             DBA::escape($file),
253             intval(TERM_OBJ_POST),
254             intval($termtype),
255             intval($uid)
256         );
257
258         if (!DBA::isResult($r))
259         {
260             $saved = PConfig::get($uid, 'system', 'filetags');
261             PConfig::set($uid, 'system', 'filetags', str_replace($pattern, '', $saved));
262         }
263
264         return true;
265     }
266 }