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