Test Setup Failed
Push — master ( 4e700f...c7183e )
by Julito
63:12
created

ScheduledAnnouncement::get_count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Class ScheduledAnnouncement
6
 * Requires DB change:
7
 *
8
 * CREATE TABLE scheduled_announcements (id INT AUTO_INCREMENT NOT NULL, subject VARCHAR(255) NOT NULL, message LONGTEXT NOT NULL, date DATETIME DEFAULT NULL, sent TINYINT(1) NOT NULL, session_id INT NOT NULL, c_id INT DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
9
 *
10
 * Config setting:
11
 * $_configuration['allow_scheduled_announcements'] = true;
12
 *
13
 * Setup linux cron file:
14
 * main/cron/scheduled_announcement.php
15
 *
16
 * Requires:
17
 * composer update
18
 *
19
 * @package chamilo.library
20
 */
21
class ScheduledAnnouncement extends Model
22
{
23
    public $table;
24
    public $columns = array('id', 'subject', 'message', 'date', 'sent', 'session_id');
25
26
    /**
27
     * Constructor
28
     */
29
    public function __construct()
30
    {
31
        parent::__construct();
32
        $this->table = 'scheduled_announcements';
33
    }
34
35
    /**
36
     * @param array $where_conditions
37
     *
38
     * @return array
39
     */
40
    public function get_all($where_conditions = array())
41
    {
42
        return Database::select(
43
            '*',
44
            $this->table,
45
            array('where' => $where_conditions, 'order' => 'subject ASC')
46
        );
47
    }
48
49
    /**
50
     * @return mixed
51
     */
52
    public function get_count()
53
    {
54
        $row = Database::select(
55
            'count(*) as count',
56
            $this->table,
57
            array(),
58
            'first'
59
        );
60
61
        return $row['count'];
62
    }
63
64
    /**
65
     * Displays the title + grid
66
     */
67
    public function getGrid($sessionId)
68
    {
69
        // action links
70
        $action = '<div class="actions" style="margin-bottom:20px">';
71
        $action .= Display::url(
72
            Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM),
73
            api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$sessionId
74
        );
75
76
        $action .= '<a href="'.api_get_self().'?action=add&session_id='.$sessionId.'">'.
77
            Display::return_icon('add.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
78
        $action .= '<a href="scheduled_announcement.php?action=run&session_id='.$sessionId.'">'.
79
            Display::return_icon('mail_send.png', get_lang('Send'), '', ICON_SIZE_MEDIUM).
80
            '</a>';
81
82
        $action .= '</div>';
83
84
        $html = $action;
85
        $html .= '<div id="session-table" class="table-responsive">';
86
        $html .= Display::grid_html('programmed');
87
        $html .= '</div>';
88
89
        return $html;
90
    }
91
92
    /**
93
     * Returns a Form validator Obj
94
     * @param   string  $url
95
     * @param   string  $action add, edit
96
     *
97
     * @return  FormValidator form validator obj
98
     */
99
    public function returnSimpleForm($url, $action, $sessionInfo = [])
100
    {
101
        $form = new FormValidator(
102
            'announcement',
103
            'post',
104
            $url
105
        );
106
107
        $form->addHidden('session_id', $sessionInfo['id']);
108
        $form->addDateTimePicker('date', get_lang('Date'));
109
        $form->addText('subject', get_lang('Subject'));
110
        $form->addHtmlEditor('message', get_lang('Message'));
111
        $this->setTagsInForm($form);
112
113
        $form->addCheckBox('sent', null, get_lang('MessageSent'));
114
115
        if ($action == 'edit') {
116
            $form->addButtonUpdate(get_lang('Modify'));
117
        }
118
119
        return $form;
120
    }
121
122
    /**
123
     * @param FormValidator $form
124
     */
125
    private function setTagsInForm(& $form)
126
    {
127
        $form->addLabel(
128
            get_lang('Tags'),
129
            Display::return_message(
130
                implode('<br />', $this->getTags()),
131
                'normal',
132
                false
133
            )
134
        );
135
    }
136
137
    /**
138
     * Returns a Form validator Obj
139
     * @todo the form should be auto generated
140
     * @param   string  $url
141
     * @param   string  $action add, edit
142
     * @param array
143
     * @return  FormValidator form validator obj
144
     */
145
    public function returnForm($url, $action, $sessionInfo = [])
146
    {
147
        // Setting the form elements
148
        $header = get_lang('Add');
149
150
        if ($action == 'edit') {
151
            $header = get_lang('Modify');
152
        }
153
154
        $form = new FormValidator(
155
            'announcement',
156
            'post',
157
            $url
158
        );
159
160
        $form->addHeader($header);
161
        if ($action == 'add') {
162
            $form->addHtml(
163
                Display::return_message(
164
                    nl2br(get_lang('ScheduleAnnouncementDescription')),
165
                    'normal',
166
                    false
167
                )
168
            );
169
        }
170
        $form->addHidden('session_id', $sessionInfo['id']);
171
172
        $useBaseDate = false;
173
        $startDate = $sessionInfo['access_start_date'];
174
        $endDate = $sessionInfo['access_end_date'];
175
176
        if (!empty($startDate) || !empty($endDate)) {
177
            $useBaseDate = true;
178
        }
179
180
        $typeOptions = [
181
            'specific_date' => get_lang('SpecificDate')
182
        ];
183
184
        if ($useBaseDate) {
185
            $typeOptions['base_date'] = get_lang('BaseDate');
186
        }
187
188
        $form->addSelect(
189
            'type',
190
            get_lang('Type'),
191
            $typeOptions,
192
            [
193
                'onchange' => "javascript: 
194
                    if (this.options[this.selectedIndex].value == 'base_date') {
195
                        document.getElementById('options').style.display = 'block';
196
                        document.getElementById('specific_date').style.display = 'none';
197
                    } else {
198
                        document.getElementById('options').style.display = 'none';
199
                        document.getElementById('specific_date').style.display = 'block';
200
                    }
201
            "]
202
        );
203
204
        $form->addElement('html', '<div id="specific_date">');
205
        $form->addDateTimePicker('date', get_lang('Date'));
206
        $form->addElement('html', '</div>');
207
        $form->addElement('html', '<div id="options" style="display:none">');
208
209
        $startDate = $sessionInfo['access_start_date'];
210
        $endDate = $sessionInfo['access_end_date'];
211
212
        $form->addText(
213
            'days',
214
            get_lang('Days'),
215
            false
216
        );
217
218
        $form->addSelect(
219
            'moment_type',
220
            get_lang('AfterOrBefore'),
221
            [
222
                'after' => get_lang('After'),
223
                'before' => get_lang('Before'),
224
            ]
225
        );
226
227
        if (!empty($startDate)) {
228
            $options['start_date'] = get_lang('StartDate').' - '.$startDate;
229
        }
230
231
        if (!empty($endDate)) {
232
            $options['end_date'] = get_lang('EndDate').' - '.$endDate;
233
        }
234
        if (!empty($options)) {
235
            $form->addSelect('base_date', get_lang('BaseDate'), $options);
236
        }
237
238
        $form->addElement('html', '</div>');
239
240
        $form->addText('subject', get_lang('Subject'));
241
        $form->addHtmlEditor('message', get_lang('Message'));
242
        $this->setTagsInForm($form);
243
244
        if ($action == 'edit') {
245
            $form->addButtonUpdate(get_lang('Modify'));
246
        } else {
247
            $form->addButtonCreate(get_lang('Add'));
248
        }
249
250
        return $form;
251
    }
252
253
    /**
254
     * @return int
255
     */
256
    public function sendPendingMessages()
257
    {
258
        if (!$this->allowed()) {
259
            return 0;
260
        }
261
262
        $messagesSent = 0;
263
        $now = api_get_utc_datetime();
264
        $courseCode = api_get_course_id();
265
        $result = $this->get_all();
266
267
        foreach ($result as $result) {
268
            if (empty($result['sent'])) {
269
                if (!empty($result['date']) && $result['date'] < $now) {
270
                    $sessionId = $result['session_id'];
271
                    $sessionInfo = api_get_session_info($sessionId);
272
                    self::update(['id' => $result['id'], 'sent' => 1]);
273
                    $users = SessionManager::get_users_by_session(
274
                        $sessionId,
275
                        0
276
                    );
277
                    $subject = $result['subject'];
278
                    $message = $result['message'];
279
280
                    if ($users) {
281
                        foreach ($users as $user) {
0 ignored issues
show
Bug introduced by
The expression $users of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
282
                            $userInfo = api_get_user_info($user['user_id']);
283
                            $progress = Tracking::get_avg_student_progress(
284
                                $user['user_id'],
285
                                $courseCode,
286
                                null,
287
                                $sessionId
288
                            );
289
290
                            if (is_numeric($progress)) {
291
                                $progress = $progress.'%';
292
                            } else {
293
                                $progress = '0%';
294
                            }
295
296
                            $startTime = api_get_local_time(
297
                                $sessionInfo['access_start_date'],
298
                                null,
299
                                null,
300
                                true
301
                            );
302
                            $endTime = api_get_local_time(
303
                                $sessionInfo['access_end_date'],
304
                                null,
305
                                null,
306
                                true
307
                            );
308
309
                            $generalCoach = '';
310
                            $generalCoachEmail = '';
311
                            if (!empty($sessionInfo['coach_id'])) {
312
                                $coachInfo = api_get_user_info($sessionInfo['coach_id']);
313
                                if (!empty($coachInfo)) {
314
                                    $generalCoach = $coachInfo['complete_name'];
315
                                    $generalCoachEmail = $coachInfo['email'];
316
                                }
317
                            }
318
                            $tags = [
319
                                '((session_name))' => $sessionInfo['name'],
320
                                '((session_start_date))' => $startTime,
321
                                '((general_coach))' => $generalCoach,
322
                                '((general_coach_email))' => $generalCoachEmail,
323
                                '((session_end_date))' => $endTime,
324
                                '((user_complete_name))' => $userInfo['complete_name'],
325
                                '((user_first_name))' => $userInfo['firstname'],
326
                                '((user_last_name))' => $userInfo['lastname'],
327
                                '((lp_progress))' => $progress,
328
                            ];
329
330
                            $message = str_replace(array_keys($tags), $tags, $message);
331
332
                            MessageManager::send_message(
333
                                $user['user_id'],
334
                                $subject,
335
                                $message
336
                            );
337
                        }
338
                    }
339
340
                    $messagesSent++;
341
                }
342
            }
343
        }
344
345
        return $messagesSent;
346
    }
347
348
    /**
349
     * @return array
350
     */
351 View Code Duplication
    public function getTags()
352
    {
353
        $tags = [
354
            '((session_name))',
355
            '((session_start_date))',
356
            '((session_end_date))',
357
            '((general_coach))',
358
            '((general_coach_email))',
359
            '((user_complete_name))',
360
            '((user_first_name))',
361
            '((user_last_name))',
362
            '((lp_progress))'
363
        ];
364
365
        return $tags;
366
    }
367
368
    /**
369
     * @return bool
370
     */
371
    public function allowed()
372
    {
373
        return api_get_configuration_value('allow_scheduled_announcements');
374
    }
375
}
376