CMS  Version 3.9
blog_subscription_manager.inc
Go to the documentation of this file.
1 <?php
7 Fakoli::using("blog", "email");
8 
9 class BlogSubscriptionManager
10 {
11  var $daily_digest = array();
12  var $weekly_digest = array();
13  var $subscribers;
14  var $blogs;
15 
16  function BlogSubscriptionManager()
17  {
18  $this->subscribers = Query::create(BlogSubscriber, "WHERE subscription_type IN ('daily', 'weekly') AND blog_id IN (SELECT blog_id FROM blog WHERE published=true)")->execute();
19 
20  $numSubscribers = count($this->subscribers);
21  trace(pluralize($numSubscribers." blog subscriber", $numSubscribers)." found", 3);
22  $this->daily_digest = $this->getDailyDigest();
23  $this->weekly_digest = $this->getWeeklyDigest();
24  }
25 
26  static function generateToken()
27  {
28  return md5(guid());
29  }
30 
31  function getDailyDigest()
32  {
33  $today = new DateTime(today() . "00:00:00");
34  $yesterday = clone($today);
35  $yesterday->modify("-1 days");
36 
37  $articles = Query::create(Article, "WHERE published=true AND publish_date=:yesterday")
38  ->bind(":yesterday", $yesterday->format("Y-m-d H:i:s"))
39  ->execute();
40 
41  if(!count($articles)) return null;
42 
43  $daily_digest = array();
44  foreach($articles as $article)
45  {
46  $blog = $article->Blog();
47 
48  if(!$blog || !$blog->published) continue;
49 
50  if(!array_key_exists($blog->blog_id, $this->blogs))
51  {
52  $this->blogs[$blog->blog_id] = $blog;
53  }
54  $daily_digest[$blog->blog_id][] = $article;
55  }
56 
57  return $daily_digest;
58  }
59 
60  function getWeeklyDigest()
61  {
62  $today = new DateTime(now());
63  $start_of_week = Settings::getValue("blog", "weekly_digest_day");
64 
65  if($today->format("D") != $start_of_week)
66  {
67  return;
68  }
69 
70  $last_week = clone $today;
71  $last_week->modify("-7 days");
72 
73  $articles = Query::create(Article, "WHERE published=true AND publish_date BETWEEN :last_week AND :today")
74  ->bind(":last_week", $last_week->format("Y-m-d"), ":today", $today->format("Y-m-d"))
75  ->execute();
76 
77  if(!count($articles)) return null;
78 
79  $weekly_digest = array();
80  foreach($articles as $article)
81  {
82  $blog = $article->Blog();
83 
84  if(!$blog || !$blog->published) continue;
85 
86  if(!array_key_exists($blog->blog_id, $this->blogs))
87  {
88  $this->blogs[$blog->blog_id] = $blog;
89  }
90  $weekly_digest[$blog->blog_id][] = $article;
91  }
92 
93  return $weekly_digest;
94  }
95 
96  function sendDigests()
97  {
98  if(!count($this->subscribers)) return;
99 
100  foreach($this->subscribers as $subscriber)
101  {
102  $this->sendDigest($subscriber);
103  }
104  }
105 
106  function sendDigest($subscriber)
107  {
108  $blog_id = $subscriber->blog_id;
109  $blog = $this->blogs[$blog_id];
110 
111  if(($subscriber->subscription_type == "daily" && !array_key_exists($blog_id, $this->daily_digest)) ||
112  ($subscriber->subscription_type == "weekly" && !array_key_exists($blog_id, $this->weekly_digest)))
113  {
114  return;
115  }
116 
117  echo $subscriber->format("Sending {subscription_type} digest to {subscriber_email}\n");
118 
119  $articles = ($subscriber->subscription_type == "daily") ? $this->daily_digest[$blog_id] : $this->weekly_digest[$blog_id];
120 
121  $sitename = Settings::getValue("settings", "sitename");
122  $label = $subscriber->format("{subscription_type:prettify}");
123 
124  $subject = "{$sitename} $label Digest for {$blog->title}";
125 
126  $url = $blog->getURL();
127 
128  // set pseudo field for use in formatArticleMessage
129  if (count($articles))
130  {
131  foreach($articles as $article)
132  {
133  $article->set("url", $url);
134  }
135  }
136 
137  $message .= formatItems($articles, "{BlogSubscriptionManager::formatArticleMessage}","\n<br/><hr/><br/>\n");
138  $message .= $this->formatUnsubscribeMessageFooter($subscriber);
139 
140  $emailHandler = new EmailHandler($subscriber->subscriber_email, $subject, $message);
141  $emailHandler->send();
142  }
143 
150  static function formatArticleMessage($article)
151  {
152  $authorName = $article->getAuthorName();
153 
154  if($authorName)
155  {
156  $author = "<br><label>Author </label>$authorName";
157  }
158 
159  if($article->publication)
160  {
161  $publisher = " {$article->publication}";
162  }
163 
164  // pseudo field
165  $url = $article->get("url");
166 
167  return $article->format("<h3>{title}</h3><br>{message}<br><br>{$url}?article_id={article_id}{$author}<br><label>Published </label> {publish_date:short}{$publisher}");
168  }
169 
170  function formatUnsubscribeMessageFooter($subscriber)
171  {
172  global $config;
173 
174  $url = "http://" . $config["http_host"] . "/blog_subscription_preferences?subscription_token={subscription_token}";
175  $messageFooter = $subscriber->format("</br></br>To unsubscribe to these messages or change your subscription preferences, go to $url\n\n");
176 
177  return $messageFooter;
178  }
179 
180  /*
181  * Subscribe to entire forum, leave topic_id blank.
182  * If user is subscribed to any topics within this forum,
183  * delete the subscriptions.
184  */
185  static function updateSubscription($subscriber, $subscription_type)
186  {
187  // update subscription type for either a forum or topic subscription
189  $subscription_type != $subscriber->subscription_type)
190  {
191  $subscriber->filter = new InclusionFilter("subscription_type");
192  $subscriber->subscription_type = $subscription_type;
193  $subscriber->save();
194  }
196  {
197  $subscriber->delete();
198  }
199  }
200 
201  static function formatTitleLink($blogSubscriber)
202  {
203  $blog = $blogSubscriber->Blog();
204 
205  if($blog->published)
206  {
207  $url = $blog->getURL();
208  $out = $blog->format("<a href='$url'>{title:65}</a>");
209  }
210  else
211  {
212  $out = $blog->format("{title:65}");
213  }
214 
215  return $out;
216  }
217 
218  static function renderSubscriptionTypeSelect($blogSubscriber)
219  {
220  $subscriptionTypes = BlogSubscriber::$subscriptionTypes;
221  $subscriptionTypes["unsubscribe"] = "Unsubscribe";
222 
223  if(!Settings::getValue("blog", "allow_subscription_options"))
224  {
225  unset($subscriptionTypes["daily"]);
226  unset($subscriptionTypes["weekly"]);
227  }
228 
229  if(!array_key_exists($blogSubscriber->subscription_type, $subscriptionTypes))
230  {
231  $blogSubscriber->subscription_type = "instant";
232  }
233 
234  $current = $blogSubscriber->subscription_type;
235  $blog_subscriber_id = $blogSubscriber->blog_subscriber_id;
236 
237  foreach($subscriptionTypes as $value => $name)
238  {
239  $selected = ($current == $value) ? " checked" : "";
240  $field = "blog_subscriber_id_{$blog_subscriber_id}[$value]";
241  $html .= "<input style='border: none' type='radio' id='{$field}' name='{$blog_subscriber_id}[]' value='$value' $selected>$name</option><br>\n";
242  }
243 
244  return $html;
245  }
246 
247  static function writeSubscriptionPreferenceScript($div_id)
248  {
249  ob_start();
250  ?>
251  <script type="text/javascript" src="/components/blog/js/blog_subscriber_preference_manager.js"></script>
252  <script type="text/javascript">
253  var blogSubscriberMgr;
254 
255  window.addEvent('domready', function()
256  {
257  blogSubscriberMgr = new BlogSubscriberPreferenceManager('<?php echo $div_id ?>');
258  });
259 
260  </script>
261  <?
262  $script .= ob_get_contents();
263  ob_end_clean();
264 
265  return $script;
266  }
267 }?>
$article
$blog
$out
Definition: page.inc:66
$blog_id
Definition: edit.inc:45
$name
Definition: upload.inc:54
if(! $token) $subscriber
Defines the Article class.
Definition: article.inc:45
static $subscriptionTypes
static using()
Import the datamodels, views and manifest for the specified component(s).
Definition: core.inc:116
static getValue($component, $name)
Retrieve the value of the specified Setting.
Definition: settings.inc:104
const subscription_unsubscribe
global $config
Definition: import.inc:4
$message
Definition: mail_to.inc:49
$articles
Definition: rss.inc:62
if(! $blog->published||! $blog->enable_rss_feed||!checkRole($blog->allow_read)) $url
Definition: rss.inc:58
$messageFooter
$blog_subscriber_id
Definition: unsubscribe.inc:39