ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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
5include_once "Services/Cron/classes/class.ilCronJob.php";
6
13{
17 protected $data;
18
19 public function getId()
20 {
21 return "mem_notification";
22 }
23
24 public function getTitle()
25 {
26 global $DIC;
27
28 $lng = $DIC['lng'];
29
30 return $lng->txt("enable_course_group_notifications");
31 }
32
33 public function getDescription()
34 {
35 global $DIC;
36
37 $lng = $DIC['lng'];
38
39 return $lng->txt("enable_course_group_notifications_desc");
40 }
41
42 public function getDefaultScheduleType()
43 {
45 }
46
47 public function getDefaultScheduleValue()
48 {
49 return;
50 }
51
52 public function hasAutoActivation()
53 {
54 return false;
55 }
56
57 public function hasFlexibleSchedule()
58 {
59 return true;
60 }
61
62 public function run()
63 {
64 global $DIC;
65
66 $lng = $DIC['lng'];
67 $ilDB = $DIC['ilDB'];
68
69 $log = $DIC->logger()->mmbr();
70 $log->debug("===Member Notifications=== start");
71
73 $status_details = null;
74
75 $setting = new ilSetting("cron");
76 $last_run = $setting->get(get_class($this));
77
78 // no last run?
79 if (!$last_run) {
80 $last_run = date("Y-m-d H:i:s", strtotime("yesterday"));
81
82 $status_details = "No previous run found - starting from yesterday.";
83 }
84 // migration: used to be date-only value
85 elseif (strlen($last_run) == 10) {
86 $last_run .= " 00:00:00";
87
88 $status_details = "Switched from daily runs to open schedule.";
89 }
90 //$last_run = date("Y-m-d H:i:s", strtotime("yesterday"));
91
92 $log->debug("Last run: " . $last_run);
93
94 include_once("./Services/Membership/classes/class.ilMembershipCronNotificationsData.php");
95 $this->data = new ilMembershipCronNotificationsData($last_run, $this->getId());
96
97 $log->debug("prepare sending mails");
98
99 // send mails (1 max for each user)
100
101 $old_lng = $lng;
104
105 $user_news_aggr = $this->data->getAggregatedNews();
106 if (sizeof($user_news_aggr)) {
107 foreach ($user_news_aggr as $user_id => $user_news) {
108 $log->debug("sending mails to user " . $user_id . ", nr news: " . count($user_news));
109
110 $this->sendMail($user_id, $user_news, $last_run);
111
112 ilCronManager::ping($this->getId());
113 }
114
115 // mails were sent - set cron job status accordingly
117 }
118
120 $lng = $old_lng;
121
122 $log->debug("save run");
123
124 // save last run
125 $setting->set(get_class($this), date("Y-m-d H:i:s"));
126
127 $result = new ilCronJobResult();
128 $result->setStatus($status);
129
130 if ($status_details) {
131 $result->setMessage($status_details);
132 }
133
134 $log->debug("===Member Notifications=== done");
135
136 return $result;
137 }
138
148 protected function parseNewsItem($a_parent_ref_id, array &$a_filter_map, array $a_item, $a_is_sub = false, $a_user_id = 0)
149 {
150 global $DIC;
151
152 $lng = $DIC['lng'];
153 $obj_definiton = $DIC["objDefinition"];
154
155 $lng->loadLanguageModule("news");
156
157 $wrong_parent = (array_key_exists($a_item["id"], $a_filter_map) &&
158 $a_parent_ref_id != $a_filter_map[$a_item["id"]]);
159
160 // #18223
161 if ($wrong_parent) {
162 return;
163 }
164
165 $item_obj_title = trim(ilObject::_lookupTitle($a_item["context_obj_id"]));
166 $item_obj_type = $a_item["context_obj_type"];
167
168 // sub-items
169 $sub = null;
170 if ($a_item["aggregation"]) {
171 $do_sub = true;
172 if ($item_obj_type == "file" &&
173 sizeof($a_item["aggregation"]) == 1) {
174 $do_sub = false;
175 }
176 if ($do_sub) {
177 $sub = array();
178 foreach ($a_item["aggregation"] as $subitem) {
179 $sub_res = $this->parseNewsItem($a_parent_ref_id, $a_filter_map, $subitem, true, $a_user_id);
180 if ($sub_res) {
181 $sub[md5($sub_res)] = $sub_res;
182 }
183 }
184 }
185 }
186
187 if (!$a_is_sub) {
189 $a_item["context_obj_type"],
190 $a_item["title"],
191 $a_item["content_is_lang_var"],
192 $a_item["agg_ref_id"],
193 $a_item["aggregation"]
194 );
195 } else {
197 $a_item["context_obj_type"],
198 $a_item["title"],
199 $a_item["content_is_lang_var"]
200 );
201 }
202
204 $a_item["context_obj_type"],
205 $a_item["content"],
206 $a_item["content_text_is_lang_var"]
207 );
208
209 $title = trim($title);
210
211 // #18067 / #18186
212 $content = ilUtil::shortenText(trim(strip_tags($content)), 200, true);
213
214 $res = "";
215 switch ($item_obj_type) {
216 case "frm":
217 if (!$a_is_sub) {
218 $res = $lng->txt("obj_" . $item_obj_type) .
219 ' "' . $item_obj_title . '": ' . $title;
220 } else {
221 $res .= '"' . $title . '": "' . $content . '"';
222 }
223 break;
224
225 case "file":
226 if (!is_array($a_item["aggregation"]) ||
227 sizeof($a_item["aggregation"]) == 1) {
228 $res = $lng->txt("obj_" . $item_obj_type) .
229 ' "' . $item_obj_title . '" - ' . $title;
230 } else {
231 // if files were removed from aggregation update summary count
232 $title = str_replace(
233 " " . sizeof($a_item["aggregation"]) . " ",
234 " " . sizeof($sub) . " ",
235 $title
236 );
237 $res = $title;
238 }
239 break;
240
241 default:
242 $type_txt = ($obj_definiton->isPlugin($item_obj_type))
243 ? ilObjectPlugin::lookupTxtById($item_obj_type, "obj_" . $item_obj_type)
244 : $lng->txt("obj_" . $item_obj_type);
245 $res = $type_txt .
246 ' "' . $item_obj_title . '"';
247 if ($title) {
248 $res .= ': "' . $title . '"';
249 }
250 if ($content) {
251 $res .= ' - ' . $content;
252 }
253 break;
254 }
255
256 // comments
257 $comments = $this->data->getComments($a_item["id"], $a_user_id);
258 if (count($comments) > 0) {
259 $res .= "\n" . $lng->txt("news_new_comments") . " (" . count($comments) . ")";
260 }
261 foreach ($comments as $c) {
262 $res .= "\n* " .
264 new ilDateTime($c->getCreationDate(), IL_CAL_DATETIME)
265 ) . ": " .
266 ilUtil::shortenText(trim(strip_tags($c->getText())), 60, true, true);
267 }
268
269
270 // likes
271 include_once("./Services/Like/classes/class.ilLikeGUI.php");
272 $likes = $this->data->getLikes($a_item["id"], $a_user_id);
273 if (count($likes) > 0) {
274 $res .= "\n" . $lng->txt("news_new_reactions") . " (" . count($likes) . ")";
275 }
276 foreach ($likes as $l) {
277 $res .= "\n* " .
279 new ilDateTime($l["timestamp"], IL_CAL_DATETIME)
280 ) . ": " .
281 ilLikeGUI::getExpressionText((int) $l["expression"]);
282 }
283
284
285 $res = $a_is_sub
286 ? "- " . $res
287 : "# " . $res;
288
289 if (is_array($sub) && sizeof($sub)) {
290 $res .= "\n" . implode("\n", $sub);
291 }
292 // see 29967
293 $res = str_replace("<br />", " ", $res);
294 $res = strip_tags($res);
295
296 return trim($res);
297 }
298
305 protected function filterDuplicateItems(array $a_objects)
306 {
307 global $DIC;
308
309 $tree = $DIC['tree'];
310
311 $parent_map = $news_map = $parsed_map = array();
312
313 // gather news ref ids and news parent ref ids
314 foreach ($a_objects as $parent_ref_id => $news) {
315 foreach ($news as $item) {
316 $news_map[$item["id"]] = $item["ref_id"];
317 $parent_map[$item["id"]][$parent_ref_id] = $parent_ref_id;
318
319 if ($item["aggregation"]) {
320 foreach ($item["aggregation"] as $subitem) {
321 $news_map[$subitem["id"]] = $subitem["ref_id"];
322 $parent_map[$subitem["id"]][$parent_ref_id] = $parent_ref_id;
323 }
324 }
325 }
326 }
327 // if news has multiple parents find "lowest" parent in path
328 foreach ($parent_map as $news_id => $parents) {
329 if (sizeof($parents) > 1 && $news_map[$news_id] > 0) {
330 $path = $tree->getPathId($news_map[$news_id]);
331 $lookup = array_flip($path);
332
333 $level = 0;
334 foreach ($parents as $parent_ref_id) {
335 $level = max($level, $lookup[$parent_ref_id]);
336 }
337
338 $parsed_map[$news_id] = $path[$level];
339 }
340 }
341
342 return $parsed_map;
343 }
344
352 protected function sendMail($a_user_id, array $a_objects, $a_last_run)
353 {
354 global $DIC;
355
356 $lng = $DIC['lng'];
357 $ilUser = $DIC['ilUser'];
358 $ilClientIniFile = $DIC['ilClientIniFile'];
359 $tree = $DIC['tree'];
360
362
363 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
364 $ntf = new ilSystemNotification();
365 $ntf->setLangModules(array("crs", "news"));
366 // no single object anymore
367 // $ntf->setRefId($a_ref_id);
368 // $ntf->setGotoLangId('url');
369 // $ntf->setSubjectLangId('crs_subject_course_group_notification');
370
371 // user specific language
372 $lng = $ntf->getUserLanguage($a_user_id);
373
374 include_once './Services/Locator/classes/class.ilLocatorGUI.php';
375 require_once "./Services/UICore/classes/class.ilTemplate.php";
376 require_once "./Services/Link/classes/class.ilLink.php";
377
378 $filter_map = $this->filterDuplicateItems($a_objects);
379
380 $tmp = array();
381
382 foreach ($a_objects as $parent_ref_id => $items) {
383 $parent = array();
384
385 // path
386 $path = array();
387 foreach ($tree->getPathId($parent_ref_id) as $node) {
388 $path[] = $node;
389 }
390 $path = implode("-", $path);
391
392 $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
393 $parent_type = ilObject::_lookupType($parent_obj_id);
394
395 $parent["title"] = $lng->txt("obj_" . $parent_type) . ' "' . ilObject::_lookupTitle($parent_obj_id) . '"';
396 $parent["url"] = " " . $lng->txt("crs_course_group_notification_link") . " " . ilLink::_getStaticLink($parent_ref_id);
397
398 $log->debug("ref id: " . $parent_ref_id . ", items: " . count($items));
399
400 // news summary
401 $parsed = array();
402 if (is_array($items)) {
403 foreach ($items as $news_item) {
404 // # Type "<Object Title>": "<News Title>" - News Text
405 $parsed_item = $this->parseNewsItem($parent_ref_id, $filter_map, $news_item, false, $a_user_id);
406 if ($parsed_item) {
407 $parsed[md5($parsed_item)] = $parsed_item;
408 }
409 }
410 }
411
412 // any news?
413 if (sizeof($parsed)) {
414 $parent["news"] = implode("\n\n", $parsed);
415 $tmp[$path] = $parent;
416 }
417 }
418
419 // any objects?
420 if (!sizeof($tmp)) {
421 $log->debug("returning");
422 return;
423 }
424
425 ksort($tmp);
426 $counter = 0;
427 $obj_index = array();
428 $txt = "";
429 foreach ($tmp as $path => $item) {
430 $counter++;
431
432 $txt .= "(" . $counter . ") " . $item["title"] . "\n" .
433 $item["url"] . "\n\n" .
434 $item["news"] . "\n\n";
435
436 $obj_index[] = "(" . $counter . ") " . $item["title"];
437 }
438
439 $ntf->setIntroductionLangId("crs_intro_course_group_notification_for");
440
441 // index
442 $period = sprintf(
443 $lng->txt("crs_intro_course_group_notification_index"),
446 );
447 $ntf->addAdditionalInfo(
448 $period,
449 trim(implode("\n", $obj_index)),
450 true,
451 true
452 );
453
454 // object list
455 $ntf->addAdditionalInfo(
456 "",
457 trim($txt),
458 true
459 );
460
461 // :TODO: does it make sense to add client to subject?
462 $client = $ilClientIniFile->readVariable('client', 'name');
463 $subject = sprintf($lng->txt("crs_subject_course_group_notification"), $client);
464
465 $mail_content = $ntf->composeAndGetMessage($a_user_id, null, "read", true);
466 $log->debug("sending mail content: ".$mail_content);
467
468 // #10044
469 $mail = new ilMail(ANONYMOUS_USER_ID);
470 $mail->enqueue(
471 ilObjUser::_lookupLogin($a_user_id),
472 null,
473 null,
474 $subject,
475 $mail_content,
476 []
477 );
478 }
479
480 public function addToExternalSettingsForm($a_form_id, array &$a_fields, $a_is_active)
481 {
482 global $DIC;
483
484 $lng = $DIC['lng'];
485
486 switch ($a_form_id) {
489 $a_fields["enable_course_group_notifications"] = $a_is_active ?
490 $lng->txt("enabled") :
491 $lng->txt("disabled");
492 break;
493 }
494 }
495
496 public function activationWasToggled($a_currently_active)
497 {
498 global $DIC;
499
500 $ilSetting = $DIC['ilSetting'];
501
502 // propagate cron-job setting to object setting
503 $ilSetting->set("crsgrp_ntf", (bool) $a_currently_active);
504 }
505}
$result
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_UNIX
const IL_CAL_DATETIME
Cron job result data container.
Cron job application base class.
const SCHEDULE_TYPE_DAILY
static ping($a_job_id)
Keep cron job alive.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date @access public.
static setUseRelativeDates($a_status)
set use relative dates
static useRelativeDates()
check if relative dates are used
@classDescription Date and time handling
static getExpressionText($a_const)
Get unicode for const.
static getLogger($a_component_id)
Get component logger.
Manage data for ilMembershipCronNotifications cron job.
parseNewsItem($a_parent_ref_id, array &$a_filter_map, array $a_item, $a_is_sub=false, $a_user_id=0)
Convert news item to summary html.
sendMail($a_user_id, array $a_objects, $a_last_run)
Send news mail for 1 user and n objects.
activationWasToggled($a_currently_active)
Cron job status was changed.
filterDuplicateItems(array $a_objects)
Filter duplicate news items from structure.
addToExternalSettingsForm($a_form_id, array &$a_fields, $a_is_active)
Add external settings to form.
hasFlexibleSchedule()
Can the schedule be configured?
hasAutoActivation()
Is to be activated on "installation".
static determineNewsContent($a_context_obj_type, $a_content, $a_is_lang_var)
Determine new content.
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
static lookupTxtById($plugin_id, $lang_var)
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
static _lookupType($a_id, $a_reference=false)
lookup object type
ILIAS Setting Class.
Wrapper classes for system notifications.
static getNamePresentation( $a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false, $a_ctrl_path="ilpublicuserprofilegui")
Default behaviour is:
static shortenText( $a_str, $a_len, $a_dots=false, $a_next_blank=false, $a_keep_extension=false)
shorten a string to given length.
if($_SERVER['argc']< 4) $client
Definition: cron.php:12
$txt
Definition: error.php:13
global $ilSetting
Definition: privfeed.php:17
$log
Definition: result.php:15
$lng
foreach($_POST as $key=> $value) $res
global $ilDB
$ilUser
Definition: imgupload.php:18
$DIC
Definition: xapitoken.php:46