Version Description
- Fixed access control on form manager base class
Download this release
Release Info
Developer | satollo |
Plugin | Newsletter |
Version | 7.5.5 |
Comparing to | |
See all releases |
Code changes from version 7.5.4 to 7.5.5
- includes/addon.php +396 -396
- plugin.php +2 -2
- profile/profile.php +494 -494
- readme.txt +5 -1
includes/addon.php
CHANGED
@@ -1,396 +1,396 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* User by add-ons as base-class.
|
5 |
-
*/
|
6 |
-
class NewsletterAddon {
|
7 |
-
|
8 |
-
var $logger;
|
9 |
-
var $admin_logger;
|
10 |
-
var $name;
|
11 |
-
var $options;
|
12 |
-
var $version;
|
13 |
-
var $labels;
|
14 |
-
|
15 |
-
public function __construct($name, $version = '0.0.0') {
|
16 |
-
$this->name = $name;
|
17 |
-
$this->version = $version;
|
18 |
-
if (is_admin()) {
|
19 |
-
$old_version = get_option('newsletter_' . $name . '_version');
|
20 |
-
if ($version !== $old_version) {
|
21 |
-
$this->upgrade($old_version === false);
|
22 |
-
update_option('newsletter_' . $name . '_version', $version, false);
|
23 |
-
}
|
24 |
-
}
|
25 |
-
add_action('newsletter_init', array($this, 'init'));
|
26 |
-
//Load translations from specific addon /languages/ directory
|
27 |
-
load_plugin_textdomain('newsletter-' . $this->name, false, 'newsletter-' . $this->name . '/languages/');
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Method to be overridden and invoked on version change or on first install.
|
32 |
-
*
|
33 |
-
* @param bool $first_install
|
34 |
-
*/
|
35 |
-
function upgrade($first_install = false) {
|
36 |
-
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Method to be overridden to initialize the add-on. It is invoked when Newsletter
|
41 |
-
* fires the <code>newsletter_init</code> event.
|
42 |
-
*/
|
43 |
-
function init() {
|
44 |
-
|
45 |
-
}
|
46 |
-
|
47 |
-
function get_current_language() {
|
48 |
-
return Newsletter::instance()->get_current_language();
|
49 |
-
}
|
50 |
-
|
51 |
-
function is_all_languages() {
|
52 |
-
return Newsletter::instance()->is_all_languages();
|
53 |
-
}
|
54 |
-
|
55 |
-
function is_allowed() {
|
56 |
-
return Newsletter::instance()->is_allowed();
|
57 |
-
}
|
58 |
-
|
59 |
-
function get_languages() {
|
60 |
-
return Newsletter::instance()->get_languages();
|
61 |
-
}
|
62 |
-
|
63 |
-
function is_multilanguage() {
|
64 |
-
return Newsletter::instance()->is_multilanguage();
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* General logger for this add-on.
|
69 |
-
*
|
70 |
-
* @return NewsletterLogger
|
71 |
-
*/
|
72 |
-
function get_logger() {
|
73 |
-
if (!$this->logger) {
|
74 |
-
$this->logger = new NewsletterLogger($this->name);
|
75 |
-
}
|
76 |
-
return $this->logger;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Specific logger for administrator actions.
|
81 |
-
*
|
82 |
-
* @return NewsletterLogger
|
83 |
-
*/
|
84 |
-
function get_admin_logger() {
|
85 |
-
if (!$this->admin_logger) {
|
86 |
-
$this->admin_logger = new NewsletterLogger($this->name . '-admin');
|
87 |
-
}
|
88 |
-
return $this->admin_logger;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Loads and prepares the options. It can be used to late initialize the options to save some resources on
|
93 |
-
* add-ons which do not need to do something on each page load.
|
94 |
-
*/
|
95 |
-
function setup_options() {
|
96 |
-
if ($this->options) {
|
97 |
-
return;
|
98 |
-
}
|
99 |
-
$this->options = get_option('newsletter_' . $this->name, []);
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Retrieve the stored options, merged with the specified language set.
|
104 |
-
*
|
105 |
-
* @param string $language
|
106 |
-
* @return array
|
107 |
-
*/
|
108 |
-
function get_options($language = '') {
|
109 |
-
if ($language) {
|
110 |
-
return array_merge(get_option('newsletter_' . $this->name, []), get_option('newsletter_' . $this->name . '_' . $language, []));
|
111 |
-
} else {
|
112 |
-
return get_option('newsletter_' . $this->name, []);
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Saved the options under the correct keys and update the internal $options
|
118 |
-
* property.
|
119 |
-
* @param array $options
|
120 |
-
*/
|
121 |
-
function save_options($options, $language = '') {
|
122 |
-
if ($language) {
|
123 |
-
update_option('newsletter_' . $this->name . '_' . $language, $options);
|
124 |
-
} else {
|
125 |
-
update_option('newsletter_' . $this->name, $options);
|
126 |
-
$this->options = $options;
|
127 |
-
}
|
128 |
-
}
|
129 |
-
|
130 |
-
function merge_defaults($defaults) {
|
131 |
-
$options = get_option('newsletter_' . $this->name, []);
|
132 |
-
$options = array_merge($defaults, $options);
|
133 |
-
$this->save_options($options);
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
*
|
138 |
-
*/
|
139 |
-
function setup_labels() {
|
140 |
-
if (!$this->labels) {
|
141 |
-
$labels = [];
|
142 |
-
}
|
143 |
-
}
|
144 |
-
|
145 |
-
function get_label($key) {
|
146 |
-
if (!$this->options)
|
147 |
-
$this->setup_options();
|
148 |
-
|
149 |
-
if (!empty($this->options[$key])) {
|
150 |
-
return $this->options[$key];
|
151 |
-
}
|
152 |
-
|
153 |
-
if (!$this->labels)
|
154 |
-
$this->setup_labels();
|
155 |
-
|
156 |
-
// We assume the required key is defined. If not there is an error elsewhere.
|
157 |
-
return $this->labels[$key];
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* Equivalent to $wpdb->query() but logs the event in case of error.
|
162 |
-
*
|
163 |
-
* @global wpdb $wpdb
|
164 |
-
* @param string $query
|
165 |
-
*/
|
166 |
-
function query($query) {
|
167 |
-
global $wpdb;
|
168 |
-
|
169 |
-
$r = $wpdb->query($query);
|
170 |
-
if ($r === false) {
|
171 |
-
$logger = $this->get_logger();
|
172 |
-
$logger->fatal($query);
|
173 |
-
$logger->fatal($wpdb->last_error);
|
174 |
-
}
|
175 |
-
return $r;
|
176 |
-
}
|
177 |
-
|
178 |
-
}
|
179 |
-
|
180 |
-
/**
|
181 |
-
* Used by mailer add-ons as base-class. Some specific options collected by the mailer
|
182 |
-
* are interpreted automatically.
|
183 |
-
*
|
184 |
-
* They are:
|
185 |
-
*
|
186 |
-
* `enabled` if not empty it means the mailer is active and should be registered
|
187 |
-
*
|
188 |
-
* The options are set up in the constructor, there is no need to setup them later.
|
189 |
-
*/
|
190 |
-
class NewsletterMailerAddon extends NewsletterAddon {
|
191 |
-
|
192 |
-
var $enabled = false;
|
193 |
-
var $menu_title = null;
|
194 |
-
var $menu_description = null;
|
195 |
-
var $dir = '';
|
196 |
-
|
197 |
-
function __construct($name, $version = '0.0.0', $dir = '') {
|
198 |
-
parent::__construct($name, $version);
|
199 |
-
$this->dir = $dir;
|
200 |
-
$this->setup_options();
|
201 |
-
$this->enabled = !empty($this->options['enabled']);
|
202 |
-
}
|
203 |
-
|
204 |
-
/**
|
205 |
-
* This method must be called as `parent::init()` is overridden.
|
206 |
-
*/
|
207 |
-
function init() {
|
208 |
-
parent::init();
|
209 |
-
add_action('newsletter_register_mailer', function () {
|
210 |
-
if ($this->enabled) {
|
211 |
-
Newsletter::instance()->register_mailer($this->get_mailer());
|
212 |
-
}
|
213 |
-
});
|
214 |
-
|
215 |
-
if (is_admin() && !empty($this->menu_title) && !empty($this->dir) && current_user_can('administrator')) {
|
216 |
-
add_action('admin_menu', [$this, 'hook_admin_menu'], 101);
|
217 |
-
add_filter('newsletter_menu_settings', [$this, 'hook_newsletter_menu_settings']);
|
218 |
-
}
|
219 |
-
}
|
220 |
-
|
221 |
-
function hook_newsletter_menu_settings($entries) {
|
222 |
-
$entries[] = array('label' => '<i class="fas fa-envelope"></i> ' . $this->menu_title, 'url' => '?page=newsletter_' . $this->name . '_index', 'description' => $this->menu_description);
|
223 |
-
return $entries;
|
224 |
-
}
|
225 |
-
|
226 |
-
function hook_admin_menu() {
|
227 |
-
add_submenu_page('newsletter_main_index', $this->menu_title, '<span class="tnp-side-menu">' . $this->menu_title . '</span>', 'manage_options', 'newsletter_' . $this->name . '_index',
|
228 |
-
function () {
|
229 |
-
require $this->dir . '/index.php';
|
230 |
-
}
|
231 |
-
);
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
* Must return an implementation of NewsletterMailer.
|
236 |
-
* @return NewsletterMailer
|
237 |
-
*/
|
238 |
-
function get_mailer() {
|
239 |
-
return null;
|
240 |
-
}
|
241 |
-
|
242 |
-
function get_last_run() {
|
243 |
-
return get_option('newsletter_' . $this->name . '_last_run', 0);
|
244 |
-
}
|
245 |
-
|
246 |
-
function save_last_run($time) {
|
247 |
-
update_option('newsletter_' . $this->name . '_last_run', $time);
|
248 |
-
}
|
249 |
-
|
250 |
-
function save_options($options, $language = '') {
|
251 |
-
parent::save_options($options, $language);
|
252 |
-
$this->enabled = !empty($options['enabled']);
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* Returns a TNP_Mailer_Message built to send a test message to the <code>$to</code>
|
257 |
-
* email address.
|
258 |
-
*
|
259 |
-
* @param string $to
|
260 |
-
* @param string $subject
|
261 |
-
* @return TNP_Mailer_Message
|
262 |
-
*/
|
263 |
-
static function get_test_message($to, $subject = '', $type = '') {
|
264 |
-
$message = new TNP_Mailer_Message();
|
265 |
-
$message->to = $to;
|
266 |
-
$message->to_name = '';
|
267 |
-
if (empty($type) || $type == 'html') {
|
268 |
-
$message->body = file_get_contents(NEWSLETTER_DIR . '/includes/test-message.html');
|
269 |
-
$message->body = str_replace('{plugin_url}', NEWSLETTER_URL, $message->body);
|
270 |
-
}
|
271 |
-
|
272 |
-
if (empty($type) || $type == 'text') {
|
273 |
-
$message->body_text = 'This is the TEXT version of a test message. You should see this message only if you email client does not support the rich text (HTML) version.';
|
274 |
-
}
|
275 |
-
|
276 |
-
$message->headers['X-Newsletter-Email-Id'] = '0';
|
277 |
-
|
278 |
-
if (empty($subject)) {
|
279 |
-
$message->subject = '[' . get_option('blogname') . '] Test message from Newsletter (' . date(DATE_ISO8601) . ')';
|
280 |
-
} else {
|
281 |
-
$message->subject = $subject;
|
282 |
-
}
|
283 |
-
|
284 |
-
if ($type) {
|
285 |
-
$message->subject .= ' - ' . $type . ' only';
|
286 |
-
}
|
287 |
-
|
288 |
-
$message->from = Newsletter::instance()->options['sender_email'];
|
289 |
-
$message->from_name = Newsletter::instance()->options['sender_name'];
|
290 |
-
return $message;
|
291 |
-
}
|
292 |
-
|
293 |
-
/**
|
294 |
-
* Returns a set of test messages to be sent to the specified email address. Used for
|
295 |
-
* turbo mode tests. Each message has a different generated subject.
|
296 |
-
*
|
297 |
-
* @param string $to The destination mailbox
|
298 |
-
* @param int $count Number of message objects to create
|
299 |
-
* @return TNP_Mailer_Message[]
|
300 |
-
*/
|
301 |
-
function get_test_messages($to, $count, $type = '') {
|
302 |
-
$messages = array();
|
303 |
-
for ($i = 0; $i < $count; $i++) {
|
304 |
-
$messages[] = self::get_test_message($to, '[' . get_option('blogname') . '] Test message ' . ($i + 1) . ' from Newsletter (' . date(DATE_ISO8601) . ')', $type);
|
305 |
-
}
|
306 |
-
return $messages;
|
307 |
-
}
|
308 |
-
|
309 |
-
}
|
310 |
-
|
311 |
-
class NewsletterFormManagerAddon extends NewsletterAddon {
|
312 |
-
|
313 |
-
var $menu_title = null;
|
314 |
-
var $menu_description = null;
|
315 |
-
var $dir = '';
|
316 |
-
|
317 |
-
function __construct($name, $version, $dir) {
|
318 |
-
parent::__construct($name, $version);
|
319 |
-
$this->dir = $dir;
|
320 |
-
$this->setup_options();
|
321 |
-
}
|
322 |
-
|
323 |
-
function init() {
|
324 |
-
parent::init();
|
325 |
-
|
326 |
-
if (is_admin() && !empty($this->menu_title) && !empty($this->dir) && Newsletter::instance()->is_allowed()) {
|
327 |
-
add_action('admin_menu', [$this, 'hook_admin_menu'], 101);
|
328 |
-
add_filter('newsletter_menu_subscription', [$this, 'hook_newsletter_menu_subscription']);
|
329 |
-
}
|
330 |
-
}
|
331 |
-
|
332 |
-
function hook_newsletter_menu_subscription($entries) {
|
333 |
-
$entries[] = array('label' => '<i class="fas fa-envelope"></i> ' . $this->menu_title, 'url' => '?page=newsletter_' . $this->name . '_index', 'description' => $this->menu_description);
|
334 |
-
return $entries;
|
335 |
-
}
|
336 |
-
|
337 |
-
function hook_admin_menu() {
|
338 |
-
add_submenu_page('newsletter_main_index', $this->menu_title, '<span class="tnp-side-menu">' . $this->menu_title . '</span>', '
|
339 |
-
function () {
|
340 |
-
require $this->dir . '/admin/index.php';
|
341 |
-
}
|
342 |
-
);
|
343 |
-
}
|
344 |
-
|
345 |
-
/**
|
346 |
-
* Returns a lists of representations of forms available in the plugin subject of integration.
|
347 |
-
* Usually the $fields is not set up on returned objects.
|
348 |
-
* Must be implemented.
|
349 |
-
*
|
350 |
-
* @return TNP_FormManager_Form[] List of forms by 3rd party plugin
|
351 |
-
*/
|
352 |
-
function get_forms() {
|
353 |
-
return [];
|
354 |
-
}
|
355 |
-
|
356 |
-
/**
|
357 |
-
* Build a form general representation of a real form from a form manager plugin extracting
|
358 |
-
* only the data required to integrate. The form id is domain of the form manager plugin, so it can be
|
359 |
-
* anything.
|
360 |
-
* Must be implemented.
|
361 |
-
*
|
362 |
-
* @param mixed $form_id
|
363 |
-
* @return TNP_FormManager_Form
|
364 |
-
*/
|
365 |
-
function get_form($form_id) {
|
366 |
-
return null;
|
367 |
-
}
|
368 |
-
|
369 |
-
/**
|
370 |
-
* Saves the form mapping and integration settings.
|
371 |
-
* @param mixed $form_id
|
372 |
-
* @param array $data
|
373 |
-
*/
|
374 |
-
public function save_form_options($form_id, $data) {
|
375 |
-
update_option('newsletter_' . $this->name . '_' . $form_id, $data, false);
|
376 |
-
}
|
377 |
-
|
378 |
-
/**
|
379 |
-
* Gets the form mapping and integration settings. Returns an empty array if the dataset is missing.
|
380 |
-
* @param mixed $form_id
|
381 |
-
* @return array
|
382 |
-
*/
|
383 |
-
public function get_form_options($form_id) {
|
384 |
-
return get_option('newsletter_' . $this->name . '_' . $form_id, []);
|
385 |
-
}
|
386 |
-
|
387 |
-
}
|
388 |
-
|
389 |
-
class TNP_FormManager_Form {
|
390 |
-
|
391 |
-
var $id = null;
|
392 |
-
var $title = '';
|
393 |
-
var $fields = [];
|
394 |
-
var $connected = false;
|
395 |
-
|
396 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* User by add-ons as base-class.
|
5 |
+
*/
|
6 |
+
class NewsletterAddon {
|
7 |
+
|
8 |
+
var $logger;
|
9 |
+
var $admin_logger;
|
10 |
+
var $name;
|
11 |
+
var $options;
|
12 |
+
var $version;
|
13 |
+
var $labels;
|
14 |
+
|
15 |
+
public function __construct($name, $version = '0.0.0') {
|
16 |
+
$this->name = $name;
|
17 |
+
$this->version = $version;
|
18 |
+
if (is_admin()) {
|
19 |
+
$old_version = get_option('newsletter_' . $name . '_version');
|
20 |
+
if ($version !== $old_version) {
|
21 |
+
$this->upgrade($old_version === false);
|
22 |
+
update_option('newsletter_' . $name . '_version', $version, false);
|
23 |
+
}
|
24 |
+
}
|
25 |
+
add_action('newsletter_init', array($this, 'init'));
|
26 |
+
//Load translations from specific addon /languages/ directory
|
27 |
+
load_plugin_textdomain('newsletter-' . $this->name, false, 'newsletter-' . $this->name . '/languages/');
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Method to be overridden and invoked on version change or on first install.
|
32 |
+
*
|
33 |
+
* @param bool $first_install
|
34 |
+
*/
|
35 |
+
function upgrade($first_install = false) {
|
36 |
+
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Method to be overridden to initialize the add-on. It is invoked when Newsletter
|
41 |
+
* fires the <code>newsletter_init</code> event.
|
42 |
+
*/
|
43 |
+
function init() {
|
44 |
+
|
45 |
+
}
|
46 |
+
|
47 |
+
function get_current_language() {
|
48 |
+
return Newsletter::instance()->get_current_language();
|
49 |
+
}
|
50 |
+
|
51 |
+
function is_all_languages() {
|
52 |
+
return Newsletter::instance()->is_all_languages();
|
53 |
+
}
|
54 |
+
|
55 |
+
function is_allowed() {
|
56 |
+
return Newsletter::instance()->is_allowed();
|
57 |
+
}
|
58 |
+
|
59 |
+
function get_languages() {
|
60 |
+
return Newsletter::instance()->get_languages();
|
61 |
+
}
|
62 |
+
|
63 |
+
function is_multilanguage() {
|
64 |
+
return Newsletter::instance()->is_multilanguage();
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* General logger for this add-on.
|
69 |
+
*
|
70 |
+
* @return NewsletterLogger
|
71 |
+
*/
|
72 |
+
function get_logger() {
|
73 |
+
if (!$this->logger) {
|
74 |
+
$this->logger = new NewsletterLogger($this->name);
|
75 |
+
}
|
76 |
+
return $this->logger;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Specific logger for administrator actions.
|
81 |
+
*
|
82 |
+
* @return NewsletterLogger
|
83 |
+
*/
|
84 |
+
function get_admin_logger() {
|
85 |
+
if (!$this->admin_logger) {
|
86 |
+
$this->admin_logger = new NewsletterLogger($this->name . '-admin');
|
87 |
+
}
|
88 |
+
return $this->admin_logger;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Loads and prepares the options. It can be used to late initialize the options to save some resources on
|
93 |
+
* add-ons which do not need to do something on each page load.
|
94 |
+
*/
|
95 |
+
function setup_options() {
|
96 |
+
if ($this->options) {
|
97 |
+
return;
|
98 |
+
}
|
99 |
+
$this->options = get_option('newsletter_' . $this->name, []);
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Retrieve the stored options, merged with the specified language set.
|
104 |
+
*
|
105 |
+
* @param string $language
|
106 |
+
* @return array
|
107 |
+
*/
|
108 |
+
function get_options($language = '') {
|
109 |
+
if ($language) {
|
110 |
+
return array_merge(get_option('newsletter_' . $this->name, []), get_option('newsletter_' . $this->name . '_' . $language, []));
|
111 |
+
} else {
|
112 |
+
return get_option('newsletter_' . $this->name, []);
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Saved the options under the correct keys and update the internal $options
|
118 |
+
* property.
|
119 |
+
* @param array $options
|
120 |
+
*/
|
121 |
+
function save_options($options, $language = '') {
|
122 |
+
if ($language) {
|
123 |
+
update_option('newsletter_' . $this->name . '_' . $language, $options);
|
124 |
+
} else {
|
125 |
+
update_option('newsletter_' . $this->name, $options);
|
126 |
+
$this->options = $options;
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
function merge_defaults($defaults) {
|
131 |
+
$options = get_option('newsletter_' . $this->name, []);
|
132 |
+
$options = array_merge($defaults, $options);
|
133 |
+
$this->save_options($options);
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
*
|
138 |
+
*/
|
139 |
+
function setup_labels() {
|
140 |
+
if (!$this->labels) {
|
141 |
+
$labels = [];
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
function get_label($key) {
|
146 |
+
if (!$this->options)
|
147 |
+
$this->setup_options();
|
148 |
+
|
149 |
+
if (!empty($this->options[$key])) {
|
150 |
+
return $this->options[$key];
|
151 |
+
}
|
152 |
+
|
153 |
+
if (!$this->labels)
|
154 |
+
$this->setup_labels();
|
155 |
+
|
156 |
+
// We assume the required key is defined. If not there is an error elsewhere.
|
157 |
+
return $this->labels[$key];
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Equivalent to $wpdb->query() but logs the event in case of error.
|
162 |
+
*
|
163 |
+
* @global wpdb $wpdb
|
164 |
+
* @param string $query
|
165 |
+
*/
|
166 |
+
function query($query) {
|
167 |
+
global $wpdb;
|
168 |
+
|
169 |
+
$r = $wpdb->query($query);
|
170 |
+
if ($r === false) {
|
171 |
+
$logger = $this->get_logger();
|
172 |
+
$logger->fatal($query);
|
173 |
+
$logger->fatal($wpdb->last_error);
|
174 |
+
}
|
175 |
+
return $r;
|
176 |
+
}
|
177 |
+
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Used by mailer add-ons as base-class. Some specific options collected by the mailer
|
182 |
+
* are interpreted automatically.
|
183 |
+
*
|
184 |
+
* They are:
|
185 |
+
*
|
186 |
+
* `enabled` if not empty it means the mailer is active and should be registered
|
187 |
+
*
|
188 |
+
* The options are set up in the constructor, there is no need to setup them later.
|
189 |
+
*/
|
190 |
+
class NewsletterMailerAddon extends NewsletterAddon {
|
191 |
+
|
192 |
+
var $enabled = false;
|
193 |
+
var $menu_title = null;
|
194 |
+
var $menu_description = null;
|
195 |
+
var $dir = '';
|
196 |
+
|
197 |
+
function __construct($name, $version = '0.0.0', $dir = '') {
|
198 |
+
parent::__construct($name, $version);
|
199 |
+
$this->dir = $dir;
|
200 |
+
$this->setup_options();
|
201 |
+
$this->enabled = !empty($this->options['enabled']);
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* This method must be called as `parent::init()` is overridden.
|
206 |
+
*/
|
207 |
+
function init() {
|
208 |
+
parent::init();
|
209 |
+
add_action('newsletter_register_mailer', function () {
|
210 |
+
if ($this->enabled) {
|
211 |
+
Newsletter::instance()->register_mailer($this->get_mailer());
|
212 |
+
}
|
213 |
+
});
|
214 |
+
|
215 |
+
if (is_admin() && !empty($this->menu_title) && !empty($this->dir) && current_user_can('administrator')) {
|
216 |
+
add_action('admin_menu', [$this, 'hook_admin_menu'], 101);
|
217 |
+
add_filter('newsletter_menu_settings', [$this, 'hook_newsletter_menu_settings']);
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
function hook_newsletter_menu_settings($entries) {
|
222 |
+
$entries[] = array('label' => '<i class="fas fa-envelope"></i> ' . $this->menu_title, 'url' => '?page=newsletter_' . $this->name . '_index', 'description' => $this->menu_description);
|
223 |
+
return $entries;
|
224 |
+
}
|
225 |
+
|
226 |
+
function hook_admin_menu() {
|
227 |
+
add_submenu_page('newsletter_main_index', $this->menu_title, '<span class="tnp-side-menu">' . $this->menu_title . '</span>', 'manage_options', 'newsletter_' . $this->name . '_index',
|
228 |
+
function () {
|
229 |
+
require $this->dir . '/index.php';
|
230 |
+
}
|
231 |
+
);
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Must return an implementation of NewsletterMailer.
|
236 |
+
* @return NewsletterMailer
|
237 |
+
*/
|
238 |
+
function get_mailer() {
|
239 |
+
return null;
|
240 |
+
}
|
241 |
+
|
242 |
+
function get_last_run() {
|
243 |
+
return get_option('newsletter_' . $this->name . '_last_run', 0);
|
244 |
+
}
|
245 |
+
|
246 |
+
function save_last_run($time) {
|
247 |
+
update_option('newsletter_' . $this->name . '_last_run', $time);
|
248 |
+
}
|
249 |
+
|
250 |
+
function save_options($options, $language = '') {
|
251 |
+
parent::save_options($options, $language);
|
252 |
+
$this->enabled = !empty($options['enabled']);
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Returns a TNP_Mailer_Message built to send a test message to the <code>$to</code>
|
257 |
+
* email address.
|
258 |
+
*
|
259 |
+
* @param string $to
|
260 |
+
* @param string $subject
|
261 |
+
* @return TNP_Mailer_Message
|
262 |
+
*/
|
263 |
+
static function get_test_message($to, $subject = '', $type = '') {
|
264 |
+
$message = new TNP_Mailer_Message();
|
265 |
+
$message->to = $to;
|
266 |
+
$message->to_name = '';
|
267 |
+
if (empty($type) || $type == 'html') {
|
268 |
+
$message->body = file_get_contents(NEWSLETTER_DIR . '/includes/test-message.html');
|
269 |
+
$message->body = str_replace('{plugin_url}', NEWSLETTER_URL, $message->body);
|
270 |
+
}
|
271 |
+
|
272 |
+
if (empty($type) || $type == 'text') {
|
273 |
+
$message->body_text = 'This is the TEXT version of a test message. You should see this message only if you email client does not support the rich text (HTML) version.';
|
274 |
+
}
|
275 |
+
|
276 |
+
$message->headers['X-Newsletter-Email-Id'] = '0';
|
277 |
+
|
278 |
+
if (empty($subject)) {
|
279 |
+
$message->subject = '[' . get_option('blogname') . '] Test message from Newsletter (' . date(DATE_ISO8601) . ')';
|
280 |
+
} else {
|
281 |
+
$message->subject = $subject;
|
282 |
+
}
|
283 |
+
|
284 |
+
if ($type) {
|
285 |
+
$message->subject .= ' - ' . $type . ' only';
|
286 |
+
}
|
287 |
+
|
288 |
+
$message->from = Newsletter::instance()->options['sender_email'];
|
289 |
+
$message->from_name = Newsletter::instance()->options['sender_name'];
|
290 |
+
return $message;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Returns a set of test messages to be sent to the specified email address. Used for
|
295 |
+
* turbo mode tests. Each message has a different generated subject.
|
296 |
+
*
|
297 |
+
* @param string $to The destination mailbox
|
298 |
+
* @param int $count Number of message objects to create
|
299 |
+
* @return TNP_Mailer_Message[]
|
300 |
+
*/
|
301 |
+
function get_test_messages($to, $count, $type = '') {
|
302 |
+
$messages = array();
|
303 |
+
for ($i = 0; $i < $count; $i++) {
|
304 |
+
$messages[] = self::get_test_message($to, '[' . get_option('blogname') . '] Test message ' . ($i + 1) . ' from Newsletter (' . date(DATE_ISO8601) . ')', $type);
|
305 |
+
}
|
306 |
+
return $messages;
|
307 |
+
}
|
308 |
+
|
309 |
+
}
|
310 |
+
|
311 |
+
class NewsletterFormManagerAddon extends NewsletterAddon {
|
312 |
+
|
313 |
+
var $menu_title = null;
|
314 |
+
var $menu_description = null;
|
315 |
+
var $dir = '';
|
316 |
+
|
317 |
+
function __construct($name, $version, $dir) {
|
318 |
+
parent::__construct($name, $version);
|
319 |
+
$this->dir = $dir;
|
320 |
+
$this->setup_options();
|
321 |
+
}
|
322 |
+
|
323 |
+
function init() {
|
324 |
+
parent::init();
|
325 |
+
|
326 |
+
if (is_admin() && !empty($this->menu_title) && !empty($this->dir) && Newsletter::instance()->is_allowed()) {
|
327 |
+
add_action('admin_menu', [$this, 'hook_admin_menu'], 101);
|
328 |
+
add_filter('newsletter_menu_subscription', [$this, 'hook_newsletter_menu_subscription']);
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
function hook_newsletter_menu_subscription($entries) {
|
333 |
+
$entries[] = array('label' => '<i class="fas fa-envelope"></i> ' . $this->menu_title, 'url' => '?page=newsletter_' . $this->name . '_index', 'description' => $this->menu_description);
|
334 |
+
return $entries;
|
335 |
+
}
|
336 |
+
|
337 |
+
function hook_admin_menu() {
|
338 |
+
add_submenu_page('newsletter_main_index', $this->menu_title, '<span class="tnp-side-menu">' . $this->menu_title . '</span>', 'exist', 'newsletter_' . $this->name . '_index',
|
339 |
+
function () {
|
340 |
+
require $this->dir . '/admin/index.php';
|
341 |
+
}
|
342 |
+
);
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Returns a lists of representations of forms available in the plugin subject of integration.
|
347 |
+
* Usually the $fields is not set up on returned objects.
|
348 |
+
* Must be implemented.
|
349 |
+
*
|
350 |
+
* @return TNP_FormManager_Form[] List of forms by 3rd party plugin
|
351 |
+
*/
|
352 |
+
function get_forms() {
|
353 |
+
return [];
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Build a form general representation of a real form from a form manager plugin extracting
|
358 |
+
* only the data required to integrate. The form id is domain of the form manager plugin, so it can be
|
359 |
+
* anything.
|
360 |
+
* Must be implemented.
|
361 |
+
*
|
362 |
+
* @param mixed $form_id
|
363 |
+
* @return TNP_FormManager_Form
|
364 |
+
*/
|
365 |
+
function get_form($form_id) {
|
366 |
+
return null;
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Saves the form mapping and integration settings.
|
371 |
+
* @param mixed $form_id
|
372 |
+
* @param array $data
|
373 |
+
*/
|
374 |
+
public function save_form_options($form_id, $data) {
|
375 |
+
update_option('newsletter_' . $this->name . '_' . $form_id, $data, false);
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Gets the form mapping and integration settings. Returns an empty array if the dataset is missing.
|
380 |
+
* @param mixed $form_id
|
381 |
+
* @return array
|
382 |
+
*/
|
383 |
+
public function get_form_options($form_id) {
|
384 |
+
return get_option('newsletter_' . $this->name . '_' . $form_id, []);
|
385 |
+
}
|
386 |
+
|
387 |
+
}
|
388 |
+
|
389 |
+
class TNP_FormManager_Form {
|
390 |
+
|
391 |
+
var $id = null;
|
392 |
+
var $title = '';
|
393 |
+
var $fields = [];
|
394 |
+
var $connected = false;
|
395 |
+
|
396 |
+
}
|
plugin.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
Plugin Name: Newsletter
|
5 |
Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
|
6 |
Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
|
7 |
-
Version: 7.5.
|
8 |
Author: Stefano Lissa & The Newsletter Team
|
9 |
Author URI: https://www.thenewsletterplugin.com
|
10 |
Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
|
@@ -37,7 +37,7 @@ if (version_compare(phpversion(), '5.6', '<')) {
|
|
37 |
return;
|
38 |
}
|
39 |
|
40 |
-
define('NEWSLETTER_VERSION', '7.5.
|
41 |
|
42 |
global $newsletter, $wpdb;
|
43 |
|
4 |
Plugin Name: Newsletter
|
5 |
Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
|
6 |
Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
|
7 |
+
Version: 7.5.5
|
8 |
Author: Stefano Lissa & The Newsletter Team
|
9 |
Author URI: https://www.thenewsletterplugin.com
|
10 |
Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
|
37 |
return;
|
38 |
}
|
39 |
|
40 |
+
define('NEWSLETTER_VERSION', '7.5.5');
|
41 |
|
42 |
global $newsletter, $wpdb;
|
43 |
|
profile/profile.php
CHANGED
@@ -1,494 +1,494 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
defined('ABSPATH') || exit;
|
4 |
-
|
5 |
-
class NewsletterProfile extends NewsletterModule {
|
6 |
-
|
7 |
-
static $instance;
|
8 |
-
|
9 |
-
/**
|
10 |
-
* @return NewsletterProfile
|
11 |
-
*/
|
12 |
-
static function instance() {
|
13 |
-
if (self::$instance == null) {
|
14 |
-
self::$instance = new NewsletterProfile();
|
15 |
-
}
|
16 |
-
return self::$instance;
|
17 |
-
}
|
18 |
-
|
19 |
-
function __construct() {
|
20 |
-
parent::__construct('profile', '1.1.0');
|
21 |
-
add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
|
22 |
-
add_filter('newsletter_replace', array($this, 'hook_newsletter_replace'), 10, 4);
|
23 |
-
add_filter('newsletter_page_text', array($this, 'hook_newsletter_page_text'), 10, 3);
|
24 |
-
add_action('newsletter_action', array($this, 'hook_newsletter_action'), 12, 3);
|
25 |
-
}
|
26 |
-
|
27 |
-
function hook_newsletter_action($action, $user, $email) {
|
28 |
-
|
29 |
-
if (in_array($action, ['p', 'profile', 'pe', 'profile-save', 'profile_export', 'ps'])) {
|
30 |
-
if (!$user || $user->status != TNP_User::STATUS_CONFIRMED) {
|
31 |
-
|
32 |
-
$this->dienow(__('The subscriber was not found or is not confirmed.', 'newsletter'), '', 404);
|
33 |
-
}
|
34 |
-
}
|
35 |
-
|
36 |
-
switch ($action) {
|
37 |
-
case 'profile':
|
38 |
-
case 'p':
|
39 |
-
case 'pe':
|
40 |
-
|
41 |
-
$profile_url = $this->build_message_url($this->options['url'], 'profile', $user, $email);
|
42 |
-
$profile_url = apply_filters('newsletter_profile_url', $profile_url, $user);
|
43 |
-
|
44 |
-
wp_redirect($profile_url);
|
45 |
-
die();
|
46 |
-
|
47 |
-
break;
|
48 |
-
|
49 |
-
case 'profile-save':
|
50 |
-
case 'ps':
|
51 |
-
$res = $this->save_profile($user);
|
52 |
-
if (is_wp_error($res)) {
|
53 |
-
wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $res->get_error_message()));
|
54 |
-
die();
|
55 |
-
}
|
56 |
-
|
57 |
-
wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $res));
|
58 |
-
die();
|
59 |
-
break;
|
60 |
-
|
61 |
-
case 'profile_export':
|
62 |
-
header('Content-Type: application/json;charset=UTF-8');
|
63 |
-
echo $this->to_json($user);
|
64 |
-
die();
|
65 |
-
}
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
*
|
70 |
-
* @param stdClass $user
|
71 |
-
*/
|
72 |
-
function get_profile_export_url($user) {
|
73 |
-
return $this->build_action_url('profile_export', $user);
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* URL to the subscriber profile edit action. This URL MUST NEVER be changed by
|
78 |
-
* 3rd party plugins. Plugins can change the final URL after the action has been executed using the
|
79 |
-
* <code>newsletter_profile_url</code> filter.
|
80 |
-
*
|
81 |
-
* @param stdClass $user
|
82 |
-
*/
|
83 |
-
function get_profile_url($user, $email = null) {
|
84 |
-
return $this->build_action_url('profile', $user, $email);
|
85 |
-
}
|
86 |
-
|
87 |
-
function hook_newsletter_replace($text, $user, $email, $html = true) {
|
88 |
-
if (!$user) {
|
89 |
-
$text = $this->replace_url($text, 'PROFILE_URL', $this->build_action_url('nul'));
|
90 |
-
return $text;
|
91 |
-
}
|
92 |
-
|
93 |
-
// Profile edit page URL and link
|
94 |
-
$url = $this->get_profile_url($user, $email);
|
95 |
-
$text = $this->replace_url($text, 'profile_url', $url);
|
96 |
-
// Profile export URL and link
|
97 |
-
$url = $this->get_profile_export_url($user);
|
98 |
-
$text = $this->replace_url($text, 'profile_export_url', $url);
|
99 |
-
|
100 |
-
if (strpos($text, '{profile_form}') !== false) {
|
101 |
-
$text = str_replace('{profile_form}', $this->get_profile_form($user), $text);
|
102 |
-
}
|
103 |
-
return $text;
|
104 |
-
}
|
105 |
-
|
106 |
-
/**
|
107 |
-
*
|
108 |
-
* @param type $text
|
109 |
-
* @param type $key
|
110 |
-
* @param TNP_User $user
|
111 |
-
* @return string
|
112 |
-
*/
|
113 |
-
function hook_newsletter_page_text($text, $key, $user) {
|
114 |
-
if ($key == 'profile') {
|
115 |
-
if (!$user || $user->status == TNP_User::STATUS_UNSUBSCRIBED) {
|
116 |
-
return 'Subscriber not found.';
|
117 |
-
}
|
118 |
-
$options = $this->get_options('main', $this->get_current_language($user));
|
119 |
-
return $options['text'];
|
120 |
-
}
|
121 |
-
return $text;
|
122 |
-
}
|
123 |
-
|
124 |
-
function shortcode_newsletter_profile($attrs, $content) {
|
125 |
-
$user = $this->check_user();
|
126 |
-
|
127 |
-
if (empty($user)) {
|
128 |
-
if (empty($content)) {
|
129 |
-
return __('Subscriber not found.', 'newsletter');
|
130 |
-
} else {
|
131 |
-
return $content;
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
return $this->get_profile_form($user);
|
136 |
-
}
|
137 |
-
|
138 |
-
function to_json($user) {
|
139 |
-
global $wpdb;
|
140 |
-
|
141 |
-
|
142 |
-
$fields = array('name', 'surname', 'sex', 'created', 'ip', 'email');
|
143 |
-
$data = array(
|
144 |
-
'email' => $user->email,
|
145 |
-
'name' => $user->name,
|
146 |
-
'last_name' => $user->surname,
|
147 |
-
'gender' => $user->sex,
|
148 |
-
'created' => $user->created,
|
149 |
-
'ip' => $user->ip,
|
150 |
-
);
|
151 |
-
|
152 |
-
// Lists
|
153 |
-
$data['lists'] = array();
|
154 |
-
|
155 |
-
$lists = $this->get_lists_public();
|
156 |
-
foreach ($lists as $list) {
|
157 |
-
$field = 'list_' . $list->id;
|
158 |
-
if ($user->$field == 1) {
|
159 |
-
$data['lists'][] = $list->name;
|
160 |
-
}
|
161 |
-
}
|
162 |
-
|
163 |
-
// Profile
|
164 |
-
$options_profile = get_option('newsletter_profile', array());
|
165 |
-
$data['profiles'] = array();
|
166 |
-
for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
|
167 |
-
$field = 'profile_' . $i;
|
168 |
-
if ($options_profile[$field . '_status'] != 1 && $options_profile[$field . '_status'] != 2) {
|
169 |
-
continue;
|
170 |
-
}
|
171 |
-
$data['profiles'][] = array('name' => $options_profile[$field], 'value' => $user->$field);
|
172 |
-
}
|
173 |
-
|
174 |
-
// Newsletters
|
175 |
-
if ($this->options['export_newsletters']) {
|
176 |
-
$sent = $wpdb->get_results($wpdb->prepare("select * from {$wpdb->prefix}newsletter_sent where user_id=%d order by email_id asc", $user->id));
|
177 |
-
$newsletters = array();
|
178 |
-
foreach ($sent as $item) {
|
179 |
-
$action = 'none';
|
180 |
-
if ($item->open == 1) {
|
181 |
-
$action = 'read';
|
182 |
-
} else if ($item->open == 2) {
|
183 |
-
$action = 'click';
|
184 |
-
}
|
185 |
-
|
186 |
-
$email = $this->get_email($item->email_id);
|
187 |
-
if (!$email) {
|
188 |
-
continue;
|
189 |
-
}
|
190 |
-
// 'id'=>$item->email_id,
|
191 |
-
$newsletters[] = array('subject' => $email->subject, 'action' => $action, 'sent' => date('Y-m-d h:i:s', $email->send_on));
|
192 |
-
}
|
193 |
-
|
194 |
-
$data['newsletters'] = $newsletters;
|
195 |
-
}
|
196 |
-
|
197 |
-
$extra = apply_filters('newsletter_profile_export_extra', array());
|
198 |
-
|
199 |
-
$data = array_merge($extra, $data);
|
200 |
-
|
201 |
-
return json_encode($data, JSON_PRETTY_PRINT);
|
202 |
-
}
|
203 |
-
|
204 |
-
/**
|
205 |
-
* Build the profile editing form for the specified subscriber.
|
206 |
-
*
|
207 |
-
* @param TNP_User $user
|
208 |
-
* @return string
|
209 |
-
*/
|
210 |
-
function get_profile_form($user) {
|
211 |
-
// Do not pay attention to option name here, it's a compatibility problem
|
212 |
-
|
213 |
-
$language = $this->get_user_language($user);
|
214 |
-
$options = NewsletterSubscription::instance()->get_options('profile', $language);
|
215 |
-
|
216 |
-
$buffer = '';
|
217 |
-
|
218 |
-
$buffer .= '<div class="tnp tnp-profile">';
|
219 |
-
$buffer .= '<form action="' . $this->build_action_url('ps') . '" method="post">';
|
220 |
-
$buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
|
221 |
-
|
222 |
-
$buffer .= '<div class="tnp-field tnp-field-email">';
|
223 |
-
$buffer .= '<label>' . esc_html($options['email']) . '</label>';
|
224 |
-
$buffer .= '<input class="tnp-email" type="text" name="ne" required value="' . esc_attr($user->email) . '">';
|
225 |
-
$buffer .= "</div>\n";
|
226 |
-
|
227 |
-
|
228 |
-
if ($options['name_status'] >= 1) {
|
229 |
-
$buffer .= '<div class="tnp-field tnp-field-firstname">';
|
230 |
-
$buffer .= '<label>' . esc_html($options['name']) . '</label>';
|
231 |
-
$buffer .= '<input class="tnp-firstname" type="text" name="nn" value="' . esc_attr($user->name) . '"' . ($options['name_rules'] == 1 ? ' required' : '') . '>';
|
232 |
-
$buffer .= "</div>\n";
|
233 |
-
}
|
234 |
-
|
235 |
-
if ($options['surname_status'] >= 1) {
|
236 |
-
$buffer .= '<div class="tnp-field tnp-field-lastname">';
|
237 |
-
$buffer .= '<label>' . esc_html($options['surname']) . '</label>';
|
238 |
-
$buffer .= '<input class="tnp-lastname" type="text" name="ns" value="' . esc_attr($user->surname) . '"' . ($options['surname_rules'] == 1 ? ' required' : '') . '>';
|
239 |
-
$buffer .= "</div>\n";
|
240 |
-
}
|
241 |
-
|
242 |
-
if ($options['sex_status'] >= 1) {
|
243 |
-
$buffer .= '<div class="tnp-field tnp-field-gender">';
|
244 |
-
$buffer .= '<label>' . esc_html($options['sex']) . '</label>';
|
245 |
-
$buffer .= '<select name="nx" class="tnp-gender"';
|
246 |
-
if ($options['sex_rules']) {
|
247 |
-
$buffer .= ' required ';
|
248 |
-
}
|
249 |
-
$buffer .= '>';
|
250 |
-
if ($options['sex_rules']) {
|
251 |
-
$buffer .= '<option value=""></option>';
|
252 |
-
}
|
253 |
-
$buffer .= '<option value="n"' . ($user->sex == 'n' ? ' selected' : '') . '>' . esc_html($options['sex_none']) . '</option>';
|
254 |
-
$buffer .= '<option value="f"' . ($user->sex == 'f' ? ' selected' : '') . '>' . esc_html($options['sex_female']) . '</option>';
|
255 |
-
$buffer .= '<option value="m"' . ($user->sex == 'm' ? ' selected' : '') . '>' . esc_html($options['sex_male']) . '</option>';
|
256 |
-
$buffer .= '</select>';
|
257 |
-
$buffer .= "</div>\n";
|
258 |
-
}
|
259 |
-
|
260 |
-
if ($this->is_multilanguage()) {
|
261 |
-
|
262 |
-
$languages = $this->get_languages();
|
263 |
-
|
264 |
-
$buffer .= '<div class="tnp-field tnp-field-language">';
|
265 |
-
$buffer .= '<label>' . __('Language', 'newsletter') . '</label>';
|
266 |
-
$buffer .= '<select name="nlng" class="tnp-language">';
|
267 |
-
|
268 |
-
$buffer .= '<option value="" disabled ' . ( empty($user->language) ? ' selected' : '' ) . '>' . __('Select language', 'newsletter') . '</option>';
|
269 |
-
foreach ($languages as $key => $l) {
|
270 |
-
$buffer .= '<option value="' . $key . '"' . ( $user->language == $key ? ' selected' : '' ) . '>' . esc_html($l) . '</option>';
|
271 |
-
}
|
272 |
-
|
273 |
-
$buffer .= '</select>';
|
274 |
-
$buffer .= "</div>\n";
|
275 |
-
}
|
276 |
-
|
277 |
-
// Profile
|
278 |
-
$profiles = NewsletterSubscription::instance()->get_profiles_for_profile($user->language);
|
279 |
-
foreach ($profiles as $profile) {
|
280 |
-
$i = $profile->id; // I'm lazy
|
281 |
-
|
282 |
-
$buffer .= '<div class="tnp-field tnp-field-profile">';
|
283 |
-
$buffer .= '<label>' . esc_html($profile->name) . '</label>';
|
284 |
-
|
285 |
-
$field = 'profile_' . $i;
|
286 |
-
|
287 |
-
if ($profile->is_text()) {
|
288 |
-
$buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . esc_attr($user->$field) . '"' .
|
289 |
-
($profile->is_required() ? ' required' : '') . '>';
|
290 |
-
}
|
291 |
-
|
292 |
-
if ($profile->is_select()) {
|
293 |
-
$buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '"' . ($profile->is_required() ? ' required' : '') . '>';
|
294 |
-
foreach ($profile->options as $option) {
|
295 |
-
$buffer .= '<option';
|
296 |
-
if ($option == $user->$field) {
|
297 |
-
$buffer .= ' selected';
|
298 |
-
}
|
299 |
-
$buffer .= '>' . esc_html($option) . '</option>';
|
300 |
-
}
|
301 |
-
$buffer .= '</select>';
|
302 |
-
}
|
303 |
-
|
304 |
-
$buffer .= "</div>\n";
|
305 |
-
}
|
306 |
-
|
307 |
-
// Lists
|
308 |
-
$lists = $this->get_lists_for_profile($language);
|
309 |
-
$tmp = '';
|
310 |
-
foreach ($lists as $list) {
|
311 |
-
|
312 |
-
$tmp .= '<div class="tnp-field tnp-field-list">';
|
313 |
-
$tmp .= '<label><input class="tnp-list tnp-list-' . $list->id . '" type="checkbox" name="nl[]" value="' . $list->id . '"';
|
314 |
-
$field = 'list_' . $list->id;
|
315 |
-
if ($user->$field == 1) {
|
316 |
-
$tmp .= ' checked';
|
317 |
-
}
|
318 |
-
$tmp .= '><span class="tnp-list-label">' . esc_html($list->name) . '</span></label>';
|
319 |
-
$tmp .= "</div>\n";
|
320 |
-
}
|
321 |
-
|
322 |
-
if (!empty($tmp)) {
|
323 |
-
$buffer .= '<div class="tnp-lists">' . "\n" . $tmp . "\n" . '</div>';
|
324 |
-
}
|
325 |
-
|
326 |
-
// Obsolete
|
327 |
-
$extra = apply_filters('newsletter_profile_extra', array(), $user);
|
328 |
-
foreach ($extra as $x) {
|
329 |
-
$buffer .= '<div class="tnp-field">';
|
330 |
-
$buffer .= '<label>' . $x['label'] . "</label>";
|
331 |
-
$buffer .= $x['field'];
|
332 |
-
$buffer .= "</div>\n";
|
333 |
-
}
|
334 |
-
|
335 |
-
$local_options = $this->get_options('', $language);
|
336 |
-
|
337 |
-
// Privacy
|
338 |
-
$privacy_url = NewsletterSubscription::instance()->get_privacy_url();
|
339 |
-
if (!empty($local_options['privacy_label']) && !empty($privacy_url)) {
|
340 |
-
$buffer .= '<div class="tnp-field tnp-field-privacy">';
|
341 |
-
if ($privacy_url) {
|
342 |
-
$buffer .= '<a href="' . $privacy_url . '" target="_blank">';
|
343 |
-
}
|
344 |
-
|
345 |
-
$buffer .= $local_options['privacy_label'];
|
346 |
-
|
347 |
-
if ($privacy_url) {
|
348 |
-
$buffer .= '</a>';
|
349 |
-
}
|
350 |
-
$buffer .= "</div>\n";
|
351 |
-
}
|
352 |
-
|
353 |
-
$buffer .= '<div class="tnp-field tnp-field-button">';
|
354 |
-
$buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($local_options['save_label']) . '">';
|
355 |
-
$buffer .= "</div>\n";
|
356 |
-
|
357 |
-
$buffer .= "</form>\n</div>\n";
|
358 |
-
|
359 |
-
return $buffer;
|
360 |
-
}
|
361 |
-
|
362 |
-
/**
|
363 |
-
* Saves the subscriber data extracting them from the $_REQUEST and for the
|
364 |
-
* subscriber identified by the <code>$user</code> object.
|
365 |
-
*
|
366 |
-
* @return string|WP_Error If not an error the string represent the message to show
|
367 |
-
*/
|
368 |
-
function save_profile($user) {
|
369 |
-
global $wpdb;
|
370 |
-
|
371 |
-
// Conatains the cleaned up user data to be saved
|
372 |
-
$data = array();
|
373 |
-
$data['id'] = $user->id;
|
374 |
-
|
375 |
-
$options = $this->get_options('', $this->get_current_language($user));
|
376 |
-
$options_profile = get_option('newsletter_profile', array());
|
377 |
-
$options_main = get_option('newsletter_main', array());
|
378 |
-
|
379 |
-
// Not an elegant interaction between modules but...
|
380 |
-
$subscription_module = NewsletterSubscription::instance();
|
381 |
-
|
382 |
-
require_once NEWSLETTER_INCLUDES_DIR . '/antispam.php';
|
383 |
-
|
384 |
-
$antispam = NewsletterAntispam::instance();
|
385 |
-
|
386 |
-
$email = $this->normalize_email(stripslashes($_REQUEST['ne']));
|
387 |
-
|
388 |
-
if ($antispam->is_address_blacklisted($email)) {
|
389 |
-
return new WP_Error('spam', 'That email address is not accepted');
|
390 |
-
}
|
391 |
-
|
392 |
-
if (!$email) {
|
393 |
-
return new WP_Error('email', $options['error']);
|
394 |
-
}
|
395 |
-
|
396 |
-
$email_changed = ($email != $user->email);
|
397 |
-
|
398 |
-
// If the email has been changed, check if it is available
|
399 |
-
if ($email_changed) {
|
400 |
-
$tmp = $this->get_user($email);
|
401 |
-
if ($tmp != null && $tmp->id != $user->id) {
|
402 |
-
return new WP_Error('inuse', $options['error']);
|
403 |
-
}
|
404 |
-
}
|
405 |
-
|
406 |
-
if ($email_changed && $subscription_module->is_double_optin()) {
|
407 |
-
set_transient('newsletter_user_' . $user->id . '_email', $email, DAY_IN_SECONDS);
|
408 |
-
} else {
|
409 |
-
$data['email'] = $email;
|
410 |
-
}
|
411 |
-
|
412 |
-
if (isset($_REQUEST['nn'])) {
|
413 |
-
$data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
|
414 |
-
if ($antispam->is_spam_text($data['name'])) {
|
415 |
-
return new WP_Error('spam', 'That name/surname');
|
416 |
-
}
|
417 |
-
}
|
418 |
-
if (isset($_REQUEST['ns'])) {
|
419 |
-
$data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
|
420 |
-
if ($antispam->is_spam_text($data['surname'])) {
|
421 |
-
return new WP_Error('spam', 'That name/surname');
|
422 |
-
}
|
423 |
-
}
|
424 |
-
if ($options_profile['sex_status'] >= 1) {
|
425 |
-
$data['sex'] = $_REQUEST['nx'][0];
|
426 |
-
// Wrong data injection check
|
427 |
-
if ($data['sex'] != 'm' && $data['sex'] != 'f' && $data['sex'] != 'n') {
|
428 |
-
die('Wrong sex field');
|
429 |
-
}
|
430 |
-
}
|
431 |
-
if (isset($_REQUEST['nlng'])) {
|
432 |
-
$languages = $this->get_languages();
|
433 |
-
if (isset($languages[$_REQUEST['nlng']])) {
|
434 |
-
$data['language'] = $_REQUEST['nlng'];
|
435 |
-
}
|
436 |
-
}
|
437 |
-
|
438 |
-
// Lists. If not list is present or there is no list to choose or all are unchecked.
|
439 |
-
$nl = array();
|
440 |
-
if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
|
441 |
-
$nl = $_REQUEST['nl'];
|
442 |
-
}
|
443 |
-
|
444 |
-
// Every possible list shown in the profile must be processed
|
445 |
-
$lists = $this->get_lists_for_profile();
|
446 |
-
foreach ($lists as $list) {
|
447 |
-
$field_name = 'list_' . $list->id;
|
448 |
-
$data[$field_name] = in_array($list->id, $nl) ? 1 : 0;
|
449 |
-
}
|
450 |
-
|
451 |
-
// Profile
|
452 |
-
$profiles = $this->get_profiles_public();
|
453 |
-
foreach ($profiles as $profile) {
|
454 |
-
if (isset($_REQUEST['np' . $profile->id])) {
|
455 |
-
$data['profile_' . $profile->id] = stripslashes($_REQUEST['np' . $profile->id]);
|
456 |
-
}
|
457 |
-
}
|
458 |
-
|
459 |
-
// Feed by Mail service is saved here
|
460 |
-
$data = apply_filters('newsletter_profile_save', $data);
|
461 |
-
|
462 |
-
if ($user->status == TNP_User::STATUS_NOT_CONFIRMED) {
|
463 |
-
$data['status'] = TNP_User::STATUS_CONFIRMED;
|
464 |
-
}
|
465 |
-
|
466 |
-
$user = $this->save_user($data);
|
467 |
-
$this->add_user_log($user, 'profile');
|
468 |
-
|
469 |
-
// Send the activation again only if we use double opt-in, otherwise it has no meaning
|
470 |
-
if ($email_changed && $subscription_module->is_double_optin()) {
|
471 |
-
$user->email = $email;
|
472 |
-
$subscription_module->send_activation_email($user);
|
473 |
-
return $options['email_changed'];
|
474 |
-
}
|
475 |
-
|
476 |
-
return $options['saved'];
|
477 |
-
}
|
478 |
-
|
479 |
-
function admin_menu() {
|
480 |
-
$this->add_admin_page('index', 'Profile');
|
481 |
-
}
|
482 |
-
|
483 |
-
// Patch to avoid conflicts with the "newsletter_profile" option of the subscription module
|
484 |
-
// TODO: Fix it
|
485 |
-
public function get_prefix($sub = '', $language = '') {
|
486 |
-
if (empty($sub)) {
|
487 |
-
$sub = 'main';
|
488 |
-
}
|
489 |
-
return parent::get_prefix($sub, $language);
|
490 |
-
}
|
491 |
-
|
492 |
-
}
|
493 |
-
|
494 |
-
NewsletterProfile::instance();
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined('ABSPATH') || exit;
|
4 |
+
|
5 |
+
class NewsletterProfile extends NewsletterModule {
|
6 |
+
|
7 |
+
static $instance;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return NewsletterProfile
|
11 |
+
*/
|
12 |
+
static function instance() {
|
13 |
+
if (self::$instance == null) {
|
14 |
+
self::$instance = new NewsletterProfile();
|
15 |
+
}
|
16 |
+
return self::$instance;
|
17 |
+
}
|
18 |
+
|
19 |
+
function __construct() {
|
20 |
+
parent::__construct('profile', '1.1.0');
|
21 |
+
add_shortcode('newsletter_profile', array($this, 'shortcode_newsletter_profile'));
|
22 |
+
add_filter('newsletter_replace', array($this, 'hook_newsletter_replace'), 10, 4);
|
23 |
+
add_filter('newsletter_page_text', array($this, 'hook_newsletter_page_text'), 10, 3);
|
24 |
+
add_action('newsletter_action', array($this, 'hook_newsletter_action'), 12, 3);
|
25 |
+
}
|
26 |
+
|
27 |
+
function hook_newsletter_action($action, $user, $email) {
|
28 |
+
|
29 |
+
if (in_array($action, ['p', 'profile', 'pe', 'profile-save', 'profile_export', 'ps'])) {
|
30 |
+
if (!$user || $user->status != TNP_User::STATUS_CONFIRMED) {
|
31 |
+
|
32 |
+
$this->dienow(__('The subscriber was not found or is not confirmed.', 'newsletter'), '', 404);
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
switch ($action) {
|
37 |
+
case 'profile':
|
38 |
+
case 'p':
|
39 |
+
case 'pe':
|
40 |
+
|
41 |
+
$profile_url = $this->build_message_url($this->options['url'], 'profile', $user, $email);
|
42 |
+
$profile_url = apply_filters('newsletter_profile_url', $profile_url, $user);
|
43 |
+
|
44 |
+
wp_redirect($profile_url);
|
45 |
+
die();
|
46 |
+
|
47 |
+
break;
|
48 |
+
|
49 |
+
case 'profile-save':
|
50 |
+
case 'ps':
|
51 |
+
$res = $this->save_profile($user);
|
52 |
+
if (is_wp_error($res)) {
|
53 |
+
wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $res->get_error_message()));
|
54 |
+
die();
|
55 |
+
}
|
56 |
+
|
57 |
+
wp_redirect($this->build_message_url($this->options['url'], 'profile', $user, $email, $res));
|
58 |
+
die();
|
59 |
+
break;
|
60 |
+
|
61 |
+
case 'profile_export':
|
62 |
+
header('Content-Type: application/json;charset=UTF-8');
|
63 |
+
echo $this->to_json($user);
|
64 |
+
die();
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
*
|
70 |
+
* @param stdClass $user
|
71 |
+
*/
|
72 |
+
function get_profile_export_url($user) {
|
73 |
+
return $this->build_action_url('profile_export', $user);
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* URL to the subscriber profile edit action. This URL MUST NEVER be changed by
|
78 |
+
* 3rd party plugins. Plugins can change the final URL after the action has been executed using the
|
79 |
+
* <code>newsletter_profile_url</code> filter.
|
80 |
+
*
|
81 |
+
* @param stdClass $user
|
82 |
+
*/
|
83 |
+
function get_profile_url($user, $email = null) {
|
84 |
+
return $this->build_action_url('profile', $user, $email);
|
85 |
+
}
|
86 |
+
|
87 |
+
function hook_newsletter_replace($text, $user, $email, $html = true) {
|
88 |
+
if (!$user) {
|
89 |
+
$text = $this->replace_url($text, 'PROFILE_URL', $this->build_action_url('nul'));
|
90 |
+
return $text;
|
91 |
+
}
|
92 |
+
|
93 |
+
// Profile edit page URL and link
|
94 |
+
$url = $this->get_profile_url($user, $email);
|
95 |
+
$text = $this->replace_url($text, 'profile_url', $url);
|
96 |
+
// Profile export URL and link
|
97 |
+
$url = $this->get_profile_export_url($user);
|
98 |
+
$text = $this->replace_url($text, 'profile_export_url', $url);
|
99 |
+
|
100 |
+
if (strpos($text, '{profile_form}') !== false) {
|
101 |
+
$text = str_replace('{profile_form}', $this->get_profile_form($user), $text);
|
102 |
+
}
|
103 |
+
return $text;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
*
|
108 |
+
* @param type $text
|
109 |
+
* @param type $key
|
110 |
+
* @param TNP_User $user
|
111 |
+
* @return string
|
112 |
+
*/
|
113 |
+
function hook_newsletter_page_text($text, $key, $user) {
|
114 |
+
if ($key == 'profile') {
|
115 |
+
if (!$user || $user->status == TNP_User::STATUS_UNSUBSCRIBED) {
|
116 |
+
return 'Subscriber not found.';
|
117 |
+
}
|
118 |
+
$options = $this->get_options('main', $this->get_current_language($user));
|
119 |
+
return $options['text'];
|
120 |
+
}
|
121 |
+
return $text;
|
122 |
+
}
|
123 |
+
|
124 |
+
function shortcode_newsletter_profile($attrs, $content) {
|
125 |
+
$user = $this->check_user();
|
126 |
+
|
127 |
+
if (empty($user)) {
|
128 |
+
if (empty($content)) {
|
129 |
+
return __('Subscriber not found.', 'newsletter');
|
130 |
+
} else {
|
131 |
+
return $content;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
return $this->get_profile_form($user);
|
136 |
+
}
|
137 |
+
|
138 |
+
function to_json($user) {
|
139 |
+
global $wpdb;
|
140 |
+
|
141 |
+
|
142 |
+
$fields = array('name', 'surname', 'sex', 'created', 'ip', 'email');
|
143 |
+
$data = array(
|
144 |
+
'email' => $user->email,
|
145 |
+
'name' => $user->name,
|
146 |
+
'last_name' => $user->surname,
|
147 |
+
'gender' => $user->sex,
|
148 |
+
'created' => $user->created,
|
149 |
+
'ip' => $user->ip,
|
150 |
+
);
|
151 |
+
|
152 |
+
// Lists
|
153 |
+
$data['lists'] = array();
|
154 |
+
|
155 |
+
$lists = $this->get_lists_public();
|
156 |
+
foreach ($lists as $list) {
|
157 |
+
$field = 'list_' . $list->id;
|
158 |
+
if ($user->$field == 1) {
|
159 |
+
$data['lists'][] = $list->name;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
// Profile
|
164 |
+
$options_profile = get_option('newsletter_profile', array());
|
165 |
+
$data['profiles'] = array();
|
166 |
+
for ($i = 1; $i < NEWSLETTER_PROFILE_MAX; $i++) {
|
167 |
+
$field = 'profile_' . $i;
|
168 |
+
if ($options_profile[$field . '_status'] != 1 && $options_profile[$field . '_status'] != 2) {
|
169 |
+
continue;
|
170 |
+
}
|
171 |
+
$data['profiles'][] = array('name' => $options_profile[$field], 'value' => $user->$field);
|
172 |
+
}
|
173 |
+
|
174 |
+
// Newsletters
|
175 |
+
if ($this->options['export_newsletters']) {
|
176 |
+
$sent = $wpdb->get_results($wpdb->prepare("select * from {$wpdb->prefix}newsletter_sent where user_id=%d order by email_id asc", $user->id));
|
177 |
+
$newsletters = array();
|
178 |
+
foreach ($sent as $item) {
|
179 |
+
$action = 'none';
|
180 |
+
if ($item->open == 1) {
|
181 |
+
$action = 'read';
|
182 |
+
} else if ($item->open == 2) {
|
183 |
+
$action = 'click';
|
184 |
+
}
|
185 |
+
|
186 |
+
$email = $this->get_email($item->email_id);
|
187 |
+
if (!$email) {
|
188 |
+
continue;
|
189 |
+
}
|
190 |
+
// 'id'=>$item->email_id,
|
191 |
+
$newsletters[] = array('subject' => $email->subject, 'action' => $action, 'sent' => date('Y-m-d h:i:s', $email->send_on));
|
192 |
+
}
|
193 |
+
|
194 |
+
$data['newsletters'] = $newsletters;
|
195 |
+
}
|
196 |
+
|
197 |
+
$extra = apply_filters('newsletter_profile_export_extra', array());
|
198 |
+
|
199 |
+
$data = array_merge($extra, $data);
|
200 |
+
|
201 |
+
return json_encode($data, JSON_PRETTY_PRINT);
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Build the profile editing form for the specified subscriber.
|
206 |
+
*
|
207 |
+
* @param TNP_User $user
|
208 |
+
* @return string
|
209 |
+
*/
|
210 |
+
function get_profile_form($user) {
|
211 |
+
// Do not pay attention to option name here, it's a compatibility problem
|
212 |
+
|
213 |
+
$language = $this->get_user_language($user);
|
214 |
+
$options = NewsletterSubscription::instance()->get_options('profile', $language);
|
215 |
+
|
216 |
+
$buffer = '';
|
217 |
+
|
218 |
+
$buffer .= '<div class="tnp tnp-profile">';
|
219 |
+
$buffer .= '<form action="' . $this->build_action_url('ps') . '" method="post">';
|
220 |
+
$buffer .= '<input type="hidden" name="nk" value="' . esc_attr($user->id . '-' . $user->token) . '">';
|
221 |
+
|
222 |
+
$buffer .= '<div class="tnp-field tnp-field-email">';
|
223 |
+
$buffer .= '<label>' . esc_html($options['email']) . '</label>';
|
224 |
+
$buffer .= '<input class="tnp-email" type="text" name="ne" required value="' . esc_attr($user->email) . '">';
|
225 |
+
$buffer .= "</div>\n";
|
226 |
+
|
227 |
+
|
228 |
+
if ($options['name_status'] >= 1) {
|
229 |
+
$buffer .= '<div class="tnp-field tnp-field-firstname">';
|
230 |
+
$buffer .= '<label>' . esc_html($options['name']) . '</label>';
|
231 |
+
$buffer .= '<input class="tnp-firstname" type="text" name="nn" value="' . esc_attr($user->name) . '"' . ($options['name_rules'] == 1 ? ' required' : '') . '>';
|
232 |
+
$buffer .= "</div>\n";
|
233 |
+
}
|
234 |
+
|
235 |
+
if ($options['surname_status'] >= 1) {
|
236 |
+
$buffer .= '<div class="tnp-field tnp-field-lastname">';
|
237 |
+
$buffer .= '<label>' . esc_html($options['surname']) . '</label>';
|
238 |
+
$buffer .= '<input class="tnp-lastname" type="text" name="ns" value="' . esc_attr($user->surname) . '"' . ($options['surname_rules'] == 1 ? ' required' : '') . '>';
|
239 |
+
$buffer .= "</div>\n";
|
240 |
+
}
|
241 |
+
|
242 |
+
if ($options['sex_status'] >= 1) {
|
243 |
+
$buffer .= '<div class="tnp-field tnp-field-gender">';
|
244 |
+
$buffer .= '<label>' . esc_html($options['sex']) . '</label>';
|
245 |
+
$buffer .= '<select name="nx" class="tnp-gender"';
|
246 |
+
if ($options['sex_rules']) {
|
247 |
+
$buffer .= ' required ';
|
248 |
+
}
|
249 |
+
$buffer .= '>';
|
250 |
+
if ($options['sex_rules']) {
|
251 |
+
$buffer .= '<option value=""></option>';
|
252 |
+
}
|
253 |
+
$buffer .= '<option value="n"' . ($user->sex == 'n' ? ' selected' : '') . '>' . esc_html($options['sex_none']) . '</option>';
|
254 |
+
$buffer .= '<option value="f"' . ($user->sex == 'f' ? ' selected' : '') . '>' . esc_html($options['sex_female']) . '</option>';
|
255 |
+
$buffer .= '<option value="m"' . ($user->sex == 'm' ? ' selected' : '') . '>' . esc_html($options['sex_male']) . '</option>';
|
256 |
+
$buffer .= '</select>';
|
257 |
+
$buffer .= "</div>\n";
|
258 |
+
}
|
259 |
+
|
260 |
+
if ($this->is_multilanguage()) {
|
261 |
+
|
262 |
+
$languages = $this->get_languages();
|
263 |
+
|
264 |
+
$buffer .= '<div class="tnp-field tnp-field-language">';
|
265 |
+
$buffer .= '<label>' . __('Language', 'newsletter') . '</label>';
|
266 |
+
$buffer .= '<select name="nlng" class="tnp-language">';
|
267 |
+
|
268 |
+
$buffer .= '<option value="" disabled ' . ( empty($user->language) ? ' selected' : '' ) . '>' . __('Select language', 'newsletter') . '</option>';
|
269 |
+
foreach ($languages as $key => $l) {
|
270 |
+
$buffer .= '<option value="' . $key . '"' . ( $user->language == $key ? ' selected' : '' ) . '>' . esc_html($l) . '</option>';
|
271 |
+
}
|
272 |
+
|
273 |
+
$buffer .= '</select>';
|
274 |
+
$buffer .= "</div>\n";
|
275 |
+
}
|
276 |
+
|
277 |
+
// Profile
|
278 |
+
$profiles = NewsletterSubscription::instance()->get_profiles_for_profile($user->language);
|
279 |
+
foreach ($profiles as $profile) {
|
280 |
+
$i = $profile->id; // I'm lazy
|
281 |
+
|
282 |
+
$buffer .= '<div class="tnp-field tnp-field-profile">';
|
283 |
+
$buffer .= '<label>' . esc_html($profile->name) . '</label>';
|
284 |
+
|
285 |
+
$field = 'profile_' . $i;
|
286 |
+
|
287 |
+
if ($profile->is_text()) {
|
288 |
+
$buffer .= '<input class="tnp-profile tnp-profile-' . $i . '" type="text" name="np' . $i . '" value="' . esc_attr($user->$field) . '"' .
|
289 |
+
($profile->is_required() ? ' required' : '') . '>';
|
290 |
+
}
|
291 |
+
|
292 |
+
if ($profile->is_select()) {
|
293 |
+
$buffer .= '<select class="tnp-profile tnp-profile-' . $i . '" name="np' . $i . '"' . ($profile->is_required() ? ' required' : '') . '>';
|
294 |
+
foreach ($profile->options as $option) {
|
295 |
+
$buffer .= '<option';
|
296 |
+
if ($option == $user->$field) {
|
297 |
+
$buffer .= ' selected';
|
298 |
+
}
|
299 |
+
$buffer .= '>' . esc_html($option) . '</option>';
|
300 |
+
}
|
301 |
+
$buffer .= '</select>';
|
302 |
+
}
|
303 |
+
|
304 |
+
$buffer .= "</div>\n";
|
305 |
+
}
|
306 |
+
|
307 |
+
// Lists
|
308 |
+
$lists = $this->get_lists_for_profile($language);
|
309 |
+
$tmp = '';
|
310 |
+
foreach ($lists as $list) {
|
311 |
+
|
312 |
+
$tmp .= '<div class="tnp-field tnp-field-list">';
|
313 |
+
$tmp .= '<label><input class="tnp-list tnp-list-' . $list->id . '" type="checkbox" name="nl[]" value="' . $list->id . '"';
|
314 |
+
$field = 'list_' . $list->id;
|
315 |
+
if ($user->$field == 1) {
|
316 |
+
$tmp .= ' checked';
|
317 |
+
}
|
318 |
+
$tmp .= '><span class="tnp-list-label">' . esc_html($list->name) . '</span></label>';
|
319 |
+
$tmp .= "</div>\n";
|
320 |
+
}
|
321 |
+
|
322 |
+
if (!empty($tmp)) {
|
323 |
+
$buffer .= '<div class="tnp-lists">' . "\n" . $tmp . "\n" . '</div>';
|
324 |
+
}
|
325 |
+
|
326 |
+
// Obsolete
|
327 |
+
$extra = apply_filters('newsletter_profile_extra', array(), $user);
|
328 |
+
foreach ($extra as $x) {
|
329 |
+
$buffer .= '<div class="tnp-field">';
|
330 |
+
$buffer .= '<label>' . $x['label'] . "</label>";
|
331 |
+
$buffer .= $x['field'];
|
332 |
+
$buffer .= "</div>\n";
|
333 |
+
}
|
334 |
+
|
335 |
+
$local_options = $this->get_options('', $language);
|
336 |
+
|
337 |
+
// Privacy
|
338 |
+
$privacy_url = NewsletterSubscription::instance()->get_privacy_url();
|
339 |
+
if (!empty($local_options['privacy_label']) && !empty($privacy_url)) {
|
340 |
+
$buffer .= '<div class="tnp-field tnp-field-privacy">';
|
341 |
+
if ($privacy_url) {
|
342 |
+
$buffer .= '<a href="' . $privacy_url . '" target="_blank">';
|
343 |
+
}
|
344 |
+
|
345 |
+
$buffer .= $local_options['privacy_label'];
|
346 |
+
|
347 |
+
if ($privacy_url) {
|
348 |
+
$buffer .= '</a>';
|
349 |
+
}
|
350 |
+
$buffer .= "</div>\n";
|
351 |
+
}
|
352 |
+
|
353 |
+
$buffer .= '<div class="tnp-field tnp-field-button">';
|
354 |
+
$buffer .= '<input class="tnp-submit" type="submit" value="' . esc_attr($local_options['save_label']) . '">';
|
355 |
+
$buffer .= "</div>\n";
|
356 |
+
|
357 |
+
$buffer .= "</form>\n</div>\n";
|
358 |
+
|
359 |
+
return $buffer;
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Saves the subscriber data extracting them from the $_REQUEST and for the
|
364 |
+
* subscriber identified by the <code>$user</code> object.
|
365 |
+
*
|
366 |
+
* @return string|WP_Error If not an error the string represent the message to show
|
367 |
+
*/
|
368 |
+
function save_profile($user) {
|
369 |
+
global $wpdb;
|
370 |
+
|
371 |
+
// Conatains the cleaned up user data to be saved
|
372 |
+
$data = array();
|
373 |
+
$data['id'] = $user->id;
|
374 |
+
|
375 |
+
$options = $this->get_options('', $this->get_current_language($user));
|
376 |
+
$options_profile = get_option('newsletter_profile', array());
|
377 |
+
$options_main = get_option('newsletter_main', array());
|
378 |
+
|
379 |
+
// Not an elegant interaction between modules but...
|
380 |
+
$subscription_module = NewsletterSubscription::instance();
|
381 |
+
|
382 |
+
require_once NEWSLETTER_INCLUDES_DIR . '/antispam.php';
|
383 |
+
|
384 |
+
$antispam = NewsletterAntispam::instance();
|
385 |
+
|
386 |
+
$email = $this->normalize_email(stripslashes($_REQUEST['ne']));
|
387 |
+
|
388 |
+
if ($antispam->is_address_blacklisted($email)) {
|
389 |
+
return new WP_Error('spam', 'That email address is not accepted');
|
390 |
+
}
|
391 |
+
|
392 |
+
if (!$email) {
|
393 |
+
return new WP_Error('email', $options['error']);
|
394 |
+
}
|
395 |
+
|
396 |
+
$email_changed = ($email != $user->email);
|
397 |
+
|
398 |
+
// If the email has been changed, check if it is available
|
399 |
+
if ($email_changed) {
|
400 |
+
$tmp = $this->get_user($email);
|
401 |
+
if ($tmp != null && $tmp->id != $user->id) {
|
402 |
+
return new WP_Error('inuse', $options['error']);
|
403 |
+
}
|
404 |
+
}
|
405 |
+
|
406 |
+
if ($email_changed && $subscription_module->is_double_optin()) {
|
407 |
+
set_transient('newsletter_user_' . $user->id . '_email', $email, DAY_IN_SECONDS);
|
408 |
+
} else {
|
409 |
+
$data['email'] = $email;
|
410 |
+
}
|
411 |
+
|
412 |
+
if (isset($_REQUEST['nn'])) {
|
413 |
+
$data['name'] = $this->normalize_name(stripslashes($_REQUEST['nn']));
|
414 |
+
if ($antispam->is_spam_text($data['name'])) {
|
415 |
+
return new WP_Error('spam', 'That name/surname');
|
416 |
+
}
|
417 |
+
}
|
418 |
+
if (isset($_REQUEST['ns'])) {
|
419 |
+
$data['surname'] = $this->normalize_name(stripslashes($_REQUEST['ns']));
|
420 |
+
if ($antispam->is_spam_text($data['surname'])) {
|
421 |
+
return new WP_Error('spam', 'That name/surname');
|
422 |
+
}
|
423 |
+
}
|
424 |
+
if ($options_profile['sex_status'] >= 1) {
|
425 |
+
$data['sex'] = $_REQUEST['nx'][0];
|
426 |
+
// Wrong data injection check
|
427 |
+
if ($data['sex'] != 'm' && $data['sex'] != 'f' && $data['sex'] != 'n') {
|
428 |
+
die('Wrong sex field');
|
429 |
+
}
|
430 |
+
}
|
431 |
+
if (isset($_REQUEST['nlng'])) {
|
432 |
+
$languages = $this->get_languages();
|
433 |
+
if (isset($languages[$_REQUEST['nlng']])) {
|
434 |
+
$data['language'] = $_REQUEST['nlng'];
|
435 |
+
}
|
436 |
+
}
|
437 |
+
|
438 |
+
// Lists. If not list is present or there is no list to choose or all are unchecked.
|
439 |
+
$nl = array();
|
440 |
+
if (isset($_REQUEST['nl']) && is_array($_REQUEST['nl'])) {
|
441 |
+
$nl = $_REQUEST['nl'];
|
442 |
+
}
|
443 |
+
|
444 |
+
// Every possible list shown in the profile must be processed
|
445 |
+
$lists = $this->get_lists_for_profile();
|
446 |
+
foreach ($lists as $list) {
|
447 |
+
$field_name = 'list_' . $list->id;
|
448 |
+
$data[$field_name] = in_array($list->id, $nl) ? 1 : 0;
|
449 |
+
}
|
450 |
+
|
451 |
+
// Profile
|
452 |
+
$profiles = $this->get_profiles_public();
|
453 |
+
foreach ($profiles as $profile) {
|
454 |
+
if (isset($_REQUEST['np' . $profile->id])) {
|
455 |
+
$data['profile_' . $profile->id] = stripslashes($_REQUEST['np' . $profile->id]);
|
456 |
+
}
|
457 |
+
}
|
458 |
+
|
459 |
+
// Feed by Mail service is saved here
|
460 |
+
$data = apply_filters('newsletter_profile_save', $data);
|
461 |
+
|
462 |
+
if ($user->status == TNP_User::STATUS_NOT_CONFIRMED) {
|
463 |
+
$data['status'] = TNP_User::STATUS_CONFIRMED;
|
464 |
+
}
|
465 |
+
|
466 |
+
$user = $this->save_user($data);
|
467 |
+
$this->add_user_log($user, 'profile');
|
468 |
+
|
469 |
+
// Send the activation again only if we use double opt-in, otherwise it has no meaning
|
470 |
+
if ($email_changed && $subscription_module->is_double_optin()) {
|
471 |
+
$user->email = $email;
|
472 |
+
$subscription_module->send_activation_email($user);
|
473 |
+
return $options['email_changed'];
|
474 |
+
}
|
475 |
+
|
476 |
+
return $options['saved'];
|
477 |
+
}
|
478 |
+
|
479 |
+
function admin_menu() {
|
480 |
+
$this->add_admin_page('index', 'Profile');
|
481 |
+
}
|
482 |
+
|
483 |
+
// Patch to avoid conflicts with the "newsletter_profile" option of the subscription module
|
484 |
+
// TODO: Fix it
|
485 |
+
public function get_prefix($sub = '', $language = '') {
|
486 |
+
if (empty($sub)) {
|
487 |
+
$sub = 'main';
|
488 |
+
}
|
489 |
+
return parent::get_prefix($sub, $language);
|
490 |
+
}
|
491 |
+
|
492 |
+
}
|
493 |
+
|
494 |
+
NewsletterProfile::instance();
|
readme.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
=== Newsletter - Send awesome emails from WordPress ===
|
2 |
Tags: newsletter, email marketing, welcome email, signup forms, lead generation, marketing automation
|
3 |
Tested up to: 6.1
|
4 |
-
Stable tag: 7.5.
|
5 |
Contributors: satollo,webagile,michael-travan
|
6 |
License: GPLv2 or later
|
7 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
@@ -126,6 +126,10 @@ Thank you, The Newsletter Team
|
|
126 |
|
127 |
== Changelog ==
|
128 |
|
|
|
|
|
|
|
|
|
129 |
= 7.5.4 =
|
130 |
|
131 |
* Fixed composer icons path for Amazon AWS+Bitnami installations
|
1 |
=== Newsletter - Send awesome emails from WordPress ===
|
2 |
Tags: newsletter, email marketing, welcome email, signup forms, lead generation, marketing automation
|
3 |
Tested up to: 6.1
|
4 |
+
Stable tag: 7.5.5
|
5 |
Contributors: satollo,webagile,michael-travan
|
6 |
License: GPLv2 or later
|
7 |
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
126 |
|
127 |
== Changelog ==
|
128 |
|
129 |
+
= 7.5.5 =
|
130 |
+
|
131 |
+
* Fixed access control on form manager base class
|
132 |
+
|
133 |
= 7.5.4 =
|
134 |
|
135 |
* Fixed composer icons path for Amazon AWS+Bitnami installations
|