PluginProbe
PilotPress / trunk
PilotPress vtrunk
trunk 1.9.2 1.9.3 1.9.5 2.0.7 stable
pilotpress / pilotpress.php

pilotpress.php in PilotPress trunk, at pilotpress.php

4,716 lines 195.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: PilotPress
4 Plugin URI: https://ontraport.com/
5 Description: ONTRAPORT WordPress integration plugin.
6 Version: 2.0.39
7 Author: ONTRAPORT Inc.
8 Author URI: https://ontraport.com/
9 Text Domain: pilotpress
10 Copyright: 2025, Ontraport
11 */
12
13 define("JS_DIR", plugin_dir_url(__FILE__) . "js/");
14
15 if(defined("ABSPATH")) {
16 global $wp_version;
17 if (version_compare($wp_version,"5.9","<="))
18 {
19 include_once(ABSPATH.WPINC.'/class-http.php');
20 }
21 else
22 {
23 include_once(ABSPATH.WPINC.'/class-wp-http.php');
24 }
25 if (version_compare($wp_version,"3.1","<"))
26 {
27 include_once(ABSPATH.WPINC.'/registration.php');
28 }
29 register_activation_hook(__FILE__, "enable_pilotpress");
30 register_deactivation_hook(__FILE__, "disable_pilotpress");
31 $pilotpress = new PilotPress;
32 //create and load up the PilotPress Text Widget statically
33 add_action( 'widgets_init',array( 'PilotPress_Widget', 'register' ) );
34 //Hook into the admin footer so as to load this JS
35 add_action( 'admin_footer-widgets.php' , "pilotpress_widget_js" );
36 }
37
38
39
40 class PilotPress {
41
42 const VERSION = "2.0.39";
43 const WP_MIN = "3.6";
44 const NSPACE = "_pilotpress_";
45 const AUTH_SALT = "M!E%VxpKvuQHn!PTPOTohtLbnOl&)5&0mb(Uj^c#Zz!-0898yfS#7^xttNW(x1ia";
46 const TTL = 43200; /* 60*60*12 --> 12 hours in seconds */
47 const FIVE_MINUTES = 300; //seconds
48
49 public $system_pages = array();
50
51 public static $brand = "ONTRAPORT";
52 public static $brand_url = "ontraport.com";
53 public static $url_api = "https://api.ontraport.com/pilotpress.php";
54
55 // Will be init on construct, can't use defines + concat here
56 public static $path_jqcss;
57 public static $path_tjs;
58 public static $path_jswpcss;
59 public static $path_mrcss;
60
61 //WP post statuses
62 public static $valid_state = array(
63 "publish",
64 "draft"
65 );
66
67 /* Used for keeping a record of the current shortcodes to be merged */
68 public $shortcodeFields = array();
69
70 /* the various Centers */
71 public $centers = array(
72 "customer_center" => array(
73 "title" => "Customer Center",
74 "slug" => "customer-center",
75 "content" => "This content will be replaced by the Customer Center"
76 ),
77 "affiliate_center" => array(
78 "title" => "Partner Center",
79 "slug" => "partner-center",
80 "content" => "This content will be replaced by the Partner Center"
81 ),
82 );
83
84 /* Various runtime, shared variables */
85 private $uri;
86 private $metaboxes;
87 private $settings;
88 private $api_version;
89 private $status = 0;
90 private $do_login = false;
91 private $homepage_url;
92 private $incrementalnumber = 1;
93 private $tagsSequences;
94 private static $stashed_transients = array();
95
96 //Global ppprotect-category reference
97 private $ppp;
98
99 function __construct()
100 {
101 self::$path_jqcss = JS_DIR . "jquery-ui.css";
102 self::$path_tjs = JS_DIR . "tracking.js";
103 self::$path_jswpcss = JS_DIR . "moonrayJS-only-wp-forms.css";
104 self::$path_mrcss = JS_DIR . "moonray.css";
105 // Includes new ppprotect class that has enhanced protections for things like categories etc.
106 require_once( plugin_dir_path( __FILE__ ) . 'ppprotect-categories.php');
107 $this->ppp = new PPProtect();
108
109 $this->bind_hooks(); /* hook into WP */
110 $this->start_session();
111
112 $this->ppp->ppprotectHooks();
113
114 /* use this var, it's handy */
115 $this->uri = plugins_url('pilotpress', __FILE__);
116
117
118
119 if (get_transient("pilotpress_admin_preview"))
120 {
121 self::$stashed_transients["pilotpress_admin_preview"] = array(get_transient("pilotpress_admin_preview"));
122 delete_transient("pilotpress_admin_preview");
123 }
124 }
125
126 /* this function loads up runtime settings from API or transient caches for both plugin and user (if logged in) */
127 function load_settings() {
128 global $wpdb;
129
130 $this->system_pages = $this->get_system_pages();
131
132 if(get_transient('pilotpress_cache')) {
133 $this->settings = get_transient('pilotpress_cache');
134 $this->api_version = get_option("pilotpress_api_version");
135
136 // for debugging
137 if(is_file(ABSPATH . "/pp_debug_include.php"))
138 {
139 include_once(ABSPATH . "/pp_debug_include.php");
140 }
141
142 $this->settings["user"] = $this->get_user_settings();
143 $contact_id = $this->get_setting("contact_id", "user");
144
145 if(get_transient("usertags_".$contact_id))
146 {
147 $tags = get_transient("usertags_".$contact_id);
148 }
149 else
150 {
151 if (!empty($contact_id))
152 {
153 $tags = $this->api_call("get_contact_tags", array("contact_id" => $contact_id));
154 set_transient('usertags_'.$contact_id, $tags, self::TTL);
155 }
156 }
157
158 if(!empty($tags) && is_array($tags["tags"])) {
159 $this->settings["user"]["tags"] = $tags["tags"];
160 }
161
162 $this->status = 1;
163
164 if($this->get_setting("usehome")) {
165 $this->homepage_url = home_url();
166 } else {
167 $this->homepage_url = site_url();
168 }
169
170 $user_info= $this->get_stashed("authenticate_user", true);
171
172 if (isset($user_info["authenticate_user"]) && !is_bool($user_info["authenticate_user"]))
173 {
174 $this->ppp->ppprotectSetPPMemLevels($user_info["authenticate_user"]["membership_level"]);
175 }
176 $this->ppp->ppprotectSetPPSiteLevels($this->get_setting("membership_levels", "oap", true));
177
178 } else {
179
180 $this->settings["wp"] = array();
181 $this->settings["wp"]["post_types"] = array();
182 $this->settings["wp"]["permalink"] = get_option('permalink_structure');
183 $this->settings["wp"]["template"] = get_option('template');
184 $this->settings["wp"]["plugins"] = get_option('active_plugins');
185 $this->settings["wp"]["post_types"] = get_post_types();
186
187 $this->settings["pilotpress"] = get_option("pilotpress-settings");
188 if (!is_array($this->settings["pilotpress"])) {
189 $this->settings["pilotpress"] = array();
190 }
191
192 $this->api_version = get_option("pilotpress_api_version");
193
194 if($this->get_setting("usehome")) {
195 $this->homepage_url = home_url();
196 } else {
197 $this->homepage_url = site_url();
198 }
199
200 $this->settings["pilotpress"]["error_redirect_field"] = 'select-keyvalue';
201 $this->settings["pilotpress"]["error_redirect_message"] = "Redirect to THIS page on error.";
202
203 $results = $wpdb->get_results("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_show_in_nav'", ARRAY_A);
204 if (is_array($results))
205 {
206 foreach($results as $index => $page) {
207 $this->settings["pilotpress"]["show_in_nav"][] = $page["post_id"];
208 }
209 }
210
211
212 if($this->get_setting("api_key") && $this->get_setting("app_id")) {
213
214 //check if these are stored in the cache first
215 $pilotPressTrackingURL = get_transient("pilotpress_tracking_url");
216 $pilotPressTracking = get_transient("pilotpress_tracking");
217 $pilotPressWebchatEntryURL = get_transient("pilotpress_webchat_entry_url");
218 $getSiteSettings = true;
219
220 if ($pilotPressTrackingURL !== false && $pilotPressTracking !== false && $pilotPressWebchatEntryURL !== false)
221 {
222 $this->settings["oap"]["tracking_url"] = $pilotPressTrackingURL;
223 $this->settings["oap"]["tracking"] = $pilotPressTracking;
224 $this->settings["oap"]["webchat_entry_url"] = $pilotPressWebchatEntryURL;
225 $getSiteSettings = false;
226 }
227
228 //Check to make sure we really need to even make this API call...
229 if (is_user_logged_in() || $getSiteSettings )
230 {
231 $contact_id = false;
232
233 if (isset($_COOKIE["contact_id"]))
234 {
235 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
236 }
237
238 //Only make use of cookie if not an admin user.
239 if( $contact_id !== false
240 && !current_user_can('manage_options')
241 )
242 {
243 global $current_user;
244 wp_get_current_user();
245 $username = $current_user->user_login;
246 $api_result = $this->api_call("get_site_settings", array("site" => site_url(), "contact_id" => (int) $contact_id, "username" => $username , "version"=>self::VERSION ));
247 }
248 else
249 {
250 $api_result = $this->api_call("get_site_settings", array("site" => site_url() , "version"=>self::VERSION ));
251 }
252
253 if(is_array($api_result))
254 {
255 $this->settings["oap"] = $api_result;
256
257 if(isset($this->settings["user"]))
258 {
259 unset($this->settings["user"]);
260 }
261
262 $this->ppp->ppprotectSetPPMemLevels($api_result["membership_levels"]);
263 $this->ppp->ppprotectSetPPSiteLevels($this->get_setting("membership_levels", "oap", true));
264
265 set_transient('pilotpress_cache', $this->settings, self::TTL * 2); //24 hrs
266
267 $_SESSION["default_fields"] = $this->settings["oap"]["default_fields"];
268
269
270 if(isset($api_result["membership_level"])) {
271 $_SESSION["user_levels"] = $api_result["membership_level"];
272 if(!empty($username))
273 {
274 $_SESSION["user_name"] = $username;
275 }
276 }
277
278 $this->status = 1;
279
280
281 //Lets store the API version into their options table if available
282 if (isset($api_result["pilotpress_api_version"]))
283 {
284 update_option("pilotpress_api_version" , $api_result["pilotpress_api_version"]);
285 }
286
287
288 //Cache the tracking link and custom domain so we can avoid calling this every page load
289 if (isset($api_result["tracking_url"]))
290 {
291 set_transient('pilotpress_tracking_url', $api_result["tracking_url"],self::TTL * 2); //24 hrs
292 }
293
294
295 if (isset($api_result["tracking"]))
296 {
297 set_transient('pilotpress_tracking', $api_result["tracking"],self::TTL * 2); //24 hrs
298 }
299
300 //Cache the web chat widget url too; empty means web chat is off for this site (or the API predates it)
301 set_transient('pilotpress_webchat_entry_url', isset($api_result["webchat_entry_url"]) ? $api_result["webchat_entry_url"] : "", self::TTL * 2); //24 hrs
302
303 }
304 }
305 } else {
306 $this->status = 0;
307 }
308
309 $this->settings["user"] = $this->get_user_settings();
310 if($this->get_setting("contact_id", "user")) {
311 if(get_transient("usertags_".$this->get_setting("contact_id", "user"))) {
312 $tags = get_transient("usertags_".$this->get_setting("contact_id", "user"));
313 } else {
314 $tags = $this->api_call("get_contact_tags", array("contact_id" => $this->get_setting("contact_id", "user")));
315 set_transient('usertags_'.$this->get_setting("contact_id", "user"), $tags, self::TTL);
316 }
317 if(is_array($tags["tags"])) {
318 $this->settings["user"]["tags"] = $tags["tags"];
319 }
320 }
321 }
322 }
323
324 /* what protocol? */
325 static function get_protocol() {
326 if(isset($_SERVER["HTTPS"])) {
327 if(!empty($_SERVER["HTTPS"])) {
328 return "https://";
329 }
330 }
331 return "http://";
332 }
333
334 /* add metaboxes to said post types */
335 function update_post_types() {
336
337 $exclude = array("attachment","revision","nav_menu_item");
338 $array = $this->get_setting("post_types","wp");
339
340 $post_types = get_post_types('','names');
341 if (is_array($post_types))
342 {
343 foreach($post_types as $post_type) {
344 if(!in_array($post_type, $array) && !in_array($post_type, $exclude)) {
345 $array[] = $post_type;
346 }
347 }
348 }
349
350
351 $this->settings["wp"]["post_types"] = $array;
352
353 }
354
355 function get_setting($key, $type = "pilotpress", $array = false) {
356 if(isset($this->settings[$type][$key])) {
357 if(!is_array($this->settings[$type][$key]) && $array) {
358 return array($this->settings[$type][$key]);
359 } else {
360 return $this->settings[$type][$key];
361 }
362 } else {
363 if($array) {
364 return array();
365 } else {
366 return false;
367 }
368 }
369 }
370
371 /**
372 * @brief grab field for shortcode_field
373 *
374 * @param string $key
375 * @return string $field
376 */
377 function get_field($key)
378 {
379 $key = $this->undo_quote_escaping($key);
380
381 foreach($this->get_setting("fields", "user", true) as $group => $fields)
382 {
383 if(isset($fields[$key]))
384 {
385 return $fields[$key];
386 }
387 else if (isset($fields[html_entity_decode($key,ENT_COMPAT,"UTF-8")]))
388 {
389 return $fields[html_entity_decode($key,ENT_COMPAT,"UTF-8")];
390 }
391
392 }
393
394 foreach($this->get_setting("default_fields", "oap", true) as $group => $fields)
395 {
396 if(isset($fields[$key]))
397 {
398 return $fields[$key];
399 }
400 else if (isset($fields[html_entity_decode($key,ENT_COMPAT,"UTF-8")]))
401 {
402 return $fields[html_entity_decode($key,ENT_COMPAT,"UTF-8")];
403 }
404 }
405
406 return "";
407 }
408
409 function is_setup()
410 {
411 if($this->status != 0)
412 {
413 return true;
414 }
415 else
416 {
417 return false;
418 }
419 }
420
421 /* this is a fancy getter, for user settings */
422 function get_user_settings() {
423 $return = array();
424 $user_info = $this->get_stashed("authenticate_user", true);
425
426 if (isset($user_info["authenticate_user"]['contact_id'])) {
427 $return["contact_id"] = $user_info["authenticate_user"]["contact_id"];
428 }
429
430 if(isset($user_info["authenticate_user"]["membership_level"])) {
431 $return["name"] = $user_info["authenticate_user"]["username"];
432 $return["username"] = $user_info["authenticate_user"]["username"];
433 $return["nickname"] = $user_info["authenticate_user"]["nickname"];
434 $return["levels"] = $user_info["authenticate_user"]["membership_level"];
435 }
436 return $return;
437 }
438
439 /* finally some fun: this sets up the admin edit page! */
440 function settings_init() {
441
442 add_options_page('PilotPress Settings' , 'PilotPress', 'manage_options', 'pilotpress-settings', array(&$this, 'settings_page'));
443 register_setting('pilotpress-settings', 'pilotpress-settings', array(&$this, 'settings_validate'));
444
445 add_settings_section('pilotpress-settings-general', __('General Settings', 'pilotpress'), array(&$this, 'settings_section_general'), 'pilotpress-settings');
446 add_settings_field('pilotpress_app_id', __('Application ID', 'pilotpress'), array(&$this, 'display_settings_app_id'), 'pilotpress-settings', 'pilotpress-settings-general');
447 add_settings_field('pilotpress_api_key', __('API Key', 'pilotpress'), array(&$this, 'display_settings_api_key'), 'pilotpress-settings', 'pilotpress-settings-general');
448 add_settings_field('wp_userlockout', __('Lock all users without Admin role out of profile editor', 'pilotpress'), array(&$this, 'display_settings_userlockout'), 'pilotpress-settings', 'pilotpress-settings-general');
449
450 add_settings_section('settings_section_oap', __(self::$brand . ' Integration Settings', 'pilotpress'), array(&$this, 'settings_section_oap'), 'pilotpress-settings');
451 add_settings_field('customer_center', __('Enable Customer Center', 'pilotpress'), array(&$this, 'display_settings_cc'), 'pilotpress-settings', 'settings_section_oap');
452 add_settings_field('affiliate_center', __('Enable Partner Center', 'pilotpress'), array(&$this, 'display_settings_ac'), 'pilotpress-settings', 'settings_section_oap');
453 add_settings_field('center_priority', __('Which center has priority when redirecting?'), array(&$this, 'display_settings_cpriority'), 'pilotpress-settings', 'settings_section_oap');
454 add_settings_field('discrete_nickname', __("Enable Discrete Nicknames <br> <br> Uses first part of email address rather than first and last name."), array(&$this, 'display_settings_nicknames'), 'pilotpress-settings', 'settings_section_oap');
455
456 add_settings_section('pilotpress-redirect-display', __('Post Login Redirect Settings', 'pilotpress'), array(&$this, 'settings_section_redirect'), 'pilotpress-settings');
457 add_settings_field('pilotpress_customer_plr', __('Customers Redirect To', 'pilotpress'), array(&$this, 'display_settings_customer_plr'), 'pilotpress-settings', 'pilotpress-redirect-display');
458 add_settings_field('pilotpress_affiliate_plr', __('Partners Redirect To', 'pilotpress'), array(&$this, 'display_settings_affiliate_plr'), 'pilotpress-settings', 'pilotpress-redirect-display');
459
460 //Add the Customer Center Settings
461 add_settings_section('pilotpress-customer-center-display', __('Customer Center Settings', 'pilotpress'), array(&$this, 'settings_section_customer_settings'), 'pilotpress-settings');
462 add_settings_field('pilotpress_customer_center_header_image', __('Custom Header Image', 'pilotpress'), array(&$this, 'display_settings_customer_center_header_image'), 'pilotpress-settings', 'pilotpress-customer-center-display');
463 add_settings_field('pilotpress_customer_center_primary_color', __('Primary Color', 'pilotpress'), array(&$this, 'display_settings_customer_center_primary_color'), 'pilotpress-settings', 'pilotpress-customer-center-display');
464 add_settings_field('pilotpress_customer_center_secondary_color', __('Secondary (Background) Color', 'pilotpress'), array(&$this, 'display_settings_customer_center_secondary_color'), 'pilotpress-settings', 'pilotpress-customer-center-display');
465
466 //Add the New User Register Settings
467 add_settings_section('pilotpress-new-user-display', __('New User Register Settings', 'pilotpress'), array(&$this, 'settings_section_new_user_settings'), 'pilotpress-settings');
468 add_settings_field('pilotpress_sync_users', __('Sync WordPress users to your ONTRAPORT contacts', 'pilotpress'), array(&$this, 'display_settings_sync_users'), 'pilotpress-settings', 'pilotpress-new-user-display');
469 add_settings_field('pilotpress_newly_registered_tags', __('What tags should they have?', 'pilotpress'), array(&$this, 'display_settings_newly_registered_tags'), 'pilotpress-settings', 'pilotpress-new-user-display');
470 add_settings_field('pilotpress_newly_registered_sequences', __('What sequences should they be on?', 'pilotpress'), array(&$this, 'display_settings_newly_registered_sequences'), 'pilotpress-settings', 'pilotpress-new-user-display');
471 add_settings_field('pilotpress_newly_registered_campaigns', __('What automations should they be on?', 'pilotpress'), array(&$this, 'display_settings_newly_registered_campaigns'), 'pilotpress-settings', 'pilotpress-new-user-display');
472
473
474 //Add the Logout Settings
475 add_settings_section('pilotpress-logout-users-display', __('Logout Settings', 'pilotpress'), array(&$this, 'settings_section_logout_settings'), 'pilotpress-settings');
476 add_settings_field('pilotpress_logout_users', __('Would you like to keep users logged into your site longer than normal? <br /> <br /> <i>(*Please note that if the browser is closed for a long period the user will have to log in again.</i>) ', 'pilotpress'), array(&$this, 'display_settings_logout_users'), 'pilotpress-settings', 'pilotpress-logout-users-display');
477
478
479 add_settings_section('pilotpress-settings-advanced', __('Advanced Settings', 'pilotpress'), array(&$this, 'settings_section_advanced'), 'pilotpress-settings');
480 add_settings_field('pp_sslverify', __('Disable Verify Host SSL', 'pilotpress'), array(&$this, 'display_settings_disablesslverify'), 'pilotpress-settings', 'pilotpress-settings-advanced');
481 add_settings_field('pp_use_home', __('Use WordPress URL instead of Site URL', 'pilotpress'), array(&$this, 'display_settings_usehome'), 'pilotpress-settings', 'pilotpress-settings-advanced');
482 }
483
484 /* WP is sometimes silly, this is a function to echo a checkbox and have it registered.. annoying but easy */
485 function display_settings_cc() {
486 echo "<input type='checkbox' name='pilotpress-settings[customer_center]'";
487 if($this->get_setting("customer_center")) {
488 echo " checked";
489 }
490 echo ">";
491 }
492
493 /* ditto */
494 function display_settings_ac() {
495 echo "<input type='checkbox' name='pilotpress-settings[affiliate_center]'";
496 if($this->get_setting("affiliate_center")) {
497 echo " checked";
498 }
499 echo ">";
500 }
501
502 /**
503 * @brief output priority redirection settings HTML
504 **/
505 function display_settings_cpriority()
506 {
507 $centers_active = array("Partner Center" => $this->get_setting("affiliate_center"), "Customer Center" => $this->get_setting("customer_center"));
508 $settings = $this->get_setting("center_priority");
509 $incrementer = 1;
510
511 echo "<select name=pilotpress-settings[center_priority]>";
512 echo "<option value='0' selected='selected'>Please select one</option>";
513 if (is_array($centers_active))
514 {
515 foreach ($centers_active as $center => $setting)
516 {
517 echo "<option value='".$incrementer."' ".selected($settings, $incrementer).">".$center."</option>";
518 $incrementer++;
519 }
520 }
521
522 echo "</select>";
523 }
524
525 /**
526 * @brief output discrete nicknames checkbox HTML (OIR-3224)
527 */
528 function display_settings_nicknames()
529 {
530 echo "<input type='checkbox' name='pilotpress-settings[discrete_nickname]'";
531 if($this->get_setting("discrete_nickname")) {
532 echo " checked";
533 }
534 echo ">";
535 }
536
537
538 /* customer center settings */
539 function display_settings_customer_plr() {
540
541 $setting = $this->get_setting("pilotpress_customer_plr");
542 if(!$setting) {
543 $setting = "-1";
544 }
545
546 $pages = $this->get_routeable_pages(array("-2"));
547 echo "<select name='pilotpress-settings[pilotpress_customer_plr]'>";
548 if (is_array($pages))
549 {
550 foreach($pages as $id => $title) {
551 echo "<option value='{$id}'";
552 if($id == $setting) {
553 echo " selected";
554 }
555 echo ">{$title}</option>";
556 }
557 }
558
559 echo "</select>";
560 }
561
562 /* ditto, but for affil center */
563 function display_settings_affiliate_plr() {
564
565 $setting = $this->get_setting("pilotpress_affiliate_plr");
566 if(!$setting) {
567 $setting = "-1";
568 }
569
570 $pages = $this->get_routeable_pages(array("-2"));
571 echo "<select name='pilotpress-settings[pilotpress_affiliate_plr]'>";
572 if (is_array($pages))
573 {
574 foreach($pages as $id => $title) {
575 echo "<option value='{$id}'";
576 if($id == $setting) {
577 echo " selected";
578 }
579 echo ">{$title}</option>";
580 }
581 }
582 echo "</select>";
583 }
584
585 /** @brief settings hook for showing the customer center header image */
586 function display_settings_customer_center_header_image()
587 {
588 $setting = $this->get_setting("pilotpress_customer_center_header_image");
589 if (!$setting){
590 $setting = "";
591 }
592
593 $output = "<input name='pilotpress-settings[pilotpress_customer_center_header_image]' class='pilotpress_customer_center_header_image_url' type='text' name='header_logo' size='60' value='$setting'>
594 <a href='#' class='button pilotpress_header_logo_upload'>Upload</a>";
595
596 echo $output;
597
598 }
599
600 /** @brief settings hook for showing the customer center primary color */
601 function display_settings_customer_center_primary_color()
602 {
603 $setting = $this->get_setting("pilotpress_customer_center_primary_color");
604 if (!$setting){
605 $setting = "";
606 }
607 $output = "<input type='text' name='pilotpress-settings[pilotpress_customer_center_primary_color]' id='primary-color' value='".$setting."' data-default-color='#ffffff' class='pilotpress-color-picker' />";
608
609 echo $output;
610
611 }
612
613 /** @brief settings hook for showing the customer center secondary (background) color */
614 function display_settings_customer_center_secondary_color()
615 {
616 $setting = $this->get_setting("pilotpress_customer_center_secondary_color");
617 if (!$setting){
618 $setting = "";
619 }
620 $output = "<input type='text' name='pilotpress-settings[pilotpress_customer_center_secondary_color]' id='secondary-color' value='".$setting."' data-default-color='#ffffff' class='pilotpress-color-picker' />";
621
622 echo $output;
623 }
624
625 /** @brief settings hook for showing the various sync_users options (yes --new, yes --new & existing, no) **/
626 function display_settings_sync_users()
627 {
628 $setting = $this->get_setting("pilotpress_sync_users");
629 if(!$setting)
630 {
631 $setting = "-1";
632 }
633 echo "<select name=pilotpress-settings[pilotpress_sync_users]>";
634 echo "<option value='0' ".selected($setting, 0).">No</option>";
635 echo "<option value='1' ".selected($setting, 1).">Yes, new users only</option>";
636 echo "<option value='2' ".selected($setting, 2).">Yes, new and existing users";
637 echo "</select>";
638 }
639
640 /** @brief displays the setting for the campaigns that should be added to the new user */
641 function display_settings_newly_registered_campaigns()
642 {
643 $setting = $this->get_setting("pilotpress_newly_registered_campaigns");
644 if (!$setting){
645 $setting = "-1";
646 }
647 $output = "<select multiple name=pilotpress-settings[pilotpress_newly_registered_campaigns][]>";
648 $campaigns = json_decode($this->tagsSequences["campaigns"] ,true );
649 if(is_array($campaigns))
650 {
651 foreach ($campaigns as $campaign)
652 {
653 $selected = "";
654 if(is_array($setting))
655 {
656 if (in_array($campaign['id'], $setting))
657 {
658 $selected = "selected='selected'";
659 }
660 }
661 $output .= "<option value='".$campaign['id']."' ".$selected . ">" .$campaign['name']."</option>";
662 }
663 }
664 $output .= "</select>";
665 echo $output;
666 }
667
668 /** @brief displays the setting for the sequences that should be added to the new user */
669 function display_settings_newly_registered_sequences()
670 {
671 $setting = $this->get_setting("pilotpress_newly_registered_sequences");
672 if (!$setting){
673 $setting = "-1";
674 }
675 $output = "<select multiple name=pilotpress-settings[pilotpress_newly_registered_sequences][]>";
676 $sequences = json_decode($this->tagsSequences["sequences"] ,true );
677 if(is_array($sequences))
678 {
679 foreach ($sequences as $sequence)
680 {
681 $selected = "";
682 if(is_array($setting))
683 {
684 if (in_array($sequence['drip_id'], $setting))
685 {
686 $selected = "selected='selected'";
687 }
688 }
689 $output .= "<option value='".$sequence['drip_id']."' ".$selected . ">" .$sequence['name']."</option>";
690 }
691 }
692 $output .= "</select>";
693 echo $output;
694 }
695
696 /** @brief displays the setting for the tags to be added to new users */
697 function display_settings_newly_registered_tags()
698 {
699 $setting = $this->get_setting("pilotpress_newly_registered_tags");
700 if (!$setting){
701 $setting = "";
702 }
703 $output = "<select multiple name=pilotpress-settings[pilotpress_newly_registered_tags][]>";
704 $tags = json_decode($this->tagsSequences["tags"] , true );
705 if(is_array($tags))
706 {
707 foreach ($tags as $tag)
708 {
709 $selected = "";
710 if(is_array($setting))
711 {
712 if (in_array($tag['tag_name'], $setting))
713 {
714 $selected = "selected='selected'";
715 }
716 }
717 $output .= "<option value='".$tag['tag_name']."' ".$selected . ">" .$tag['tag_name']."</option>";
718 }
719 }
720 $output .= "</select>";
721 echo $output;
722 }
723
724 /** @brief displays the setting for enabling or disabling logout duration settings */
725 function display_settings_logout_users()
726 {
727 $setting = $this->get_setting("pilotpress_logout_users");
728 if (!$setting){
729 $setting = "-1";
730 }
731 echo "<select name=pilotpress-settings[pilotpress_logout_users]>";
732 echo "<option value='0' ".selected( $setting, 0 ).">No</option>";
733 echo "<option value='1' ".selected( $setting, 1 ).">Yes</option>";
734 echo "</select>";
735 }
736
737 /* section output, blank for austerity */
738 function settings_section_customer_settings() {}
739 function settings_section_new_user_settings() {}
740 function settings_section_logout_settings() {}
741 function settings_section_general() {}
742 function settings_section_oap() {}
743 function settings_section_redirect() {}
744 function settings_section_advanced() {
745 echo "<span class='pilotpress-advanced-warning'><b>WARNING:</b> these settings affect the core functionality of the PilotPress plugin, proceed with caution.</span>";
746 }
747
748 /* notices! this is where the magic nags happen */
749 function display_notice() {
750
751 global $post, $wp_version;
752
753 if(basename($_SERVER["SCRIPT_NAME"]) == "post.php" && isset($_GET["action"]) && sanitize_text_field($_GET["action"]) == "edit" && in_array($post->ID, $this->system_pages)) {
754 echo '<div class="updated"><p>This page is used by the <b>PilotPress</b> plugin. You can edit the content but not delete the page itself.</p></div>';
755 }
756
757 if($wp_version < self::WP_MIN) {
758 echo '<div class="error" style="padding-top: 5px; padding-bottom: 5px;">';
759 _e('PilotPress requires WordPress '.self::WP_MIN.' or higher. Please de-activate the PilotPress plugin, upgrade to WordPress '.self::WP_MIN.' or higher then activate PilotPress again.', 'pilotpress');
760 echo '</div>';
761 }
762
763 if (!$this->get_setting('api_key') || !$this->get_setting('app_id')) {
764
765 echo '<div class="error" style="padding-top: 5px; padding-bottom: 5px;">';
766 _e('PilotPress must be configured with an ' . self::$brand . ' API Key and App ID.', 'pilotpress');
767
768 if(isset($_GET['page']) && sanitize_text_field($_GET['page']) != 'pilotpress-settings') {
769 _e(sprintf('Go to the <a href="%s" title="PilotPress Admin Page">PilotPress Admin Page</a> to finish setting up your site!', 'options-general.php?page=pilotpress-settings'), 'pilotpress');
770 echo ' ' ;
771 _e(sprintf('You need an <a href="%s" title="Visit '. self::$brand_url .'">' . self::$brand . '</a> account to use this plugin.', 'http://' . self::$brand_url));
772 echo ' ';
773 _e('Don\'t have one yet?', 'pilotpress');
774 echo ' ';
775 _e(sprintf('<a href="%s" title="' . self::$brand . ' SignUp">Sign up</a> now!', 'http://' . self::$brand_url, 'pilotpress'));
776 }
777
778 echo '</div>';
779 }
780
781 if(!$this->is_setup() && $this->get_setting('api_key') && $this->get_setting('app_id')) {
782 echo '<div class="error" style="padding-top: 5px; padding-bottom: 5px;">';
783 _e('Either this site <b>'.str_replace("http://","",(string)site_url()).'</b> is not configured in ' . self::$brand . ' or the <a href="options-general.php?page=pilotpress-settings">API Key / App Id settings</a> are incorrect. ', 'pilotpress');
784 _e('Most PilotPress features are disabled until this is configured. Please navigate to the plugin settings to set it up or contact <a href="mailto:support@ontraport.com">support@ontraport.com</a> for assistance.', 'pilotpress');
785 echo '</div>';
786 }
787
788 }
789
790 function display_settings_api_key() {
791 ?>
792 <input size="50" name="pilotpress-settings[api_key]" id="pilotpress_api_key" type="text" class="code" value="<?php echo $this->get_setting('api_key'); ?>" />
793 <?php
794 }
795
796 function display_settings_app_id() {
797 ?>
798 <input size="50" name="pilotpress-settings[app_id]" id="pilotpress_app_id" type="text" class="code" value="<?php echo $this->get_setting('app_id'); ?>" />
799 <?php
800 }
801
802 function display_settings_userlockout() {
803 echo "<input type='checkbox' name='pilotpress-settings[wp_userlockout]'";
804 if($this->get_setting("wp_userlockout")) {
805 echo " checked";
806 }
807 echo ">";
808 }
809
810 function display_settings_disablesslverify() {
811 echo "<input type='checkbox' name='pilotpress-settings[disablesslverify]'";
812 if($this->get_setting("disablesslverify")) {
813 echo " checked";
814 }
815 echo ">";
816 }
817
818 function display_settings_disableprotected() {
819 echo "<input type='checkbox' name='pilotpress-settings[disableprotected]'";
820 if($this->get_setting("disableprotected")) {
821 echo " checked";
822 }
823 echo ">";
824 }
825
826 function display_settings_usehome() {
827 echo "<input type='checkbox' name='pilotpress-settings[usehome]'";
828 if($this->get_setting("usehome")) {
829 echo " checked";
830 }
831 echo ">";
832 }
833
834 /* finally, we register the settings page itself. */
835 function settings_page() {
836
837 //get the sequences and tags... (and campaigns)
838 $this->tagsSequences = $this->api_call("get_tags_sequences", array("site" => site_url()));
839
840 ?>
841 <div class="wrap"><h2><?php _e('PilotPress Settings', 'pilotpress'); ?></h2><?php
842
843 ?><form name="pilotpress-settings" method="post" action="options.php"><?php
844
845 settings_fields('pilotpress-settings');
846 do_settings_sections('pilotpress-settings');
847
848
849
850 include_once(ABSPATH.'wp-admin/includes/plugin.php');
851 if(!is_plugin_active('object-cache.php'))
852 {
853 echo "<input type='button' class='button-secondary' name='pilotpress-purge' value='Clear PilotPress Cache'></input>
854 <p class='pilotpress-advanced-warning'>This will clear out all cached data for all currently logged in users and force PilotPress to go grab the data from ONTRAPORT again.</p>";
855
856 wp_nonce_field( 'pp_purge_transients' , "trans_nonce");
857 }
858 ?>
859
860 <p class="submit"><input type="submit" class="button-primary" name="save" value="<?php _e('Save Changes', 'pilotpress'); ?>" />&nbsp;<input type="button" class="button-secondary" name="advanced" value="<?php _e('Advanced Settings', 'pilotpress'); ?>"></p></form></div>
861
862 <script type="text/javascript">
863
864 jQuery(function($)
865 {
866 var purge_btn = jQuery(document).find("[name=pilotpress-purge]");
867 purge_btn.click(function()
868 {
869 var conf = confirm("Are you sure?\nThis will clear out all cached data tied to PilotPress.\n\nYour users will NOT be logged out.");
870
871 var wpnonceValue = document.querySelector('form[name="pilotpress-settings"] input[name="trans_nonce"]').value;
872
873 var data = {'action':'purge_transients', 'nonce': wpnonceValue};
874 if(conf == true)
875 {
876 $.post(ajaxurl, data, function(response)
877 {
878 alert("PilotPress cache cleared successfully.");
879 });
880 }
881 });
882 });
883
884 jQuery(document).ready(function() {
885 jQuery(document).find("[name=pilotpress-settings] h3:eq(6)").toggle();
886 jQuery(document).find(".pilotpress-advanced-warning").toggle();
887 jQuery(document).find("[name=pilotpress-purge]").toggle();
888 jQuery(document).find("[name=pilotpress-settings] table:eq(6)").toggle();
889 jQuery(document).find("[name=advanced]").click(function() {
890 jQuery(document).find("[name=pilotpress-purge]").toggle();
891 jQuery(document).find("[name=pilotpress-settings] h3:eq(6)").toggle();
892 jQuery(document).find(".pilotpress-advanced-warning").toggle();
893 jQuery(document).find("[name=pilotpress-settings] table:eq(6)").toggle();
894 });
895
896
897
898 //media uploader
899 jQuery('.pilotpress_header_logo_upload').click(function(e) {
900 e.preventDefault();
901
902 var custom_uploader = wp.media({
903 title: 'Customer Center Header Image',
904 button: {
905 text: 'Upload Image'
906 },
907 multiple: false // Set this to true to allow multiple files to be selected
908 })
909 .on('select', function() {
910 var attachment = custom_uploader.state().get('selection').first().toJSON();
911 jQuery('.pilotpress_customer_center_header_image').attr('src', attachment.url);
912 jQuery('.pilotpress_customer_center_header_image_url').val(attachment.url);
913
914 })
915 .open();
916 });
917 //primary color picker init
918 jQuery('#primary-color.pilotpress-color-picker').iris();
919 jQuery('#primary-color.pilotpress-color-picker').iris({ change: function(event, ui)
920 {
921 var colorpickervar = jQuery("#primary-color.pilotpress-color-picker").val()
922 jQuery("#primary-color.pilotpress-color-picker").siblings('.iris-border').css('background-color', colorpickervar);
923 }
924 });
925
926 //secondary color picker init
927 jQuery('#secondary-color.pilotpress-color-picker').iris();
928 jQuery('#secondary-color.pilotpress-color-picker').iris({ change: function(event, ui)
929 {
930 var colorpickervar = jQuery("#secondary-color.pilotpress-color-picker").val()
931 jQuery("#secondary-color.pilotpress-color-picker").siblings('.iris-border').css('background-color', colorpickervar);
932 }
933 });
934 });
935
936 </script>
937
938 <?php
939 }
940
941 /* use this to validate input, for now it simply creates the pages and/or resets cache */
942 function settings_validate($input) {
943
944 if(isset($input["app_id"]))
945 {
946 $sanitize = sanitize_text_field($input["app_id"]);
947 $input["app_id"] = $sanitize;
948 }
949
950 if(isset($input["api_key"]))
951 {
952 $sanitize = sanitize_text_field($input["api_key"]);
953 $input["api_key"] = $sanitize;
954 }
955
956 if(isset($input["customer_center"])) {
957 $this->create_system_page("customer_center");
958 } else {
959 $this->delete_system_page("customer_center");
960 }
961
962 if(isset($input["affiliate_center"])) {
963 $this->create_system_page("affiliate_center");
964 } else {
965 $this->delete_system_page("affiliate_center");
966 }
967
968 delete_transient("pilotpress_cache");
969
970 return $input;
971 }
972
973 /* OH YEAH! this is the API call method, wraps the static function as some other plugins may call via their own behalf */
974 function api_call($method, $data) {
975 return self::api_call_static($method, $data, $this->get_setting("app_id"), $this->get_setting("api_key"), $this->get_setting("disablesslverify"));
976 }
977
978 /* this is the real function of the above, for errors... try dumping $post */
979 static function api_call_static($method, $data, $app_id, $api_key, $ssl_verify = false) {
980
981 $post = array('body' => array("app_id" => $app_id,
982 "api_key" => $api_key,
983 "data" => json_encode($data)), 'timeout' => 500);
984
985 if($ssl_verify) {
986 $post["sslverify"] = 0;
987 }
988
989 $endpoint = sprintf(self::$url_api.'/%s/%s/%s', "json", "pilotpress", $method);
990 $response = wp_remote_post($endpoint, $post);
991
992 if(is_object($response))
993 {
994 if ($response->errors['http_request_failed']){
995 $endpoint = sprintf(self::$url_api.'/%s/%s/%s', "json", "pilotpress", $method);
996 $response = wp_remote_post($endpoint, $post);
997 }
998 }
999
1000
1001 if(is_wp_error($response) || $response['response']['code'] == 500) {
1002 return false;
1003 } else {
1004 $body = json_decode(trim($response['body']), true);
1005 }
1006
1007 if(isset($body["type"]) && $body["type"] == "error") {
1008 return false;
1009 } else {
1010 return $body["pilotpress"];
1011 }
1012
1013 }
1014
1015 /* all WP binding happens here, mostly. consolidated for your pleasure */
1016 private function bind_hooks() {
1017
1018 /* hitup the API or grab transient */
1019 add_action("init", array(&$this, "load_settings") , 1);
1020 add_action("init", array(&$this, "load_scripts") , 10);
1021 add_action('init', array(&$this, "sessionslap_ping"));
1022 add_action('wp_print_styles', array(&$this, 'stylesheets'));
1023 add_action('wp_print_footer_scripts', array(&$this, 'tracking'));
1024 add_action('wp_print_footer_scripts', array(&$this, 'webchat'));
1025 add_action('retrieve_password', array(&$this, 'retrieve_password'));
1026 add_action('profile_update', array(&$this, 'profile_update'));
1027
1028 add_action("wp_ajax_pp_update_aff_details", array(&$this, 'update_aff_details'));
1029 add_action("wp_ajax_pp_update_cc_details", array(&$this, 'update_cc_details'));
1030
1031 if(is_admin()) {
1032 add_action('admin_menu', array(&$this, 'settings_init'));
1033 add_filter('admin_init', array(&$this, 'clean_meta'));
1034 add_filter('admin_init', array(&$this, 'flush_rewrite_rules'));
1035 add_filter('admin_init', array(&$this, 'user_lockout'));
1036 add_action('admin_enqueue_scripts', array(&$this, 'admin_load_scripts'));
1037 add_action('admin_notices', array(&$this, 'display_notice'));
1038
1039 add_action('admin_menu', array(&$this, 'metabox_add'));
1040 add_action('pre_post_update', array(&$this, 'metabox_save'));
1041
1042 add_action('media_buttons', array(&$this, 'media_button_add'), 20);
1043 add_action('media_upload_forms', array(&$this, 'media_upload_forms'));
1044 add_action('media_upload_images', array(&$this, 'media_upload_images'));
1045 add_action('media_upload_videos', array(&$this, 'media_upload_videos'));
1046 add_action('media_upload_fields', array(&$this, 'media_upload_fields'));
1047 add_action('wp_ajax_pp_insert_form', array(&$this, 'get_insert_form_html'));
1048 add_action('wp_ajax_pp_insert_video', array(&$this, 'get_insert_video_html'));
1049 add_action("wp_ajax_pp_get_aff_report", array(&$this, 'get_aff_report'));
1050
1051 add_filter('tiny_mce_before_init', array(&$this, 'mce_valid_elements'));
1052 add_filter('tiny_mce_version', array(&$this, 'tiny_mce_version') );
1053 add_filter("mce_external_plugins", array(&$this, "mce_external_plugins"));
1054 add_filter('mce_buttons_3', array(&$this, 'mce_buttons'));
1055 add_action('admin_footer', array(&$this, 'grab_mce_fields'));
1056 add_action('admin_footer', array(&$this, 'grab_mce_shortcodes'));
1057
1058 add_filter('manage_posts_columns', array(&$this, 'page_list_col'));
1059 add_action('manage_posts_custom_column', array(&$this, 'page_list_col_value'), 10, 2);
1060 add_filter('manage_pages_columns', array(&$this, 'page_list_col'));
1061 add_action('manage_pages_custom_column', array(&$this, 'page_list_col_value'), 10, 2);
1062 add_filter('user_has_cap', array(&$this, 'lock_delete'), 0, 3);
1063 add_filter('media_upload_tabs', array(&$this, 'modify_media_tab'));
1064 add_action('wp_loaded', array(&$this, 'update_post_types'));
1065
1066 // For login_form
1067 add_action('admin_head', array(&$this, 'include_form_admin_options'));
1068 add_action('admin_head', array(&$this, 'admin_preview'));
1069
1070 add_action('wp_ajax_purge_transients', array(&$this, 'purge_transients'));
1071 add_action('wp_ajax_admin_preview_redirect', array(&$this, 'admin_preview_redirect'));
1072
1073
1074 // add_action('admin_print_footer_scripts', array(&$this, 'tinymce_autop'), 50);
1075
1076 } else {
1077 add_filter('rewrite_rules_array', array(&$this, 'filter_rewrite_rules'));
1078 add_action('wp', array(&$this, 'post_process'));
1079 add_filter('get_pages', array(&$this, 'get_pages'));
1080 add_filter("wp_nav_menu", array(&$this, 'get_nav_menus'));
1081 add_filter("wp_nav_menu_objects", array(&$this, 'get_nav_menu_objects'));
1082 add_filter('posts_where', array(&$this, 'posts_where'));
1083 add_filter('query_vars', array(&$this, 'filter_query_vars'));
1084 add_filter('the_content', array(&$this, 'content_process'));
1085 add_filter('login_message', array(&$this, 'content_process'));
1086
1087 add_shortcode('protected', array(&$this, 'shortcode_show_if'));
1088 add_shortcode('show_if', array(&$this, 'shortcode_show_if'));
1089 add_shortcode('login_page', array(&$this, 'login_page'));
1090 add_shortcode('field', array(&$this, 'shortcode_field'));
1091
1092 add_shortcode('pilotpress_protected', array(&$this, 'shortcode_show_if'));
1093 add_shortcode('pilotpress_show_if', array(&$this, 'shortcode_show_if'));
1094 add_shortcode('pilotpress_login_page', array(&$this, 'login_page'));
1095 add_shortcode('pilotpress_field', array(&$this, 'shortcode_field'));
1096 add_shortcode('pilotpress_sync_contact', array(&$this, 'shortcode_sync_contact'));
1097 }
1098
1099 add_action('wp_authenticate', array(&$this, 'user_login'), 1, 2);
1100 add_action("wp_login_failed", array(&$this, 'user_login_failed'));
1101 add_action("lostpassword_post", array(&$this, 'user_lostpassword'));
1102 add_action('wp_logout', array(&$this, 'user_logout'));
1103 add_action('init', array(&$this, 'pp_login_button'));
1104 add_action('user_register', array(&$this, 'add_new_register_user_to_ONTRAPORT') , 10, 1);
1105
1106 }
1107
1108 /**
1109 * @brief echoes the necessary JS to produce the various buttons, and redirection for the admin preview functionality
1110 **/
1111 function admin_preview()
1112 {
1113 global $post;
1114
1115 if (is_object($post) && $post->ID)
1116 {
1117 // CSS so buttons aren't smooshed together.
1118 echo "<style type='text/css'>";
1119 echo ".admin-preview";
1120 echo "{margin:5px!important;font-size:110%!important;}";
1121 echo "</style>";
1122
1123 // Only allow post previews if they're published or drafts.
1124 if (in_array(get_post_status($post->ID), self::$valid_state))
1125 {
1126 echo "<script type='text/javascript'>";
1127
1128 // Grabs $_GET args.
1129 echo "function getQueryStringValue (key) {
1130 return decodeURIComponent(window.location.search.replace(new RegExp('^(?:.*[&\\?]' + encodeURIComponent(key).replace(/[\.\+\*]/g, '\\$&') + '(?:\\=([^&]*))?)?.*$', 'i'), '$1'));
1131 }";
1132
1133 // Open new tab with newly set preview-status.
1134 echo "
1135 jQuery(function($)
1136 {
1137 $('.admin-preview').click(function(event)
1138 {
1139 event.preventDefault();
1140 var post = getQueryStringValue('post');
1141 var data = {'action':'admin_preview_redirect', 'value':$(this).attr('value'), 'post':post};
1142 $.post(ajaxurl, data, function(response)
1143 {
1144 var url = $.parseJSON(response);
1145 window.open(url['data'], '_blank');
1146 });
1147 });
1148 });";
1149 echo "</script>";
1150 }
1151 else
1152 {
1153 // Disable preview buttons
1154 echo "<script type='text/javascript'>";
1155 echo "jQuery(function($)
1156 {
1157 $('.admin-preview').prop('disabled', true);
1158 });";
1159 echo "</script>";
1160 }
1161 }
1162
1163 // If not on a page w/ a post.. do nothing.
1164 }
1165
1166 /**
1167 * @brief sets transient of the admin_preview's selected preview level
1168 * @return (echoes) json encoded URL of the chosen post back to the JS for redirection
1169 **/
1170 function admin_preview_redirect()
1171 {
1172 set_transient("pilotpress_admin_preview", self::validatePostVar($_POST['value'], "string"), self::TTL);
1173 $data = array('data' => get_permalink(self::validatePostVar($_POST["post"], "numeric")));
1174 echo json_encode($data);
1175 wp_die();
1176 }
1177
1178
1179 /**
1180 * @brief gets transient data related to the user or site. If not available -- call the API and make it
1181 * @params string $name, bool $unique(used to differentiate whether to grab site settings or user data)
1182 * @return array of various data
1183 **/
1184 function get_stashed($name, $unique)
1185 {
1186
1187 $user = wp_get_current_user();
1188
1189 $api_call_args = array();
1190 $suffix = $unique ? "_pilotpress_user".$user->ID : "_pilotpress_site";
1191
1192
1193 //try to grab transient from stash, return if success
1194 if(isset(self::$stashed_transients[$name.$suffix]))
1195 {
1196 return self::$stashed_transients[$name.$suffix];
1197 }
1198
1199 //not in stash, build API call
1200 //load args array, if not admin, pass in username
1201 $api_call_args["site"] = site_url();
1202 $api_call_args["version"] = self::VERSION;
1203 $api_call_args["disablesslverify"] = $this->get_setting("disablesslverify");
1204 $api_call_args["app_id"] = $this->get_setting("app_id");
1205 $api_call_args["api_key"] = $this->get_setting("api_key");
1206
1207 if(!$this->is_site_admin())
1208 {
1209 $api_call_args["username"] = $user->user_login;
1210 if($name == "authenticate_user" && (!isset($api_call_args["username"]) || $api_call_args["username"] == null))
1211 {
1212 return array();
1213 }
1214 }
1215
1216
1217 if ($name == "authenticate_user" && $user->ID > 0) //$user->ID = 0 when not logged in, don't want to resync them
1218 {
1219 // Need to bypass password check as this is not a log in call but a re sync...
1220 $api_call_args["resync_user"] = true;
1221 }
1222
1223 //build or grab transient from DB, stash & return it
1224 $transient = self::get_stashed_static($name, $unique, $api_call_args);
1225 self::$stashed_transients[$name.$suffix] = $transient;
1226
1227 return self::$stashed_transients[$name.$suffix];
1228 }
1229
1230 /**
1231 * @brief takes in name of API call, a unique flag and API call args --> sets result as a transient
1232 * @params string $name, bool $unique, array $data
1233 * @return array of data from API call
1234 **/
1235 static function get_stashed_static($name, $unique, $data)
1236 {
1237 $options = get_option("pilotpress-settings");
1238 if (!is_array($options)) {
1239 $options = array();
1240 }
1241 $suffix = $unique ? "_pilotpress_user".get_current_user_id() : "_pilotpress_site";
1242
1243 //try to grab from DB
1244 $return = get_transient($name.$suffix);
1245
1246 //we got it!
1247 if($return)
1248 {
1249 return $return;
1250 }
1251
1252 if (!is_array($return))
1253 {
1254 $return = array();
1255 }
1256
1257 //prep args for API call
1258 $data["site"] = site_url();
1259 $data["version"] = self::VERSION;
1260 if(array_key_exists("disablesslverify", $data))
1261 {
1262 $options["disablesslverify"] = $data["disablesslverify"];
1263 unset($data["disablesslverify"]);
1264 }
1265 if(array_key_exists("api_key", $data))
1266 {
1267 $options["api_key"] = $data["api_key"];
1268 unset($data["api_key"]);
1269 }
1270 if(array_key_exists("app_id", $data))
1271 {
1272 $options["app_id"] = $data["app_id"];
1273 unset($data["app_id"]);
1274 }
1275
1276 $return[$name] = self::api_call_static($name, $data, $options["app_id"], $options["api_key"], $options["disablesslverify"]);
1277
1278 if ($return[$name])
1279 {
1280 $return["timestamp"] = time();
1281 set_transient($name.$suffix, $return, self::TTL);
1282 }
1283
1284 return $return;
1285 }
1286
1287 /**
1288 * @brief cleans up all transients associated with the current user
1289 **/
1290 function destroy_transients_logout()
1291 {
1292 $suffix = "_pilotpress_user".get_current_user_id();
1293 unset($stashed_transients);
1294 delete_transient("authenticate_user".$suffix);
1295
1296 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
1297 delete_transient("login_url_pilotpress_user".(int) $contact_id);
1298 delete_transient("pilotpress_redirect_to".(int) $contact_id);
1299 delete_transient("usertags_".(int) $contact_id);
1300 }
1301
1302 /**
1303 * @brief deletes all PilotPress related transients from the DB, triggered by a button on the admin settings page
1304 * @return error log back to the JS on the Front End
1305 **/
1306 function purge_transients()
1307 {
1308 global $wpdb;
1309
1310 if (!is_user_logged_in())
1311 {
1312 return;
1313 }
1314
1315 if (!current_user_can("manage_options"))
1316 {
1317 return;
1318 }
1319
1320 if (!check_ajax_referer("pp_purge_transients", "nonce"))
1321 {
1322 return;
1323 }
1324
1325
1326 $error_log = array();
1327 $user = "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '\_transient\_%pilotpress\_%'";
1328 $tags = "DELETE FROM {$wpdb->prefix}options WHERE option_name LIKE '\_transient\_%usertags\_%'";
1329 try
1330 {
1331 $user_results = $wpdb->get_results($user);
1332 $tag_results = $wpdb->get_results($tags);
1333 }
1334 catch (Exception $e)
1335 {
1336 $error_log["error"] = "error during clearing";
1337 }
1338
1339 if(empty($error_log))
1340 {
1341 $error_log["data"] = "success";
1342 }
1343
1344 echo json_encode($error_log);
1345
1346 wp_die();
1347 }
1348
1349 /**
1350 * @brief translates the redirect transient into a URL
1351 * @param int $contact_id from $_COOKIE["contact_id"]
1352 *
1353 * @return string URL or false if no transient or bad type
1354 *
1355 * @author Richard Young <ryoung@ontraport.com>
1356 **/
1357 function getRedirectURL($contact_id)
1358 {
1359 if (!isset($contact_id) || $contact_id === false)
1360 {
1361 return false;
1362 }
1363
1364 $transient = get_transient("pilotpress_redirect_to".$contact_id);
1365
1366 if($transient)
1367 {
1368 $transient = explode("_", $transient);
1369 $type = $transient[0];
1370 $id = $transient[1];
1371
1372 switch($type)
1373 {
1374 case "post":
1375 $redirect_to = get_permalink($id);
1376 break;
1377
1378 case "category":
1379 $redirect_to = get_category_link($id);
1380 break;
1381
1382 default:
1383 return false;
1384 }
1385
1386 return $redirect_to;
1387 }
1388 else
1389 {
1390 return false;
1391 }
1392 }
1393
1394 /**
1395 * @brief checks whether or not the user passed in has administrator priveleges
1396 * @params WP_User $user
1397 * @return bool
1398 **/
1399 function is_site_admin($user = false)
1400 {
1401 if($user == false || ($user == true && !is_array($user->roles)))
1402 {
1403 $user_roles = wp_get_current_user()->roles;
1404 if (is_array($user_roles))
1405 {
1406 return in_array('administrator', $user_roles);
1407 }
1408 }
1409 else
1410 {
1411 return in_array('administrator', $user->roles);
1412 }
1413 }
1414
1415
1416 function retrieve_password($name) {
1417 if(!isset($name) || $name == null)
1418 {
1419 return;
1420 }
1421 $return = $this->api_call("retrieve_password", array("site" => site_url(), "username" => $name));
1422 }
1423
1424 /* update a persons profile */
1425 function profile_update($user_id) {
1426 if(isset($_POST['first_name']) && isset($_POST['last_name']) && isset($_POST['nickname']) && isset($_POST['pass1'])) {
1427 $user = get_userdata($user_id);
1428
1429 $details = array();
1430 $details["site"] = site_url();
1431 $details["username"] = $user->user_login;
1432 $details["firstname"] = self::validatePostVar($_POST['first_name'], "string");
1433 $details["lastname"] = self::validatePostVar($_POST['last_name'], "string");
1434 $details["nickname"] = self::validatePostVar($_POST['nickname'], "string");
1435 $details["password"] = self::validatePostVar($_POST["pass1"], "string");
1436
1437
1438 $this->destroy_transients_logout();
1439 $return = $this->api_call("profile_update", $details);
1440 }
1441 }
1442
1443 function user_lockout() {
1444 global $current_user;
1445 if(!current_user_can('manage_options') && $this->get_setting("wp_userlockout") && !isset($_POST["action"]))
1446 {
1447 if (function_exists("wp_doing_ajax") && wp_doing_ajax())
1448 {
1449 return;
1450 }
1451
1452 $customer = $this->get_setting("pilotpress_customer_plr");
1453 if(!empty($customer) && $customer != "-1") {
1454 self::redirect(get_permalink($customer));
1455 } else {
1456 self::redirect($this->homepage_url);
1457 }
1458 die;
1459 }
1460 }
1461
1462 /* please load scripts here vs. printing. it's so much healthier */
1463 function load_scripts() {
1464 wp_enqueue_script("jquery");
1465 wp_register_script("mr_tracking", self::$path_tjs, array('jquery'));
1466 wp_enqueue_script("mr_tracking");
1467 }
1468
1469 /*
1470 @brief only load these scripts if in the admin dashboard
1471
1472 */
1473 function admin_load_scripts()
1474 {
1475 // Here to determine if the automattic color picker 'iris' is included with wordpress... if not, include and use it
1476 $version = get_bloginfo('version');
1477 if ($version < 3.5)
1478 {
1479 wp_register_style('irisstyle', plugins_url( '/js/iris.css' , __FILE__ ));
1480 wp_enqueue_style('irisstyle');
1481 wp_register_style('jquery-ui', JS_DIR . "jquery.ui.all.css");
1482 wp_enqueue_style('jquery-ui');
1483
1484 wp_deregister_script('jquery-color');
1485 wp_register_script('jquery-color', plugins_url( 'color.js' , __FILE__ ));
1486 wp_enqueue_script('jquery-color');
1487 wp_enqueue_script('jquery-ui-core');
1488 wp_enqueue_script('jquery-ui-draggable');
1489 wp_enqueue_script('jquery-ui-slider');
1490 wp_enqueue_script('jquery-ui-widget');
1491 wp_enqueue_script('jquery-ui-mouse');
1492 wp_enqueue_script('jquery-ui-tabs');
1493 wp_register_script('iris', plugins_url( '/js/iris.js' , __FILE__ ), array( 'jquery', 'jquery-color', 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-ui-mouse', 'jquery-ui-tabs' ));
1494 wp_enqueue_script('iris');
1495 }
1496 else
1497 {
1498 wp_register_style('jquery-ui', JS_DIR . "jquery.ui.all.css");
1499 wp_enqueue_style('jquery-ui');
1500 wp_enqueue_script('jquery-ui-tabs');
1501 wp_enqueue_style( 'wp-color-picker' );
1502 wp_enqueue_script('iris');
1503 }
1504 if(function_exists( 'wp_enqueue_media' )){
1505 wp_enqueue_media();
1506 }else{
1507 wp_enqueue_style('thickbox');
1508 wp_enqueue_script('media-upload');
1509 wp_enqueue_script('thickbox');
1510 }
1511
1512 }
1513
1514 function stylesheets() {
1515 wp_register_style("mrjswp", self::$path_jswpcss);
1516 wp_enqueue_style("mrjswp");
1517
1518 wp_register_style("mrcss", self::$path_mrcss);
1519 wp_enqueue_style("mrcss");
1520
1521 wp_register_style("jqcss", self::$path_jqcss);
1522 wp_enqueue_style("jqcss");
1523 }
1524
1525 /* except this one. */
1526 function tracking() {
1527 echo "<script>_mri = \"".$this->get_setting('tracking','oap')."\";_mr_domain = \"" . $this->get_setting('tracking_url', 'oap') . "\"; mrtracking();</script>";
1528 }
1529
1530 /* prints the ONTRAPORT web chat widget loader when web chat is enabled for this site */
1531 function webchat() {
1532 $webchat_entry_url = $this->get_setting('webchat_entry_url', 'oap');
1533 if (!empty($webchat_entry_url)) {
1534 echo '<script src="' . esc_url($webchat_entry_url) . '" type="text/javascript" async=""></script>';
1535 }
1536 }
1537
1538 /* first of a few tinymce functions, this registers some of our buttons */
1539 function mce_buttons($buttons) {
1540 array_push($buttons, "separator", "merge_fields");
1541 array_push($buttons, "separator", "short_codes");
1542 return $buttons;
1543 }
1544
1545 /* load up our marshalled plugin code (see comment prefixed: Xevious) */
1546 function mce_external_plugins($plugin_array) {
1547 global $wp_version;
1548 $version = 3.9;
1549 //test for wordpress version to load proper plugin scripts
1550 if ( version_compare( $wp_version, $version, '>=' ) ) {
1551 $plugin_array['pilotpress'] = plugins_url('js/', __FILE__) . 'pilotpress_mce_plugin.js';
1552 }
1553 else
1554 {
1555 $plugin_array['pilotpress'] = plugins_url('js/', __FILE__) . 'pilotpress_mce_plugin_old.js';
1556 }
1557 return $plugin_array;
1558 }
1559
1560 /* i forget what this did, but it is important */
1561 function tiny_mce_version($version) {
1562 return ++$version;
1563 }
1564
1565 /* right so... lets just make most useful elements avaliable */
1566 function mce_valid_elements($in) {
1567 $em = '#p[*],p[*],form[*],div[*],span[*],script[*],link[*]';
1568
1569 if(!is_array($in))
1570 {
1571 $in = array();
1572 }
1573
1574 if(isset($in["extended_valid_elements"]))
1575 {
1576 $in["extended_valid_elements"] .= ',';
1577 $in["extended_valid_elements"] .= $em;
1578 } else {
1579 $in["extended_valid_elements"] = $em;
1580 }
1581
1582 if (isset($in['valid_children']))
1583 {
1584 $in['valid_children'] .= ',+body[link]';
1585 }
1586 else
1587 {
1588 $in['valid_children'] = '+body[link]';
1589 }
1590
1591 $in["entity_encoding"] = "raw";
1592
1593 return $in;
1594 }
1595
1596 /* horrible but it gets the job done. WP said they'd fix this in 3.3, but they lied */
1597 function lock_delete($allcaps, $caps, $args) {
1598
1599 global $wp_post;
1600
1601 if(is_array($this->system_pages)) {
1602 if(isset($_GET["post"])) {
1603 $post_id = intval($_GET["post"]); // Sanitize as integer since this should be a post ID
1604 if(in_array($post_id, $this->system_pages)) {
1605 if(is_array($allcaps)) {
1606 foreach($allcaps as $cap => $value) {
1607 if(strpos($cap, "delete") !== false) {
1608 $allcaps[$cap] = 0;
1609 }
1610 }
1611 }
1612 }
1613 }
1614 }
1615 return $allcaps;
1616 }
1617
1618 /* adds a column to the post list view */
1619 function page_list_col($cols) {
1620 $_cols = array();
1621 if(is_array($cols)) {
1622 foreach($cols as $col => $value) {
1623 //need both terms in case date is loaded before author -- don't want to set twice
1624 if(!isset($_cols["pilotpress"]) && $col == "author") {
1625 $_cols["pilotpress"] = "PilotPress Levels";
1626 }
1627 else if(!isset($_cols["pilotpress"]) && $col == "date")
1628 {
1629 $_cols["pilotpress"] = "PilotPress Levels";
1630 }
1631 $_cols[$col] = $value;
1632 }
1633 if(!isset($_cols["pilotpress"]))
1634 {
1635 $_cols["pilotpress"] = "PilotPress Levels";
1636 }
1637 }
1638 return $_cols;
1639 }
1640
1641 /* prints value of above */
1642 function page_list_col_value($column_name, $id) {
1643 if ($column_name == "pilotpress") {
1644 if(in_array($id, $this->system_pages)) {
1645 echo '<img src="https://optassets.ontraport.com/opt_assets/images/pilot_press/lock-icon-pp.png" width="16" height="16" alt="Locked" />&nbsp;System';
1646 } else {
1647 $levels = get_post_meta($id, self::NSPACE.'level', false);
1648 if(!empty($levels)) {
1649 if(count($levels) == 1) {
1650 echo $levels[0];
1651 } else {
1652 echo implode(', ', $levels);
1653 }
1654 }
1655 else if ( $catLevels = $this->ppp->ppprotectCheckForProtection( $id ) ) {
1656 echo 'Category Protection - ' . $catLevels;
1657 }
1658 else {
1659 echo '(not set)';
1660 }
1661 }
1662 }
1663 }
1664
1665 /* handy ajax call for Affiliate Center */
1666 function get_aff_report() {
1667 $return = $this->api_call("get_aff_report", $_POST);
1668 echo($return["report"]);
1669 die();
1670 }
1671
1672 /* same but for aff details (setter) */
1673 function update_aff_details() {
1674 $return = $this->api_call("update_aff_details", $_POST);
1675 $this->destroy_transients_logout();
1676
1677 echo($return["update"]);
1678 die();
1679 }
1680
1681 /* same but for cc details (setter) */
1682 function update_cc_details() {
1683 global $wpdb;
1684
1685 if(wp_verify_nonce($_POST['nonce'], basename(__FILE__))) {
1686
1687 $data = $_POST;
1688 $data["site"] = site_url();
1689
1690 $return = $this->api_call("update_cc_details", $data);
1691
1692 if( (self::validatePostVar($_POST["oguser"],"string") != self::validatePostVar($_POST["username"], "string")) &&
1693 username_exists(self::validatePostVar($_POST["username"], "string")) ||
1694 (
1695 array_key_exists("username_exists",$return) &&
1696 $return["username_exists"]
1697 )
1698 )
1699 {
1700 echo "display_notice('Error: That username is taken. Please try another username.');";
1701 die();
1702 }
1703
1704 $current_user = wp_get_current_user();
1705
1706 if(isset($return["updateUser"]))
1707 {
1708 $wpdb->query($wpdb->prepare("UPDATE {$wpdb->users} SET `user_login` = %s WHERE `ID` = %d", self::validatePostVar($_POST['username'], "string"), $current_user->ID));
1709
1710 if(self::validatePostVar($_POST["nickname"], "string") == self::validatePostVar($_POST["oguser"], "string"))
1711 {
1712 wp_update_user(array("ID" => $current_user->ID, "nickname" => self::validatePostVar($_POST["username"], "string"), "display_name" => self::validatePostVar($_POST["username"], "string")));
1713 }
1714 }
1715 else {
1716 wp_update_user(array("ID" => $current_user->ID, "user_pass" => self::validatePostVar($_POST["password"], "string")));
1717 }
1718
1719 $this->destroy_transients_logout();
1720 echo($return["update"]);
1721 die();
1722 }
1723 }
1724
1725 /* grabs form insert code, disables that pesky wpautop */
1726 function get_insert_form_html(){
1727 if(isset($_POST["form_id"])) {
1728 remove_filter('the_content', 'wpautop');
1729 $api_result = $this->api_call("get_form", array("form_id" => self::validatePostVar($_POST["form_id"], "numeric")));
1730 echo html_entity_decode($api_result["code"],ENT_COMPAT,"UTF-8");
1731 die;
1732 }
1733 }
1734
1735 /* grabs video code */
1736 function get_insert_video_html(){
1737 if((bool) ($video_id = self::validatePostVar($_POST["video_id"], "numeric")) === true)
1738 {
1739 $player_selection = self::validatePostVar($_POST["use_player"], "numeric");
1740 $use_autoplay = self::validatePostVar($_POST["use_autoplay"], "numeric");
1741 $use_viral = self::validatePostVar($_POST["use_viral"], "numeric");
1742 $omit_flowplayer = self::validatePostVar($_POST["omit_flowplayerjs"], "boolean");
1743
1744 $api_result = $this->api_call("get_video", array(
1745 "video_id" => $video_id,
1746 "width" => '480',
1747 "height" => "320",
1748 "player" => $player_selection,
1749 "autoplay" => $use_autoplay,
1750 "viral" => $use_viral,
1751 "omit_flowplayerjs" => $omit_flowplayer
1752 ));
1753 echo $api_result["code"];
1754 die;
1755 }
1756 }
1757
1758 /**
1759 * @param mixed $post_var
1760 * @param string $type
1761 *
1762 * @return mixed|bool false if $post_var is not valid given $type
1763 *
1764 * @author Richard Young <ryoung@ontraport.com>
1765 */
1766 public static function validatePostVar($post_var, $type)
1767 {
1768 $valid = false;
1769 if (isset($post_var))
1770 {
1771 switch($type)
1772 {
1773 case "string":
1774 $valid = is_string($post_var) ? sanitize_text_field($post_var) : false;
1775 break;
1776 case "numeric":
1777 $valid = is_numeric($post_var) ? $post_var : false;
1778 break;
1779 case "boolean":
1780 $valid = is_bool($post_var) ? $post_var : false;
1781 break;
1782 }
1783 }
1784 return $valid;
1785 }
1786
1787 /* does media insert form itself*/
1788 function media_upload_type_forms() {
1789
1790 global $wpdb, $wp_query, $wp_locale, $type, $tab, $post_mime_types;
1791
1792 media_upload_header();
1793
1794 ?>
1795 <script type="text/javascript">
1796
1797 var $ = jQuery;
1798
1799 function insertForm(the_form_id) {
1800
1801 $.post("<?php echo $this->homepage_url; ?>/wp-admin/admin-ajax.php", { action:"pp_insert_form", form_id: the_form_id, 'cookie': encodeURIComponent(document.cookie) },
1802 function(str){
1803
1804 if(typeof top.tinyMCE != 'undefined' && (ed = top.tinyMCE.activeEditor)) {
1805
1806 ed = top.tinyMCE.activeEditor;
1807 ed.focus();
1808
1809 if(top.tinymce.isIE) {
1810 ed.selection.moveToBookmark(top.tinymce.EditorManager.activeEditor.windowManager.bookmark);
1811 }
1812
1813 ed.execCommand('mceInsertContent', false, str);
1814 top.tb_remove();
1815 } else {
1816 top.send_to_editor(str);
1817 top.tb_remove();
1818 }
1819
1820 });
1821 }
1822
1823
1824 </script>
1825 <?php
1826
1827 $forms_list = $this->api_call("get_form_list","");
1828 if(is_array($forms_list)) {
1829 foreach($forms_list as $group => $forms) {
1830 natcasesort($forms);
1831 echo "<div style='padding: 5px; line-height: 16px;'>";
1832 echo "<h2>{$group}</h2>";
1833 if(is_array($forms)) {
1834 echo "<ul style='padding-left: 20px; list-style-type: disc !important;'>";
1835 foreach($forms as $idx => $name) {
1836 echo "<li><b><a href='JavaScript:insertForm({$idx});' title='form_{$idx}'>{$name}</a></b></li>";
1837 }
1838 echo "</ul>";
1839 }
1840 echo "</div>";
1841 echo "<hr>";
1842 }
1843 }
1844
1845 }
1846
1847
1848 /* same but for videos */
1849 function media_upload_type_videos() {
1850 media_upload_header();
1851
1852 $api_result = $this->api_call("get_video_list","");
1853
1854 ?>
1855
1856 <style type="text/css">
1857 div.img
1858 {
1859 background: #EFEFEF;
1860 margin:2px;
1861 border:1px solid #CCC;
1862 height:auto;
1863 width:auto;
1864 float:left;
1865 }
1866 div.img img
1867 {
1868 display:inline;
1869 margin:3px;
1870 border:1px solid #ffffff;
1871 }
1872 div.desc
1873 {
1874 font-size: 10px;
1875 width:200px;
1876 margin:2px;
1877 }
1878 div.controls
1879 {
1880 font-size: 10px;
1881 }
1882 div.control_button img {
1883 padding: 0px;
1884 margin: 0px;
1885 }
1886 div.control_button {
1887 padding: 0px;
1888 margin: 0px;
1889 border: 1px solid #CCC;
1890 }
1891 </style>
1892
1893 <script>
1894 var $ = jQuery;
1895
1896 function toggle_autoplay(the_video_id) {
1897 if($('#autoplay_'+the_video_id).val() != 0) {
1898 $('#autoplay_'+the_video_id).val(0);
1899 $('#autoplaybtn_'+the_video_id).css('background-color','#EEE');
1900 } else {
1901 $('#autoplay_'+the_video_id).val(1);
1902 $('#autoplaybtn_'+the_video_id).css('background-color','#CCC');
1903 }
1904 }
1905
1906 function toggle_viral(the_video_id) {
1907 if($('#viral_'+the_video_id).val() != 0) {
1908 $('#viral_'+the_video_id).val(0);
1909 $('#viralbtn_'+the_video_id).css('background-color','#EEE');
1910 } else {
1911 $('#viral_'+the_video_id).val(1);
1912 $('#viralbtn_'+the_video_id).css('background-color','#CCC');
1913 }
1914 }
1915
1916 function insertVideo(the_video_id) {
1917
1918 var player = $('#player_'+the_video_id).val();
1919 var autoplay = $('#autoplay_'+the_video_id).val();
1920 var viral = $('#viral_'+the_video_id).val();
1921 var omit_flowplayerjs = false;
1922
1923 if($("#wpwrap", top.document).val().indexOf("oap_flow/flowplayer") !== -1) {
1924 omit_flowplayerjs = true;
1925 }
1926
1927 $.post("<?php echo $this->homepage_url; ?>/wp-admin/admin-ajax.php", { action: "pp_insert_video", video_id: the_video_id, use_viral: viral, use_player: player, use_autoplay: autoplay, 'cookie': encodeURIComponent(document.cookie), "omit_flowplayerjs": omit_flowplayerjs },
1928 function(str){
1929 var ed;
1930 if(typeof top.tinyMCE != 'undefined' && (ed = top.tinyMCE.activeEditor)) {
1931
1932 ed = top.tinyMCE.activeEditor;
1933 ed.focus();
1934
1935 if(top.tinymce.isIE) {
1936 ed.selection.moveToBookmark(top.tinymce.EditorManager.activeEditor.windowManager.bookmark);
1937 }
1938
1939 ed.execCommand('mceInsertContent', false, str);
1940 top.tb_remove();
1941 } else {
1942 top.send_to_editor(str);
1943 top.tb_remove();
1944 }
1945
1946 });
1947 }
1948 </script>
1949
1950 <?php
1951
1952 if(is_array($api_result["list"]) && count($api_result["list"]) > 0) {
1953 echo "<div style='padding: 5px; line-height: 16px;'>";
1954 echo "<h2>Videos</h2>";
1955 if (is_array($api_result["list"]))
1956 {
1957 foreach($api_result["list"] as $video) {
1958
1959 if(empty($api_result["thumb_url"]) OR $api_result["thumb_url"] == "") {
1960 $thumb = $api_result["default_thumb"];
1961 } else {
1962 $thumb = $api_result["thumb_url"].$video["thumb_filename"];
1963 }
1964
1965 echo "<div class='img' style=\"cursor: pointer;\"><div onClick='insertVideo({$video["video_id"]})'><img width='200' src='{$thumb}'></div>";
1966 echo "<div class='desc'>{$video["name"]} <span>({$video["duration"]})</span></div>";
1967 echo "<table><tr><td><select id='player_{$video["video_id"]}' name='player_{$video["video_id"]}'><option value='4' selected>HTML5</option><option value='0'>Hidden</option><option value='1'>Player 1</option><option value='2'>Player 2</option><option value='3'>Player 3</option></select></td>";
1968 echo "<td><input type='hidden' id='autoplay_{$video["video_id"]}' name='autoplay_{$video["video_id"]}' value='0'><div id='autoplaybtn_{$video["video_id"]}' onClick='toggle_autoplay({$video["video_id"]})' style=\"cursor: pointer;\" class=\"control_button floatLeft\"><img title=\"Autoplay\" src=\"".$this->get_setting("mr_url", "oap")."include/images/boxes/autoplay_ico.gif\"></div></td>";
1969 echo "<td><input type='hidden' id='viral_{$video["video_id"]}' name='viral_{$video["video_id"]}' value='0'><div id='viralbtn_{$video["video_id"]}' onClick='toggle_viral({$video["video_id"]})' style=\"cursor: pointer;\" class=\"control_button floatLeft\"><img title=\"Viral Features\" src=\"".$this->get_setting("mr_url", "oap")."include/images/boxes/viral_vid_ico.gif\"></div></td></tr></table>";
1970 echo "</div>";
1971 }
1972 }
1973 echo "</div>";
1974 }
1975
1976 }
1977
1978
1979
1980
1981
1982
1983
1984 /* headers for images.. never happened */
1985 function media_upload_type_images() {
1986 media_upload_header();
1987 echo "<div style='padding: 5px; line-height: 16px;'>";
1988 echo "<h2>Images</h2>";
1989 echo "</div>";
1990 }
1991
1992 /* binds tab! */
1993 function modify_media_tab($tabs) {
1994 $new_tabs = array(
1995 'forms' => __('Forms', 'wp-media-oapforms'),
1996 'videos' => __('Videos', 'wp-media-oapvideos')
1997 );
1998 return array_merge($new_tabs, $tabs);
1999 }
2000
2001 /* shows tab */
2002 function media_upload_forms() {
2003 wp_iframe(array($this, 'media_upload_type_forms'));
2004 }
2005
2006 function media_upload_images() {
2007 wp_iframe(array($this, 'media_upload_type_images'));
2008 }
2009
2010 function media_upload_videos() {
2011 wp_iframe(array($this, 'media_upload_type_videos'));
2012 }
2013
2014 /* this function is disabled for now as it screws up HTML view tidyness... should be an advanced setting in the future */
2015 function tinymce_autop() {
2016 ?>
2017 <script type="text/javascript">
2018 //<![CDATA[
2019 jQuery('body').bind('afterPreWpautop', function(e, o){
2020 o.data = o.unfiltered
2021 .replace(/caption\]\[caption/g, 'caption] [caption')
2022 .replace(/<object[\s\S]+?<\/object>/g, function(a) {
2023 return a.replace(/[\r\n]+/g, ' ');
2024 });
2025
2026 }).bind('afterWpautop', function(e, o){
2027 o.data = o.unfiltered;
2028 });
2029 //]]>
2030 </script>
2031 <?php
2032 }
2033
2034 function modify_tinymce() {}
2035
2036 /* south side rockers */
2037 function media_button_add() {
2038
2039 global $post_ID, $temp_ID;
2040
2041 if($this->is_setup()) {
2042 $uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
2043 $media_upload_iframe_src = "media-upload.php?post_id=$uploading_iframe_ID";
2044 $media_oap_iframe_src = apply_filters('media_oap_iframe_src', "$media_upload_iframe_src&amp;tab=forms");
2045 $media_oap_title = __('Add ' . self::$brand . ' Media', 'wp-media-oapform');
2046 echo "<a href=\"{$media_oap_iframe_src}&amp;TB_iframe=true&amp;height=500&amp;width=640\" class=\"thickbox\" title=\"$media_oap_title\"><img src=\"".$this->get_setting("mr_url", "oap")."static/media-button-pp.gif\" alt=\"$media_oap_title\" /></a>";
2047 }
2048 }
2049
2050 /* this function adds the metaboxes defined in construct() to the WP admin */
2051 function metabox_add() {
2052 if($this->is_setup()) {
2053 $this->load_metaboxes();
2054 foreach($this->metaboxes as $id => $details) {
2055 $types = array();
2056 foreach($this->get_setting("post_types","wp") as $type) {
2057 add_meta_box($details['id'], $details['title'], array($this, "metabox_display"), $type, $details['context'], $details['priority']);
2058 array_push($types, $type);
2059 }
2060 if ( !in_array( 'ontrapage', $types ) )
2061 {
2062 add_meta_box($details['id'], $details['title'], array($this, "metabox_display"), 'ontrapage', $details['context'], $details['priority']);
2063 }
2064 }
2065 }
2066 }
2067
2068 /* loop through and save some stuff for us */
2069 function metabox_save($post_id) {
2070
2071 if (!wp_verify_nonce($_POST[self::NSPACE.'nonce'], basename(__FILE__))) {
2072 return $post_id;
2073 }
2074
2075 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
2076 return $post_id;
2077 }
2078
2079 if ('page' == $_POST['post_type']) {
2080 if(!current_user_can('edit_page', $post_id)) {
2081 return $post_id;
2082 }
2083 } elseif (!current_user_can('edit_post', $post_id)) {
2084 return $post_id;
2085 }
2086
2087 foreach($_POST[self::NSPACE."metaboxes"] as $metabox) {
2088 foreach ($this->metaboxes[$metabox]["fields"] as $field) {
2089
2090 if(empty($_POST[$field['id']])) {
2091 delete_post_meta($post_id, $field['id']);
2092 }
2093
2094 if(isset($_POST[$field["id"]]) && is_array($_POST[$field['id']])) {
2095 delete_post_meta($post_id, $field["id"]);
2096 foreach($_POST[$field['id']] as $new) {
2097 add_post_meta($post_id, $field['id'], sanitize_text_field($new));
2098 }
2099 } else {
2100 if(isset($_POST[$field["id"]]) && !empty($_POST[$field['id']])) {
2101 update_post_meta($post_id, $field['id'], sanitize_text_field($_POST[$field['id']]));
2102 }
2103 }
2104 }
2105 }
2106 }
2107
2108
2109 function metabox_display($post_ref, $pass_thru) {
2110
2111 global $post;
2112
2113 echo '<input type="hidden" name="'.self::NSPACE.'nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';
2114 echo '<input type="hidden" name="'.self::NSPACE.'metaboxes[]" value="'.$pass_thru["id"].'" />';
2115 echo '<table class="form-table">';
2116
2117 foreach ($this->metaboxes[$pass_thru["id"]]['fields'] as $field) {
2118
2119 $meta = get_post_meta($post->ID, $field['id']);
2120
2121 if(is_array($meta) && count($meta) < 2 && array_key_exists(0, $meta)) {
2122 $meta = $meta[0];
2123 }
2124
2125 if(empty($meta)) {
2126 $meta = array();
2127 }
2128
2129 if($field["type"] != "single-checkbox") {
2130 echo '<tr><td><label for="', $field['id'], '"><b>', $field['name'], '</b></label><br/>';
2131 }
2132
2133 switch ($field['type']) {
2134
2135 case "text":
2136 echo "<input type='text' name='{$field['id']}' id='{$field['id']}'";
2137 if(!empty($meta)) {
2138 if(is_array($meta)) {
2139 echo " value='" . esc_attr($meta[0]) . "'";
2140 } else {
2141 echo " value='" . esc_attr($meta) . "'";
2142 }
2143 }
2144 echo "><br/>";
2145 break;
2146
2147 case 'select':
2148 echo '<select name="', $field['id'], '" id="', $field['id'], '">';
2149 if (is_array($field["options"]))
2150 {
2151 foreach ($field['options'] as $option) {
2152 echo '<option', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>';
2153 }
2154 }
2155 echo '</select><br/>';
2156 break;
2157
2158 case 'select-keyvalue':
2159
2160 if($field["id"] == self::NSPACE."redirect_location") {
2161 $field["options"] = $this->get_routeable_pages(array($post->ID));
2162 }
2163
2164 echo '<select name="', $field['id'], '" id="', $field['id'], '">';
2165 if (is_array($field["options"]))
2166 {
2167 foreach ($field['options'] as $key => $option) {
2168 echo '<option value="'.$key.'" ', $meta == $key ? ' selected="selected"' : '', '>', $option, '</option>';
2169 }
2170 }
2171 echo '</select><br/>';
2172
2173 break;
2174
2175 case 'multi-checkbox':
2176 if(in_array($post->ID, $this->system_pages)) {
2177 echo "<b style='color: green;'>N/A</b><br/>";
2178 } else {
2179 if(is_array($field["options"]) && count($field["options"]) > 0) {
2180 foreach ($field['options'] as $key => $option) {
2181 if(is_array($meta)) {
2182 echo '<label class="pp-access-level"><input type="checkbox" name="'.$field['id'].'[]" value="'.$option.'" ', in_array($option, $meta) ? ' checked' : '', ' /><span class="pp-access-level-label"> ', $option, '</span></label>';
2183 } else {
2184 echo '<label class="pp-access-level"><input type="checkbox" name="'.$field['id'].'[]" value="'.$option.'" ', $option == $meta ? ' checked' : '', ' /><span class="pp-access-level-label"> ', $option, '</span></label>';
2185 }
2186 }
2187 }
2188 }
2189
2190 break;
2191 case 'radio':
2192 if(is_array($field["options"]) && count($field["options"]) > 0) {
2193 foreach ($field['options'] as $option) {
2194 echo '<input type="radio" name="', $field['id'], '" value="', $option['value'], '"', $meta == $option['value'] ? ' checked="checked"' : '', ' />&nbsp;', $option['name'];
2195 echo "&nbsp;";
2196 }
2197 }
2198 break;
2199 case 'single-checkbox':
2200 echo '<tr><td><input type="checkbox" name="', $field['id'], '" id="', $field['id'], '"', $meta ? ' checked="checked"' : '', ' /> <label for="', $field['id'], '"><b>', $field['name'], '</b></label>';
2201 echo '';
2202 break;
2203 case 'preview-button':
2204 if(is_array($field["options"]) && count($field["options"]) > 0)
2205 {
2206 foreach ($field['options'] as $option)
2207 {
2208 echo "<button class='admin-preview button button-small' value='".$option."'>".$option."</button>";
2209 }
2210 }
2211 break;
2212 }
2213
2214 if($field["id"] != self::NSPACE."redirect_location") {
2215
2216 } else {
2217
2218 }
2219
2220 if($field["desc"]) {
2221 echo '<span class="pp-access-level-note">'.$field["desc"].'</span>';
2222 }
2223
2224 echo '</tr>';
2225 }
2226
2227 echo '</table>';
2228 }
2229
2230
2231
2232 /* ok, time for some seriousness... this does the login. see additional comments inline */
2233 function user_login($username, $password) {
2234 //Some plugins/themes pass a WP_User object through the wp_authenticate hook instead of the login string.
2235 if (is_a($username, 'WP_User')) {
2236 $username = $username->user_login;
2237 }
2238
2239 do_action('pilotpress_pre_user_login');
2240 if(isset($_POST["wp-submit"])) {
2241 if (!empty($username)) {
2242
2243
2244 //Wordpress trims trailing and leading spaces before authenticating, lets do the same.
2245 $password = trim($password);
2246
2247 $hashed_password = $username . self::VERSION . $password . self::AUTH_SALT;
2248
2249 $supported_algos = hash_algos();
2250 if (in_array("sha256", $supported_algos)) {
2251 $algo = "sha256";
2252 $hash = hash("sha256", $hashed_password);
2253 } else {
2254 $algo = "md5";
2255 $hash = md5($hashed_password);
2256 }
2257
2258 if (isset($_COOKIE["sess_"])) {
2259 $session_id = $_COOKIE["sess_"];
2260 } else {
2261 $session_id = $this->genmrSess(rand(15, 20));
2262 }
2263
2264
2265 $api_result = $this->api_call("authenticate_user", array("site" => site_url(), "username" => $username, "password" => $hash, "version" => self::VERSION, "algo" => $algo, "session_id" => $session_id));
2266
2267 if ($api_result == false && $this->get_setting('pilotpress_sync_users') == '2') {
2268 //make sure user checks out with WP
2269 $user = wp_authenticate($username, $password);
2270 if (!$this->is_site_admin($user) && $user) {
2271
2272 $tagList = $this->get_setting("pilotpress_newly_registered_tags");
2273 $sequenceList = $this->get_setting("pilotpress_newly_registered_sequences");
2274 $campaignsList = $this->get_setting("pilotpress_newly_registered_campaigns");
2275 $userData = array(
2276 "username" => $user->user_login,
2277 "password" => $password,
2278 "firstname" => $user->user_firstname,
2279 "lastname" => $user->user_lastname,
2280 "email" => $user->user_email,
2281 "website" => $user->user_url,
2282 "tags" => $tagList,
2283 "sequences" => $sequenceList,
2284 "campaigns" => $campaignsList,
2285 "site" => site_url(),
2286 "version" => self::VERSION
2287 );
2288
2289 //should return like "authenticate_user"
2290 $api_result = $this->api_call("sync_user", $userData);
2291 }
2292 }
2293
2294 /* user does exist */
2295 if (is_array($api_result)) {
2296
2297 if ( (!username_exists($username) && !email_exists($username)) && $api_result["status"] != 0 ) {
2298 /* if their email is used (might have been a blog user before OAP perhaps), use alternate name */
2299 if (email_exists($api_result["email"])) {
2300 $email = $api_result["email_alt"];
2301 $email_alt = $api_result["email"];
2302 } else {
2303 $email = $api_result["email"];
2304 $email_alt = $api_result["email_alt"];
2305 }
2306
2307 $firstname = "";
2308 $lastname = "";
2309
2310 if ($api_result["firstname"]) {
2311 $firstname = $api_result["firstname"];
2312 }
2313
2314 if ($api_result["lastname"]) {
2315 $lastname = $api_result["lastname"];
2316 }
2317
2318 /* scary WP create user */
2319 $create_user = wp_create_user($username, $password, $email);
2320
2321 /* if this errors, tell us! */
2322 if (isset($create_user->errors) && isset($create_user->errors["existing_user_email"])) {
2323 unset($create_user);
2324 $create_user = wp_create_user($username, $password, $email_alt);
2325 }
2326
2327 if (isset($create_user->errors)) {
2328 $this->api_call("create_user_error", array("message" => site_url()));
2329 return false;
2330 }
2331
2332 if (isset($api_result["nickname"]))
2333 {
2334 $update = array(
2335 "ID" => $create_user,
2336 "nickname" => $api_result["nickname"],
2337 "display_name" => $api_result["nickname"],
2338 "first_name" => $firstname,
2339 "last_name" => $lastname
2340 );
2341
2342 if($this->get_setting("discrete_nickname") == "on")
2343 {
2344 $email_split = explode("@", $email);
2345 $update["nickname"] = $email_split[0];
2346 }
2347
2348 wp_update_user($update);
2349 }
2350
2351 } else {
2352
2353 /* this user does exist, so log us in */
2354 $user = get_user_by("login", $username);
2355 if ($user === false)
2356 {
2357 $user = get_user_by("email", $username);
2358 }
2359
2360 if ($user === false) // If still false, something else is amiss, bail.
2361 {
2362 return false;
2363 }
2364
2365 /* ruhroh, this person is no longer welcomed! */
2366 if ($api_result["status"] == "0")
2367 {
2368 add_user_meta($user->ID, "pilotpress_blocked", "yes", true);
2369 update_user_meta($user->ID, "pilotpress_blocked", "yes");
2370 return false;
2371 }
2372 else if ($api_result["status"] == "1")
2373 {
2374 update_user_meta($user->ID, "pilotpress_blocked", "no");
2375 // We want to sync the password into wordpress in this case, but when we call
2376 // wp_set_password it boots out any other sessions for this user. So, just do it once.
2377 $recent_password_set = get_transient("pilotpress_recent_password_set". (int) $user->ID);
2378 if ($recent_password_set === false)
2379 {
2380 wp_set_password($password, $user->ID); // should sync pwd when auth'd to avoid the weird email issue.
2381 set_transient("pilotpress_recent_password_set". (int) $user->ID, 86400*30); // 30-day ttl to avoid buildup of transients for old users
2382 }
2383 }
2384 else if ($user->user_level != 10)
2385 {
2386 wp_set_password($password, $user->ID);
2387 }
2388 else
2389 {
2390 return false;
2391 }
2392 }
2393
2394 /* store where the user logged in from for redirection after logout */
2395 $referrer = false;
2396 if (isset($_SERVER['HTTP_REFERER']))
2397 {
2398 $referrer = $_SERVER['HTTP_REFERER'];
2399 }
2400 if (!empty($referrer)) {
2401 $_SESSION["loginURL"] = $referrer;
2402 }
2403
2404
2405 $user = get_user_by("login", $username);
2406 if ($user === false)
2407 {
2408 $user = get_user_by("email", $username);
2409 }
2410
2411 //User is not the admin user... admin doesnt get to have their session set.
2412 if ($user->user_level != 10) {
2413
2414 /* this person is not an admit, so lets make this person special */
2415 if (defined("COOKIE_DOMAIN") && COOKIE_DOMAIN == "") {
2416 $cookie_domain = str_replace($this->get_protocol(), "", site_url());
2417 } else {
2418 $cookie_domain = COOKIE_DOMAIN;
2419 }
2420
2421 setcookie("contact_id", $api_result["contact_id"], (time() + 2419200), COOKIEPATH, $cookie_domain, false); //1 month
2422
2423 $contact_id = false;
2424 if (isset($_COOKIE["contact_id"]))
2425 {
2426 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
2427 }
2428 set_transient("login_url_pilotpress_user" . (int) $contact_id, $referrer, self::TTL);
2429
2430
2431 $user_id = $user->ID;
2432 $remember = false;
2433 if (!empty($_POST["rememberme"])) {
2434 $remember = true;
2435 }
2436 wp_set_current_user($user_id, $username);
2437 wp_set_auth_cookie($user_id, $remember);
2438 do_action('wp_login', $username, $user);
2439
2440 if (!isset($_SESSION["user_name"])) {
2441
2442 $this->start_session();
2443
2444 if (is_array($api_result))
2445 {
2446 foreach ($api_result as $key => $value) {
2447 $_SESSION[$key] = $value;
2448 }
2449 }
2450
2451 $_SESSION["user_name"] = $api_result["username"];
2452 $_SESSION["nickname"] = $api_result["nickname"];
2453 $_SESSION["user_levels"] = $api_result["membership_level"];
2454 $_SESSION["rehash"] = true;
2455 }
2456
2457 set_transient("authenticate_user_pilotpress_user" . get_current_user_id(), array("authenticate_user" => $api_result, "timestamp" => time()), self::TTL);
2458 $this->ppp->ppprotectSetPPMemLevels($api_result["membership_level"]);
2459
2460 setcookie("sess_", $session_id, (time() + 2419200), COOKIEPATH, $cookie_domain, false);
2461
2462 do_action('pilotpress_post_user_login');
2463
2464 $contact_id = false;
2465 /* where to go from here */
2466 if (isset($_COOKIE["contact_id"]))
2467 {
2468 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
2469 }
2470 $redirect_to = $this->getRedirectURL((int) $contact_id);
2471 if ($redirect_to && !empty($redirect_to) && !strpos($referrer, 'wp-login.php'))
2472 {
2473 unset($_SESSION["redirect_to"]);
2474 delete_transient("pilotpress_redirect_to". (int) $contact_id);
2475 self::redirect($redirect_to);
2476 die;
2477 }
2478
2479 /* this person is an affiliate, put them somewhere nice */
2480 $center_priority = $this->get_setting("center_priority");
2481 if ($center_priority == 2) //2 -> customer center
2482 {
2483 $cust_plr = $this->get_setting("pilotpress_customer_plr");
2484 if ($cust_plr && $cust_plr != "-1") {
2485 self::redirect(get_permalink($cust_plr));
2486 die;
2487 } else {
2488 self::redirect(site_url());
2489 die;
2490 }
2491 } else {
2492 if (isset($api_result["program_id"])) {
2493 $aff_plr = $this->get_setting("pilotpress_affiliate_plr");
2494 if ($aff_plr && $aff_plr != "-1") {
2495 self::redirect(get_permalink($aff_plr));
2496 die;
2497 exit;
2498 } else {
2499 self::redirect(site_url());
2500 die;
2501 }
2502 } else {
2503
2504 $cust_plr = $this->get_setting("pilotpress_customer_plr");
2505 if ($cust_plr && $cust_plr != "-1") {
2506 self::redirect(get_permalink($cust_plr));
2507 die;
2508 } else {
2509 self::redirect(site_url());
2510 die;
2511 }
2512 }
2513 }
2514 die;
2515 }
2516 }
2517 }
2518 }
2519 }
2520
2521 /* redirect the user to a failed login page */
2522 function user_login_failed() {
2523 do_action('pilotpress_user_login_failed');
2524
2525 $referrer = false;
2526 if (isset($_SERVER['HTTP_REFERER']))
2527 {
2528 $referrer = $_SERVER['HTTP_REFERER'];
2529 }
2530
2531 if(!empty($referrer) && !strstr($referrer, "wp-login") && !strstr($referrer, "wp-admin") ) {
2532 set_transient("pilotpress_login_failed", "true", self::TTL);
2533 $_SESSION["loginFailed"] = true;
2534 self::redirect($referrer);
2535 die;
2536 }
2537 }
2538
2539 function user_lostpassword() {
2540 do_action('pilotpress_user_lostpassword');
2541 $api_result = $this->api_call("user_lostpassword", array("site" => site_url(), "username" => self::validatePostVar($_POST['user_login'], "string")));
2542
2543 if(!is_array($api_result) || empty($api_result['email']))
2544 {
2545 /* display invalid username or e-mail message*/
2546 $_POST['user_login'] = "";
2547 }
2548 else
2549 {
2550 /* notify user of e-mail, end the rest of WP's processing */
2551 self::redirect(site_url() . "/wp-login.php?checkemail=confirm");
2552 die;
2553 }
2554 }
2555
2556 function user_logout() {
2557 do_action('pilotpress_pre_user_logout');
2558
2559 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
2560 $redirect_to = get_transient("login_url_pilotpress_user". (int) $contact_id);
2561 $this->destroy_transients_logout();
2562 $this->end_session(true);
2563
2564 do_action('pilotpress_post_user_logout');
2565
2566 if(isset($redirect_to) && !empty($redirect_to))
2567 {
2568 self::redirect($redirect_to);
2569 }
2570 else
2571 {
2572 self::redirect(site_url());
2573 }
2574 }
2575
2576 /** @brief if possible add the new user to ONTRAPORT when registered in WordPress */
2577 function add_new_register_user_to_ONTRAPORT($user_id) {
2578 $bAddUser = $this->get_setting("pilotpress_sync_users");
2579 if ($bAddUser !== '1')
2580 {
2581 return;
2582 }
2583 $appid = $this->get_setting("app_id");
2584 $key = $this->get_setting("api_key");
2585 $tagList = $this->get_setting("pilotpress_newly_registered_tags");
2586 $sequenceList = $this->get_setting("pilotpress_newly_registered_sequences");
2587 $campaignList = $this->get_setting("pilotpress_newly_registered_campaigns");
2588 $user = get_userdata($user_id);
2589 $userData = array(
2590 "username" => $user->user_login,
2591 "password" => self::validatePostVar($_POST['pass1'], "string"),
2592 "firstname"=>$user->user_firstname,
2593 "lastname"=>$user->user_lastname,
2594 "email"=>$user->user_email,
2595 "tags"=>$tagList,
2596 "sequences"=>$sequenceList,
2597 "campaigns"=>$campaignList,
2598 "site" => site_url(),
2599 "version" => self::VERSION
2600 );
2601
2602 $api_result = $this->api_call("sync_user", $userData);
2603 }
2604
2605
2606 static function start_session()
2607 {
2608 //sessions break theme editor & admin page doesn't need sessions
2609 if(!is_admin())
2610 {
2611 ob_start();
2612 if(!session_id()) {
2613 session_start();
2614 }
2615 ob_end_clean();
2616 }
2617 }
2618
2619 static function end_session($logout = false) {
2620
2621 if($logout) {
2622 /* redirect the user to where they logged in from */
2623 if(isset($_SESSION["loginURL"]))
2624 self::redirect($_SESSION["loginURL"]);
2625 else
2626 self::redirect(site_url());
2627 }
2628
2629 ob_start();
2630 if(session_id()) {
2631 delete_transient("pilotpress_cache");
2632 if(isset($_SESSION["contact_id"])) {
2633 delete_transient("usertags_".$_SESSION["contact_id"]);
2634 }
2635 unset($_SESSION);
2636 session_destroy();
2637 }
2638 ob_end_clean();
2639
2640 if($logout) die;
2641 }
2642
2643 function filter_query_vars($vars) {
2644 return $vars;
2645 }
2646
2647 function filter_rewrite_rules($rules) {
2648 global $wp_rewrite;
2649 $newRule = array('ref/(.+)' => 'index.php?ref='.$wp_rewrite->preg_index(1));
2650 $newRules = $newRule + $rules;
2651 return $newRules;
2652 }
2653
2654 function flush_rewrite_rules() {
2655 global $wp_rewrite;
2656 $wp_rewrite->flush_rules();
2657 }
2658
2659 function clean_meta() {
2660 global $wpdb;
2661 $wpdb->query("DELETE FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_level' AND meta_value = ''");
2662 }
2663
2664 /* Load up the membership level meta boxes but after we have gotten the levels */
2665 function load_metaboxes() {
2666
2667 /* metaboxes in admin */
2668 $this->metaboxes[self::NSPACE."page_box"] = array(
2669 'id' => self::NSPACE.'page_box',
2670 'title' => 'PilotPress Options',
2671 'context' => 'side',
2672 'priority' => 'high',
2673 'fields' => array(
2674 array(
2675 'name' => 'Access Levels',
2676 'desc' => '(Leave blank to allow access to all users.)',
2677 'id' => self::NSPACE.'level',
2678 'type' => 'multi-checkbox',
2679 'options' => $this->get_setting("membership_levels", "oap")
2680 ),
2681 array(
2682 'name' => 'Show in Navigation',
2683 'desc' => false,
2684 'id' => self::NSPACE.'show_in_nav',
2685 'type' => 'single-checkbox'
2686 ),
2687 array(
2688 'name' => 'On Error',
2689 'desc' => $this->get_setting("error_redirect_message"),
2690 'id' => self::NSPACE.'redirect_location',
2691 'type' => $this->get_setting("error_redirect_field"),
2692 'options' => array()
2693 )
2694 )
2695 );
2696
2697 $this->metaboxes[self::NSPACE."admin_preview"] = array(
2698 'id' => self::NSPACE."admin_preview",
2699 'title' => 'PilotPress Admin View As',
2700 'context' => 'side',
2701 'priority' => 'high',
2702 'fields' => array(
2703 array(
2704 'name' => 'Select membership level to view as:',
2705 'desc' => false,
2706 'id' => self::NSPACE.'view_as',
2707 'options' => $this->get_setting("membership_levels", "oap"),
2708 'type' => 'preview-button'
2709 )
2710 )
2711 );
2712
2713 }
2714
2715
2716 /**
2717 * @brief prevents a user from overloading the API using customizable params
2718 * @params array $options --> (string)id, (int)timeout, (int)passes, (int)interval, (bool ref)throttled, (bool)admin
2719 * @return sets (bool ref)throttled to true when user has hit its limit
2720 **/
2721 function throttle($options)
2722 {
2723 if (is_array($options) && isset($options['id']) && isset($options['throttled']))
2724 {
2725
2726 //allow admin user to override the throttle
2727 $admin = $options['admin'];
2728 if(!$admin)
2729 {
2730 $now = time();
2731 $id = $options['id'];
2732 $passes = $options['passes'];
2733 $timeout = $options['timeout'];
2734 $interval = $options['interval'];
2735
2736 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
2737 $throttle_data = get_transient("pilotpress_throttle".(int) $contact_id);
2738
2739 //pass limit hit, need to check to throttle
2740 if (isset($throttle_data[$id]['allowed']))
2741 {
2742 $timeLeft = $now - $throttle_data[$id]['allowed'];
2743
2744 if ($timeLeft < 0)
2745 {
2746 $options['throttled'] = true;
2747 }
2748 else //reset their timers
2749 {
2750 unset($throttle_data[$id]);
2751 $throttle_data[$id]['pass'] = 1;
2752 $throttle_data[$id]['setAt'] = $now;
2753
2754 //edge case -- 1 pass allowed
2755 if ($throttle_data[$id]['pass'] == $passes)
2756 {
2757 $throttle_data[$id]['allowed'] = $now + $timeout;
2758 }
2759 }
2760 }
2761 else
2762 {
2763 if (!isset($throttle_data[$id]['setAt']))
2764 {
2765 $throttle_data[$id]['setAt'] = $now;
2766 }
2767 else
2768 {
2769 //waited long enough, reset throttle
2770 if ($now > ($throttle_data[$id]['setAt'] + $interval))
2771 {
2772 unset($throttle_data[$id]);
2773 $throttle_data[$id]['setAt'] = $now;
2774 $throttle_data[$id]['pass'] = 0;
2775 }
2776 }
2777
2778 //# of passes handling
2779 if (isset($throttle_data[$id]['pass']))
2780 {
2781 $throttle_data[$id]['pass']++;
2782 }
2783 else
2784 {
2785 $throttle_data[$id]['pass'] = 1;
2786 }
2787
2788 if ($throttle_data[$id]['pass'] == ($passes))
2789 {
2790 $throttle_data[$id]['allowed'] = $now + ($timeout);
2791 }
2792 }
2793
2794 set_transient("pilotpress_throttle".(int) $contact_id, $throttle_data, self::TTL);
2795 }
2796 }
2797 }
2798
2799 /**
2800 * @brief shortcode that re-syncs whichever user hits the page containing it, destroys all assoc. data and re-grabs it
2801 * @params array $atts, string $content
2802 * @return nothing, just carries on w/ other shortcode magic
2803 **/
2804 function shortcode_sync_contact($atts, $content = null)
2805 {
2806 $throttled = false;
2807
2808 //throttle them for 5 minutes if they try to do this more than 3 times within a 5 minutes gap
2809 $this->throttle(array(
2810 'id' => "sync_contact",
2811 'timeout' => 60 * 5, //5 minutes
2812 'passes' => 3,
2813 'interval' => 60 * 5, //5 minutes
2814 'throttled' => &$throttled,
2815 'admin' => current_user_can("manage_options")
2816 ));
2817
2818
2819 if(!$throttled)
2820 {
2821 $this->destroy_transients_logout();
2822 $this->load_settings();
2823 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2824 }
2825 else
2826 {
2827 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2828 }
2829 }
2830
2831 /* shortcodes for conditional ifs */
2832 function shortcode_show_if($atts, $content = null) {
2833
2834 if(isset($atts[0]) && $atts[0] == "not_contact") {
2835 if(!$this->get_setting("contact_id","user")) {
2836 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2837 }
2838 }
2839
2840 $user_info = $this->get_stashed("authenticate_user", true);
2841
2842 $contact_id = false;
2843 //make cookie check befor login check to bypass it
2844 if (isset($_COOKIE["contact_id"]))
2845 {
2846 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
2847 }
2848
2849 if ( isset($atts[0]) && $atts[0] == "is_cookied_contact")
2850 {
2851 if ($contact_id !== false)
2852 {
2853 return '<span class="pilotpress_protected">'.do_shortcode($content) . '</span>';
2854 }
2855 }
2856
2857 if (isset($atts[0]) && $atts[0] == "not_cookied_contact")
2858 {
2859 if ($contact_id === false)
2860 {
2861 return '<span class="pilotpress_protected">'.do_shortcode($content) . '</span>';
2862 }
2863 }
2864 if(!is_user_logged_in() || get_user_meta(get_current_user_id(), "pilotpress_blocked", true) == "yes")
2865 {
2866 return;
2867 }
2868
2869 if ($found = self::DoShortcodeMagic($atts,$content))
2870 {
2871 return $found;
2872 }
2873
2874 //if we fail to find something lets make sure Wordpress hasnt encoded the tags and membership levels.
2875 if(is_array($atts))
2876 {
2877 foreach ($atts as $key => $att)
2878 {
2879 $atts[$key] = html_entity_decode($atts[$key],ENT_COMPAT,"UTF-8");
2880 }
2881 }
2882
2883 //process shortcodes with decoded entities
2884 return self::DoShortcodeMagic($atts,$content);
2885 }
2886
2887 /*
2888 * @brief Process additional shortcode logic here
2889 *
2890 **/
2891 function DoShortcodeMagic($atts,$content)
2892 {
2893 $user_info = $this->get_stashed("authenticate_user", true);
2894 $user_levels = false;
2895
2896 if(current_user_can("manage_options") && isset(self::$stashed_transients["pilotpress_admin_preview"]))
2897 {
2898 $user_levels = self::$stashed_transients["pilotpress_admin_preview"];
2899 }
2900 else
2901 {
2902 if (isset($user_info["authenticate_user"]["membership_level"]))
2903 {
2904 $user_levels = $user_info["authenticate_user"]["membership_level"];
2905 }
2906 }
2907
2908 if(!is_array($user_levels))
2909 {
2910 $user_levels = array();
2911 }
2912
2913 if(isset($atts["level"])) {
2914 if(in_array($atts["level"], $user_levels)) {
2915 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2916 }
2917 } else {
2918
2919 if(isset($atts["has_one"])) {
2920 $content_levels = explode(",", $atts["has_one"]);
2921 if (is_array($user_levels))
2922 {
2923 foreach($user_levels as $level) {
2924 if(in_array(ltrim(rtrim($level)), $content_levels)) {
2925 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2926 }
2927 }
2928 }
2929 }
2930
2931 if(isset($atts["has_all"])) {
2932 $content_levels = explode(",", $atts["has_all"]);
2933 if (is_array($content_levels))
2934 {
2935 foreach($content_levels as $level) {
2936 if(!in_array(ltrim(rtrim($level)), $user_levels)) {
2937 return false;
2938 }
2939 }
2940 }
2941 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2942 }
2943
2944 if(isset($atts["not_one"])) {
2945 $content_levels = explode(",", $atts["not_one"]);
2946 if (is_array($content_levels))
2947 {
2948 foreach($content_levels as $level) {
2949 if(in_array(ltrim(rtrim($level)), $user_levels)) {
2950 return false;
2951 }
2952 }
2953 }
2954 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2955 }
2956
2957 if(isset($atts["not_any"])) {
2958 $content_levels = explode(",", $atts["not_any"]);
2959 if (is_array($content_levels))
2960 {
2961 foreach($content_levels as $level) {
2962 if(!in_array(ltrim(rtrim($level)), $user_levels)) {
2963 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2964 }
2965 }
2966 }
2967 }
2968
2969 if(isset($atts[0]) && $atts[0] == "is_contact") {
2970 if($user_info["authenticate_user"]["contact_id"]) {
2971 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2972 }
2973 }
2974 if (isset($atts["has_tag"]))
2975 {
2976 $tags = $this->get_setting("tags", "user");
2977 if (is_array($tags))
2978 {
2979 $content_tags = explode(",", strtolower($atts["has_tag"]));
2980 $content_tags = array_map('trim', $content_tags);
2981 $tags = array_map('strtolower', $tags);
2982 foreach ($tags as $tag)
2983 {
2984 if (in_array(trim($tag), $content_tags))
2985 {
2986 return '<span class="pilotpress_protected">' . do_shortcode($content) . '</span>';
2987 }
2988 }
2989 }
2990 }
2991
2992 if(isset($atts["does_not_have_tag"]))
2993 {
2994 $tags = $this->get_setting("tags", "user");
2995 if(empty($tags) || !(in_array($atts["does_not_have_tag"], $tags)))
2996 {
2997 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
2998 }
2999 }
3000
3001 if(isset($atts[0]) && in_array($atts[0], $user_levels)) {
3002 return '<span class="pilotpress_protected">'.do_shortcode($content).'</span>';
3003 }
3004 }
3005 }
3006
3007 function shortcode_field($atts, $content = null) {
3008
3009 extract(shortcode_atts(array("name" => "All"), $atts));
3010 if(isset($atts["name"]))
3011 {
3012 return $this->get_field($atts["name"]);
3013 }
3014
3015 }
3016
3017 /* the big nasty content hiding function... tread carefully */
3018 function post_process()
3019 {
3020 global $post;
3021 if (isset($post->ID))
3022 {
3023 $id = $post->ID;
3024 }
3025 else
3026 {
3027 $id = $this->get_postid_by_url();
3028 if (empty($id) && get_option('show_on_front') == 'page')
3029 {
3030 $id = get_option('page_on_front');
3031 }
3032 }
3033
3034 if (!$this->is_viewable($id) || get_user_meta(get_current_user_id(), "pilotpress_blocked", true) == "yes")
3035 {
3036 $redirect = get_post_meta($id, self::NSPACE . "redirect_location", true);
3037 if (!empty($redirect))
3038 {
3039 $contact_id = false;
3040 if (isset($_COOKIE["contact_id"]))
3041 {
3042 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
3043 }
3044
3045 if ($redirect == "-1")
3046 {
3047 return self::redirect(site_url());
3048 }
3049
3050 if ($redirect == "-2")
3051 {
3052 if (!empty($id))
3053 {
3054 $_SESSION["redirect_to"] = $id;
3055 if ($contact_id !== false)
3056 {
3057 set_transient("pilotpress_redirect_to" . $contact_id, "post_" . $id, self::FIVE_MINUTES);
3058 }
3059 }
3060 }
3061 $_SESSION["redirect_to"] = $id;
3062 if ($contact_id !== false)
3063 {
3064 set_transient("pilotpress_redirect_to" . $contact_id, "post_" . $id, self::FIVE_MINUTES);
3065 }
3066 return self::redirect(get_permalink($redirect));
3067 }
3068 return self::redirect($this->homepage_url);
3069 }
3070 }
3071
3072 /* is this a special page? if so render such */
3073 function content_process($content) {
3074 global $post;
3075
3076 $loginFailed = get_transient("pilotpress_login_failed");
3077
3078 //check to see if login failed on a custom login page!
3079 if(has_shortcode($content, 'login_page') && $loginFailed == "true")
3080 {
3081 preg_match_all("/\[login_page\s*[^\[\]]*\]/", $content, $matches);
3082 foreach($matches[0] as $index => $shortcode)
3083 {
3084 $atts = shortcode_parse_atts($shortcode);
3085 $login_page = $this->login_page($atts, 3);
3086 $content = str_replace($shortcode, $login_page, $content, $count);
3087 }
3088 delete_transient("pilotpress_login_failed");
3089 return $content;
3090 }
3091
3092 if($this->do_login == true) {
3093 if(!is_user_logged_in() && $loginFailed == "true") {
3094 $login_page = $this->login_page(array(), 3);
3095 $content = str_replace("[login_page]", $login_page, $content, $count);
3096 if($count == 0) {
3097 $content = $login_page;
3098 }
3099 delete_transient("pilotpress_login_failed");
3100 unset($_SESSION["loginFailed"]);
3101 } else if(!is_user_logged_in()) {
3102 $content = $this->login_page(array(), 1);
3103 } else {
3104 $content = $this->login_page(array(), 2);
3105 }
3106 $this->do_login = false;
3107 add_filter("comments_open", array(&$this, 'ppDisableComments'), 10, 2);
3108 add_filter("get_comments_number", array(&$this, 'ppZeroCommentsNumber'), 10, 1);
3109 } else {
3110 if(is_page() && in_array($post->ID, $this->system_pages)) {
3111 $content = $this->do_system_page($post->ID);
3112 }
3113
3114 if (has_shortcode($content, "pilotpress_field") || has_shortcode($content, "field"))
3115 {
3116 // Lets grab all the fields here with the API call and store them later
3117 // Since the shortcode hook runs after this one it is a safe spot to check and make if needed.
3118 $this->get_merge_field_settings($content);
3119 }
3120 }
3121
3122 return $content;
3123 }
3124
3125 /**
3126 * @brief close comments section by returning false
3127 * @param bool $open
3128 * @param int $post_id
3129 *
3130 * @return bool
3131 */
3132 public function ppDisableComments($open, $post_id)
3133 {
3134 return false;
3135 }
3136
3137 /**
3138 * @brief Zero out comments number so comments don't load in template
3139 * @param int $post_id
3140 *
3141 * @return int
3142 */
3143 public function ppZeroCommentsNumber($post_id)
3144 {
3145 return 0;
3146 }
3147
3148 /**
3149 * @brief Make api call to grab merge fields that are only present in the content
3150 *
3151 * @param String $content the string to check if merge fields are present
3152 *
3153 */
3154 function get_merge_field_settings($content , $makeApiCall = true)
3155 {
3156 $pattern = get_shortcode_regex();
3157
3158 preg_match_all('/'.$pattern.'/uis', $content, $matches);
3159
3160 for ( $i=0; $i < count($matches[0]); $i++ )
3161 {
3162 $fields = shortcode_parse_atts($matches[3][$i]);
3163 if (!is_array($fields)) // Case we only have one
3164 {
3165 $fields = array("name" => $fields);
3166 }
3167 $fields["name"] = $this->undo_quote_escaping($fields["name"]);
3168
3169 if ( isset( $matches[2][$i] ) && ($matches[2][$i] == "pilotpress_field" || $matches[2][$i] == "field") )
3170 {
3171 $this->shortcodeFields[$fields["name"]] = 1;
3172 }
3173 elseif (!empty($matches[5][$i]))
3174 {
3175 //call this recursively so we can process shortcodes inside shortcodes
3176 $this->get_merge_field_settings($matches[5][$i] , false);
3177 }
3178 }
3179
3180 $user_info = $this->get_stashed("authenticate_user", true);
3181 if(!isset($user_info["authenticate_user"]["username"]) || $user_info["authenticate_user"]["username"] == null)
3182 {
3183 return false;
3184 }
3185
3186 //Since this can be called recursively lets make sure when it does call it we only make this at the initial call of the function
3187 if ($makeApiCall)
3188 {
3189 //make API call now as well if needed!
3190 if (!empty($this->shortcodeFields) && is_array($this->shortcodeFields) && !empty($user_info["authenticate_user"]["username"]))
3191 {
3192 $data = array(
3193 "username" => $user_info["authenticate_user"]["username"],
3194 "fields" => $this->shortcodeFields,
3195 "site" => site_url()
3196 );
3197
3198 $api_result = $this->api_call("get_contact_merge_fields" , $data);
3199
3200 if(isset($api_result["fields"]))
3201 {
3202 // In order for the get_field() to work later on we need to add these fields to the group list of known merged fields.
3203 $this->settings["user"]["fields"]["--merged fields--"] = $api_result["fields"];
3204 $_SESSION["user_fields"]["--merged fields--"] = $api_result["fields"];
3205 }
3206 }
3207 }
3208 }
3209
3210 /* this is arguably the nastiest part of PilotPress, but unfortunately WP has consistently decided to not allow non-theme based manipulation of viewable pages */
3211 function get_routeable_pages($exclude = "") {
3212
3213 global $wpdb;
3214
3215 $array = array('-1' => "(homepage)", "-2" => "(login page)");
3216
3217 $query = $wpdb->get_results("SELECT ID, post_title FROM $wpdb->posts WHERE post_status = 'publish' AND (post_type = 'page' OR post_type ='oaplesson' OR post_type ='ontrapage') AND post_title != ''");
3218
3219 foreach($query as $index => $page) {
3220 $array[$page->ID] = $page->post_title;
3221 }
3222
3223 if(is_array($exclude)) {
3224 foreach($exclude as $id) {
3225 unset($array[$id]);
3226 }
3227 }
3228
3229 return apply_filters("pilotpress_get_routeable_pages",$array);
3230 }
3231
3232
3233
3234 /* this is where we part the seas: if something isn't routable, then tree falls in the woods to no fuss */
3235 function posts_where($where)
3236 {
3237 global $wpdb;
3238
3239 if(current_user_can('manage_options'))
3240 {
3241 if (empty(self::$stashed_transients["pilotpress_admin_preview"]))
3242 {
3243 return $where;
3244 }
3245 $user_levels = self::$stashed_transients["pilotpress_admin_preview"];
3246 }
3247 else
3248 {
3249 $user_levels = $this->get_setting("levels", "user", true);
3250 }
3251
3252 $site_levels = $this->get_setting("membership_levels", "oap", true);
3253
3254 //note empty beginner is important in situations where level_in or level_not_in are otherwise empty
3255 $level_in = "'',";
3256 $level_not_in = "'',";
3257
3258 if (is_array($site_levels))
3259 {
3260 foreach ($site_levels as $level)
3261 {
3262 if (in_array($level, $user_levels))
3263 {
3264 $level_in .= "'" . addslashes($level) . "',";
3265 }
3266 else
3267 {
3268 $level_not_in .= "'" . addslashes($level) . "',";
3269 }
3270 }
3271 }
3272
3273 $id = (int)$this->get_postid_by_url();
3274 if (empty($id) && get_option('show_on_front') == 'page')
3275 {
3276 $id = get_option('page_on_front');
3277 }
3278
3279 if (!empty($id))
3280 {
3281 if ($this->is_viewable($id))
3282 {
3283 return $where;
3284 }
3285
3286 $redirect = get_post_meta($id, self::NSPACE . "redirect_location", true);
3287 if ($redirect == "-2")
3288 {
3289 $this->do_login = $id;
3290 return $where;
3291 }
3292 }
3293
3294 $level_in = rtrim($level_in, ",");
3295 $level_not_in = rtrim($level_not_in, ",");
3296
3297 if (!empty($level_in))
3298 {
3299 $where .= "
3300 AND ID NOT IN
3301 (SELECT `post_id` FROM {$wpdb->postmeta}
3302 WHERE `meta_key` = '_pilotpress_level'
3303 AND `meta_value` IN (" . $level_not_in . ")
3304 AND `post_id` NOT IN
3305 (SELECT `post_id` FROM {$wpdb->postmeta}
3306 WHERE `meta_key` = '_pilotpress_level'
3307 AND `meta_value` IN (" . $level_in . " )))";
3308 }
3309
3310 return $where;
3311 }
3312
3313 /* filters nav menu objects */
3314 function get_pages($pages) {
3315 global $wpdb;
3316
3317 $show_in_nav = $this->get_setting("show_in_nav", "pilotpress", true);
3318
3319 $filtered = array();
3320 if (is_array($pages))
3321 {
3322 foreach($pages as $page) {
3323 if($this->is_viewable($page->ID) OR in_array($page->ID, $show_in_nav)) {
3324 $filtered[] = $page;
3325 }
3326 }
3327 }
3328
3329 return $filtered;
3330 }
3331
3332 function get_nav_menu_objects($menus) {
3333 $show_in_nav = $this->get_setting("show_in_nav", "pilotpress", true);
3334 $new_menus = array();
3335 if (is_array($menus))
3336 {
3337 foreach($menus as $id => $object) {
3338 $object_id = $object->object_id;
3339 if($this->is_viewable($object_id)) {
3340 $new_menus[] = $object;
3341 } else {
3342 if(in_array($object_id, $show_in_nav)) {
3343 $new_menus[] = $object;
3344 }
3345 }
3346 }
3347 }
3348
3349 return $new_menus;
3350 }
3351
3352 /* really returns filtered menus */
3353 function get_nav_menus($menus) {
3354
3355 $show_in_nav = $this->get_setting("show_in_nav", "pilotpress", true);
3356
3357 $excludes = array();
3358 $output = $menus;
3359 $xml = @simplexml_load_string($menus);
3360
3361 if(is_object($xml)) {
3362 if(isset($xml->ul->li)) {
3363 foreach($xml->ul->li as $obj) {
3364 $post_id = url_to_postid((string)$obj->a->attributes()->href);
3365 if(!$post_id){
3366 $pages = preg_replace('#^.+/([^/]+)/*$#','$1',(string)$obj->a->attributes()->href);
3367 $query = new WP_Query('pagename='.$pages);
3368
3369 if( $query->is_page && isset($query->queried_object) ) {
3370 $post_id = $query->queried_object->ID;
3371 }
3372 }
3373
3374 if(!$this->is_viewable($post_id) AND !in_array($post_id, $show_in_nav)) {
3375 $excludes[] = (string)$obj->attributes()->id;
3376 }
3377 }
3378 }
3379
3380 if(is_array($excludes) && count($excludes) > 0) {
3381 $output = "<style type='text/css'>";
3382 foreach($excludes as $index => $id) {
3383 $output .= '#'.$id." { display: none; }\n";
3384 }
3385 $output .= "</style>";
3386 $output .= $menus;
3387 }
3388 }
3389
3390 return $output;
3391 }
3392
3393 /* i take it back, this is horrible. at the time of writing, WP cannot find what page(s) are being displayed, so this finds it by URL. */
3394 function get_postid_by_url()
3395 {
3396 global $wp, $wpdb;
3397 $vars_to_check = array(
3398 "page_id" => "int",
3399 "p" => "int",
3400 "pagename" => "str",
3401 "name" => "str"
3402 );
3403
3404 foreach ($vars_to_check as $key => $type)
3405 {
3406 if (isset($wp->query_vars[$key]))
3407 {
3408 switch ($type)
3409 {
3410 case "int":
3411 return $wp->query_vars[$key];
3412 case "str":
3413 $name = $wp->query_vars[$key];
3414 $subpage = explode("/", $name);
3415 if (count($subpage) > 1)
3416 {
3417 $name = $subpage[1];
3418 }
3419 return $wpdb->get_var($wpdb->prepare("SELECT `ID` FROM {$wpdb->posts} WHERE `post_name` = %s", $name));
3420 }
3421 }
3422 }
3423
3424 return false;
3425 }
3426
3427 /* the most important function for content hiding. this finally decides if something can be seen or not. */
3428 function is_viewable($id) {
3429 global $wpdb, $post;
3430
3431 do_action('pilotpress_content_hiding');
3432
3433 $ref = get_query_var("ref");
3434 if($ref) {
3435 switch($ref) {
3436 case "customer_center":
3437 $page_id = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_system_page' AND meta_value = 'customer_center'", ARRAY_A);
3438 if($page_id) {
3439 self::redirect(get_permalink($page_id));
3440 die;
3441 }
3442 break;
3443 case "affiliate_center":
3444 $page_id = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_system_page' AND meta_value = 'affiliate_center'", ARRAY_A);
3445 if($page_id) {
3446 self::redirect(get_permalink($page_id));
3447 die;
3448 }
3449 break;
3450 default:
3451 break;
3452 }
3453 }
3454
3455 $page_levels = get_post_meta($id, "_pilotpress_level");
3456
3457 if(current_user_can('manage_options') && isset(self::$stashed_transients["pilotpress_admin_preview"])) {
3458 $user_levels = self::$stashed_transients["pilotpress_admin_preview"];
3459 }
3460 else if(current_user_can('manage_options') && !isset(self::$stashed_transients["pilotpress_admin_preview"]))
3461 {
3462 return true;
3463 }
3464 else
3465 {
3466 $user_info = $this->get_stashed("authenticate_user", true);
3467 if (isset($user_info["authenticate_user"]["membership_level"]))
3468 {
3469 $user_levels = $user_info["authenticate_user"]["membership_level"];
3470 }
3471 else
3472 {
3473 $user_levels = array();
3474 }
3475 }
3476
3477 if(!is_array($user_levels)) {
3478 $user_levels = array($user_levels);
3479 }
3480
3481 if(in_array($id, $this->system_pages)) {
3482 if(!is_user_logged_in()) {
3483 return false;
3484 } else {
3485 return true;
3486 }
3487 }
3488
3489 if (empty($page_levels) || count($page_levels) == 0)
3490 {
3491 return true;
3492 }
3493
3494 if(count($page_levels) > 0) {
3495 if(count($user_levels) == 0) {
3496 return false;
3497 } else {
3498 foreach($user_levels as $level) {
3499 if(in_array($level, $page_levels)) {
3500 return true;
3501 }
3502 }
3503 return false;
3504 }
3505 }
3506 }
3507
3508 /* simple getter */
3509 function get_system_pages() {
3510 global $wpdb;
3511 $return = array();
3512 $results = $wpdb->get_results("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_system_page'", ARRAY_A);
3513 if(is_array($results)) {
3514 foreach($results as $q_post) {
3515 $return[] = $q_post["post_id"];
3516 }
3517 }
3518 return $return;
3519 }
3520
3521 /* renders a system page */
3522 function do_system_page($id) {
3523
3524 $type = get_post_meta($id, self::NSPACE."system_page", true);
3525 //send over our colors to style the pages nicely
3526 $styles["primary_color"] = $this->get_setting("pilotpress_customer_center_primary_color");
3527 $styles["secondary_color"] = $this->get_setting("pilotpress_customer_center_secondary_color");
3528 $styles["header_image"] = $this->get_setting("pilotpress_customer_center_header_image");
3529
3530 $user_info = $this->get_stashed("authenticate_user", true);
3531
3532 if(!is_user_logged_in() || $user_info["authenticate_user"]["username"] == null
3533 || !isset($user_info["authenticate_user"]["username"]))
3534 {
3535 $return = $this->login_page(array(), 1);
3536 return $return;
3537 }
3538
3539 if($type == "affiliate_center") {
3540 $program_id = false;
3541 if (isset($user_info["authenticate_user"]["program_id"]))
3542 {
3543 $program_id = self::validatePostVar($user_info["authenticate_user"]["program_id"], "numeric");
3544 }
3545 $api_result = $this->api_call("get_".$type, array("username" => $user_info["authenticate_user"]["username"], "program_id" => $program_id, "site" => site_url() , "styles"=>$styles ));
3546 }
3547
3548 if($type == "customer_center"){
3549 $api_result = $this->api_call("get_".$type, array("username" => $user_info["authenticate_user"]["username"], "site" => site_url(), "nonce" => wp_create_nonce(basename(__FILE__)) , "styles"=>$styles , "version"=>self::VERSION ));
3550 }
3551
3552 if($api_result) {
3553 if($api_result["code"] != "0") {
3554 return $api_result["code"];
3555 } else {
3556 $return = $this->login_page(array(), 2);
3557 return $return;
3558 }
3559 }
3560 }
3561
3562 /* creates a system page in a post somewhere */
3563 function create_system_page($name) {
3564 global $wpdb;
3565 $sql = $wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_system_page' AND meta_value = %s", $name );
3566
3567 $pages = $wpdb->get_results($sql, ARRAY_A);
3568 if(count($pages) == 0) {
3569 $post = array(
3570 'post_title' => "{$this->centers[$name]["title"]}",
3571 'slug' => "{$this->centers[$name]["slug"]}",
3572 'post_status' => 'publish',
3573 'post_type' => 'page',
3574 'comment_status' => "closed",
3575 'visibility' => "public",
3576 'ping_status' => "closed",
3577 'post_category' => array(1),
3578 'post_content' => "{$this->centers[$name]["content"]}");
3579 $post_id = wp_insert_post($post);
3580 add_post_meta($post_id, PilotPress::NSPACE."system_page", $name);
3581 add_post_meta($post_id, PilotPress::NSPACE."redirect_location", "-2");
3582 $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->posts} WHERE `post_status` = 'trash' AND `post_name` = %s", $name));
3583 $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts } SET `post_name` = %s WHERE `ID` = %d", $name, $post_id));
3584 $this->flush_rewrite_rules();
3585 }
3586 }
3587
3588 /* banished. */
3589 function delete_system_page($name)
3590 {
3591 global $wpdb;
3592 $pages = $wpdb->get_results($wpdb->prepare("SELECT `post_id` FROM {$wpdb->postmeta} WHERE `meta_key` = '_pilotpress_system_page' AND `meta_value` = %s",$name), ARRAY_A);
3593
3594 if(!empty($pages)) {
3595 foreach($pages as $page) {
3596 delete_post_meta($page["post_id"], "_pilotpress_system_page");
3597 wp_delete_post($page["post_id"], true);
3598 }
3599 }
3600 }
3601
3602 /**
3603 * Ping Logic
3604 *
3605 * Imports jQuery logic to head which can then be utilized
3606 * to send ajax calls to the same file to update the PilotPress
3607 * session.
3608 *
3609 *
3610 * @uses add_action()
3611 */
3612 function sessionslap_ping(){
3613 // Register JavaScript
3614 wp_enqueue_script('jquery');
3615
3616 require_once( plugin_dir_path( __FILE__ ) . "/ping.php");
3617
3618 // Append dynamic js to both admin and regular users head.
3619 add_action( "admin_head", "pilotpress_sessionslap_face" );
3620 add_action( "wp_head", "pilotpress_sessionslap_face" );
3621
3622 }
3623
3624 /* renders cute login page */
3625 function login_page ($atts, $message = false)
3626 {
3627 // Allows shortcodes to be put in text widgets
3628 add_filter('widget_text', 'do_shortcode');
3629
3630 global $wpdb;
3631 // This section allows the users to add custom styling by adding custom attributes to the shortcode [login_page]
3632 // Form general styling options
3633 if ( isset($atts['width']) )
3634 {
3635 $width = $atts['width'];
3636 $width = 'max-width: '.$width.'!important;';
3637 }
3638 else
3639 {
3640 $width = 'max-width: 320px;';
3641 }
3642
3643 if ( isset($atts['formalign']) )
3644 {
3645 $formalign = $atts['formalign'];
3646
3647 if ( $formalign == 'left' )
3648 {
3649 $formalign = 'margin: 30px 30px 30px 0px; float: left;';
3650 }
3651 else if ( $formalign == 'center' )
3652 {
3653 $formalign = 'margin: 30px auto!important;';
3654 }
3655 else if ( $formalign == 'right' )
3656 {
3657 $formalign = 'margin: 30px 0px 30px 30px; float: right;';
3658 }
3659 else
3660 {
3661 $formalign = 'margin: 30px 0px;';
3662 }
3663 }
3664 else
3665 {
3666 $formalign = 'margin: 30px 0px; width: 100%;';
3667 }
3668
3669 if ( isset($atts['bgcolor']) )
3670 {
3671 $bgcolor = $atts['bgcolor'];
3672 $bgcolor = 'background-color: '.$bgcolor.'!important;';
3673 }
3674 else
3675 {
3676 $bgcolor = 'background-color: #fff;';
3677 }
3678
3679 if ( isset($atts['textcolor']) )
3680 {
3681 $textcolor = $atts['textcolor'];
3682 $textcolor = 'color: '.$textcolor.'!important;';
3683 }
3684 else
3685 {
3686 $textcolor = '';
3687 }
3688
3689 // Header Text styling
3690 if ( isset($atts['headertextalignment']) )
3691 {
3692 $headertextalignment = $atts['headertextalignment'];
3693 $headertextalignment = 'text-align: '.$headertextalignment.'!important;';
3694 }
3695 else
3696 {
3697 $headertextalignment = '';
3698 }
3699
3700 if ( isset($atts['headertextfont']) )
3701 {
3702 $headertextfont = $atts['headertextfont'];
3703 $headertextfont = 'font-family: '.$headertextfont.'!important;';
3704 }
3705 else
3706 {
3707 $headertextfont = '';
3708 }
3709
3710 if ( isset($atts['headertextfontsize']) )
3711 {
3712 $headertextfontsize = $atts['headertextfontsize'];
3713 $headertextfontsize = 'font-size: '.$headertextfontsize.'!important;';
3714 }
3715 else
3716 {
3717 $headertextfontsize = 'font-size: 20pt;';
3718 }
3719
3720 if ( isset($atts['headertextfontcolor']) )
3721 {
3722 $headertextfontcolor = $atts['headertextfontcolor'];
3723 $headertextfontcolor = 'color: '.$headertextfontcolor.'!important;';
3724 }
3725 else
3726 {
3727 $headertextfontcolor = 'color: #222;';
3728 }
3729
3730 // Supporting Text styling
3731 if ( isset($atts['supportingtextfont']) )
3732 {
3733 $supportingtextfont = $atts['supportingtextfont'];
3734 $supportingtextfont = 'font-family: '.$supportingtextfont.'!important;';
3735 }
3736 else
3737 {
3738 $supportingtextfont = '';
3739 }
3740
3741 if ( isset($atts['supportingtextfontsize']) )
3742 {
3743 $supportingtextfontsize = $atts['supportingtextfontsize'];
3744 $supportingtextfontsize = 'font-size: '.$supportingtextfontsize.'!important;';
3745 }
3746 else
3747 {
3748 $supportingtextfontsize = 'font-size: 12pt;';
3749 }
3750
3751 if ( isset($atts['supportingtextfontcolor']) )
3752 {
3753 $supportingtextfontcolor = $atts['supportingtextfontcolor'];
3754 $supportingtextfontcolor = 'color: '.$supportingtextfontcolor.'!important;';
3755 }
3756 else
3757 {
3758 $supportingtextfontcolor = 'color: #555;';
3759 }
3760
3761 // Form Input styling
3762 if ( isset($atts['inputcolor']) )
3763 {
3764 $inputcolor = $atts['inputcolor'];
3765 $inputcolor = 'background-color: '.$inputcolor.'!important;';
3766 }
3767 else
3768 {
3769 $inputcolor = '';
3770 }
3771
3772 if ( isset($atts['inputtextcolor']) )
3773 {
3774 $inputtextcolor = $atts['inputtextcolor'];
3775 $inputtextcolor = 'color: '.$inputtextcolor.'!important;';
3776 }
3777 else
3778 {
3779 $inputtextcolor = '';
3780 }
3781
3782 if ( isset($atts['inputbordercolor']) )
3783 {
3784 $inputbordercolor = $atts['inputbordercolor'];
3785 $inputbordercolor = 'border: 1px solid '.$inputbordercolor.'!important;';
3786 }
3787 else
3788 {
3789 $inputbordercolor = '';
3790 }
3791
3792 if ( isset($atts['inputfieldsize']) )
3793 {
3794 $inputfieldsize = $atts['inputfieldsize'];
3795 if ( $inputfieldsize == 'large' )
3796 {
3797 $inputfieldsize = 'padding: 16px!important; font-size: 15pt;';
3798 }
3799 if ( $inputfieldsize == 'medium' )
3800 {
3801 $inputfieldsize = 'padding: 9px!important; font-size: 12pt;';
3802 }
3803 if ( $inputfieldsize == 'small' )
3804 {
3805 $inputfieldsize = 'padding: 6px!important; font-size: 10pt;';
3806 }
3807 }
3808 else
3809 {
3810 $inputfieldsize = 'padding: 6px!important; font-size: 10pt;';
3811 }
3812
3813 // Form Button styling
3814 if ( isset($atts['buttonbgcolor']) )
3815 {
3816 $buttonbgcolor = $atts['buttonbgcolor'];
3817 $buttonbgcolor = 'background-color: '.$buttonbgcolor.'!important; background-image: none!important;';
3818 }
3819 else
3820 {
3821 $buttonbgcolor = '';
3822 }
3823
3824 if ( isset($atts['buttontextcolor']) )
3825 {
3826 $buttontextcolor = $atts['buttontextcolor'];
3827 $buttontextcolor = 'color: '.$buttontextcolor.'!important;';
3828 }
3829 else
3830 {
3831 $buttontextcolor = '';
3832 }
3833
3834 if ( isset($atts['buttonbordercolor']) )
3835 {
3836 $buttonbordercolor = $atts['buttonbordercolor'];
3837 $buttonbordercolor = 'border: 1px solid '.$buttonbordercolor.'!important;';
3838 }
3839 else
3840 {
3841 $buttonbordercolor = '';
3842 }
3843
3844 if ( isset($atts['buttonfont']) )
3845 {
3846 $buttonfont = $atts['buttonfont'];
3847 $buttonfont = 'font-family: '.$buttonfont.'!important;';
3848 }
3849 else
3850 {
3851 $buttonfont = '';
3852 }
3853
3854 if ( isset($atts['buttonfontsize']) )
3855 {
3856 $buttonfontsize = $atts['buttonfontsize'];
3857 $buttonfontsize = 'font-size: '.$buttonfontsize.'!important;';
3858 }
3859 else
3860 {
3861 $buttonfontsize = 'font-size: 11pt;';
3862 }
3863
3864 if ( isset($atts['buttonhovertextcolor']) )
3865 {
3866 $buttonhovertextcolor = $atts['buttonhovertextcolor'];
3867 $buttonhovertextcolor = 'color: '.$buttonhovertextcolor.'!important;';
3868 }
3869 else
3870 {
3871 $buttonhovertextcolor = '';
3872 }
3873
3874 if ( isset($atts['buttonhoverbgcolor']) )
3875 {
3876 $buttonhoverbgcolor = $atts['buttonhoverbgcolor'];
3877 $buttonhoverbgcolor = 'background-color: '.$buttonhoverbgcolor.'!important;';
3878 }
3879 else
3880 {
3881 $buttonhoverbgcolor = '';
3882 }
3883
3884 if ( isset($atts['buttonhoverbordercolor']) )
3885 {
3886 $buttonhoverbordercolor = $atts['buttonhoverbordercolor'];
3887 $buttonhoverbordercolor = 'border: 1px solid '.$buttonhoverbordercolor.'!important;';
3888 }
3889 else
3890 {
3891 $buttonhoverbordercolor = '';
3892 }
3893
3894 if ( isset($atts['buttonsize']) )
3895 {
3896 $buttonsize = $atts['buttonsize'];
3897 switch ($buttonsize)
3898 {
3899 case 'extralarge':
3900 $buttonsize = 'padding: 25px!important; font-size: 23pt;';
3901 break;
3902
3903 case 'large':
3904 $buttonsize = 'padding: 18px!important; font-size: 18pt;';
3905 break;
3906
3907 case 'medium':
3908 $buttonsize = 'padding: 10px!important; font-size: 13pt;';
3909 break;
3910
3911 case 'small':
3912 $buttonsize = 'padding: 6px!important; font-size: 10pt;';
3913 break;
3914 }
3915 }
3916 else
3917 {
3918 $buttonsize = 'padding: 10px!important; font-size: 13pt;';
3919 }
3920
3921 // Form Style - Responsible for the full width or side by side form style
3922 $default = '#pp-loginform .login-username LABEL
3923 {
3924 max-width: 100%!important;
3925 width: 100%!important;
3926 }
3927 #pp-loginform .login-username INPUT
3928 {
3929 max-width: 100%!important;
3930 width: 100%!important;
3931 }
3932 #pp-loginform .login-password LABEL
3933 {
3934 max-width: 100%!important;
3935 width: 100%!important;
3936 }
3937 #pp-loginform .login-password INPUT
3938 {
3939 max-width: 100%!important;
3940 width: 100%!important;
3941 }
3942 #pp-loginform .login-remember [type="checkbox"]
3943 {
3944 opacity: 1;
3945 position: static;
3946 pointer-events: auto;
3947 }';
3948
3949 if ( isset($atts['style']) )
3950 {
3951 $style = $atts['style'];
3952
3953 if ( $style == 'default' )
3954 {
3955 $style = $default;
3956 }
3957 else if ( $style == 'fullwidth' )
3958 {
3959 $style = $default . '.op-login-form { max-width: 100%!important; }';
3960 }
3961 }
3962 else
3963 {
3964 $style = $default;
3965 }
3966
3967
3968 // TEXT - Options to change the form text
3969 if ( isset($atts['headertext']) )
3970 {
3971 $headertext = $atts['headertext'];
3972 }
3973 else
3974 {
3975 $headertext = '';
3976 }
3977
3978 if ( isset($atts['supportingtext']) )
3979 {
3980 $supportingtext = $atts['supportingtext'];
3981 }
3982 else
3983 {
3984 $supportingtext = '';
3985 }
3986
3987 if ( isset($atts['usernametext']) )
3988 {
3989 $usernametext = $atts['usernametext'];
3990 $usernametext = __($usernametext);
3991 }
3992 else
3993 {
3994 $usernametext = __('Username');
3995 }
3996
3997 if ( isset($atts['passwordtext']) )
3998 {
3999 $passwordtext = $atts['passwordtext'];
4000 $passwordtext = __($passwordtext);
4001 }
4002 else
4003 {
4004 $passwordtext = __('Password');
4005 }
4006
4007 if ( isset($atts['remembertext']) )
4008 {
4009 $remembertext = $atts['remembertext'];
4010 $remembertext = __($remembertext);
4011 }
4012 else
4013 {
4014 $remembertext = __('Remember me');
4015 }
4016
4017 if ( isset($atts['buttontext']) )
4018 {
4019 $buttontext = $atts['buttontext'];
4020 $buttontext = __($buttontext);
4021 }
4022 else
4023 {
4024 $buttontext = __('Log In');
4025 }
4026
4027
4028 // New style for the [login_page] forms with variables for user customization
4029 $output = "<style type='text/css'>
4030 .op-login-form-".$this->incrementalnumber."
4031 {
4032 ".$formalign."
4033 padding: 30px;
4034 box-sizing: border-box;
4035 -webkit-box-sizing: border-box;
4036 -moz-box-sizing: border-box;
4037 -moz-box-shadow: 0px 0px 2px 1px rgba(51,51,51,0.27);
4038 -webkit-box-shadow: 0px 0px 2px 1px rgba(51,51,51,0.27);
4039 box-shadow: 0px 0px 2px 1px rgba(51, 51, 51, 0.27);
4040 -ms-filter: 'progid:DXImageTransform.Microsoft.Glow(Color=#ff333333,Strength=3)';
4041 filter: progid:DXImageTransform.Microsoft.Glow(Color=#ff333333,Strength=3);
4042 ".$bgcolor."
4043 ".$width."
4044 }
4045 .op-login-form-".$this->incrementalnumber." .op-header-text-container
4046 {
4047 margin-bottom: 25px;
4048 width: 100%;
4049 ".$headertextalignment."
4050 }
4051 .op-login-form-".$this->incrementalnumber." .op-header-text
4052 {
4053 line-height: 1.2!important;
4054 margin-bottom: 4px;".$headertextfont.$headertextfontsize.$headertextfontcolor."
4055 }
4056 .op-login-form-".$this->incrementalnumber." .op-supporting-text
4057 {
4058 line-height: 1.2!important;".$supportingtextfont.$supportingtextfontsize.$supportingtextfontcolor."
4059 }
4060 .op-login-form-".$this->incrementalnumber." #pp-loginform P
4061 {
4062 width: 100%;
4063 display: table;
4064 margin: 0px 0px 4px;
4065 padding: 0px;
4066 }
4067 .op-login-form-".$this->incrementalnumber." LABEL,
4068 .op-login-form-".$this->incrementalnumber." INPUT
4069 {
4070 display: table-cell;
4071 box-sizing: border-box;
4072 -webkit-box-sizing: border-box;
4073 -moz-box-sizing: border-box;
4074 line-height: 1.3;
4075 }
4076 .op-login-form-".$this->incrementalnumber." .login-username
4077 {
4078 position: relative;
4079 }
4080 .op-login-form-".$this->incrementalnumber." .login-username LABEL
4081 {
4082 width: 100%;
4083 max-width: 25%;
4084 min-width: 90px;
4085 padding-right: 3%;
4086 float: left;".$textcolor."
4087 }
4088 .op-login-form-".$this->incrementalnumber." .login-username INPUT
4089 {
4090 width: 100%;
4091 max-width: 72%;
4092 float: right;
4093 border-radius: 3px;".$inputcolor.$inputtextcolor.$inputbordercolor.$inputfieldsize."
4094 }
4095 .op-login-form-".$this->incrementalnumber." .login-password LABEL
4096 {
4097 width: 100%;
4098 max-width: 25%;
4099 min-width: 90px;
4100 padding-right: 3%;
4101 float: left;".$textcolor."
4102 }
4103 .op-login-form-".$this->incrementalnumber." .login-password INPUT
4104 {
4105 width: 100%;
4106 max-width: 72%;
4107 float: right;
4108 border-radius: 3px;".$inputcolor.$inputtextcolor.$inputbordercolor.$inputfieldsize."
4109 }
4110 .op-login-form-".$this->incrementalnumber." .login-remember
4111 {
4112 text-align: right;
4113 font-style: italic;
4114 cursor: pointer;".$textcolor."
4115 }
4116 .op-login-form-".$this->incrementalnumber." .login-remember INPUT
4117 {
4118 float: right;
4119 margin-left: 10px;
4120 margin-top: 5px;
4121 cursor: pointer;
4122 }
4123 .op-login-form-".$this->incrementalnumber." .login-remember LABEL
4124 {
4125 cursor: pointer;".$textcolor."
4126 }
4127 .op-login-form-".$this->incrementalnumber." #wp-submit
4128 {
4129 width: 100%;
4130 padding: 10px;
4131 margin-top: 15px;
4132 margin-bottom: 0px;
4133 white-space: pre-wrap;
4134 border-radius: 3px;".$buttonbgcolor.$buttontextcolor.$buttonbordercolor.$buttonfont.$buttonfontsize.$buttonsize."
4135 }
4136 .op-login-form-".$this->incrementalnumber." #wp-submit:hover
4137 {
4138 transition: background-color 1s ease, color 1s ease;
4139 -moz-transition: background-color 1s ease, color 1s ease;
4140 -webkit-transition: background-color 1s ease, color 1s ease;".$buttonhovertextcolor.$buttonhoverbgcolor.$buttonhoverbordercolor."
4141 }
4142 .op-login-form-".$this->incrementalnumber." .login_box
4143 {
4144 margin-top: 6px;
4145 padding: 5px;
4146 border: 1px solid #E6D855;
4147 background-color: #FFFFE0;
4148 box-sizing: border-box;
4149 -webkit-box-sizing: border-box;
4150 -moz-box-sizing: border-box;
4151 }
4152 @media screen and (max-width: 480px)
4153 {
4154 .op-login-form-".$this->incrementalnumber." .login-username LABEL
4155 {
4156 max-width: 100%!important;
4157 }
4158 .op-login-form-".$this->incrementalnumber." .login-username INPUT
4159 {
4160 max-width: 100%!important;
4161 }
4162 .op-login-form-".$this->incrementalnumber." .login-password LABEL
4163 {
4164 max-width: 100%!important;
4165 }
4166 .op-login-form-".$this->incrementalnumber." .login-password INPUT
4167 {
4168 max-width: 100%!important;
4169 }
4170 }
4171 ".$style."
4172 </style>";
4173
4174 // Start Form output
4175 $output .= '<div class="op-login-form-'.$this->incrementalnumber.'">';
4176
4177 // Setting header text
4178 if ( isset($atts['headertext']) || isset($atts['supporting']) )
4179 {
4180 $output .= '<div class="op-header-text-container"><div class="op-header-text">'.$headertext.'</div><div class="op-supporting-text">'.$supportingtext.'</div></div>';
4181 }
4182
4183 if(!empty($message))
4184 {
4185 switch($message)
4186 {
4187 case "1":
4188 $output_message = "Must be logged in to see this page.";
4189 break;
4190 case "2":
4191 $output_message = "You do not have sufficient access to view this page.";
4192 break;
4193 case "3":
4194 $output_message = "Invalid Username or Password.";
4195 break;
4196 default:
4197 $output_message = $message;
4198 break;
4199 }
4200 $output .= "<p class='login_box' id='login_message_normal'>{$output_message}</p>";
4201 }
4202
4203 if ( isset($atts['redirect']) )
4204 {
4205 $redirect = $atts['redirect'];
4206 }
4207 else
4208 {
4209 $contact_id = self::validatePostVar($_COOKIE["contact_id"], "numeric");
4210 $redirect_to = get_transient("pilotpress_redirect_to". (int) $contact_id);
4211 if(isset($redirect_to) && !empty($redirect_to))
4212 {
4213 $redirect = get_permalink($redirect_to);
4214 }
4215 else
4216 {
4217 $redirect = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
4218 }
4219
4220 }
4221
4222 $args = array(
4223 'echo' => false,
4224 'redirect' => $redirect,
4225 'form_id' => 'pp-loginform',
4226 'label_username' => $usernametext,
4227 'label_password' => $passwordtext,
4228 'label_remember' => $remembertext,
4229 'label_log_in' => $buttontext,
4230 'id_username' => 'user_login',
4231 'id_password' => 'user_pass',
4232 'id_remember' => 'rememberme',
4233 'id_submit' => 'wp-submit',
4234 'remember' => true,
4235 'value_username' => NULL,
4236 'value_remember' => true);
4237 $output .= wp_login_form($args);
4238
4239 // Adds functionality for Lost Passwords
4240 if ( isset($atts['forgotpw']) && $atts['forgotpw'] == 'false')
4241 {
4242 $output .= '</div>';
4243
4244 $this->incrementalnumber++;
4245
4246 return $output;
4247 }
4248 else
4249 {
4250 $output .= '<div class="pp-lf-forgot-username" style="text-align: right;"><a id="pp-lf-forgotpw" href="javascript://">Forgot password?</a></div>';
4251
4252 $output .= '<script>
4253 jQuery(".op-login-form-'.$this->incrementalnumber.' #pp-lf-forgotpw").click(function()
4254 {
4255 jQuery(".op-login-form-'.$this->incrementalnumber.' .login-password, .op-login-form-'.$this->incrementalnumber.' .login-remember").hide(300);
4256 jQuery(".op-login-form-'.$this->incrementalnumber.' #pp-loginform").attr( "action", "'.site_url().'/wp-login.php?action=lostpassword&wpe-login=true");
4257 jQuery(".op-login-form-'.$this->incrementalnumber.' .login-username label").text("Enter your Username or Email");
4258 jQuery(".op-login-form-'.$this->incrementalnumber.' .login-username input").attr("name", "user_login");
4259 jQuery(".op-login-form-'.$this->incrementalnumber.' #wp-submit").attr("value", "Get New Password");
4260 });
4261 </script>';
4262 }
4263
4264 $output .= '</div>';
4265
4266 $this->incrementalnumber++;
4267
4268 return $output;
4269
4270 }
4271
4272
4273 /**
4274 * @brief clean up quotes and double quotes for shortcodes
4275 * @arg string str
4276 * @return string that's been cleaned
4277 */
4278 public function quote_escaping($str)
4279 {
4280 $str = str_replace("'", "|pp_single_quote|", $str);
4281 $str = str_replace('"', "|pp_double_quote|", $str);
4282 return $str;
4283 }
4284
4285 /**
4286 * @brief undo the quote_escaping function
4287 * @arg string str
4288 * @return string that is back to normal
4289 */
4290 public function undo_quote_escaping($str)
4291 {
4292 if(strpos($str, "|pp_single_quote|"))
4293 {
4294 $str = str_replace("|pp_single_quote|", "'", $str);
4295 }
4296 else if(strpos($str, "|pp_double_quote|"))
4297 {
4298 $str = str_replace("|pp_double_quote|", '"', $str);
4299 }
4300
4301 return $str;
4302 }
4303
4304 /**
4305 * @brief output the various merge fields available to our tinyMCE plugin
4306 * @return jsonified array back to JS
4307 **/
4308 public function grab_mce_fields()
4309 {
4310 $site_settings = $this->get_stashed("get_site_settings", false);
4311 $fields = $site_settings["get_site_settings"]["default_fields"];
4312
4313 global $wp_version;
4314 $version = 3.9;
4315 // test for wordpress version to load proper plugin scripts
4316 if ( version_compare( $wp_version, $version, '>=' ))
4317 {
4318 $json = array();
4319 $keys = array();
4320 $values = array();
4321 if (is_array($fields))
4322 {
4323 foreach ($fields as $group => $items)
4324 {
4325 $keys[] = $group;
4326 $values[] = '';
4327 if (is_array($items))
4328 {
4329 foreach ($items as $key => $value)
4330 {
4331 $keys[] = ' + '.$key;
4332 $values[] = $this->quote_escaping($key);
4333 }
4334 }
4335 }
4336 }
4337
4338
4339 $i = 0;
4340 foreach ($keys as $key)
4341 {
4342 $json[] = array('text' => $key, 'value' => $values[$i]);
4343 $i++;
4344 }
4345
4346 $jsonified =json_encode($json);
4347 $js_to_echo = "
4348 <!--FIELDS FOR PILOTPRESS MCE PLUGIN -->
4349 <script type='text/javascript'>
4350 var pilotpress_tiny_mce_plugin_default_fields = $jsonified;
4351 </script>
4352 <!--END FIELDS FOR PILOTPRESS MCE PLUGIN -->";
4353 echo $js_to_echo;
4354 }
4355 else
4356 {
4357 $jsonified = json_encode($fields);
4358 $js_to_echo = "
4359 <!--SHORTCODES FOR PILOTPRESS MCE PLUGIN -->
4360 <script type='text/javascript'>
4361 var pilotpress_tiny_mce_plugin_default_fields_old = $jsonified;
4362 </script>
4363 <!--END SHORTCODES FOR PILOTPRESS MCE PLUGIN -->";
4364 echo $js_to_echo;
4365 }
4366 }
4367
4368 /**
4369 * @brief output the various shortcodes available to our tinyMCE plugin
4370 * @return jsonified array back to JS
4371 **/
4372 public function grab_mce_shortcodes()
4373 {
4374 $shortcodes = array("","has_one=\"\"", "has_all=\"\"", "not_one=\"\"", "not_any=\"\"", "has_tag=\"\"", "does_not_have_tag=\"\"", "is_contact", "not_contact", "is_cookied_contact", "not_cookied_contact", "pilotpress_sync_contact");
4375 $names = array("--shortcodes--", " + Has one", " + Has all", " + Does not have one", " + Does not have any", " + Has tag(s)", " + Does not have tag(s)", " + Is a contact", " + Is not a contact", " + Is a cookied contact", " + Is not a cookied contact", " + Resync contact");
4376 $json = array();
4377 $i = 0;
4378 foreach ($shortcodes as $shortcode)
4379 {
4380 $json[] = array("text" => $names[$i], "value" => $shortcode);
4381 $i++;
4382 }
4383 $jsonified = json_encode($json);
4384 $js_to_echo = "
4385 <!--FIELDS FOR PILOTPRESS MCE PLUGIN -->
4386 <script type='text/javascript'>
4387 var pilotpress_tiny_mce_plugin_shortcodes = $jsonified;
4388 </script>
4389 <!--END FIELDS FOR PILOTPRESS MCE PLUGIN -->";
4390 echo $js_to_echo;
4391 }
4392
4393 public function include_form_admin_options ()
4394 {
4395 include_once(plugin_dir_path(__FILE__) . "/login-button.php");
4396 }
4397
4398 public function register_login_button ( $buttons )
4399 {
4400 array_push( $buttons, "|", "addloginform" );
4401 return $buttons;
4402 }
4403
4404 public function add_login_button ( $plugin_array )
4405 {
4406 $plugin_array['addloginform'] = plugins_url( '/js/login-button.js' , __FILE__ );
4407 return $plugin_array;
4408 }
4409
4410 public function pp_login_button ()
4411 {
4412 if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') )
4413 {
4414 return;
4415 }
4416 if ( get_user_option('rich_editing') == 'true' )
4417 {
4418 add_filter( 'mce_external_plugins', array(&$this, 'add_login_button') );
4419 add_filter( 'mce_buttons_3', array(&$this, 'register_login_button') );
4420 }
4421 }
4422
4423
4424 /* the first process... enable the plugin create some values and cleanup "older" PilotPress metadata. could probably do with a redo. */
4425 public function do_enable() {
4426
4427 global $wpdb;
4428
4429 $data = array();
4430 $data["site"] = site_url();
4431 $data["version"] = self::VERSION;
4432 $data["url"] = $this->uri."/".basename(__FILE__);
4433 $api_result = $this->api_call("enable_pilotpress", $data);
4434
4435 $um = array();
4436 $user = get_userdatabylogin("pilotpress-user");
4437 if(isset($user->ID)) {
4438 wp_delete_user($user->ID);
4439 }
4440
4441 $meta = $wpdb->get_results("SELECT meta_id, post_id, meta_key, meta_value FROM $wpdb->postmeta WHERE meta_key LIKE '".PilotPress::NSPACE."%'");
4442 foreach($meta as $result) {
4443
4444 if($result->meta_key == "_pilotpress_system_page" && $result->meta_value == "1") {
4445 delete_post_meta($result->post_id, $result->meta_key);
4446 }
4447
4448 if($result->meta_key == "_pilotpress_affiliate_center") {
4449 $ac_exists = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_system_page' AND meta_value = 'affiliate_center'");
4450
4451 if(empty($ac_exists)) {
4452 delete_post_meta($result->post_id, $result->meta_key);
4453 add_post_meta($post_id, PilotPress::NSPACE."system_page", "affiliate_center");
4454 wp_update_post(array("ID" => $post_id, "post_content" => "This content will be replaced by the Partner Center."));
4455 }
4456 }
4457
4458 if($result->meta_key == "_pilotpress_customer_center") {
4459 $cc_exists = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_pilotpress_system_page' AND meta_value = 'customer_center'");
4460
4461 if(empty($cc_exists)) {
4462 delete_post_meta($result->post_id, $result->meta_key);
4463 add_post_meta($post_id, PilotPress::NSPACE."system_page", "customer_center");
4464 wp_update_post(array("ID" => $post_id, "post_content" => "This content will be replaced by the Customer Center."));
4465 }
4466 }
4467
4468 if($result->meta_key == "_pilotpress_user_level") {
4469 if($result->meta_value == "All") {
4470 delete_post_meta($result->post_id, $result->meta_key);
4471 } else {
4472 $um[$result->meta_value][] = $result->post_id;
4473 }
4474 }
4475 }
4476
4477 if(isset($api_result["upgrade"])) {
4478 $levels = $this->get_setting("membership_levels", "oap");
4479 $keys = array_flip($levels);
4480 if(count($um) > 0) {
4481 foreach($keys as $level => $pos) {
4482 $rec = array_slice($levels, $pos);
4483 if(isset($um[$level])) {
4484 foreach($um[$level] as $idx => $post_id) {
4485 foreach($rec as $value) {
4486 add_post_meta($post_id, PilotPress::NSPACE."level", $value);
4487 }
4488 delete_post_meta($post_id, PilotPress::NSPACE."user_level");
4489 }
4490 }
4491 }
4492 }
4493 }
4494 }
4495
4496 /* let us know */
4497 public function do_disable() {
4498 $data = array();
4499 $data["site"] = site_url();
4500 $data["version"] = self::VERSION;
4501 $data["url"] = $this->uri."/".basename(__FILE__);
4502 $return = $this->api_call("disable_pilotpress", $data);
4503 }
4504
4505 public static function redirect($url) {
4506 // Workaround for trac bug #21602
4507 $current_url = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
4508
4509 if(substr($current_url, -1) == "/") {
4510 $current_url = substr($current_url, 0, -1);
4511 }
4512 $compare_url = str_replace("https://", "", $url);
4513 $compare_url = str_replace("http://", "", $compare_url);
4514
4515 if($current_url != $compare_url) {
4516 return wp_redirect($url);
4517 }
4518 }
4519
4520 /* used by external plugins: get items available to this account */
4521 static function get_oap_items() {
4522 $options = get_option("pilotpress-settings");
4523 if(!empty($options)) {
4524 if(isset($options["app_id"]) && isset($options["api_key"])) {
4525 $return = array();
4526 $return["files"] = PilotPress::api_call_static("get_files_list", "", $options["app_id"], $options["api_key"], $options["disablesslverify"]);
4527 $return["videos"] = PilotPress::api_call_static("get_video_list", "", $options["app_id"], $options["api_key"], $options["disablesslverify"]);
4528 return $return;
4529 }
4530 }
4531 return false;
4532 }
4533
4534 /* grab some video code! also for external plugins */
4535 static function get_oap_video($video_id) {
4536 $options = get_option("pilotpress-settings");
4537 if(!empty($options)) {
4538 if(isset($options["app_id"]) && isset($options["api_key"])) {
4539 $return= PilotPress::api_call_static("get_video",
4540 array(
4541 "video_id" => $video_id,
4542 "width" => '480',
4543 "height" => "320",
4544 "player" => 1,
4545 "autoplay" => 0,
4546 "viral" => 0
4547 ),
4548 $options["app_id"],
4549 $options["api_key"],
4550 $options["disablesslverify"]);
4551 return $return;
4552 }
4553 }
4554 return false;
4555 }
4556
4557 /**
4558 * @brief generates a unique session ID
4559 * @params int $length
4560 * @return int $session (unique ID)
4561 **/
4562 public function genmrSess($length)
4563 {
4564 $session = "";
4565 $possible = "0123456789bcdfghjkmnpqrstvwxyz";
4566 $i = 0;
4567 while ($i < $length)
4568 {
4569 $mychar = substr($possible, rand(0, strlen($possible)), 1);
4570 $session .= $mychar;
4571 $i++;
4572 }
4573 return $session;
4574 }
4575 }
4576
4577
4578 //Since we ping this file independent of the WordPress bootstrap lets make sure the class exists...
4579 if (class_exists("WP_Widget"))
4580 {
4581 // Creating the widget
4582 class Pilotpress_Widget extends WP_Widget {
4583
4584 //Registers the widget with the WordPress Widget API.
4585 public static function register() {
4586 register_widget( __CLASS__ );
4587 }
4588
4589 public function __construct() {
4590
4591 parent::__construct(
4592 // Base ID of your widget
4593 'pilotpress_widget',
4594
4595 // Widget name will appear in UI
4596 __('PilotPress Text', 'pilotpress_widget_domain'),
4597
4598 // Widget description
4599 array(
4600 'description' => __( 'An enhanced text area widget that helps you display your ONTRAPORT merge fields', 'pilotpress_widget_domain' )
4601 )
4602 );
4603 }
4604
4605 // Creating widget front-end
4606 public function widget( $args, $instance ) {
4607 global $pilotpress;
4608 $title = apply_filters( 'widget_title', $instance['title'] );
4609
4610 $textarea = $instance["textarea"];
4611 // before and after widget arguments are defined by themes
4612 echo $args['before_widget'];
4613 if ( ! empty( $title ) )
4614 {
4615 echo $args['before_title'] . $title . $args['after_title'];
4616 }
4617 //Lets check and process merge fields if we need too!
4618 if (has_shortcode( $textarea , "pilotpress_field") || has_shortcode( $textarea ,"field") )
4619 {
4620 $pilotpress->get_merge_field_settings($textarea);
4621 }
4622 //Apply the default filter in case they have somehting to make PHP work...
4623 echo apply_filters( 'widget_text' , do_shortcode($textarea) );
4624
4625 echo $args['after_widget'];
4626 }
4627
4628 // Widget Backend
4629 public function form( $instance ) {
4630 global $pilotpress;
4631
4632 //Handle merge codes
4633 $mergeFieldDropDown = "<p>";
4634 $mergeFieldDropDown .= "<label for='" . $this->get_field_id( "merge-codes" ) ."'>" . __("Merge Fields:", "pilotpress_widget_domain") . "</label>";
4635 $mergeFieldDropDown .= "<select id='" . $this->get_field_id( "merge-codes" ) . "' class='op-merge-codes__select' name='" . $this->get_field_id( "merge-codes" ) . "'>";
4636 $mergeFieldDropDown .= "</p>";
4637
4638 foreach($pilotpress->get_setting("default_fields", "oap", true) as $group => $fields) {
4639
4640 $mergeFieldDropDown .= "<option value=''> " . $group . "</option>";
4641 foreach ($fields as $key => $field)
4642 {
4643
4644 $mergeFieldDropDown .= "<option value='[pilotpress_field name=\"{$key}\"]'>&nbsp;&nbsp;&nbsp;" . $key . "</option>";
4645 }
4646 }
4647
4648 $mergeFieldDropDown .= "</select>";
4649
4650 if ( isset( $instance[ 'title' ] ) ) {
4651 $title = $instance[ 'title' ];
4652 }
4653 else {
4654 $title = __( '', 'pilotpress_widget_domain' );
4655 }
4656
4657 if (isset( $instance[ 'textarea' ] )) {
4658 $textarea = $instance[ 'textarea' ];
4659 }
4660 else {
4661 $textarea = __( '', 'pilotpress_widget_domain' );
4662 }
4663
4664 $titleText = "<p>";
4665 $titleText .= "<label for='" . $this->get_field_id( 'title' ) ."'>". __( 'Title:' ) ."</label>";
4666 $titleText .= "<input class='widefat' id='". $this->get_field_id( 'title' ) ."' name='". $this->get_field_name( 'title' )."' type='text' value='". esc_attr( $title )."' />";
4667 $titleText .= "</p>";
4668
4669 $textAreaText = "<p>";
4670 $textAreaText .= "<textarea class='widefat' id='". $this->get_field_id( 'textarea' )."' name='" . $this->get_field_name( 'textarea' ) ."' rows='16' cols='20'>". esc_attr( $textarea ) ."</textarea>";
4671 $textAreaText .= "</p>";
4672
4673 //echo out the actual widget content block
4674 echo $mergeFieldDropDown;
4675 echo $titleText;
4676 echo $textAreaText;
4677
4678 }
4679
4680 // Updating widget replacing old instances with new
4681 public function update( $new_instance, $old_instance ) {
4682 $instance = array();
4683 $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
4684 $instance['textarea'] = ( ! empty( $new_instance['textarea'] ) ) ? $new_instance['textarea'] : '';
4685 return $instance;
4686 }
4687 } // Class pilotpress_widget ends here
4688
4689 }
4690
4691 function pilotpress_widget_js() {
4692 $widgetJavascript = "
4693 <script type='text/javascript'>
4694 jQuery( document ).ready( function(){
4695 jQuery( 'body' ).on( 'change', 'select.op-merge-codes__select', function( ev ) {
4696 var textarea = jQuery(this).closest( 'form' ).find( 'textarea' );
4697 textarea.val(textarea.val() + jQuery(this).val());
4698 } );
4699 } );
4700 </script>
4701 ";
4702 echo $widgetJavascript;
4703 }
4704
4705 function enable_pilotpress() {
4706 $pilotpress = new PilotPress;
4707 $pilotpress->do_enable();
4708 }
4709
4710 function disable_pilotpress() {
4711 $pilotpress = new PilotPress;
4712 $pilotpress->do_disable();
4713 }
4714
4715
4716