ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilMembershipCronNotifications.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once "Services/Cron/classes/class.ilCronJob.php";
6 
13 {
14  public function getId()
15  {
16  return "mem_notification";
17  }
18 
19  public function getTitle()
20  {
21  global $lng;
22 
23  return $lng->txt("enable_course_group_notifications");
24  }
25 
26  public function getDescription()
27  {
28  global $lng;
29 
30  return $lng->txt("enable_course_group_notifications_desc");
31  }
32 
33  public function getDefaultScheduleType()
34  {
35  return self::SCHEDULE_TYPE_DAILY;
36  }
37 
38  public function getDefaultScheduleValue()
39  {
40  return;
41  }
42 
43  public function hasAutoActivation()
44  {
45  return false;
46  }
47 
48  public function hasFlexibleSchedule()
49  {
50  return true;
51  }
52 
53  public function run()
54  {
55  global $lng, $ilDB;
56 
58  $log->debug("===Member Notifications=== start");
59 
61  $status_details = null;
62 
63  $setting = new ilSetting("cron");
64  $last_run = $setting->get(get_class($this));
65 
66  // no last run?
67  if(!$last_run)
68  {
69  $last_run = date("Y-m-d H:i:s", strtotime("yesterday"));
70 
71  $status_details = "No previous run found - starting from yesterday.";
72  }
73  // migration: used to be date-only value
74  else if(strlen($last_run) == 10)
75  {
76  $last_run .= " 00:00:00";
77 
78  $status_details = "Switched from daily runs to open schedule.";
79  }
80 
81  include_once "Services/Membership/classes/class.ilMembershipNotifications.php";
83 
84  if(sizeof($objects))
85  {
86  $log->debug("nr of objects: ".count($objects));
87 
88  // gather news for each user over all objects
89 
90  $user_news_aggr = array();
91 
92  include_once "Services/News/classes/class.ilNewsItem.php";
93  foreach($objects as $ref_id => $user_ids)
94  {
95  $log->debug("handle ref id ".$ref_id.", users: ".count($user_ids));
96 
97  // gather news per object
98  $news_item = new ilNewsItem();
99  if($news_item->checkNewsExistsForGroupCourse($ref_id, $last_run))
100  {
101  foreach($user_ids as $user_id)
102  {
103  // gather news for user
104  $user_news = $news_item->getNewsForRefId($ref_id,
105  false, false, $last_run, false, false, false, false,
106  $user_id);
107  if($user_news)
108  {
109  $user_news_aggr[$user_id][$ref_id] = $user_news;
110 
111  // #17928
112  ilCronManager::ping($this->getId());
113  }
114  }
115  }
116  }
117  unset($objects);
118 
119  $log->debug("prepare sending mails");
120 
121  // send mails (1 max for each user)
122 
123  $old_lng = $lng;
126 
127  if(sizeof($user_news_aggr))
128  {
129  foreach($user_news_aggr as $user_id => $user_news)
130  {
131  $log->debug("sending mails to user ".$user_id.", nr news: ".count($user_news));
132 
133  $this->sendMail($user_id, $user_news, $last_run);
134 
135  // #17928
136  ilCronManager::ping($this->getId());
137  }
138 
139  // mails were sent - set cron job status accordingly
140  $status = ilCronJobResult::STATUS_OK;
141  }
142 
144  $lng = $old_lng;
145  }
146 
147  $log->debug("save run");
148 
149  // save last run
150  $setting->set(get_class($this), date("Y-m-d H:i:s"));
151 
152  $result = new ilCronJobResult();
153  $result->setStatus($status);
154 
155  if($status_details)
156  {
157  $result->setMessage($status_details);
158  }
159 
160  $log->debug("===Member Notifications=== done");
161 
162  return $result;
163  }
164 
174  protected function parseNewsItem($a_parent_ref_id, array &$a_filter_map, array $a_item, $a_is_sub = false)
175  {
176  global $lng;
177 
178  $wrong_parent = (array_key_exists($a_item["id"], $a_filter_map) &&
179  $a_parent_ref_id != $a_filter_map[$a_item["id"]]);
180 
181  // #18223
182  if($wrong_parent)
183  {
184  return;
185  }
186 
187  $item_obj_title = trim(ilObject::_lookupTitle($a_item["context_obj_id"]));
188  $item_obj_type = $a_item["context_obj_type"];
189 
190  // sub-items
191  $sub = null;
192  if($a_item["aggregation"])
193  {
194  $do_sub = true;
195  if($item_obj_type == "file" &&
196  sizeof($a_item["aggregation"]) == 1)
197  {
198  $do_sub = false;
199  }
200  if($do_sub)
201  {
202  $sub = array();
203  foreach($a_item["aggregation"] as $subitem)
204  {
205  $sub_res = $this->parseNewsItem($a_parent_ref_id, $a_filter_map, $subitem, true);
206  if($sub_res)
207  {
208  $sub[md5($sub_res)] = $sub_res;
209  }
210  }
211  }
212  }
213 
214  if(!$a_is_sub)
215  {
217  $a_item["context_obj_type"],
218  $a_item["title"],
219  $a_item["content_is_lang_var"],
220  $a_item["agg_ref_id"],
221  $a_item["aggregation"]
222  );
223  }
224  else
225  {
227  $a_item["context_obj_type"],
228  $a_item["title"],
229  $a_item["content_is_lang_var"]
230  );
231  }
232 
234  $a_item["context_obj_type"],
235  $a_item["content"],
236  $a_item["content_text_is_lang_var"]
237  );
238 
239  $title = trim($title);
240 
241  // #18067 / #18186
242  $content = ilUtil::shortenText(trim(strip_tags($content)), 200, true);
243 
244  $res = "";
245  switch($item_obj_type)
246  {
247  case "frm":
248  if(!$a_is_sub)
249  {
250  $res = $lng->txt("obj_".$item_obj_type).
251  ' "'.$item_obj_title.'": '.$title;
252  }
253  else
254  {
255  $res .= '"'.$title.'": "'.$content.'"';
256  }
257  break;
258 
259  case "file":
260  if(!is_array($a_item["aggregation"]) ||
261  sizeof($a_item["aggregation"]) == 1)
262  {
263  $res = $lng->txt("obj_".$item_obj_type).
264  ' "'.$item_obj_title.'" - '.$title;
265  }
266  else
267  {
268  // if files were removed from aggregation update summary count
269  $title = str_replace(
270  " ".sizeof($a_item["aggregation"])." ",
271  " ".sizeof($sub)." ",
272  $title
273  );
274  $res = $title;
275  }
276  break;
277 
278  default:
279  $res = $lng->txt("obj_".$item_obj_type).
280  ' "'.$item_obj_title.'"';
281  if($title)
282  {
283  $res .= ': "'.$title.'"';
284  }
285  if($content)
286  {
287  $res .= ' - '.$content;
288  }
289  break;
290  }
291 
292  $res = $a_is_sub
293  ? "- ".$res
294  : "# ".$res;
295 
296  if(sizeof($sub))
297  {
298  $res .= "\n".implode("\n", $sub);
299  }
300 
301  return trim($res);
302  }
303 
310  protected function filterDuplicateItems(array $a_objects)
311  {
312  global $tree;
313 
314  $parent_map = $news_map = $parsed_map = array();
315 
316  // gather news ref ids and news parent ref ids
317  foreach($a_objects as $parent_ref_id => $news)
318  {
319  foreach($news as $item)
320  {
321  $news_map[$item["id"]] = $item["ref_id"];
322  $parent_map[$item["id"]][$parent_ref_id] = $parent_ref_id;
323 
324  if($item["aggregation"])
325  {
326  foreach($item["aggregation"] as $subitem)
327  {
328  $news_map[$subitem["id"]] = $subitem["ref_id"];
329  $parent_map[$subitem["id"]][$parent_ref_id] = $parent_ref_id;
330  }
331  }
332  }
333  }
334  // if news has multiple parents find "lowest" parent in path
335  foreach($parent_map as $news_id => $parents)
336  {
337  if(sizeof($parents) > 1)
338  {
339  $path = $tree->getPathId($news_map[$news_id]);
340  $lookup = array_flip($path);
341 
342  $level = 0;
343  foreach($parents as $parent_ref_id)
344  {
345  $level = max($level, $lookup[$parent_ref_id]);
346  }
347 
348  $parsed_map[$news_id] = $path[$level];
349  }
350  }
351 
352  return $parsed_map;
353  }
354 
362  protected function sendMail($a_user_id, array $a_objects, $a_last_run)
363  {
364  global $lng, $ilUser, $ilClientIniFile, $tree;
365 
366  include_once "./Services/Notification/classes/class.ilSystemNotification.php";
367  $ntf = new ilSystemNotification();
368  $ntf->setLangModules(array("crs", "news"));
369  // no single object anymore
370  // $ntf->setRefId($a_ref_id);
371  // $ntf->setGotoLangId('url');
372  // $ntf->setSubjectLangId('crs_subject_course_group_notification');
373 
374  // user specific language
375  $lng = $ntf->getUserLanguage($a_user_id);
376 
377  include_once './Services/Locator/classes/class.ilLocatorGUI.php';
378  require_once "./Services/UICore/classes/class.ilTemplate.php";
379  require_once "./Services/Link/classes/class.ilLink.php";
380 
381  $filter_map = $this->filterDuplicateItems($a_objects);
382 
383  $tmp = array();
384  foreach($a_objects as $parent_ref_id => $news)
385  {
386  $parent = array();
387 
388  // path
389  $path = array();
390  foreach($tree->getPathId($parent_ref_id) as $node)
391  {
392  $path[] = $node;
393  }
394  $path = implode("-", $path);
395 
396  $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
397  $parent_type = ilObject::_lookupType($parent_obj_id);
398 
399  $parent["title"] = $lng->txt("obj_".$parent_type).' "'.ilObject::_lookupTitle($parent_obj_id).'"';
400  $parent["url"] = " ".$lng->txt("crs_course_group_notification_link")." ".ilLink::_getStaticLink($parent_ref_id);
401 
402  // news summary
403  $parsed = array();
404  foreach($news as $item)
405  {
406  $parsed_item = $this->parseNewsItem($parent_ref_id, $filter_map, $item);
407  if($parsed_item)
408  {
409  $parsed[md5($parsed_item)] = $parsed_item;
410  }
411  }
412  // any news?
413  if(sizeof($parsed))
414  {
415  $parent["news"] = implode("\n", $parsed);
416  $tmp[$path] = $parent;
417  }
418  }
419 
420  // any objects?
421  if(!sizeof($tmp))
422  {
423  return;
424  }
425 
426  ksort($tmp);
427  $counter = 0;
428  $obj_index = array();
429  $txt = "";
430  foreach($tmp as $path => $item)
431  {
432  $counter++;
433 
434  $txt .= "(".$counter.") ".$item["title"]."\n".
435  $item["url"]."\n\n".
436  $item["news"]."\n\n";
437 
438  $obj_index[] = "(".$counter.") ".$item["title"];
439  }
440 
441  $ntf->setIntroductionLangId("crs_intro_course_group_notification_for");
442 
443  // index
444  $period = sprintf(
445  $lng->txt("crs_intro_course_group_notification_index"),
448  );
449  $ntf->addAdditionalInfo($period,
450  trim(implode("\n", $obj_index)),
451  true,
452  true);
453 
454  // object list
455  $ntf->addAdditionalInfo("",
456  trim($txt),
457  true);
458 
459  // :TODO: does it make sense to add client to subject?
460  $client = $ilClientIniFile->readVariable('client', 'name');
461  $subject = sprintf($lng->txt("crs_subject_course_group_notification"), $client);
462 
463  // #10044
464  $mail = new ilMail(ANONYMOUS_USER_ID);
465  $mail->enableSOAP(false); // #10410
466  $mail->sendMail(ilObjUser::_lookupLogin($a_user_id),
467  null,
468  null,
469  $subject,
470  $ntf->composeAndGetMessage($a_user_id, null, "read", true),
471  null,
472  array("system"));
473  }
474 
475  public function addToExternalSettingsForm($a_form_id, array &$a_fields, $a_is_active)
476  {
477  global $lng;
478 
479  switch($a_form_id)
480  {
483  $a_fields["enable_course_group_notifications"] = $a_is_active ?
484  $lng->txt("enabled") :
485  $lng->txt("disabled");
486  break;
487  }
488  }
489 
490  public function activationWasToggled($a_currently_active)
491  {
492  global $ilSetting;
493 
494  // propagate cron-job setting to object setting
495  $ilSetting->set("crsgrp_ntf", (bool)$a_currently_active);
496  }
497 }
498 
499 ?>
static determineNewsTitle($a_context_obj_type, $a_title, $a_content_is_lang_var, $a_agg_ref_id=0, $a_aggregation="")
Determine title for news item entry.
static _lookupLogin($a_user_id)
lookup login
ILIAS Setting Class.
$path
Definition: aliased.php:25
const IL_CAL_DATETIME
$result
Cron job application base class.
static shortenText($a_str, $a_len, $a_dots=false, $a_next_blank=false, $a_keep_extension=false)
shorten a string to given length.
static setUseRelativeDates($a_status)
set use relative dates
static _lookupTitle($a_id)
lookup object title
filterDuplicateItems(array $a_objects)
Filter duplicate news items from structure.
const IL_CAL_UNIX
parseNewsItem($a_parent_ref_id, array &$a_filter_map, array $a_item, $a_is_sub=false)
Convert news item to summary html.
static useRelativeDates()
check if relative dates are used
$counter
$client
static determineNewsContent($a_context_obj_type, $a_content, $a_is_lang_var)
Determine new content.
This class handles base functions for mail handling.
static _lookupObjId($a_id)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
static formatDate(ilDateTime $date)
Format a date public.
Date and time handling
$ilUser
Definition: imgupload.php:18
$txt
Definition: error.php:12
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
addToExternalSettingsForm($a_form_id, array &$a_fields, $a_is_active)
static ping($a_job_id)
Keep cron job alive.
$ref_id
Definition: sahs_server.php:39
global $ilSetting
Definition: privfeed.php:17
global $lng
Definition: privfeed.php:17
global $ilDB
static getLogger($a_component_id)
Get component logger.
static getActiveUsersforAllObjects()
Get active notifications for all objects.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
Cron job result data container.
Wrapper classes for system notifications.
sendMail($a_user_id, array $a_objects, $a_last_run)
Send news mail for 1 user and n objects.