Completed
Push — development ( 43bb99...2fa2b9 )
by Thomas
03:02 queued 02:41
created

htdocs/lib2/logic/cachelist.class.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/***************************************************************************
3
 * for license information see LICENSE.md
4
 *
5
 *
6
 *   get/set has to be committed with save
7
 *   add/remove etc. is executed instantly
8
 ***************************************************************************/
9
10
require_once __DIR__ . '/../translate.class.php';
11
12
define('ERROR_BAD_LISTNAME', 1);
13
define('ERROR_DUPLICATE_LISTNAME', 2);
14
15
16
class cachelist
17
{
18
    public $nCachelistId = 0;
19
    public $reCachelist;
20
21
    public function __construct($nNewCacheListId = ID_NEW, $nUserId = 0)
22
    {
23
        $this->reCachelist = new rowEditor('cache_lists');
24
        $this->reCachelist->addPKInt('id', null, false, RE_INSERT_AUTOINCREMENT);
25
        $this->reCachelist->addString('uuid', '', false, RE_INSERT_AUTOUUID);
26
        $this->reCachelist->addInt('node', 0, false);
27
        $this->reCachelist->addInt('user_id', $nUserId, false);
28
        $this->reCachelist->addDate('date_created', time(), true, RE_INSERT_IGNORE);
29
        $this->reCachelist->addDate('last_modified', time(), true, RE_INSERT_IGNORE);
30
        $this->reCachelist->addDate('last_added', null, true);
31
        $this->reCachelist->addString('name', '', false);
32
        $this->reCachelist->addInt('is_public', 0, false);
33
        $this->reCachelist->addString('description', '', false);
34
        $this->reCachelist->addInt('desc_htmledit', 1, false);
35
        $this->reCachelist->addString('password', '', false);
36
37
        $this->nCachelistId = $nNewCacheListId + 0;
38
39
        if ($nNewCacheListId == ID_NEW) {
40
            $this->reCachelist->addNew(null);
41
        } else {
42
            $this->reCachelist->load($this->nCachelistId);
43
        }
44
    }
45
46
    public function exist()
47
    {
48
        return $this->reCachelist->exist();
49
    }
50
51
    public function getId()
52
    {
53
        return $this->nCachelistId;
54
    }
55
56
    public function getUUID()
57
    {
58
        return $this->reCachelist->getValue('uuid');
59
    }
60
61
    public function setNode($value)
62
    {
63
        return $this->reCachelist->setValue('node', $value);
64
    }
65
66
    public function getNode()
67
    {
68
        return $this->reCachelist->getValue('node');
69
    }
70
71
    public function getUserId()
72
    {
73
        return $this->reCachelist->getValue('user_id');
74
    }
75
76
    public function isMyList()
77
    {
78
        global $login;
79
80
        return $this->getUserId() == $login->userid;
81
    }
82
83
    public function getName()
84
    {
85
        return $this->reCachelist->getValue('name');
86
    }
87
88
    // 0 = private, 1 = private & friends (not impl.), 2 = public, 3 = public + listing display
89
    public function getVisibility()
90
    {
91
        return $this->reCachelist->getValue('is_public');
92
    }
93
94
    // !! This method returns an error state instead of a success flag; false means "no error".
95
    public function setNameAndVisibility($name, $visibility)
96
    {
97
        $name = trim($name);
98
        if ($name == '') {
99
            return ERROR_BAD_LISTNAME;
100
        } else {
101
            if (sql_value(
0 ignored issues
show
Deprecated Code introduced by
The function sql_value() has been deprecated with message: use DBAL Conenction instead. See adminreports.php for an example implementation

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
102
                "SELECT `id`
103
                 FROM `cache_lists`
104
                 WHERE `user_id`='&1' AND `id`<>'&2' AND `name`='&3'",
105
                false,
106
                $this->getUserId(),
107
                $this->getId(),
108
                $name
109
            )) {
110
                // $this->getId() is 0 when creating a new list -> condition has no effect
111
                return ERROR_DUPLICATE_LISTNAME;
112
            } elseif ($visibility >= 2 && strlen($name) < 10) {
113
                return ERROR_BAD_LISTNAME;
114
            }
115
        }
116
117
        $error = !$this->reCachelist->setValue('name', trim($name));
118
        if ($visibility == 0 || $visibility == 2 || $visibility == 3) {
119
            $error |= !$this->reCachelist->setValue('is_public', $visibility);
120
        }
121
122
        return $error;
123
    }
124
125
    // return description in HTML format
126
    public function getDescription()
127
    {
128
        return $this->reCachelist->getValue('description');
129
    }
130
131
    public function getDescriptionForDisplay()
132
    {
133
        return use_current_protocol_in_html(getDescription());
134
    }
135
136
    public function getDescHtmledit()
137
    {
138
        return $this->reCachelist->getValue('desc_htmledit');
139
    }
140
141
    // set description in HTML format, must be purified!
142
    public function setDescription($desc, $htmledit)
143
    {
144
        $this->reCachelist->setValue('desc_htmledit', $htmledit ? 1 : 0);
145
146
        return $this->reCachelist->setValue('description', $desc);
147
    }
148
149
    public function setPassword($pw)
150
    {
151
        $this->reCachelist->setValue('password', $pw);
152
    }
153
154
    public function getPassword()
155
    {
156
        return $this->reCachelist->getValue('password');
157
    }
158
159
    public function getCachesCount()
160
    {
161
        return sql_value(
162
            "
163
            SELECT `entries` FROM `stat_cache_lists`
164
            WHERE `stat_cache_lists`.`cache_list_id`='" . sql_escape($this->getId()) . "'",
165
            0
166
        );
167
    }
168
169
    public function getWatchersCount()
170
    {
171
        return sql_value(
172
            "
173
            SELECT `watchers` FROM `stat_cache_lists`
174
            WHERE `stat_cache_lists`.`cache_list_id`='" . sql_escape($this->getId()) . "'",
175
            0
176
        );
177
    }
178
179
    public function save()
180
    {
181
        if ($this->getVisibility() > 0) {
182
            $this->setPassword('');
183
        }
184
        sql_slave_exclude();
185
        if ($this->reCachelist->save()) {
186
            if ($this->getId() == ID_NEW) {
187
                $this->nCachelistId = $this->reCachelist->getValue('id');
188
            }
189
190
            return true;
191
        }
192
193
        return false;
194
    }
195
196
    // get and set list contents
197
198
    // locked/hidden caches may be added to a list by the owner or an administrator,
199
    // but getCaches() will return visible==0 if the list is queried by someone else.
200
    // The 'visible' flag MUST be evaluated and the cache name must not be shown
201
    // if it is 0. This also ensures that cache names are hidden if a cache is locked/hidden
202
    // after being added to a list.
203
204
    public function getCaches()
205
    {
206
        global $login;
207
        $login->verify();
208
209
        $rs = sql(
210
            "
211
            SELECT `cache_list_items`.`cache_id`, `caches`.`wp_oc`, `caches`.`name`,
212
                   `caches`.`type`, `caches`.`status`,
213
                   (`cache_status`.`allow_user_view` OR `caches`.`user_id`='&2' OR '&3') AS `visible`,
214
                   `ca`.`attrib_id` IS NOT NULL AS `oconly`
215
            FROM `cache_list_items`
216
            LEFT JOIN `caches` ON `caches`.`cache_id`=`cache_list_items`.`cache_id`
217
            LEFT JOIN `cache_status` ON `cache_status`.`id`=`caches`.`status`
218
            LEFT JOIN `caches_attributes` `ca` ON `ca`.`cache_id`=`caches`.`cache_id` AND `ca`.`attrib_id`=6
219
            WHERE `cache_list_items`.`cache_list_id` = '&1'
220
            ORDER BY `caches`.`name`",
221
            $this->nCachelistId,
222
            $login->userid,
223
            ($login->admin & ADMIN_USER) ? 1 : 0
224
        );
225
226
        return sql_fetch_assoc_table($rs);
227
    }
228
229
    public function addCacheByWP($wp)
230
    {
231
        $cache = cache::fromWP($wp);
232
        if (!is_object($cache)) {
233
            return false;
234
        }
235
236
        return $this->addCache($cache);
237
    }
238
239
    // returns true if all wayPoints were valid, or an array of invalid wayPoints
240
    public function addCachesByWPs($wps)
241
    {
242
        $wpa = explode(' ', trim($wps));
243
        $non_added_wps = [];
244
        foreach ($wpa as $wp) {
245
            $wp = trim($wp);
246
            if ($wp) {
247
                $result = $this->addCacheByWP($wp);
248
                if ($result !== true) {
249
                    $non_added_wps[] = $wp;
250
                }
251
            }
252
        }
253
        if (count($non_added_wps)) {
254
            return $non_added_wps;
255
        }
256
257
        return true;
258
    }
259
260
    public function addCacheByID($cache_id)
261
    {
262
        return $this->addCache(new cache($cache_id));
263
    }
264
265
    public function addCache($cache)
266
    {
267
        if (!$cache->exist() || !$cache->allowView()) {
268
            return false;
269
        }
270
        sql(
271
            "
272
            INSERT IGNORE INTO `cache_list_items` (`cache_list_id`, `cache_id`)
273
            VALUES ('&1', '&2')",
274
            $this->nCachelistId,
275
            $cache->getCacheId()
276
        );
277
278
        return true;
279
    }
280
281
    public function removeCacheById($cache_id)
282
    {
283
        sql(
284
            "DELETE FROM `cache_list_items` WHERE `cache_list_id`='&1' AND `cache_id`='&2'",
285
            $this->nCachelistId,
286
            $cache_id
287
        );
288
    }
289
290
    // watching, bookmarking and access tests
291
    public function watch($watch)
292
    {
293
        global $login;
294
        $login->verify();
295
296
        if ($login->userid != 0) {
297
            if ($watch) {
298
                if ($this->allowView()) {
299
                    sql(
300
                        "
301
                        INSERT IGNORE INTO `cache_list_watches` (`cache_list_id`, `user_id`)
302
                        VALUES ('&1','&2')",
303
                        $this->getId(),
304
                        $login->userid
305
                    );
306
                }
307
            } else {
308
                sql(
309
                    "
310
                    DELETE FROM `cache_list_watches`
311
                    WHERE `cache_list_id`='&1' AND `user_id`='&2'",
312
                    $this->getId(),
313
                    $login->userid
314
                );
315
            }
316
        }
317
    }
318
319
    public function isWatchedByMe()
320
    {
321
        global $login;
322
323
        return sql_value(
324
            "SELECT 1 FROM `cache_list_watches`
325
             WHERE `cache_list_id`='&1' AND `user_id`='&2'",
326
            0,
327
            $this->getId(),
328
            $login->userid
329
        ) != 0;
330
    }
331
332
    public function bookmark($pw)
333
    {
334
        global $login;
335
336
        if ($login->userid != 0 &&
337
            !$this->isMyList() &&
338
            ($this->getVisibility() >= 2 || ($this->getPassword() != "" && $pw == $this->getPassword()))
339
        ) {
340
            sql(
341
                "INSERT IGNORE INTO `cache_list_bookmarks` (`cache_list_id`, `user_id`, `password`)
342
                 VALUES('&1','&2','&3')
343
                 ON DUPLICATE KEY UPDATE `password`='&3'",
344
                $this->getId(),
345
                $login->userid,
346
                $pw
347
            );
348
        }
349
    }
350
351
    public function unbookmark()
352
    {
353
        global $login;
354
355
        sql(
356
            "DELETE FROM `cache_list_bookmarks`
357
             WHERE `cache_list_id`='&1' AND `user_id`='&2'",
358
            $this->getId(),
359
            $login->userid
360
        );
361
    }
362
363
    public function allowView($pw = '')
364
    {
365
        global $login;
366
367
        if (!$this->exist()) {
368
            return false;
369
        }
370
371
        return $this->isMyList() ||
372
        $this->getVisibility() >= 2 ||
373
        ($this->getPassword() != '' && $pw == $this->getPassword()) ||
374
        sql_value(
375
            "
376
                         SELECT COUNT(*)
377
                         FROM `cache_lists` `cl`
378
                         LEFT JOIN `cache_list_bookmarks` `clb` ON `clb`.`cache_list_id`=`cl`.`id`
379
                         WHERE `cl`.`id`='&1' AND `cl`.`password`<>''
380
                           AND `clb`.`user_id`='&2' AND `clb`.`password`=`cl`.`password`",
381
            0,
382
            $this->getId(),
383
            $login->userid
384
        );
385
    }
386
387
    // get list of lists -- public static functions
388
    public static function getMyLists()
389
    {
390
        global $login;
391
392
        return cachelist::getLists("`cache_lists`.`user_id`='" . sql_escape($login->userid) . "'");
393
    }
394
395
    public static function getListsWatchedByMe()
396
    {
397
        global $login;
398
399
        return cachelist::getLists(
400
            "`id` IN (SELECT `cache_list_id` FROM `cache_list_watches` WHERE `user_id`='" . sql_escape(
401
                $login->userid
402
            ) . "')"
403
        );
404
    }
405
406
    public static function getBookmarkedLists()
407
    {
408
        global $login;
409
410
        return cachelist::getLists(
411
            "`id` IN (SELECT `cache_list_id` FROM `cache_list_bookmarks` WHERE `user_id`='" . sql_escape(
412
                $login->userid
413
            ) . "')"
414
        );
415
    }
416
417
    public static function getPublicListCount($namelike = '', $userlike = '')
418
    {
419
        return sql_value(
420
            '
421
            SELECT COUNT(*)
422
            FROM `cache_lists`
423
            LEFT JOIN `stat_cache_lists` ON  `stat_cache_lists`.`cache_list_id`=`cache_lists`.`id`
424
            LEFT JOIN `user` ON `user`.`user_id`=`cache_lists`.`user_id`
425
            WHERE `is_public`>=2 AND `entries`>0'
426
            . ($namelike ? " AND `name` LIKE '%" . sql_escape($namelike) . "%'" : '')
427
            . ($userlike ? " AND `username` LIKE '%" . sql_escape($userlike) . "%'" : ''),
428
            0
429
        );
430
    }
431
432
    public static function getPublicLists($startat = 0, $maxitems = PHP_INT_MAX, $namelike = '', $userlike = '')
433
    {
434
        return cachelist::getLists(
435
            '`is_public`>=2 AND `entries`>0'
436
            . ($namelike ? " AND `name` LIKE '%" . sql_escape($namelike) . "%'" : '')
437
            . ($userlike ? " AND `username` LIKE '%" . sql_escape($userlike) . "%'" : ''),
438
            0,
439
            $startat,
440
            $maxitems,
441
            true
442
        );
443
    }
444
445
    public static function getPublicListsOf($userid)
446
    {
447
        return cachelist::getLists(
448
            "`is_public`>=2 AND `entries`>0 AND `cache_lists`.`user_id`='" . sql_escape($userid) . "'"
449
        );
450
    }
451
452
    // If $all is false, only own lists and public lists of the cache owner will be returned.
453
    public static function getListsByCacheId($cacheid, $all)
454
    {
455
        global $login;
456
457
        $cache_owner_id = sql_value(
458
            "
459
            SELECT `user_id`
460
            FROM `caches`
461
            WHERE `cache_id`='" . sql_escape($cacheid) . "'",
462
            0
463
        );
464
        $my_watches = sql_fetch_column(
465
            sql("SELECT `cache_list_id` FROM `cache_list_watches` WHERE `user_id`='&1'", $login->userid)
466
        );
467
468
        return cachelist::getLists(
469
            "
470
            `id` IN
471
                (SELECT `cache_list_id`
472
                 FROM `cache_list_items`
473
                 WHERE `cache_id`='" . sql_escape($cacheid) . "')
474
            AND
475
            (
476
                `cache_lists`.`user_id`='" . sql_escape($login->userid) . "' " .
477
            ($all ? "OR `is_public`= 3 " : "") .
478
            "OR (`is_public`> 0 AND
479
                   `cache_lists`.`id` IN ('" . implode("','", array_map('sql_escape', $my_watches)) . "'))
480
            )",
481
            "`cache_lists`.`user_id`<>'" . sql_escape($cache_owner_id) . "'",
482
            0,
483
            20,
484
            true
485
        );
486
    }
