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

pilotpress.php in PilotPress stable, at pilotpress.php

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