This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace samsoncms\newsletter; |
||
4 | |||
5 | use samson\activerecord\email_distribution; |
||
6 | use samson\activerecord\email_letter; |
||
7 | use samson\activerecord\email_template; |
||
8 | use samson\core\SamsonLocale; |
||
9 | |||
10 | class Application extends \samsoncms\Application |
||
11 | { |
||
12 | /** @var string Module identifier */ |
||
13 | protected $id = 'newsletter'; |
||
14 | |||
15 | /** @var string Entity class name */ |
||
16 | protected $entity = '\samson\activerecord\email_distribution'; |
||
17 | |||
18 | /** Application name */ |
||
19 | public $name = 'Newsletter'; |
||
20 | |||
21 | /** Application description */ |
||
22 | public $description = 'Newsletter distribution management'; |
||
23 | |||
24 | /** @var string $icon Icon class */ |
||
25 | public $icon = 'envelope'; |
||
26 | |||
27 | public $hide = false; |
||
28 | |||
29 | /** |
||
30 | * Prepare DB for application settings |
||
31 | * @return mixed |
||
32 | */ |
||
33 | public function prepare() |
||
34 | { |
||
35 | db()->execute( |
||
36 | " |
||
37 | CREATE TABLE IF NOT EXISTS `email_distribution` ( |
||
38 | `distribution_id` int(11) NOT NULL AUTO_INCREMENT, |
||
39 | `template_id` int(11) NOT NULL, |
||
40 | `status` int(11) DEFAULT '0', |
||
41 | `recipient_count` int(11) DEFAULT '0', |
||
42 | `bounce_count` int(11) DEFAULT '0', |
||
43 | `open_count` int(11) DEFAULT '0', |
||
44 | `click_count` int(11) DEFAULT '0', |
||
45 | `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||
46 | `finished` datetime NOT NULL, |
||
47 | `active` int(11) NOT NULL DEFAULT '0', |
||
48 | PRIMARY KEY (`distribution_id`) |
||
49 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; |
||
50 | " |
||
51 | ); |
||
52 | |||
53 | db()->execute( |
||
54 | " |
||
55 | CREATE TABLE IF NOT EXISTS `email_letter` ( |
||
56 | `letter_id` int(11) NOT NULL AUTO_INCREMENT, |
||
57 | `distribution_id` int(11) NOT NULL, |
||
58 | `template_id` int(11) NOT NULL, |
||
59 | `recipient` varchar(50) NOT NULL, |
||
60 | `status` int(11) DEFAULT '0', |
||
61 | `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||
62 | PRIMARY KEY (`letter_id`) |
||
63 | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; |
||
64 | " |
||
65 | ); |
||
66 | |||
67 | db()->execute( |
||
68 | " |
||
69 | CREATE TABLE IF NOT EXISTS `email_template` ( |
||
70 | `template_id` int(11) NOT NULL AUTO_INCREMENT, |
||
71 | `content` text NOT NULL, |
||
72 | `locale` varchar(5) NOT NULL DEFAULT 'en', |
||
73 | `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, |
||
74 | PRIMARY KEY (`template_id`) |
||
75 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; |
||
76 | " |
||
77 | ); |
||
78 | |||
79 | return parent::prepare(); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Universal controller action. |
||
84 | * Entity collection rendering |
||
85 | */ |
||
86 | public function __template() |
||
87 | { |
||
88 | $description = t($this->description, true); |
||
89 | $name = t($this->description, true); |
||
90 | $letter = $this->createLetter('HEADER', 'MESSAGE'); |
||
91 | |||
92 | // Prepare view |
||
93 | $this->title($description) |
||
94 | ->view('form') |
||
95 | ->set('name', $name) |
||
96 | ->set('icon', $this->icon) |
||
97 | ->set('letter', $letter) |
||
98 | ->set('description', $description) |
||
99 | ; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Save number of email opens |
||
104 | * @param int $distribution_id Distribution identifier |
||
105 | */ |
||
106 | public function __openaction($distribution_id) |
||
107 | { |
||
108 | /** @var email_distribution $distribution */ |
||
109 | $distribution = null; |
||
110 | if ($this->query->entity('email_distribution')->where('distribution_id', $distribution_id)->first($distribution)) { |
||
111 | $distribution->open_count ++; |
||
0 ignored issues
–
show
|
|||
112 | $distribution->save(); |
||
113 | } |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * Save number of email clicks |
||
118 | * @param int $distribution_id Distribution identifier |
||
119 | * @param string $params |
||
120 | */ |
||
121 | public function __clickaction($distribution_id, $params = '') |
||
122 | { |
||
123 | /** @var email_distribution $distribution */ |
||
124 | $distribution = null; |
||
125 | if ($this->query->entity('email_distribution')->where('distribution_id', $distribution_id)->first($distribution)) { |
||
126 | $distribution->click_count ++; |
||
0 ignored issues
–
show
Accessing
click_count on the interface samsonframework\orm\RecordInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
If you access a property on an interface, you most likely code against a concrete implementation of the interface. Available Fixes
![]() |
|||
127 | $distribution->save(); |
||
128 | |||
129 | $params = explode('-', $params); |
||
130 | $url = 'http://'.$_SERVER['HTTP_HOST'].'/'; |
||
131 | if (sizeof($params)) { |
||
132 | foreach ($params as $param) { |
||
133 | $url .= $param.'/'; |
||
134 | } |
||
135 | } |
||
136 | |||
137 | header('Location: '.$url);die; |
||
0 ignored issues
–
show
|
|||
138 | } |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * Show template content |
||
143 | * @param int $id Template identifier |
||
144 | * @return array |
||
145 | */ |
||
146 | public function __async_templates($id) |
||
0 ignored issues
–
show
|
|||
147 | { |
||
148 | /** @var $this->entity $outfit */ |
||
0 ignored issues
–
show
The doc-type
$this->entity could not be parsed: Unknown type name "$this-" at position 0. (view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. ![]() |
|||
149 | $template = null; |
||
150 | $response = array('status' => 0, 'popup' => ''); |
||
151 | if ($this->query->entity('email_template')->where('template_id', $id)->first($template)) { |
||
152 | $response['popup'] = $this->view('template/popup')->content($template->content)->output(); |
||
0 ignored issues
–
show
Accessing
content on the interface samsonframework\orm\RecordInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
If you access a property on an interface, you most likely code against a concrete implementation of the interface. Available Fixes
![]() The method
content does not exist on object<samsoncms\newsletter\Application> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
153 | $response['status'] = 1; |
||
154 | } |
||
155 | |||
156 | return $response; |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * Create template content |
||
161 | * @param string $header Email Header |
||
162 | * @param string $message Email text |
||
163 | * @return string |
||
164 | */ |
||
165 | public function createLetter($header, $message) |
||
166 | { |
||
167 | return '<h1>'.$header.'</h1><br><div>'.$message.'</div>'; |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * @param int $preview Flag - send letters or no |
||
172 | * @return array |
||
173 | */ |
||
174 | public function __async_make($preview = 0) |
||
0 ignored issues
–
show
|
|||
175 | { |
||
176 | $recipients = explode(',', $_POST['recipients']); |
||
177 | |||
178 | $letters = array(); |
||
179 | foreach (SamsonLocale::$locales as $locale) { |
||
180 | if (isset($_POST['header-'.$locale]) && isset($_POST['message-'.$locale])) { |
||
181 | $letters[$locale] = $this->createLetter($_POST['header-'.$locale], $_POST['message-'.$locale]); |
||
182 | } |
||
183 | } |
||
184 | |||
185 | if (!$preview) { |
||
186 | $templates = array(); |
||
187 | |||
188 | foreach ($letters as $locale => $letter) { |
||
189 | $template = new email_template(); |
||
190 | $template->content = $letter; |
||
191 | $template->locale = $locale; |
||
192 | $template->save(); |
||
193 | $templates[$locale] = $template; |
||
194 | } |
||
195 | |||
196 | $distribution = new email_distribution(); |
||
197 | $distribution->template_id = $templates[SamsonLocale::$defaultLocale]->template_id; |
||
198 | $distribution->recipient_count = sizeof($recipients); |
||
199 | $distribution->active = 1; |
||
200 | $distribution->save(); |
||
201 | // Send emails to all users from POST array |
||
202 | foreach ($recipients as $recipient) { |
||
203 | $emailLetter = new email_letter(); |
||
204 | $emailLetter->distribution_id = $distribution->distribution_id; |
||
205 | $emailLetter->recipient = trim($recipient); |
||
206 | $emailLetter->template_id = $templates[SamsonLocale::$defaultLocale]->template_id; |
||
207 | $emailLetter->save(); |
||
208 | } |
||
209 | } |
||
210 | |||
211 | return array('status' => 1, 'preview' => $letters[SamsonLocale::$defaultLocale]); |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Send manual newsletters |
||
216 | */ |
||
217 | public function __manual() |
||
218 | { |
||
219 | foreach ($this->query->entity('email_letter')->where('status', 0)->exec() as $letter) { |
||
0 ignored issues
–
show
The expression
$this->query->entity('em...re('status', 0)->exec() of type boolean|array<integer,ob...k\orm\RecordInterface>> is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
220 | $template = $this->query->entity('email_template')->where('template_id', $letter->template_id)->first(); |
||
221 | $message = $template->content; |
||
222 | $img = '<img width="1" height="1" src="'.url()->build('newsletter/openaction/'.$letter->distribution_id).'">'; |
||
223 | $message .= $img; |
||
224 | $message = str_replace('clickaction/', 'clickaction/'.$letter->distribution_id.'/', $message); |
||
225 | $this->sendEmail($message, $letter->recipient); |
||
226 | $letter->status = 1; |
||
227 | $letter->save(); |
||
228 | } |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * @param string $letter Letter html content |
||
233 | * @param string $recipient email recipient |
||
234 | * @param string $from Sender email |
||
235 | * @param string $subject Email subject |
||
236 | * @param string $user Sender name |
||
237 | */ |
||
238 | public function sendEmail($letter, $recipient = '', $from = '', $subject = '', $user = '') |
||
239 | { |
||
240 | mail_send($recipient, $from, $letter, $subject, $user); |
||
241 | } |
||
242 | } |
||
243 |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: