Digest   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 214
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 110
c 2
b 0
f 0
dl 0
loc 214
rs 10
wmc 20

2 Methods

Rating   Name   Duplication   Size   Complexity  
B prepare_headlines_digest() 0 125 9
B send_headlines_digests() 0 76 11
1
<?php
2
class Digest
3
{
4
5
    /**
6
     * Send by mail a digest of last articles.
7
     *
8
     * @param mixed $link The database connection.
9
     * @param integer $limit The maximum number of articles by digest.
10
     * @return boolean Return false if digests are not enabled.
11
     */
12
    public static function send_headlines_digests() {
13
14
        $user_limit = 15; // amount of users to process (e.g. emails to send out)
15
        $limit = 1000; // maximum amount of headlines to include
16
17
        Debug::log("Sending digests, batch of max $user_limit users, headline limit = $limit");
18
19
        if (DB_TYPE == "pgsql") {
0 ignored issues
show
Bug introduced by
The constant DB_TYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
20
            $interval_qpart = "last_digest_sent < NOW() - INTERVAL '1 days'";
21
        } else if (DB_TYPE == "mysql") {
22
            $interval_qpart = "last_digest_sent < DATE_SUB(NOW(), INTERVAL 1 DAY)";
23
        }
24
25
        $pdo = Db::pdo();
26
27
        $res = $pdo->query("SELECT id,email FROM ttrss_users
28
				WHERE email != '' AND (last_digest_sent IS NULL OR $interval_qpart)");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $interval_qpart does not seem to be defined for all execution paths leading up to this point.
Loading history...
29
30
        while ($line = $res->fetch()) {
31
32
            if (@get_pref('DIGEST_ENABLE', $line['id'], false)) {
33
                $preferred_ts = strtotime(get_pref('DIGEST_PREFERRED_TIME', $line['id'], '00:00'));
34
35
                // try to send digests within 2 hours of preferred time
36
                if ($preferred_ts && time() >= $preferred_ts &&
37
                    time() - $preferred_ts <= 7200
38
                ) {
39
40
                    Debug::log("Sending digest for UID:".$line['id']." - ".$line["email"]);
41
42
                    $do_catchup = get_pref('DIGEST_CATCHUP', $line['id'], false);
43
44
                    global $tz_offset;
45
46
                    // reset tz_offset global to prevent tz cache clash between users
47
                    $tz_offset = -1;
48
49
                    $tuple = Digest::prepare_headlines_digest($line["id"], 1, $limit);
50
                    $digest = $tuple[0];
51
                    $headlines_count = $tuple[1];
52
                    $affected_ids = $tuple[2];
53
                    $digest_text = $tuple[3];
54
55
                    if ($headlines_count > 0) {
56
57
                        $mailer = new Mailer();
58
59
                        //$rc = $mail->quickMail($line["email"], $line["login"], DIGEST_SUBJECT, $digest, $digest_text);
60
61
                        $rc = $mailer->mail(["to_name" => $line["login"],
62
                            "to_address" => $line["email"],
63
                            "subject" => DIGEST_SUBJECT,
0 ignored issues
show
Bug introduced by
The constant DIGEST_SUBJECT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
64
                            "message" => $digest_text,
65
                            "message_html" => $digest]);
66
67
                        //if (!$rc && $debug) Debug::log("ERROR: " . $mailer->lastError());
68
69
                        Debug::log("RC=$rc");
70
71
                        if ($rc && $do_catchup) {
72
                            Debug::log("Marking affected articles as read...");
73
                            Article::catchupArticlesById($affected_ids, 0, $line["id"]);
74
                        }
75
                    } else {
76
                        Debug::log("No headlines");
77
                    }
78
79
                    $sth = $pdo->prepare("UPDATE ttrss_users SET last_digest_sent = NOW()
80
						WHERE id = ?");
81
                    $sth->execute([$line["id"]]);
82
83
                }
84
            }
85
        }
86
87
        Debug::log("All done.");
88
89
    }
90
91
    public static function prepare_headlines_digest($user_id, $days = 1, $limit = 1000) {
92
93
        require_once "lib/MiniTemplator.class.php";
94
95
        $tpl = new MiniTemplator;
96
        $tpl_t = new MiniTemplator;
97
98
        $tpl->readTemplateFromFile("templates/digest_template_html.txt");
99
        $tpl_t->readTemplateFromFile("templates/digest_template.txt");
100
101
        $user_tz_string = get_pref('USER_TIMEZONE', $user_id);
102
        $local_ts = convert_timestamp(time(), 'UTC', $user_tz_string);
103
104
        $tpl->setVariable('CUR_DATE', date('Y/m/d', $local_ts));
105
        $tpl->setVariable('CUR_TIME', date('G:i', $local_ts));
106
        $tpl->setVariable('TTRSS_HOST', SELF_URL_PATH);
0 ignored issues
show
Bug introduced by
The constant SELF_URL_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
107
108
        $tpl_t->setVariable('CUR_DATE', date('Y/m/d', $local_ts));
109
        $tpl_t->setVariable('CUR_TIME', date('G:i', $local_ts));
110
        $tpl_t->setVariable('TTRSS_HOST', SELF_URL_PATH);
111
112
        $affected_ids = array();
113
114
        $days = (int) $days;
115
116
        if (DB_TYPE == "pgsql") {
0 ignored issues
show
Bug introduced by
The constant DB_TYPE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
117
            $interval_qpart = "ttrss_entries.date_updated > NOW() - INTERVAL '$days days'";
118
        } else if (DB_TYPE == "mysql") {
119
            $interval_qpart = "ttrss_entries.date_updated > DATE_SUB(NOW(), INTERVAL $days DAY)";
120
        }
121
122
        $pdo = Db::pdo();
123
124
        $sth = $pdo->prepare("SELECT ttrss_entries.title,
125
				ttrss_feeds.title AS feed_title,
126
				COALESCE(ttrss_feed_categories.title, '" . __('Uncategorized')."') AS cat_title,
127
				date_updated,
128
				ttrss_user_entries.ref_id,
129
				link,
130
				score,
131
				content,
132
				" . SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated
133
			FROM
134
				ttrss_user_entries,ttrss_entries,ttrss_feeds
135
			LEFT JOIN
136
				ttrss_feed_categories ON (cat_id = ttrss_feed_categories.id)
137
			WHERE
138
				ref_id = ttrss_entries.id AND feed_id = ttrss_feeds.id
139
				AND include_in_digest = true
140
				AND $interval_qpart
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $interval_qpart does not seem to be defined for all execution paths leading up to this point.
Loading history...
141
				AND ttrss_user_entries.owner_uid = :user_id
142
				AND unread = true
143
				AND score >= 0
144
			ORDER BY ttrss_feed_categories.title, ttrss_feeds.title, score DESC, date_updated DESC
145
			LIMIT :limit");
146
        $sth->bindParam(':user_id', intval($user_id, 10), PDO::PARAM_INT);
0 ignored issues
show
Bug introduced by
intval($user_id, 10) cannot be passed to PDOStatement::bindParam() as the parameter $variable expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
        $sth->bindParam(':user_id', /** @scrutinizer ignore-type */ intval($user_id, 10), PDO::PARAM_INT);
Loading history...
147
        $sth->bindParam(':limit', intval($limit, 10), PDO::PARAM_INT);
0 ignored issues
show
Bug introduced by
intval($limit, 10) cannot be passed to PDOStatement::bindParam() as the parameter $variable expects a reference. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

147
        $sth->bindParam(':limit', /** @scrutinizer ignore-type */ intval($limit, 10), PDO::PARAM_INT);
Loading history...
148
        $sth->execute();
149
150
        $headlines_count = 0;
151
        $headlines = array();
152
153
        while ($line = $sth->fetch()) {
154
            array_push($headlines, $line);
155
            $headlines_count++;
156
        }
157
158
        for ($i = 0; $i < sizeof($headlines); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function sizeof() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
159
160
            $line = $headlines[$i];
161
162
            array_push($affected_ids, $line["ref_id"]);
163
164
            $updated = make_local_datetime($line['last_updated'], false,
165
                $user_id);
166
167
            if (get_pref('ENABLE_FEED_CATS', $user_id)) {
168
                $line['feed_title'] = $line['cat_title']." / ".$line['feed_title'];
169
            }
170
171
            $article_labels = Article::get_article_labels($line["ref_id"], $user_id);
172
            $article_labels_formatted = "";
173
174
            if (is_array($article_labels) && count($article_labels) > 0) {
175
                $article_labels_formatted = implode(", ", array_map(function($a) {
176
                    return $a[1];
177
                }, $article_labels));
178
            }
179
180
            $tpl->setVariable('FEED_TITLE', $line["feed_title"]);
181
            $tpl->setVariable('ARTICLE_TITLE', $line["title"]);
182
            $tpl->setVariable('ARTICLE_LINK', $line["link"]);
183
            $tpl->setVariable('ARTICLE_UPDATED', $updated);
184
            $tpl->setVariable('ARTICLE_EXCERPT',
185
                truncate_string(strip_tags($line["content"]), 300));
186
//			$tpl->setVariable('ARTICLE_CONTENT',
187
//				strip_tags($article_content));
188
            $tpl->setVariable('ARTICLE_LABELS', $article_labels_formatted, true);
189
190
            $tpl->addBlock('article');
191
192
            $tpl_t->setVariable('FEED_TITLE', $line["feed_title"]);
193
            $tpl_t->setVariable('ARTICLE_TITLE', $line["title"]);
194
            $tpl_t->setVariable('ARTICLE_LINK', $line["link"]);
195
            $tpl_t->setVariable('ARTICLE_UPDATED', $updated);
196
            $tpl_t->setVariable('ARTICLE_LABELS', $article_labels_formatted, true);
197
            $tpl_t->setVariable('ARTICLE_EXCERPT',
198
                truncate_string(strip_tags($line["content"]), 300, "..."), true);
199
200
            $tpl_t->addBlock('article');
201
202
            if ($headlines[$i]['feed_title'] != $headlines[$i + 1]['feed_title']) {
203
                $tpl->addBlock('feed');
204
                $tpl_t->addBlock('feed');
205
            }
206
207
        }
208
209
        $tpl->addBlock('digest');
210
        $tpl->generateOutputToString($tmp);
211
212
        $tpl_t->addBlock('digest');
213
        $tpl_t->generateOutputToString($tmp_t);
214
215
        return array($tmp, $headlines_count, $affected_ids, $tmp_t);
216
    }
217
218
}
219