Issues (896)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/class-sensei-emails.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Transactional Emails Controller
4
 *
5
 * Sensei Emails Class which handles the sending emails and email templates. This class loads in available emails.
6
 *
7
 * @package Users
8
 * @author Automattic
9
 */
10
class Sensei_Emails {
11
12
	/**
13
	 * @var array Array of email notification classes.
14
	 * @access public
15
	 */
16
	public $emails;
17
18
	/**
19
	 * @var string Stores the emailer's address.
20
	 * @access private
21
	 */
22
	private $_from_address;
23
24
	/**
25
	 * @var string Stores the emailer's name.
26
	 * @access private
27
	 */
28
	private $_from_name;
29
30
	/**
31
	 * @var mixed Content type for sent emails
32
	 * @access private
33
	 */
34
	private $_content_type;
35
36
	/**
37
	 * Constructor for the email class hooks in all emails that can be sent.
38
	 */
39
	function __construct( $file ) {
40
41
		$this->init();
42
43
		// Hooks for sending emails during Sensei events
44
		add_action( 'sensei_user_quiz_grade', array( $this, 'learner_graded_quiz' ), 10, 4 );
45
		add_action( 'sensei_course_status_updated', array( $this, 'learner_completed_course' ), 10, 4 );
46
		add_action( 'sensei_course_status_updated', array( $this, 'teacher_completed_course' ), 10, 4 );
47
		add_action( 'sensei_user_course_start', array( $this, 'teacher_started_course' ), 10, 2 );
48
        add_action( 'sensei_user_lesson_end', array( $this, 'teacher_completed_lesson' ), 10, 2 );
49
		add_action( 'sensei_user_quiz_submitted', array( $this, 'teacher_quiz_submitted' ), 10, 5 );
50
		add_action( 'sensei_new_private_message', array( $this, 'teacher_new_message' ), 10, 1 );
51
		add_action( 'sensei_private_message_reply', array( $this, 'new_message_reply' ), 10, 2 );
52
53
		// Let 3rd parties unhook the above via this hook
54
		do_action( 'sensei_emails', $this );
55
	}
56
57
	/**
58
	 * Init email classes
59
	 */
60
	function init() {
61
62
		$this->emails['learner-graded-quiz'] = include( 'emails/class-woothemes-sensei-email-learner-graded-quiz.php' );
63
		$this->emails['learner-completed-course'] = include( 'emails/class-woothemes-sensei-email-learner-completed-course.php' );
64
		$this->emails['teacher-completed-course'] = include( 'emails/class-woothemes-sensei-email-teacher-completed-course.php' );
65
        $this->emails['teacher-started-course'] = include( 'emails/class-woothemes-sensei-email-teacher-started-course.php' );
66
        $this->emails['teacher-completed-lesson'] = include( 'emails/class-woothemes-sensei-email-teacher-completed-lesson.php' );
67
        $this->emails['teacher-quiz-submitted'] = include( 'emails/class-woothemes-sensei-email-teacher-quiz-submitted.php' );
68
		$this->emails['teacher-new-message'] = include( 'emails/class-woothemes-sensei-email-teacher-new-message.php' );
69
		$this->emails['new-message-reply'] = include( 'emails/class-woothemes-sensei-email-new-message-reply.php' );
70
		$this->emails = apply_filters( 'sensei_email_classes', $this->emails );
71
	}
72
73
	/**
74
	 * Return the email classes - used in admin to load settings.
75
	 *
76
	 * @access public
77
	 * @return array
78
	 */
79
	function get_emails() {
80
		return $this->emails;
81
	}
82
83
	/**
84
	 * Get from name for email.
85
	 *
86
	 * @access public
87
	 * @return string
88
	 */
89 View Code Duplication
	function get_from_name() {
90
91
92
		if ( ! $this->_from_name ) {
93
			if( isset( Sensei()->settings->settings['email_from_name'] ) && '' != Sensei()->settings->settings['email_from_name'] ) {
94
				$this->_from_name = Sensei()->settings->settings['email_from_name'];
95
			} else {
96
				$this->_from_name = get_bloginfo( 'name' );
97
			}
98
		}
99
100
		return wp_specialchars_decode( $this->_from_name );
101
	}
102
103
	/**
104
	 * Get from email address.
105
	 *
106
	 * @access public
107
	 * @return string
108
	 */
109 View Code Duplication
	function get_from_address() {
110
111
112
		if ( ! $this->_from_address ) {
113
			if( isset( Sensei()->settings->settings['email_from_address'] ) && '' != Sensei()->settings->settings['email_from_address'] ) {
114
				$this->_from_address = Sensei()->settings->settings['email_from_address'];
115
			} else {
116
				$this->_from_address = get_bloginfo( 'admin_email' );
117
			}
118
		}
119
120
		return $this->_from_address;
121
	}
122
123
	/**
124
	 * Get the content type for the email.
125
	 *
126
	 * @access public
127
	 * @return string
128
	 */
129
	function get_content_type() {
130
		return $this->_content_type;
131
	}
132
133
	/**
134
	 * Wraps a message in the sensei mail template.
135
	 *
136
	 * @access public
137
	 * @param mixed $content
138
	 * @return string
139
	 */
140
	function wrap_message( $content ) {
141
142
		$html = '';
143
144
		$html .= $this->load_template( 'header' );
145
		$html .= wpautop( wptexturize( $content ) );
146
		$html .= $this->load_template( 'footer' );
147
148
		return $html;
149
	}
150
151
	/**
152
	 * Send the email.
153
	 *
154
	 * @access public
155
	 * @param mixed $to
156
	 * @param mixed $subject
157
	 * @param mixed $message
158
	 * @param string $headers (default: "Content-Type: text/html\r\n")
159
	 * @param string $attachments (default: "")
160
	 * @param string $content_type (default: "text/html")
161
	 * @return void
162
	 */
163
	function send( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = "", $content_type = 'text/html' ) {
164
		global $email_template;
165
166
		// Set content type
167
		$this->_content_type = $content_type;
168
169
		// Filters for the email
170
		add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
171
		add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
172
		add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
173
174
        // Send
175
        $send_email = true;
176
177
        /**
178
         * Filter Sensei's ability to send out emails.
179
         *
180
         * @since 1.8.0
181
         * @param bool $send_email default true
182
         */
183
        if( apply_filters('sensei_send_emails', $send_email,$to, $subject, $message )  ){
184
185
            wp_mail( $to, $subject, $message, $headers, $attachments );
186
187
        }
188
189
		// Unhook filters
190
		remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
191
		remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
192
		remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
193
	}
194
195
	function get_content( $email_template ) {
196
197
		$message = $this->load_template( $email_template );
198
199
		$html = $this->wrap_message( $message );
200
201
		return apply_filters( 'sensei_email', $html, $email_template );
202
	}
203
204
	function load_template( $template = '' ) {
205
		global  $email_template;
206
207
		if( ! $template ) return;
208
209
		$email_template = $template . '.php';
210
		$template = Sensei_Templates::template_loader( '' );
211
212
		ob_start();
213
214
		do_action( 'sensei_before_email_template', $email_template );
215
		include( $template );
216
		do_action( 'sensei_after_email_template', $email_template );
217
218
		return ob_get_clean();
219
	}
220
221
	/**
222
	 * Send email to learner on quiz grading (auto or manual)
223
	 *
224
	 * @access public
225
	 * @return void
226
	 */
227
	function learner_graded_quiz( $user_id, $quiz_id, $grade, $passmark ) {
228
229
230
		$send = false;
231
232
		if( isset( Sensei()->settings->settings['email_learners'] ) ) {
233
			if( in_array( 'learner-graded-quiz', (array) Sensei()->settings->settings['email_learners'] ) ) {
234
				$send = true;
235
			}
236
		} else {
237
			$send = true;
238
		}
239
240
		if( $send ) {
241
			$email = $this->emails['learner-graded-quiz'];
242
			$email->trigger( $user_id, $quiz_id, $grade, $passmark );
243
		}
244
	}
245
246
	/**
247
	 * Send email to learner on course completion
248
	 *
249
	 * @access public
250
	 * @return void
251
	 */
252 View Code Duplication
	function learner_completed_course( $status = 'in-progress', $user_id = 0, $course_id = 0, $comment_id = 0 ) {
253
254
255
		if( 'complete' != $status ) {
256
			return;
257
		}
258
259
		$send = false;
260
261
		if( isset( Sensei()->settings->settings['email_learners'] ) ) {
262
			if( in_array( 'learner-completed-course', (array) Sensei()->settings->settings['email_learners'] ) ) {
263
				$send = true;
264
			}
265
		} else {
266
			$send = true;
267
		}
268
269
		if( $send ) {
270
			$email = $this->emails['learner-completed-course'];
271
			$email->trigger( $user_id, $course_id );
272
		}
273
	}
274
275
	/**
276
	 * Send email to teacher on course completion
277
	 *
278
	 * @access public
279
	 * @return void
280
	 */
281 View Code Duplication
	function teacher_completed_course( $status = 'in-progress', $learner_id = 0, $course_id = 0, $comment_id = 0 ) {
282
283
284
		if( 'complete' != $status ) {
285
			return;
286
		}
287
288
		$send = false;
289
290
		if( isset( Sensei()->settings->settings['email_teachers'] ) ) {
291
			if( in_array( 'teacher-completed-course', (array) Sensei()->settings->settings['email_teachers'] ) ) {
292
				$send = true;
293
			}
294
		} else {
295
			$send = true;
296
		}
297
298
		if( $send ) {
299
			$email = $this->emails['teacher-completed-course'];
300
			$email->trigger( $learner_id, $course_id );
301
		}
302
	}
303
304
	/**
305
	 * Send email to teacher on course beginning
306
	 *
307
	 * @access public
308
	 * @return void
309
	 */
310 View Code Duplication
	function teacher_started_course( $learner_id = 0, $course_id = 0 ) {
311
312
313
		$send = false;
314
315
		if( isset( Sensei()->settings->settings['email_teachers'] ) ) {
316
			if( in_array( 'teacher-started-course', (array) Sensei()->settings->settings['email_teachers'] ) ) {
317
				$send = true;
318
			}
319
		} else {
320
			$send = true;
321
		}
322
323
		if( $send ) {
324
			$email = $this->emails['teacher-started-course'];
325
			$email->trigger( $learner_id, $course_id );
326
		}
327
	}
328
329
    /**
330
     * teacher_completed_lesson()
331
     *
332
     * Send email to teacher on student completing lesson
333
     *
334
     * @access public
335
     * @return void
336
     * @since 1.9.0
337
     */
338 View Code Duplication
    function teacher_completed_lesson( $learner_id = 0, $lesson_id = 0 ) {
339
340
341
        $send = false;
342
343
        if( isset( Sensei()->settings->settings[ 'email_teachers' ] ) ) {
344
            if( in_array( 'teacher-completed-lesson', (array) Sensei()->settings->settings[ 'email_teachers' ]) ) {
345
                $send = true;
346
            }
347
        } else {
348
            $send = true;
349
        }
350
351
        if( $send ) {
352
            $email = $this->emails['teacher-completed-lesson'];
353
            $email->trigger( $learner_id, $lesson_id );
354
        }
355
    }
356
357
	/**
358
	 * Send email to teacher on quiz submission
359
	 *
360
	 *
361
     * @param int $learner_id
362
     * @param int $quiz_id
363
     * @param int $grade
364
     * @param int $passmark
365
     * @param string $quiz_grade_type
366
     */
367 View Code Duplication
	function teacher_quiz_submitted( $learner_id = 0, $quiz_id = 0, $grade = 0, $passmark = 0, $quiz_grade_type = 'manual' ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
368
369
		$send = false;
370
371
		// Only trigger if the quiz was marked as manual grading, or auto grading didn't complete
372
		if( 'manual' == $quiz_grade_type || is_wp_error( $grade ) ) {
373
			if( isset( Sensei()->settings->settings['email_teachers'] ) ) {
374
				if( in_array( 'teacher-quiz-submitted', (array) Sensei()->settings->settings['email_teachers'] ) ) {
375
					$send = true;
376
				}
377
			} else {
378
				$send = true;
379
			}
380
381
			if( $send ) {
382
				$email = $this->emails['teacher-quiz-submitted'];
383
				$email->trigger( $learner_id, $quiz_id );
384
			}
385
386
		}
387
	}
388
389
	/**
390
	 * Send email to teacher when a new private message is received
391
	 *
392
	 * @access public
393
	 * @return void
394
	 */
395 View Code Duplication
	function teacher_new_message( $message_id = 0 ) {
396
397
		$send = false;
398
399
		if( isset( Sensei()->settings->settings['email_teachers'] ) ) {
400
			if( in_array( 'teacher-new-message', (array) Sensei()->settings->settings['email_teachers'] ) ) {
401
				$send = true;
402
			}
403
		} else {
404
			$send = true;
405
		}
406
407
		if( $send ) {
408
			$email = $this->emails['teacher-new-message'];
409
			$email->trigger( $message_id );
410
		}
411
	}
412
413
	/**
414
	 * Send email to a user when their private message receives a reply
415
	 *
416
	 * @access public
417
	 * @return void
418
	 */
419 View Code Duplication
	function new_message_reply( $comment, $message ) {
420
421
		$send = false;
422
423
		if( isset( Sensei()->settings->settings['email_global'] ) ) {
424
			if( in_array( 'new-message-reply', (array) Sensei()->settings->settings['email_global'] ) ) {
425
				$send = true;
426
			}
427
		} else {
428
			$send = true;
429
		}
430
431
		if( $send ) {
432
			$email = $this->emails['new-message-reply'];
433
			$email->trigger( $comment, $message );
434
		}
435
	}
436
437
}//end class
438
439
/**
440
 * Class WooThemes_Sensei_Emails
441
 * @ignore only for backward compatibility
442
 * @since 1.9.0
443
 */
444
class WooThemes_Sensei_Emails extends Sensei_Emails{}
445