487
488
    public static function getListById($listid)
489
    {
490
        $lists = cachelist::getLists("`id`='" . sql_escape($listid) . "'");
491
        if (count($lists)) {
492
            $lists[0]['description_for_display'] = use_current_protocol_in_html($lists[0]['description']);
493
494
            return $lists[0];
495
        }
496
497
        return false;
498
    }
499
500
    private static function getLists(
501
        $condition,
502
        $prio = 0,
503
        $startat = 0,
504
        $maxitems = PHP_INT_MAX,
505
        $strip_nagchars = false
506
    ) {
507
        global $login;
508
        $login->verify();
509
510
        $nameField = ($strip_nagchars ? 'STRIP_LEADING_NONALNUM(`cache_lists`.`name`)' : '`cache_lists`.`name`');
511
        $rs = sql(
512
            "SELECT `cache_lists`.`id`, `cache_lists`.`user_id`, `user`.`username`,
513
                    $nameField `name`,
514
                    `cache_lists`.`is_public` `visibility`, `cache_lists`.`password`,
515
                    `cache_lists`.`description`, `cache_lists`.`desc_htmledit`,
516
                    `cache_lists`.`user_id`='&1' `own_list`,
517
                    `stat_cache_lists`.`entries`, `stat_cache_lists`.`watchers`,
518
                    `w`.`user_id` IS NOT NULL `watched_by_me`,
519
                    `b`.`user_id` IS NOT NULL `bookmarked`,
520
                    $prio `prio`
521
             FROM `cache_lists`
522
             LEFT JOIN `stat_cache_lists` ON `stat_cache_lists`.`cache_list_id`=`cache_lists`.`id`
523
             LEFT JOIN `user` ON `user`.`user_id`=`cache_lists`.`user_id`
524
             LEFT JOIN `cache_list_watches` `w` ON `w`.`cache_list_id`=`cache_lists`.`id` AND `w`.`user_id`='&1'
525
             LEFT JOIN `cache_list_bookmarks` `b` ON `b`.`cache_list_id`=`cache_lists`.`id` AND `b`.`user_id`='&1'
526
             WHERE $condition
527
             ORDER BY `prio`, $nameField
528
             LIMIT &2,&3",
529
            $login->userid,
530
            $startat,
531
            $maxitems
532
        );
533
534
        $lists = sql_fetch_assoc_table($rs);
535
        foreach ($lists as &$list) {
536
            $list['description_for_display'] = use_current_protocol_in_html($list['description']);
537
        }
538
539
        return $lists;
540
    }
541
542
    // other
543
    public static function getMyLastAddedToListId()
544
    {
545
        global $login;
546
        $login->verify();
547
548
        $maxDate = sql_value("SELECT MAX(`last_added`) FROM `cache_lists` WHERE `user_id`='&1'", null, $login->userid);
549
        if (!$maxDate) {
550
            return 0;
551
        }
552
553
        return sql_value(
554
            "SELECT `id` FROM `cache_lists`
555
             WHERE `user_id`='&1' AND `last_added`='&2'
556
             LIMIT 1",
557
            0,
558
            $login->userid,
559
            $maxDate
560
        );
561
    }
562
563
    public static function watchingCacheByListsCount($userId, $cacheId)
564
    {
565
        if (!$userId) {
566
            return 0;
567
        }
568
569
        return sql_value(
570
            "SELECT COUNT(*)
571
             FROM `cache_list_watches` `clw`, `cache_list_items` `cli`
572
             WHERE `clw`.`user_id`='&1' AND `cli`.`cache_id`='&2' AND `clw`.`cache_list_id`=`cli`.`cache_list_id`",
573
            0,
574
            $userId,
575
            $cacheId
576
        );
577
    }
578
}
579