Passed
Push — development ( 2c0f7a...866d79 )
by Thomas
01:59
created

AutoArchive::archiveCache()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 19
nc 4
nop 3
dl 0
loc 31
rs 8.439
c 0
b 0
f 0
1
<?php
2
/***************************************************************************
3
 *  For license information see doc/license.txt
4
 *
5
 *
6
 *  Automatic archiving of disabled caches
7
 ***************************************************************************/
8
9
checkJob(new AutoArchive());
10
11
class AutoArchive
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
12
{
13
    public $name = 'autoarchive';
14
    public $interval = 43200; // twice per day
15
16
17
    public function run()
18
    {
19
        global $opt, $login;
20
21
        if ($opt['cron']['autoarchive']['run']) {
22
            if (!$login->logged_in()) {
23
                echo $this->name . ": not logged in / no system user configured\n";
24
            } elseif ($login->hasAdminPriv(ADMIN_USER)) {
25
                $this->archiveDisabledCaches();
26
                $this->archiveEvents();
27
            } else {
28
                echo $this->name . ": user '" . $opt['logic']['systemuser']['user'] . "' cannot maintain caches\n";
29
            }
30
        }
31
    }
32
33
    public function archiveDisabledCaches()
34
    {
35
        // Logging of status changes in cache_status_modified has started on June 1, 2013.
36
        // For archiving caches that were disabled earlier, we also check the listing
37
        // modification date.
38
39
        // This statement may be optimized. It typically runs for ~15 seconds at OC.de.
40
        $rs = sql(
41
            '
42
            SELECT `caches`.`cache_id`,
43
                   `caches`.`user_id`,
44
                   DATEDIFF(NOW(), `listing_last_modified`) AS `listing_age`,
45
                   (SELECT `date_modified` FROM `cache_status_modified` `csm`
46
                    WHERE `csm`.`cache_id`=`caches`.`cache_id` AND `csm`.`new_state`=2
47
                    ORDER BY `date_modified` DESC
48
                    LIMIT 1) `disable_date`,
49
                   (SELECT `user_id` FROM `cache_status_modified` `csm`
50
                    WHERE `csm`.`cache_id`=`caches`.`cache_id` AND `csm`.`new_state`=2
51
                    ORDER BY `date_modified` DESC
52
                    LIMIT 1) `disabled_by`,
53
                   IFNULL(DATEDIFF(NOW(), `user`.`last_login`), 150) `login_lag`,
54
                   `ca`.`attrib_id` IS NOT NULL `seasonal_cache`
55
            FROM `caches`
56
            LEFT JOIN `user` ON `user`.`user_id`=`caches`.`user_id`
57
            LEFT JOIN `caches_attributes` `ca` ON `ca`.`cache_id`=`caches`.`cache_id` AND `ca`.`attrib_id`=60
58
            WHERE `status`=2 AND DATEDIFF(NOW(), `listing_last_modified`) > 184
59
            ORDER BY `listing_last_modified`'
60
        );
61
62
        $archived = 0;
63
        while ($rCache = sql_fetch_assoc($rs)) {
64
            if ($rCache['listing_age'] > 366 ||
65
                ($rCache['listing_age'] > 184 &&
66
                    (sql_value("SELECT DATEDIFF(NOW(),'&1')", 0, $rCache['disable_date']) > 366 ||
67
                        (!$rCache['seasonal_cache'] &&
68
                            (($rCache['disabled_by'] != 0 && $rCache['disabled_by'] != $rCache['user_id'] && $rCache['login_lag'] > 45)
69
                                ||
70
                                ($rCache['disabled_by'] == $rCache['user_id'] && $rCache['login_lag'] >= $rCache['listing_age']))
71
                            &&
72
                            sql_value(
73
                                "SELECT MAX(`date`) FROM `cache_logs`
74
                                 WHERE `cache_logs`.`cache_id`='&1'",
75
                                '',
76
                                $rCache['cache_id']
77
                            ) <= $rCache['disable_date']
78
                            && sql_value(
79
                                "SELECT `type` FROM `cache_logs`
80
                                 WHERE `cache_id`='&1'
81
                                 ORDER BY `order_date` DESC, `date_created` DESC, `id` DESC
82
                                 LIMIT 1",
83
                                '',
84
                                $rCache['cache_id']
85
                            ) == cachelog::LOGTYPE_DISABLED
86
                        )
87
                    )
88
                )
89
            ) {
90
                $months = ($rCache['listing_age'] > 366 ? 12 : 6);
91
                $this->archiveCache(
92
                    $rCache['cache_id'],
93
                    'This cache has been "temporarily unavailable" for more than %1 months now; ' .
94
                    'therefore it is being archived automatically. The owner may decide to ' .
95
                    'maintain the cache and re-enable the listing.',
96
                    $months
97
                );
98
                ++$archived;
99
100
                // This limit throttles archiving. If something goes wrong, it won't
101
                // produce too much trouble.
102
                if ($archived >= 10) {
103
                    break;
104
                }
105
            }
106
        }
107
        sql_free_result($rs);
108
    }
109
110
    public function archiveEvents()
111
    {
112
        // To prevent archiving events that were accidentally published with a wrong
113
        // event date - before the owner notices it - we also apply a limit of one month
114
        // to the publication date.
115
        $rs = sql(
116
            'SELECT `cache_id`
117
            FROM `caches`
118
            WHERE `caches`.`type`=6 AND `caches`.`status`=1
119
            AND GREATEST(`date_hidden`,`date_created`) < NOW() - INTERVAL 35 DAY
120
            ORDER BY `date_hidden`
121
            LIMIT 1'
122
        );
123
        while ($rCache = sql_fetch_assoc($rs)) {
124
            $this->archiveCache(
125
                $rCache['cache_id'],
126
                'This event took place more than five weeks ago; therefore it is ' .
127
                'being archived automatically. The owner may re-enable the listing ' .
128
                'if it should stay active for some exceptional reason.'
129
            );
130
        }
131
        sql_free_result($rs);
132
    }
133
134
    public function archiveCache($cache_id, $comment, $months = 0)
135
    {
136
        global $login, $translate;
137
138
        $log = cachelog::createNew($cache_id, $login->userid);
139
        if ($log === false) {
140
            echo $this->name . ": cannot create log for cache $cache_id\n";
141
        } else {
142
            $cache = new cache($cache_id);
143
            if (!$cache->setStatus(3) || !$cache->save()) {
144
                echo $this->name . ": cannot change status of cache $cache_id\n";
145
            } else {
146
                // create log
147
                $log->setType(cachelog::LOGTYPE_ARCHIVED, true);
148
                $log->setOcTeamComment(true);
149
                $log->setDate(date('Y-m-d'));
150
                // Log without time, so that owner reactions will always appear AFTER
151
                // the system log, no matter if logged with or without date.
152
153
                // create log text in appropriate language
154
                $translated_comment = $translate->t($comment, '', '', 0, '', 1, $cache->getDefaultDescLanguage());
155
                $translated_comment = str_replace('%1', $months, $translated_comment);
156
                $log->setText('<p>' . $translated_comment . '</p>');
157
                $log->setTextHtml(1);
158
159
                if (!$log->save()) {
160
                    echo $this->name . ": could not save archive log for cache $cache_id\n";
161
                }
162
            }
163
        }
164
    }
165
}
166