]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - classes/Profile_tag.php
Removed plugin Google-Analytics as this is free/libre and decentralized
[quix0rs-gnu-social.git] / classes / Profile_tag.php
1 <?php
2 /**
3  * Table Definition for profile_tag
4  */
5
6 class Profile_tag extends Managed_DataObject
7 {
8     public $__table = 'profile_tag';                     // table name
9     public $tagger;                          // int(4)  primary_key not_null
10     public $tagged;                          // int(4)  primary_key not_null
11     public $tag;                             // varchar(64)  primary_key not_null
12     public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
13
14     public static function schemaDef()
15     {
16         return array(
17
18             'fields' => array(
19                 'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'),
20                 'tagged' => array('type' => 'int', 'not null' => true, 'description' => 'profile tagged'),
21                 'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'),
22                 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was added'),
23             ),
24             'primary key' => array('tagger', 'tagged', 'tag'),
25             'foreign keys' => array(
26                 'profile_tag_tagger_fkey' => array('profile', array('tagger' => 'id')),
27                 'profile_tag_tagged_fkey' => array('profile', array('tagged' => 'id')),
28                 'profile_tag_tag_fkey' => array('profile_list', array('tag' => 'tag')),
29             ),
30             'indexes' => array(
31                 'profile_tag_modified_idx' => array('modified'),
32                 'profile_tag_tagger_tag_idx' => array('tagger', 'tag'),
33                 'profile_tag_tagged_idx' => array('tagged'),
34             ),
35         );
36     }
37
38     function links()
39     {
40         return array('tagger,tag' => 'profile_list:tagger,tag');
41     }
42
43     function getMeta()
44     {
45         return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag));
46     }
47
48     static function getSelfTagsArray(Profile $target)
49     {
50         return self::getTagsArray($target->getID(), $target->getID(), $target);
51     }
52
53     static function setSelfTags(Profile $target, array $newtags, array $privacy=array())
54     {
55         return self::setTags($target->getID(), $target->getID(), $newtags, $privacy);
56     }
57
58     static function getTags($tagger, $tagged, $auth_user=null) {
59
60         $profile_list = new Profile_list();
61         $include_priv = 1;
62
63         if (!($auth_user instanceof User ||
64             $auth_user instanceof Profile) ||
65             ($auth_user->id !== $tagger)) {
66
67             $profile_list->private = false;
68             $include_priv = 0;
69         }
70
71         $key = sprintf('profile_tag:tagger_tagged_privacy:%d-%d-%d', $tagger, $tagged, $include_priv);
72         $tags = Profile_list::getCached($key);
73         if ($tags !== false) {
74             return $tags;
75         }
76
77         $qry = 'select profile_list.* from profile_list left join '.
78                'profile_tag on (profile_list.tag = profile_tag.tag and '.
79                'profile_list.tagger = profile_tag.tagger) where '.
80                'profile_tag.tagger = %d and profile_tag.tagged = %d ';
81         $qry = sprintf($qry, $tagger, $tagged);
82
83         if (!$include_priv) {
84             $qry .= ' and profile_list.private = 0';
85         }
86
87         $profile_list->query($qry);
88
89         Profile_list::setCache($key, $profile_list);
90
91         return $profile_list;
92     }
93
94     static function getTagsArray($tagger, $tagged, Profile $scoped=null)
95     {
96         $ptag = new Profile_tag();
97
98         $qry = sprintf('select profile_tag.tag '.
99                        'from profile_tag join profile_list '.
100                        ' on (profile_tag.tagger = profile_list.tagger ' .
101                        '     and profile_tag.tag = profile_list.tag) ' .
102                        'where profile_tag.tagger = %d ' .
103                        'and   profile_tag.tagged = %d ',
104                        $tagger, $tagged);
105
106         if (!$scoped instanceof Profile || $scoped->getID() !== $tagger) {
107             $qry .= 'and profile_list.private = 0';
108         }
109
110         $tags = array();
111
112         $ptag->query($qry);
113
114         while ($ptag->fetch()) {
115             $tags[] = $ptag->tag;
116         }
117
118         return $tags;
119     }
120
121     static function setTags($tagger, $tagged, array $newtags, array $privacy=array()) {
122
123         $newtags = array_unique($newtags);
124         $oldtags = self::getTagsArray($tagger, $tagged, Profile::getByID($tagger));
125
126         $ptag = new Profile_tag();
127
128         // Delete stuff that's in old and not in new
129
130         $to_delete = array_diff($oldtags, $newtags);
131
132         // Insert stuff that's in new and not in old
133
134         $to_insert = array_diff($newtags, $oldtags);
135
136         foreach ($to_delete as $deltag) {
137             self::unTag($tagger, $tagged, $deltag);
138         }
139
140         foreach ($to_insert as $instag) {
141             $private = isset($privacy[$instag]) ? $privacy[$instag] : false;
142             self::setTag($tagger, $tagged, $instag, null, $private);
143         }
144         return true;
145     }
146
147     # set a single tag
148     static function setTag($tagger, $tagged, $tag, $desc=null, $private=false) {
149
150         $ptag = Profile_tag::pkeyGet(array('tagger' => $tagger,
151                                            'tagged' => $tagged,
152                                            'tag' => $tag));
153
154         # if tag already exists, return it
155         if ($ptag instanceof Profile_tag) {
156             return $ptag;
157         }
158
159         $tagger_profile = Profile::getByID($tagger);
160         $tagged_profile = Profile::getByID($tagged);
161
162         if (Event::handle('StartTagProfile', array($tagger_profile, $tagged_profile, $tag))) {
163
164             if (!$tagger_profile->canTag($tagged_profile)) {
165                 // TRANS: Client exception thrown trying to set a tag for a user that cannot be tagged.
166                 throw new ClientException(_('You cannot tag this user.'));
167             }
168
169             $tags = new Profile_list();
170             $tags->tagger = $tagger;
171             $count = (int) $tags->count('distinct tag');
172
173             if ($count >= common_config('peopletag', 'maxtags')) {
174                 // TRANS: Client exception thrown trying to set more tags than allowed.
175                 throw new ClientException(sprintf(_('You already have created %d or more tags ' .
176                                                     'which is the maximum allowed number of tags. ' .
177                                                     'Try using or deleting some existing tags.'),
178                                                     common_config('peopletag', 'maxtags')));
179             }
180
181             $plist = new Profile_list();
182             $plist->query('BEGIN');
183
184             $profile_list = Profile_list::ensureTag($tagger, $tag, $desc, $private);
185
186             if ($profile_list->taggedCount() >= common_config('peopletag', 'maxpeople')) {
187                 // TRANS: Client exception thrown when trying to add more people than allowed to a list.
188                 throw new ClientException(sprintf(_('You already have %1$d or more people in list %2$s, ' .
189                                                     'which is the maximum allowed number. ' .
190                                                     'Try unlisting others first.'),
191                                                     common_config('peopletag', 'maxpeople'), $tag));
192             }
193
194             $newtag = new Profile_tag();
195
196             $newtag->tagger = $tagger;
197             $newtag->tagged = $tagged;
198             $newtag->tag = $tag;
199
200             $result = $newtag->insert();
201
202             if (!$result) {
203                 common_log_db_error($newtag, 'INSERT', __FILE__);
204                 $plist->query('ROLLBACK');
205                 return false;
206             }
207
208             try {
209                 $plist->query('COMMIT');
210                 Event::handle('EndTagProfile', array($newtag));
211             } catch (Exception $e) {
212                 $newtag->delete();
213                 $profile_list->delete();
214                 throw $e;
215             }
216
217             $profile_list->taggedCount(true);
218             self::blowCaches($tagger, $tagged);
219         }
220
221         return $newtag;
222     }
223
224     static function unTag($tagger, $tagged, $tag) {
225         $ptag = Profile_tag::pkeyGet(array('tagger' => $tagger,
226                                            'tagged' => $tagged,
227                                            'tag'    => $tag));
228         if (!$ptag) {
229             return true;
230         }
231
232         if (Event::handle('StartUntagProfile', array($ptag))) {
233             $orig = clone($ptag);
234             $result = $ptag->delete();
235             if ($result === false) {
236                 common_log_db_error($this, 'DELETE', __FILE__);
237                 return false;
238             }
239             Event::handle('EndUntagProfile', array($orig));
240             $profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger));
241             if (!empty($profile_list)) {
242                 $profile_list->taggedCount(true);
243             }
244             self::blowCaches($tagger, $tagged);
245             return true;
246         }
247     }
248
249     // @fixme: move this to Profile_list?
250     static function cleanup($profile_list) {
251         $ptag = new Profile_tag();
252         $ptag->tagger = $profile_list->tagger;
253         $ptag->tag = $profile_list->tag;
254         $ptag->find();
255
256         while($ptag->fetch()) {
257             if (Event::handle('StartUntagProfile', array($ptag))) {
258                 $orig = clone($ptag);
259                 $result = $ptag->delete();
260                 if (!$result) {
261                     common_log_db_error($this, 'DELETE', __FILE__);
262                 }
263                 Event::handle('EndUntagProfile', array($orig));
264             }
265         }
266     }
267
268     // move a tag!
269     static function moveTag($orig, $new) {
270         $tags = new Profile_tag();
271         $qry = 'UPDATE profile_tag SET ' .
272                'tag = "%s", tagger = "%s" ' .
273                'WHERE tag = "%s" ' .
274                'AND tagger = "%s"';
275         $result = $tags->query(sprintf($qry,
276                                        $tags->escape($new->tag),
277                                        $tags->escape($new->tagger),
278                                        $tags->escape($orig->tag),
279                                        $tags->escape($orig->tagger)));
280
281         if ($result === false) {
282             common_log_db_error($tags, 'UPDATE', __FILE__);
283             throw new Exception('Could not move Profile_tag, see db log for details.');
284         }
285         return $result;
286     }
287
288     static function blowCaches($tagger, $tagged) {
289         foreach (array(0, 1) as $perm) {
290             self::blow(sprintf('profile_tag:tagger_tagged_privacy:%d-%d-%d', $tagger, $tagged, $perm));
291         }
292         return true;
293     }
294
295     // Return profiles with a given tag
296     static function getTagged($tagger, $tag) {
297         $profile = new Profile();
298         $profile->query('SELECT profile.* ' .
299                         'FROM profile JOIN profile_tag ' .
300                         'ON profile.id = profile_tag.tagged ' .
301                         'WHERE profile_tag.tagger = ' . $profile->escape($tagger) . ' ' .
302                         'AND profile_tag.tag = "' . $profile->escape($tag) . '" ');
303         $tagged = array();
304         while ($profile->fetch()) {
305             $tagged[] = clone($profile);
306         }
307         return true;
308     }
309
310     function insert()
311     {
312         $result = parent::insert();
313         if ($result) {
314             self::blow('profile_list:tagged_count:%d:%s', 
315                        $this->tagger,
316                        $this->tag);
317         }
318         return $result;
319     }
320
321     function delete($useWhere=false)
322     {
323         $result = parent::delete($useWhere);
324         if ($result !== false) {
325             self::blow('profile_list:tagged_count:%d:%s', 
326                        $this->tagger,
327                        $this->tag);
328         }
329         return $result;
330     }
331 }