├── .gitattributes
├── .gitignore
├── README.md
├── assets
├── css
│ ├── admin.css
│ ├── admin.less
│ ├── frontend.css
│ ├── frontend.less
│ └── ussync-confirmation-email.css
└── js
│ ├── admin.js
│ ├── admin.min.js
│ ├── frontend.js
│ ├── frontend.min.js
│ ├── settings.js
│ └── settings.min.js
├── includes
├── class-user-session-synchronizer-email-verification.php
├── class-user-session-synchronizer-session-control.php
├── class-user-session-synchronizer-settings.php
├── class-user-session-synchronizer.php
├── images
│ ├── menu.png
│ ├── right_arrow.png
│ ├── send.png
│ ├── time.png
│ └── wrong_arrow.png
├── lib
│ ├── class-user-session-synchronizer-admin-api.php
│ ├── class-user-session-synchronizer-post-type.php
│ └── class-user-session-synchronizer-taxonomy.php
└── views
│ ├── demo_email.html
│ ├── email-setting.php
│ ├── email-verification.php
│ └── logging-in.php
├── index.php
├── lang
└── user-session-synchronizer.pot
├── readme.txt
├── screenshot_1.png
├── screenshot_2.png
├── screenshot_3.png
├── screenshot_4.png
├── uninstall.php
└── user-session-synchronizer.php
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.svn-base
2 | .svn/entries
3 | .svn/format
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Wordpress User Session Synchronizer
2 |
3 | Keep the user logged in from one wordpress to another by synchronizing user data and cookie session
4 |
5 | ## Description
6 |
7 | User Session Synchronizer allows you to keep the user logged in from one wordpress to another by synchronizing user data and cookie session based on a verified email.
8 | The user email is encrypted based on the current user ip and a secret key shared by the synchronized wordpress installations.
9 |
10 | ### Features
11 |
12 | - Synchronize session between installations
13 | - Verify user email through new registration
14 | - Verify user email through manual admin action
15 | - Verify user email through email verification code
16 | - Prevent user form changing email
17 | - Display historical sessions
18 | - Auto add new subscriber if user doesn't exist
19 | - Destroy session everywhere on logging out
20 |
21 | ### Upcoming
22 |
23 | - Multiple secret keys & networks
24 | - Enable ajax cross-domain requests
25 |
26 | ## Installation
27 |
28 | Installing "User Session Synchronizer" can be done either by searching for "User Session Synchronizer" via the "Plugins > Add New" screen in your WordPress dashboard, or by using the following steps:
29 |
30 | 1. Download the plugin via WordPress.org
31 | 2. Upload the ZIP file through the 'Plugins > Add New > Upload' screen in your WordPress dashboard
32 | 3. Activate the plugin through the 'Plugins' menu in WordPress
33 | 4. Set your first Secret Key throught the 'User Session Sync > Keys'
34 | 5. Repeat this installation process for every Wordpress you wish to sychnorize with the same Secret Key
35 |
36 | ## Screenshots
37 |
38 | 
39 | 
40 | 
41 | 
42 |
43 | ## Information
44 |
45 | - Contributors: rafasashi
46 | - Donate link: https://www.paypal.me/recuweb
47 | - Tags: user, session, synchronizer, cookie
48 | - Requires at least: 4.3
49 | - Tested up to: 4.7
50 | - Stable tag: 1.3.8
51 | - License: GPLv3 or later
52 | - License URI: http://www.gnu.org/licenses/gpl-3.0.html
53 |
54 | ## Frequently Asked Questions
55 |
56 | ### What is the plugin template for?
57 |
58 | This plugin template is designed to Keep the user logged in from one wordpress to another by synchronizing user data and cookie session
59 |
60 | ## Changelog ##
61 |
62 | ### 1.3.8
63 |
64 | * 2017-05-26
65 | * logout bug fixed
66 |
67 | ### 1.3.7
68 |
69 | * 2017-05-16
70 | * activate plugin email fixed
71 |
72 | ### 1.3.6
73 |
74 | * 2017-03-14
75 | * Logout everywhere fixed
76 | * Infinit loop fixed on SSL auth
77 |
78 | ### 1.3.5
79 |
80 | * 2017-02-09
81 | * Content-Security-Policy implementation
82 | * HTTPS supported
83 |
84 | ### 1.3.4
85 |
86 | * 2017-01-27
87 | * User IP detection improved
88 | * Synchronization via iframe instead of image
89 |
90 | ### 1.3.3
91 |
92 | * 2016-10-26
93 | * Resend validation email improved
94 |
95 | ### 1.3.2
96 |
97 | * 2016-10-14
98 | * Issue regarding email validation corrected
99 |
100 | ### 1.3.1
101 |
102 | * 2016-09-26
103 | * Multiple Logout issues corrected
104 |
105 | ### 1.2
106 | * 2016-09-26
107 | * Multiple subfolders under same domain
108 |
109 | ### 1.1
110 | * 2016-09-22
111 | * Theme footer hooked
112 |
113 | ### 1.0
114 | * 2016-09-06
115 | * Initial release
116 |
117 | ## Upgrade Notice
118 |
119 | ### 1.0
120 | * 2016-09-06
121 | * Initial release
122 |
--------------------------------------------------------------------------------
/assets/css/admin.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/assets/css/admin.css
--------------------------------------------------------------------------------
/assets/css/admin.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/assets/css/admin.less
--------------------------------------------------------------------------------
/assets/css/frontend.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/assets/css/frontend.css
--------------------------------------------------------------------------------
/assets/css/frontend.less:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/assets/css/frontend.less
--------------------------------------------------------------------------------
/assets/css/ussync-confirmation-email.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Plugin Name: User Session Synchronizer
3 | * Version: 1.0
4 | * Plugin URI: https://github.com/rafasashi/user-session-synchronizer/archive/master.zip
5 | * Description: Keep the user logged in from one wordpress to another by synchronizing user data and cookie session.
6 | * Author: Rafasashi
7 | * Author URI: https://www.linkedin.com/in/raphaeldartigues
8 | * Requires at least: 4.6
9 | * Tested up to: 4.6
10 | *
11 | * Text Domain: user-session-synchronizer
12 | * Domain Path: /lang/
13 | *
14 | * @package WordPress
15 | * @author Rafasashi
16 | * @since 1.0.0
17 | */
18 |
19 |
20 | #login_register{
21 | padding: 0px;
22 | border: none;
23 | margin: 0px;
24 | }
25 | .confirm_box{
26 | display: none;
27 | margin-bottom: 6px;
28 | }
29 | input#confirmdCode {
30 | width: 100%;
31 | margin-bottom: 4px;
32 | }
33 | input#confirmcode_button {
34 | width: 100%;
35 | padding: 5px;
36 | height: 36px;
37 | }
38 | #resendverifycode{
39 | width: 100%;
40 | padding: 5px;
41 | height: 36px;
42 | display:none;
43 | }
44 |
45 | .row.error_box {
46 | display:none;
47 | color: red;
48 | margin: 0px;
49 | font-size: 13px;
50 | border: 1px solid #B3B3B3;
51 | padding: 4px;
52 | }
53 | .width33{
54 | float:left;
55 | }
56 | .oknotice{
57 | color: #248805;
58 | border: 1px solid #248805;
59 | font-size: 13px;
60 | padding-left: 3px;
61 | }
--------------------------------------------------------------------------------
/assets/js/admin.js:
--------------------------------------------------------------------------------
1 | jQuery( document ).ready( function ( e ) {
2 |
3 | });
--------------------------------------------------------------------------------
/assets/js/admin.min.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function(){});
--------------------------------------------------------------------------------
/assets/js/frontend.js:
--------------------------------------------------------------------------------
1 | jQuery( document ).ready( function ( e ) {
2 |
3 | });
--------------------------------------------------------------------------------
/assets/js/frontend.min.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function(){});
--------------------------------------------------------------------------------
/assets/js/settings.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function($) {
2 |
3 | /***** Colour picker *****/
4 |
5 | $('.colorpicker').hide();
6 | $('.colorpicker').each( function() {
7 | $(this).farbtastic( $(this).closest('.color-picker').find('.color') );
8 | });
9 |
10 | $('.color').click(function() {
11 | $(this).closest('.color-picker').find('.colorpicker').fadeIn();
12 | });
13 |
14 | $(document).mousedown(function() {
15 | $('.colorpicker').each(function() {
16 | var display = $(this).css('display');
17 | if ( display == 'block' )
18 | $(this).fadeOut();
19 | });
20 | });
21 |
22 |
23 | /***** Uploading images *****/
24 |
25 | var file_frame;
26 |
27 | jQuery.fn.uploadMediaFile = function( button, preview_media ) {
28 | var button_id = button.attr('id');
29 | var field_id = button_id.replace( '_button', '' );
30 | var preview_id = button_id.replace( '_button', '_preview' );
31 |
32 | // If the media frame already exists, reopen it.
33 | if ( file_frame ) {
34 | file_frame.open();
35 | return;
36 | }
37 |
38 | // Create the media frame.
39 | file_frame = wp.media.frames.file_frame = wp.media({
40 | title: jQuery( this ).data( 'uploader_title' ),
41 | button: {
42 | text: jQuery( this ).data( 'uploader_button_text' ),
43 | },
44 | multiple: false
45 | });
46 |
47 | // When an image is selected, run a callback.
48 | file_frame.on( 'select', function() {
49 | attachment = file_frame.state().get('selection').first().toJSON();
50 | jQuery("#"+field_id).val(attachment.id);
51 | if( preview_media ) {
52 | jQuery("#"+preview_id).attr('src',attachment.sizes.thumbnail.url);
53 | }
54 | file_frame = false;
55 | });
56 |
57 | // Finally, open the modal
58 | file_frame.open();
59 | }
60 |
61 | jQuery('.image_upload_button').click(function() {
62 | jQuery.fn.uploadMediaFile( jQuery(this), true );
63 | });
64 |
65 | jQuery('.image_delete_button').click(function() {
66 | jQuery(this).closest('td').find( '.image_data_field' ).val( '' );
67 | jQuery(this).closest('td').find( '.image_preview' ).remove();
68 | return false;
69 | });
70 |
71 | });
--------------------------------------------------------------------------------
/assets/js/settings.min.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function(e){e(".colorpicker").hide();e(".colorpicker").each(function(){e(this).farbtastic(e(this).closest(".color-picker").find(".color"))});e(".color").click(function(){e(this).closest(".color-picker").find(".colorpicker").fadeIn()});e(document).mousedown(function(){e(".colorpicker").each(function(){var t=e(this).css("display");t=="block"&&e(this).fadeOut()})});var t;jQuery.fn.uploadMediaFile=function(e,n){var r=e.attr("id"),i=r.replace("_button",""),s=r.replace("_button","_preview");if(t){t.open();return}t=wp.media.frames.file_frame=wp.media({title:jQuery(this).data("uploader_title"),button:{text:jQuery(this).data("uploader_button_text")},multiple:!1});t.on("select",function(){attachment=t.state().get("selection").first().toJSON();jQuery("#"+i).val(attachment.id);n&&jQuery("#"+s).attr("src",attachment.sizes.thumbnail.url);t=!1});t.open()};jQuery(".image_upload_button").click(function(){jQuery.fn.uploadMediaFile(jQuery(this),!0)});jQuery(".image_delete_button").click(function(){jQuery(this).closest("td").find(".image_data_field").val("");jQuery(this).closest("td").find(".image_preview").remove();return!1})});
--------------------------------------------------------------------------------
/includes/class-user-session-synchronizer-email-verification.php:
--------------------------------------------------------------------------------
1 | parent = $parent;
38 |
39 | $this->user_id = get_current_user_id();
40 |
41 | register_activation_hook(__FILE__, array($this, 'activate_plugins_email'));
42 |
43 | //add_action('wp_login', array( $this, 'ussync_after_user_loggedin'),10);
44 |
45 | add_shortcode('ussyncemailverificationcode', array($this, 'get_email_verification_link'));
46 |
47 | add_filter('manage_users_columns', array($this, 'update_user_table'), 10, 1);
48 | add_filter('manage_users_custom_column', array($this, 'modify_user_table_row'), 10, 3);
49 |
50 | add_action('user_register', array( $this, 'after_user_register'), 10, 1);
51 | add_action('admin_head', array($this, 'verify_user'));
52 |
53 | add_action('init', array($this, 'verify_registered_user'));
54 | }
55 |
56 | public function after_user_register($user_id){
57 |
58 | // the new user just registered but never logged in yet
59 | add_user_meta($user_id, 'ussync_has_not_logged_in_yet', 'true');
60 | }
61 |
62 | public function verify_registered_user(){
63 |
64 | if(isset($_GET["ussync_confirmation_verify"])){
65 |
66 | $user_meta = explode("@", base64_decode($_GET["ussync_confirmation_verify"]));
67 |
68 | if (get_user_meta((int) $user_meta[1], "ussync_email_verifiedcode", TRUE) == $user_meta[0]) {
69 |
70 | update_user_meta((int) $user_meta[1], "ussync_email_verified", "true");
71 |
72 | delete_user_meta((int) $user_meta[1], "ussync_email_verifiedcode");
73 |
74 | echo '
Congratulations your account has been successfully verified!
';
75 | }
76 | elseif(get_user_meta((int) $user_meta[1], "ussync_email_verified", TRUE) == 'true'){
77 |
78 | echo 'Your account has already been verified...
';
79 | }
80 | else{
81 |
82 | echo 'Oops something went wrong during your account validation...
';
83 | }
84 | }
85 | elseif(is_user_logged_in()){
86 |
87 | $user_id = get_current_user_id();
88 |
89 | $user_meta = get_user_meta($user_id);
90 |
91 | if(isset($user_meta['ussync_has_not_logged_in_yet'])){
92 |
93 | delete_user_meta($user_id, 'ussync_has_not_logged_in_yet');
94 |
95 | update_user_meta($user_id, 'ussync_email_verified', 'true');
96 | }
97 | }
98 | }
99 |
100 | public function activate_plugins_email() {
101 |
102 | ob_start();
103 | include plugin_dir_path(__FILE__) . "views/demo_email.html";
104 | $demo_email_content = ob_get_clean();
105 |
106 | update_option("ussync-email-header", $demo_email_content);
107 | update_option("ussync_email_confemail", get_option("admin_email"));
108 | update_option("ussync_email_conf_title", "Please Verify Your email Account");
109 | }
110 |
111 | public function view_email_setting() {
112 |
113 | include plugin_dir_path(__FILE__) . "views/email-setting.php";
114 | }
115 |
116 | public function view_email_verification() {
117 |
118 | include plugin_dir_path(__FILE__) . "views/email-verification.php";
119 | }
120 |
121 | public function codeMailSender($email) {
122 |
123 | $urlparts = parse_url(site_url());
124 | $domain = $urlparts ['host'];
125 |
126 | $Email_title = get_option("ussync_email_conf_title");
127 | $sender_email = get_option("ussync_email_confemail");
128 | $message = get_option("ussync-email-header");
129 |
130 | $headers = [];
131 | $headers[] = 'From: ' . get_bloginfo('name') . ' ';
132 | $headers[] = 'MIME-Version: 1.0';
133 | $headers[] = 'Content-type: text/html';
134 |
135 | $preMesaage = "" . apply_filters('the_content', $message) . "
";
136 |
137 | if(!wp_mail($email, $Email_title, $preMesaage, $headers)){
138 |
139 | global $phpmailer;
140 |
141 | var_dump($phpmailer->ErrorInfo);exit;
142 | }
143 | }
144 |
145 | public function get_email_verification_link(){
146 |
147 | $link='';
148 |
149 | if(isset($_GET["user_id"]) && wp_verify_nonce($_GET["wp_nonce"], "ussync_email")){
150 |
151 | $user_id = $_GET['user_id'];
152 |
153 | $secret = get_user_meta( (int) $user_id, "ussync_email_verifiedcode", true);
154 |
155 | $createLink = $secret . "@" . $user_id;
156 |
157 | $hyperlink = get_admin_url() . "profile.php?ussync_confirmation_verify=" . base64_encode($createLink);
158 |
159 | $link .= " Click here to verify";
160 | }
161 |
162 | return $link;
163 | }
164 |
165 | public function update_user_table($column) {
166 |
167 | $column['ussync_verified'] = 'Verified user';
168 | return $column;
169 | }
170 |
171 | public function modify_user_table_row($val, $column_name, $user_id) {
172 |
173 | $user_role = get_userdata($user_id);
174 |
175 | $row='';
176 |
177 | if ($column_name == "ussync_verified") {
178 |
179 | if ($user_role->roles[0] != "administrator") {
180 |
181 | if (get_user_meta($user_id, "ussync_email_verified", true) != "true") {
182 |
183 | if (get_user_meta($user_id, "ussync_has_not_logged_in_yet", true) == "true") {
184 |
185 | $text = "
";
186 | $row .= " $user_id, "wp_nonce" => wp_create_nonce("ussync_email"), "ussync_confirm" => "true"), get_admin_url() . "users.php") . "\">" . apply_filters("ussync_email_confirmation_manual_verify", $text) . "";
187 | }
188 | else{
189 |
190 | $text = "
";
191 | $row .= " $user_id, "wp_nonce" => wp_create_nonce("ussync_email"), "ussync_confirm" => "true"), get_admin_url() . "users.php") . "\">" . apply_filters("ussync_email_confirmation_manual_verify", $text) . "";
192 | }
193 |
194 |
195 | $text = "
";
196 | $row .= " $user_id, "wp_nonce" => wp_create_nonce("ussync_email"), "ussync_confirm" => "resend"), get_admin_url() . "users.php") . "\">" . apply_filters("ussync_email_confirmation_manual_verify", $text) . "";
197 | }
198 | else{
199 |
200 | $text = "
";
201 | $row .= " $user_id, "wp_nonce" => wp_create_nonce("ussync_email"), "ussync_confirm" => "false"), get_admin_url() . "users.php") . "\">" . apply_filters("ussync_email_confirmation_manual_verify", $text) . "";
202 | }
203 |
204 | }
205 | else {
206 |
207 | $row .= "Admin";
208 | }
209 | }
210 |
211 | return $row;
212 | }
213 |
214 | public function verify_user() {
215 |
216 | //var_dump(wp_verify_nonce($_GET["wp_nonce"], "ussync_email"));
217 |
218 | if(isset($_GET["user_id"]) && isset($_GET["wp_nonce"]) && wp_verify_nonce($_GET["wp_nonce"], "ussync_email") && isset($_GET["ussync_confirm"])) {
219 |
220 | if($_GET["ussync_confirm"] === 'true' || $_GET["ussync_confirm"] === 'false'){
221 |
222 | update_user_meta($_GET["user_id"], "ussync_email_verified", $_GET["ussync_confirm"]);
223 | }
224 | elseif($_GET["ussync_confirm"] === 'resend'){
225 |
226 | $user_id = intval($_GET['user_id']);
227 |
228 | $email_verified = get_user_meta(($user_id), "ussync_email_verified", TRUE);
229 |
230 | if( $email_verified !== 'true' ){
231 |
232 | $user = get_user_by("id", $user_id);
233 |
234 | $scret_code = md5( $user->user_email . time() );
235 |
236 | update_user_meta($user_id, "ussync_email_verifiedcode", $scret_code);
237 |
238 | $this->codeMailSender($user->user_email);
239 |
240 | echo 'Email sent to '.$user->user_email.'
';
241 | }
242 | }
243 | }
244 | }
245 |
246 | /**
247 | * Main User_Session_Synchronizer_Email_Verification Instance
248 | *
249 | * Ensures only one instance of User_Session_Synchronizer_Email_Verification is loaded or can be loaded.
250 | *
251 | * @since 1.0.0
252 | * @static
253 | * @see User_Session_Synchronizer()
254 | * @return Main User_Session_Synchronizer_Email_Verification instance
255 | */
256 | public static function instance ( $parent ) {
257 |
258 | if ( is_null( self::$_instance ) ) {
259 |
260 | self::$_instance = new self( $parent );
261 | }
262 | return self::$_instance;
263 | } // End instance()
264 |
265 | /**
266 | * Cloning is forbidden.
267 | *
268 | * @since 1.0.0
269 | */
270 | public function __clone () {
271 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->parent->_version );
272 | } // End __clone()
273 |
274 | /**
275 | * Unserializing instances of this class is forbidden.
276 | *
277 | * @since 1.0.0
278 | */
279 | public function __wakeup () {
280 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->parent->_version );
281 | } // End __wakeup()
282 |
283 | }
--------------------------------------------------------------------------------
/includes/class-user-session-synchronizer-session-control.php:
--------------------------------------------------------------------------------
1 | parent = $parent;
36 |
37 |
38 | }
39 |
40 | /**
41 | * Callback for the custom submenu screen content
42 | *
43 | * @return void
44 | */
45 | public function session_control() {
46 |
47 | if (
48 | ! empty( $_GET['_wpnonce'] )
49 | &&
50 | ! empty( $_GET['action'] )
51 | &&
52 | 'destroy_session' === $_GET['action']
53 | &&
54 | ! empty( $_GET['user_id'] )
55 | &&
56 | ! empty( $_GET['token_hash'] )
57 | ) {
58 | $user_id = absint( $_GET['user_id'] );
59 |
60 | if ( false === wp_verify_nonce( $_GET['_wpnonce'], sprintf( 'destroy_session_nonce-%d', $user_id ) ) ) {
61 | wp_die( __( 'Cheatin’ uh?', 'user-session-synchronizer' ) );
62 | }
63 |
64 | $this->destroy_user_session( $user_id, $_GET['token_hash'] );
65 | }
66 |
67 | $results = $this->get_all_sessions();
68 | $sorted = array();
69 | $spp = ! empty( $_GET['sessions_per_page'] ) ? absint( $_GET['sessions_per_page'] ) : 20;
70 | $paged = ! empty( $_GET['paged'] ) ? absint( $_GET['paged'] ) : 1;
71 | $offset = absint( ( $paged - 1 ) * $spp );
72 | $orderby = ! empty( $_GET['orderby'] ) ? $_GET['orderby'] : 'created';
73 | $order = ! empty( $_GET['order'] ) ? $_GET['order'] : 'desc';
74 |
75 | foreach ( $results as $result ) {
76 | if ( 'ip' === $orderby ) {
77 | $sorted[] = str_replace( '.', '', $result[ $orderby ] );
78 | } else {
79 | $sorted[] = $result[ $orderby ];
80 | }
81 | }
82 |
83 | // Loose comparison needed
84 | if ( 'asc' == $order ) {
85 |
86 | array_multisort( $sorted, SORT_ASC, $results );
87 | }
88 | else {
89 |
90 | array_multisort( $sorted, SORT_DESC, $results );
91 | }
92 |
93 | $total_sessions = count( $results );
94 | $pages = absint( ceil( $total_sessions / $spp ) );
95 |
96 | $results = array_slice( $results, $offset, $spp );
97 |
98 | switch ( $order ) {
99 | case 'asc':
100 | $order_flip = 'desc';
101 | break;
102 | case 'desc':
103 | $order_flip = 'asc';
104 | break;
105 | default:
106 | $order_flip = 'desc';
107 | }
108 |
109 | $columns = array(
110 | 'username' => __( 'Username', 'user-session-synchronizer' ),
111 | //'name' => __( 'Name', 'user-session-synchronizer' ),
112 | 'email' => __( 'E-mail', 'user-session-synchronizer' ),
113 | 'role' => __( 'Role', 'user-session-synchronizer' ),
114 | 'created' => __( 'Created', 'user-session-synchronizer' ),
115 | 'expiration' => __( 'Expires', 'user-session-synchronizer' ),
116 | 'ip' => __( 'IP Address', 'user-session-synchronizer' ),
117 | );
118 |
119 | if ( is_network_admin() ) {
120 |
121 | unset( $columns['role'] );
122 | }
123 |
124 | $users = $this->get_users_with_sessions();
125 |
126 | global $wp_roles;
127 |
128 | ob_start();
129 |
130 | $first_link = $base_link = add_query_arg(
131 | array(
132 | 'page' => 'user-session-synchronizer',
133 | ),
134 | admin_url( 'users.php' )
135 | );
136 | $last_link = add_query_arg( array( 'paged' => $pages ), $first_link );
137 | $prev_link = ( $paged > 2 ) ? add_query_arg( array( 'paged' => absint( $paged - 1 ), 'sessions_per_page' => $spp, ), $first_link ) : $first_link;
138 | $next_link = ( $pages > $paged ) ? add_query_arg( array( 'paged' => absint( $paged + 1 ), 'sessions_per_page' => $spp, ), $first_link ) : $last_link;
139 | ?>
140 |
141 |
142 |
143 | 1 ) : ?>
144 |
145 |
154 |
155 |
156 |
157 |
158 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
total_users ) ) ?>
168 |
169 |
284 |
285 |
286 | get_results( "SELECT meta_value FROM $wpdb->usermeta WHERE meta_key = 'session_tokens' LIMIT 0, 9999" );
299 | $sessions = wp_list_pluck( $sessions, 'meta_value' );
300 | $sessions = array_map( 'maybe_unserialize', $sessions );
301 |
302 | foreach ( $sessions as $session ) {
303 |
304 | $results = array_merge( $results, $session );
305 | }
306 |
307 | return (array) $results;
308 | }
309 |
310 | /**
311 | * Get all users with active sessions
312 | *
313 | * @return object WP_User
314 | */
315 | public function get_users_with_sessions() {
316 | $args = array(
317 | 'number' => 9999,
318 | 'blog_id' => is_network_admin() ? 0 : get_current_blog_id(),
319 | 'meta_query' => array(
320 | array(
321 | 'key' => 'session_tokens',
322 | 'compare' => 'EXISTS',
323 | ),
324 | ),
325 | );
326 |
327 | $users = new WP_User_Query( $args );
328 |
329 | return $users;
330 | }
331 |
332 | /**
333 | * Get all sessions from all users
334 | *
335 | * @return array
336 | */
337 | public function get_all_sessions() {
338 | $results = array();
339 | $users = $this->get_users_with_sessions()->get_results();
340 | $sessions = $this->get_all_sessions_raw();
341 |
342 | foreach ( $users as $user ) {
343 | $user_sessions = get_user_meta( $user->ID, 'session_tokens', true );
344 |
345 | foreach ( $sessions as $session ) {
346 | foreach ( $user_sessions as $token_hash => $user_session ) {
347 | // Loose comparison needed
348 | if ( $user_session != $session ) {
349 | continue;
350 | }
351 | $results[] = array(
352 | 'user_id' => $user->ID,
353 | 'username' => $user->user_login,
354 | //'name' => $user->display_name,
355 | 'email' => $user->user_email,
356 | 'role' => ! empty( $user->roles[0] ) ? $user->roles[0] : '',
357 | 'created' => $user_session['login'],
358 | 'expiration' => $user_session['expiration'],
359 | 'ip' => $user_session['ip'],
360 | 'user_agent' => $user_session['ua'],
361 | 'token_hash' => $token_hash,
362 | );
363 | }
364 | }
365 | }
366 |
367 | return (array) $results;
368 | }
369 |
370 | /**
371 | * Destroy a specfic session for a specfic user
372 | *
373 | * @param int $user_id
374 | * @param string $token_hash
375 | *
376 | * @return void
377 | */
378 | public function destroy_user_session( $user_id, $token_hash ) {
379 |
380 | $session_tokens = get_user_meta( $user_id, 'session_tokens', true );
381 |
382 | unset( $session_tokens[ $token_hash ] );
383 |
384 | update_user_meta( $user_id, 'session_tokens', $session_tokens );
385 | }
386 |
387 | /**
388 | * Main User_Session_Synchronizer_Session_Control Instance
389 | *
390 | * Ensures only one instance of User_Session_Synchronizer_Session_Control is loaded or can be loaded.
391 | *
392 | * @since 1.0.0
393 | * @static
394 | * @see User_Session_Synchronizer()
395 | * @return Main User_Session_Synchronizer_Session_Control instance
396 | */
397 | public static function instance ( $parent ) {
398 | if ( is_null( self::$_instance ) ) {
399 | self::$_instance = new self( $parent );
400 | }
401 | return self::$_instance;
402 | } // End instance()
403 |
404 | /**
405 | * Cloning is forbidden.
406 | *
407 | * @since 1.0.0
408 | */
409 | public function __clone () {
410 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->parent->_version );
411 | } // End __clone()
412 |
413 | /**
414 | * Unserializing instances of this class is forbidden.
415 | *
416 | * @since 1.0.0
417 | */
418 | public function __wakeup () {
419 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->parent->_version );
420 | } // End __wakeup()
421 |
422 | }
--------------------------------------------------------------------------------
/includes/class-user-session-synchronizer-settings.php:
--------------------------------------------------------------------------------
1 | parent = $parent;
41 |
42 | $this->base = 'ussync_';
43 |
44 | // Initialise settings
45 | add_action( 'init', array( $this, 'init_settings' ), 11 );
46 |
47 | // Register plugin settings
48 | add_action( 'admin_init' , array( $this, 'register_settings' ) );
49 |
50 | // Add settings page to menu
51 | add_action( 'admin_menu' , array( $this, 'add_menu_items' ) );
52 |
53 | // Add settings link to plugins page
54 | add_filter( 'plugin_action_links_' . plugin_basename( $this->parent->file ) , array( $this, 'add_settings_link' ) );
55 | }
56 |
57 | /**
58 | * Initialise settings
59 | * @return void
60 | */
61 | public function init_settings () {
62 | $this->settings = $this->settings_fields();
63 | }
64 |
65 | /**
66 | * Add settings page to admin menu
67 | * @return void
68 | */
69 | public function add_menu_items () {
70 |
71 | //add menu in wordpress settings
72 |
73 | //$page = add_options_page( __( 'User Session Synchronizer', 'user-session-synchronizer' ) , __( 'User Session Synchronizer', 'user-session-synchronizer' ) , 'manage_options' , $this->parent->_token . '_settings' , array( $this, 'settings_page' ) );
74 | //add_action( 'admin_print_styles' . $page, array( $this, 'settings_assets' ) );
75 |
76 | //add menu in wordpress dashboard
77 |
78 | add_menu_page('User Session Sync', 'User Session Sync', 'manage_options', 'user-session-synchronizer', array($this, 'settings_page'),'dashicons-shield');
79 | add_submenu_page("user-session-synchronizer", "User Verify ", "User Verify", 'administrator', 'view_email_verification', array( $this->parent->emailVerification, "view_email_verification"));
80 | add_submenu_page("user-session-synchronizer", "User Sessions", "User Sessions", 'administrator', 'session_control', array( $this->parent->sessionControl, "session_control") );
81 | add_submenu_page("user-session-synchronizer", "Email Template", "Email Template", 'administrator', 'view_email_setting', array( $this->parent->emailVerification, "view_email_setting"));
82 |
83 | }
84 |
85 | /**
86 | * Load settings JS & CSS
87 | * @return void
88 | */
89 | public function settings_assets () {
90 |
91 | // We're including the farbtastic script & styles here because they're needed for the colour picker
92 | // If you're not including a colour picker field then you can leave these calls out as well as the farbtastic dependency for the wpt-admin-js script below
93 | wp_enqueue_style( 'farbtastic' );
94 | wp_enqueue_script( 'farbtastic' );
95 |
96 | // We're including the WP media scripts here because they're needed for the image upload field
97 | // If you're not including an image upload then you can leave this function call out
98 | wp_enqueue_media();
99 |
100 | wp_register_script( $this->parent->_token . '-settings-js', $this->parent->assets_url . 'js/settings' . $this->parent->script_suffix . '.js', array( 'farbtastic', 'jquery' ), '1.0.0' );
101 | wp_enqueue_script( $this->parent->_token . '-settings-js' );
102 | }
103 |
104 | /**
105 | * Add settings link to plugin list table
106 | * @param array $links Existing links
107 | * @return array Modified links
108 | */
109 | public function add_settings_link ( $links ) {
110 |
111 | $settings_link = '' . __( 'Settings', 'user-session-synchronizer' ) . '';
112 | array_push( $links, $settings_link );
113 | return $links;
114 | }
115 |
116 | /**
117 | * Build settings fields
118 | * @return array Fields to be displayed on settings page
119 | */
120 | private function settings_fields () {
121 |
122 | $settings['keys'] = array(
123 | 'title' => __( 'Keys', 'user-session-synchronizer' ),
124 | 'description' => __( 'This plugin uses the user email address as a unique ID to synchronize the session between two wordpress installations.', 'user-session-synchronizer' ),
125 | 'fields' => array(
126 | array(
127 | 'id' => 'secret_key_1',
128 | 'label' => __( 'Secret Key 1' , 'user-session-synchronizer' ),
129 | 'description' => __( 'The secret key is used to encrypt and decrypt the current user ID. It must be the same for every synchronized installations.', 'user-session-synchronizer' ),
130 | 'type' => 'text',
131 | 'default' => '',
132 | 'placeholder' => __( 'Your Secret Key 1', 'user-session-synchronizer' )
133 | ),
134 | array(
135 | 'id' => 'domain_list_1',
136 | 'label' => __( 'List of domains 1' , 'user-session-synchronizer' ),
137 | 'description' => __( 'List of allowed domains to synchronize together. Separate multiple domains with line breaks.', 'user-session-synchronizer' ),
138 | 'type' => 'textarea',
139 | 'default' => '',
140 | 'placeholder' => __( $_SERVER['HTTP_HOST'], 'user-session-synchronizer' )
141 | ),
142 | array(
143 | 'id' => 'no_user_1',
144 | 'label' => __( 'If user doesn\'t exist', 'user-session-synchronizer' ),
145 | 'description' => __( 'Action taken when a verified unknown user tries to synchronize with this installation', 'user-session-synchronizer' ),
146 | 'type' => 'radio',
147 | 'options' => array(
148 | 'do_nothing' => 'Do nothing',
149 | 'register_suscriber' => 'Register new subscriber'
150 | ),
151 | 'default' => 'do_nothing'
152 | ),
153 | /*
154 | array(
155 | 'id' => 'password_field',
156 | 'label' => __( 'A Password' , 'user-session-synchronizer' ),
157 | 'description' => __( 'This is a standard password field.', 'user-session-synchronizer' ),
158 | 'type' => 'password',
159 | 'default' => '',
160 | 'placeholder' => __( 'Placeholder text', 'user-session-synchronizer' )
161 | ),
162 | array(
163 | 'id' => 'secret_text_field',
164 | 'label' => __( 'Some Secret Text' , 'user-session-synchronizer' ),
165 | 'description' => __( 'This is a secret text field - any data saved here will not be displayed after the page has reloaded, but it will be saved.', 'user-session-synchronizer' ),
166 | 'type' => 'text_secret',
167 | 'default' => '',
168 | 'placeholder' => __( 'Placeholder text', 'user-session-synchronizer' )
169 | ),
170 | array(
171 | 'id' => 'ussync_add_user',
172 | 'label' => __( 'Add user', 'user-session-synchronizer' ),
173 | 'description' => __( 'Create a new user if it doesn\'t exist yet.', 'user-session-synchronizer' ),
174 | 'type' => 'checkbox',
175 | 'default' => ''
176 | ),
177 | */
178 | /*
179 | array(
180 | 'id' => 'select_box',
181 | 'label' => __( 'A Select Box', 'user-session-synchronizer' ),
182 | 'description' => __( 'A standard select box.', 'user-session-synchronizer' ),
183 | 'type' => 'select',
184 | 'options' => array( 'drupal' => 'Drupal', 'joomla' => 'Joomla', 'wordpress' => 'WordPress' ),
185 | 'default' => 'wordpress'
186 | ),
187 | array(
188 | 'id' => 'multiple_checkboxes',
189 | 'label' => __( 'Some Items', 'user-session-synchronizer' ),
190 | 'description' => __( 'You can select multiple items and they will be stored as an array.', 'user-session-synchronizer' ),
191 | 'type' => 'checkbox_multi',
192 | 'options' => array( 'square' => 'Square', 'circle' => 'Circle', 'rectangle' => 'Rectangle', 'triangle' => 'Triangle' ),
193 | 'default' => array( 'circle', 'triangle' )
194 | )
195 | */
196 | )
197 | );
198 |
199 | /*
200 | $settings['extra'] = array(
201 | 'title' => __( 'Iframes', 'user-session-synchronizer' ),
202 | 'description' => __( 'These are some extra input fields that maybe aren\'t as common as the others.', 'user-session-synchronizer' ),
203 | 'fields' => array(
204 | array(
205 | 'id' => 'number_field',
206 | 'label' => __( 'A Number' , 'user-session-synchronizer' ),
207 | 'description' => __( 'This is a standard number field - if this field contains anything other than numbers then the form will not be submitted.', 'user-session-synchronizer' ),
208 | 'type' => 'number',
209 | 'default' => '',
210 | 'placeholder' => __( '42', 'user-session-synchronizer' )
211 | ),
212 | array(
213 | 'id' => 'colour_picker',
214 | 'label' => __( 'Pick a colour', 'user-session-synchronizer' ),
215 | 'description' => __( 'This uses WordPress\' built-in colour picker - the option is stored as the colour\'s hex code.', 'user-session-synchronizer' ),
216 | 'type' => 'color',
217 | 'default' => '#21759B'
218 | ),
219 | array(
220 | 'id' => 'an_image',
221 | 'label' => __( 'An Image' , 'user-session-synchronizer' ),
222 | 'description' => __( 'This will upload an image to your media library and store the attachment ID in the option field. Once you have uploaded an imge the thumbnail will display above these buttons.', 'user-session-synchronizer' ),
223 | 'type' => 'image',
224 | 'default' => '',
225 | 'placeholder' => ''
226 | ),
227 | array(
228 | 'id' => 'multi_select_box',
229 | 'label' => __( 'A Multi-Select Box', 'user-session-synchronizer' ),
230 | 'description' => __( 'A standard multi-select box - the saved data is stored as an array.', 'user-session-synchronizer' ),
231 | 'type' => 'select_multi',
232 | 'options' => array( 'linux' => 'Linux', 'mac' => 'Mac', 'windows' => 'Windows' ),
233 | 'default' => array( 'linux' )
234 | )
235 | )
236 | );
237 | */
238 |
239 | $settings = apply_filters( $this->parent->_token . '_settings_fields', $settings );
240 |
241 | return $settings;
242 | }
243 |
244 | /**
245 | * Register plugin settings
246 | * @return void
247 | */
248 | public function register_settings () {
249 |
250 | if ( is_array( $this->settings ) ) {
251 |
252 | // Check posted/selected tab
253 | $current_section = '';
254 | if ( isset( $_POST['tab'] ) && $_POST['tab'] ) {
255 |
256 | $current_section = $_POST['tab'];
257 | }
258 | else {
259 |
260 | if ( isset( $_GET['tab'] ) && $_GET['tab'] ) {
261 |
262 | $current_section = $_GET['tab'];
263 | }
264 | }
265 |
266 | foreach ( $this->settings as $section => $data ) {
267 |
268 | if ( $current_section && $current_section != $section ) continue;
269 |
270 | // Add section to page
271 | add_settings_section( $section, $data['title'], array( $this, 'settings_section' ), $this->parent->_token . '_settings' );
272 |
273 | foreach ( $data['fields'] as $field ) {
274 |
275 | // Validation callback for field
276 | $validation = '';
277 | if ( isset( $field['callback'] ) ) {
278 |
279 | $validation = $field['callback'];
280 | }
281 |
282 | // Register field
283 | $option_name = $this->base . $field['id'];
284 | register_setting( $this->parent->_token . '_settings', $option_name, $validation );
285 |
286 | // Add field to page
287 | add_settings_field( $field['id'], $field['label'], array( $this->parent->admin, 'display_field' ), $this->parent->_token . '_settings', $section, array( 'field' => $field, 'prefix' => $this->base ) );
288 | }
289 |
290 | if ( ! $current_section ) break;
291 | }
292 | }
293 | }
294 |
295 | public function settings_section ( $section ) {
296 |
297 | $html = ' ' . $this->settings[ $section['id'] ]['description'] . '
' . "\n";
298 | echo $html;
299 | }
300 |
301 | /**
302 | * Load settings page content
303 | * @return void
304 | */
305 | public function settings_page () {
306 |
307 | // Build page HTML
308 | $html = '' . "\n";
309 | $html .= '
' . __( 'User Session Synchronizer' , 'user-session-synchronizer' ) . '
' . "\n";
310 |
311 | $tab = '';
312 | if ( isset( $_GET['tab'] ) && $_GET['tab'] ) {
313 | $tab .= $_GET['tab'];
314 | }
315 |
316 | // Show page tabs
317 | if ( is_array( $this->settings ) && 1 < count( $this->settings ) ) {
318 |
319 | $html .= '
' . "\n";
320 |
321 | $c = 0;
322 | foreach ( $this->settings as $section => $data ) {
323 |
324 | // Set tab class
325 | $class = 'nav-tab';
326 | if ( ! isset( $_GET['tab'] ) ) {
327 | if ( 0 == $c ) {
328 | $class .= ' nav-tab-active';
329 | }
330 | } else {
331 | if ( isset( $_GET['tab'] ) && $section == $_GET['tab'] ) {
332 | $class .= ' nav-tab-active';
333 | }
334 | }
335 |
336 | // Set tab link
337 | $tab_link = add_query_arg( array( 'tab' => $section ) );
338 | if ( isset( $_GET['settings-updated'] ) ) {
339 | $tab_link = remove_query_arg( 'settings-updated', $tab_link );
340 | }
341 |
342 | // Output tab
343 | $html .= '' . esc_html( $data['title'] ) . '' . "\n";
344 |
345 | ++$c;
346 | }
347 |
348 | $html .= '
' . "\n";
349 | }
350 |
351 | $html .= '
' . "\n";
364 | $html .= '
' . "\n";
365 |
366 | echo $html;
367 | }
368 |
369 | /**
370 | * Main User_Session_Synchronizer_Settings Instance
371 | *
372 | * Ensures only one instance of User_Session_Synchronizer_Settings is loaded or can be loaded.
373 | *
374 | * @since 1.0.0
375 | * @static
376 | * @see User_Session_Synchronizer()
377 | * @return Main User_Session_Synchronizer_Settings instance
378 | */
379 | public static function instance ( $parent ) {
380 | if ( is_null( self::$_instance ) ) {
381 | self::$_instance = new self( $parent );
382 | }
383 | return self::$_instance;
384 | } // End instance()
385 |
386 | /**
387 | * Cloning is forbidden.
388 | *
389 | * @since 1.0.0
390 | */
391 | public function __clone () {
392 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->parent->_version );
393 | } // End __clone()
394 |
395 | /**
396 | * Unserializing instances of this class is forbidden.
397 | *
398 | * @since 1.0.0
399 | */
400 | public function __wakeup () {
401 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->parent->_version );
402 | } // End __wakeup()
403 |
404 | }
--------------------------------------------------------------------------------
/includes/class-user-session-synchronizer.php:
--------------------------------------------------------------------------------
1 | _version = $version;
95 | $this->_token = 'user-session-synchronizer';
96 |
97 | // Load plugin environment variables
98 | $this->file = $file;
99 | $this->dir = dirname( $this->file );
100 | $this->assets_dir = trailingslashit( $this->dir ) . 'assets';
101 | $this->assets_url = esc_url( trailingslashit( plugins_url( '/assets/', $this->file ) ) );
102 |
103 | $this->script_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
104 |
105 | // set user ip
106 |
107 | $this->user_ip = $this->get_user_ip();
108 |
109 | // set user agent
110 |
111 | $this->user_agent = $_SERVER['HTTP_USER_AGENT'];
112 |
113 | // set secret key number
114 |
115 | $this -> key_num = 1;
116 |
117 | if(isset($_GET['ussync-key'])){
118 |
119 | $this -> key_num=(int)trim($_GET['ussync-key']);
120 | }
121 |
122 | //get secret_key
123 |
124 | $this -> secret_key = get_option('ussync_secret_key_'.$this -> key_num);
125 |
126 | // get proto
127 |
128 | if( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443 ){
129 |
130 | $this -> proto = 'https://';
131 | }
132 | else{
133 |
134 | $this -> proto = 'http://';
135 | }
136 |
137 | // register plugin activation hook
138 |
139 | register_activation_hook( $this->file, array( $this, 'install' ) );
140 |
141 | // Load frontend JS & CSS
142 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ), 10 );
143 | add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ), 10 );
144 |
145 | // Load admin JS & CSS
146 | add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 10, 1 );
147 | add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_styles' ), 10, 1 );
148 |
149 | // Load API for generic admin functions
150 | if ( is_admin() ) {
151 |
152 | $this->admin = new User_Session_Synchronizer_Admin_API();
153 | }
154 |
155 | // Handle login synchronization
156 | add_action( 'init', array( $this, 'synchronize_session' ), 0 );
157 |
158 | // Handle localisation
159 | $this->load_plugin_textdomain();
160 | add_action( 'init', array( $this, 'load_localisation' ), 0 );
161 |
162 | // Handle profile updates
163 | add_action( 'user_profile_update_errors', array( $this, 'prevent_email_change'), 10, 3 );
164 | add_action( 'admin_init', array( $this, 'disable_user_profile_fields'));
165 |
166 | } // End __construct ()
167 |
168 | public function get_user_ip() {
169 |
170 | foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
171 |
172 | if (array_key_exists($key, $_SERVER) === true){
173 |
174 | foreach (array_map('trim', explode(',', $_SERVER[$key])) as $ip){
175 |
176 | if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
177 |
178 | return $ip;
179 | }
180 | }
181 | }
182 | }
183 | }
184 |
185 | public function prevent_email_change( $errors, $update, $user ) {
186 |
187 | if( !empty($user->ID) ){
188 |
189 | $old = get_user_by('id', $user->ID);
190 |
191 | if( $user->user_email != $old->user_email && (!current_user_can('create_users')) ){
192 |
193 | $user->user_email = $old->user_email;
194 | }
195 | }
196 | }
197 |
198 | public function disable_user_profile_fields() {
199 |
200 | global $pagenow;
201 |
202 | // apply only to user profile or user edit pages
203 | if ($pagenow!=='profile.php' && $pagenow!=='user-edit.php') {
204 |
205 | return;
206 | }
207 |
208 | // do not change anything for the administrator
209 | if (current_user_can('administrator')) {
210 |
211 | return;
212 | }
213 |
214 | add_action( 'admin_footer', array( $this,'disable_user_profile_fields_js' ));
215 | }
216 |
217 |
218 | /**
219 | * Disables selected fields in WP Admin user profile (profile.php, user-edit.php)
220 | */
221 | public function disable_user_profile_fields_js() {
222 |
223 | ?>
224 |
235 | user_id = get_current_user_id();
243 |
244 | // check user verified
245 |
246 | if( current_user_can('administrator') ) {
247 |
248 | $this->user_verified = 'true';
249 | }
250 | else{
251 |
252 | $this->user_verified = get_user_meta( $this->user_id, "ussync_email_verified", TRUE);
253 | }
254 |
255 | // add cors header
256 | if(is_user_logged_in()){
257 |
258 | add_action( 'send_headers', array($this, 'add_cors_header') );
259 | add_action( 'send_headers', array($this, 'add_content_security_policy') );
260 | }
261 |
262 | // synchronize sessions
263 |
264 | if( isset($_GET['action']) && $_GET['action']=='logout' ){
265 |
266 | $this->get_domains(true);
267 | }
268 | elseif( isset($_GET['ussync-status']) && $_GET['ussync-status']=='loggedin' ){
269 |
270 | echo 'User logged in!';
271 | exit;
272 | }
273 | elseif( is_user_logged_in() && isset($_GET['redirect_to']) ){
274 |
275 | if( !empty($_GET['reauth']) && $_GET['reauth'] == '1' ){
276 |
277 | echo 'Error accessing the current session...';
278 | }
279 | else{
280 |
281 | wp_safe_redirect( trim( $_GET['redirect_to'] ) );
282 | }
283 |
284 | exit;
285 | }
286 | elseif( isset($_GET['ussync-token']) && isset($_GET['ussync-id']) && isset($_GET['ussync-ref']) ){
287 |
288 | //decrypted user_name
289 |
290 | $user_name = trim($_GET['ussync-id']);
291 | $user_name = $this->decrypt_uri($user_name);
292 |
293 | //decrypted user_name
294 |
295 | $user_ref = ($_GET['ussync-ref']);
296 |
297 | $user_ref = $this->decrypt_uri($user_ref);
298 |
299 | //decrypted user_email
300 |
301 | $user_email = trim($_GET['ussync-token']);
302 | $user_email = $this->decrypt_uri($user_email);
303 |
304 | //set user ID
305 |
306 | $user_email = sanitize_email($user_email);
307 |
308 | //get domain list
309 |
310 | $domain_list = get_option('ussync_domain_list_'.$this -> key_num);
311 | $domain_list = explode(PHP_EOL,$domain_list);
312 |
313 | //get valid domains
314 |
315 | $domains=[];
316 |
317 | foreach($domain_list as $domain){
318 |
319 | $domain = trim($domain);
320 | $domain = rtrim($domain,'/');
321 | $domain = preg_replace("(^https?://)", "", $domain);
322 |
323 | $domains[$domain]='';
324 | }
325 |
326 | //check referer
327 |
328 | $valid_referer=false;
329 |
330 | if(isset($domains[$user_ref])){
331 |
332 | $valid_referer=true;
333 | }
334 |
335 | if($valid_referer===true){
336 |
337 | if(isset($_GET['ussync-status']) && $_GET['ussync-status']=='loggingout'){
338 |
339 | // Logout user
340 |
341 | if( $user = get_user_by('email', $user_email ) ){
342 |
343 | // get all sessions for user with ID
344 | $sessions = WP_Session_Tokens::get_instance($user->ID);
345 |
346 | // we have got the sessions, destroy them all!
347 | $sessions->destroy_all();
348 |
349 | echo 'User logged out...';
350 | exit;
351 | }
352 | else{
353 |
354 | $this->decrypt_uri($_GET['ussync-token']);
355 |
356 | echo 'Error logging out...';
357 | exit;
358 | }
359 | }
360 | else{
361 |
362 | $current_user = wp_get_current_user();
363 |
364 | if(!is_user_logged_in()){
365 |
366 | // check if the user exists
367 |
368 | if( !email_exists( $user_email ) ){
369 |
370 | $ussync_no_user = get_option('ussync_no_user_'.$this -> key_num);
371 |
372 | if($ussync_no_user=='register_suscriber'){
373 |
374 | // register new suscriber
375 |
376 | $user_data = array(
377 | 'user_login' => $user_name,
378 | 'user_email' => $user_email,
379 | );
380 |
381 | if( get_userdatabylogin($user_name) ){
382 |
383 | echo 'User name already exists!';
384 | exit;
385 | }
386 | elseif( $user_id = wp_insert_user( $user_data ) ) {
387 |
388 | // update email status
389 |
390 | add_user_meta( $user_id, 'ussync_email_verified', 'true');
391 | }
392 | else{
393 |
394 | echo 'Error creating a new user!';
395 | exit;
396 | }
397 | }
398 | else{
399 |
400 | echo 'This user doesn\'t exist...';
401 | exit;
402 | }
403 | }
404 |
405 | // destroy current user session
406 |
407 | $sessions = WP_Session_Tokens::get_instance($current_user->ID);
408 | $sessions->destroy_all();
409 |
410 | // get new user
411 |
412 | $user = get_user_by('email',$user_email);
413 |
414 | if( isset($user->ID) && intval($user->ID) > 0 ){
415 |
416 | //do the authentication
417 |
418 | clean_user_cache($user->ID);
419 |
420 | wp_clear_auth_cookie();
421 | wp_set_current_user( $user->ID );
422 | wp_set_auth_cookie( $user->ID , true, is_ssl());
423 |
424 | update_user_caches($user);
425 |
426 | if(is_user_logged_in()){
427 |
428 | //redirect after authentication
429 |
430 | //wp_safe_redirect( rtrim( get_site_url(), '/' ) . '/?ussync-status=loggedin');
431 |
432 | echo 'User '.$user->ID . ' logged in...';
433 | exit;
434 | }
435 | }
436 | else{
437 |
438 | echo 'Error logging in...';
439 | exit;
440 | }
441 | }
442 | elseif($current_user->user_email != $user_email){
443 |
444 | //wp_mail($dev_email, 'Debug user sync id ' . $current_user->ID . ' - ip ' . $this->user_ip . ' user_email: '. $current_user->user_email .' request email: '. $user_email.' $_SERVER: ' . print_r($_SERVER,true));
445 |
446 | echo 'Another user already logged in...';
447 | exit;
448 | }
449 | else{
450 |
451 | echo 'User already logged in...';
452 | exit;
453 | }
454 | }
455 | }
456 | else{
457 |
458 | echo 'Host not allowed to synchronize...';
459 | exit;
460 | }
461 | }
462 | elseif(is_user_logged_in() && !isset($_GET['ussync-token']) && $this->user_verified === 'true'){
463 |
464 | //add footers
465 |
466 | if( is_admin() ) {
467 |
468 | add_action( 'admin_footer_text', array( $this, 'get_domains' ));
469 | }
470 | else{
471 |
472 | add_action( 'wp_footer', array( $this, 'get_domains' ));
473 | }
474 | }
475 | }
476 |
477 | public function add_cors_header() {
478 |
479 | // Allow from valid origin
480 | /*
481 | if(isset($_SERVER['HTTP_ORIGIN'])) {
482 |
483 | //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
484 | header("Access-Control-Allow-Origin: *");
485 | header('Access-Control-Allow-Credentials: true');
486 | header('Access-Control-Max-Age: 86400'); // cache for 1 day
487 | }
488 |
489 | // Access-Control headers are received during OPTIONS requests
490 |
491 | if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
492 |
493 | if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
494 | header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
495 |
496 | if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
497 | header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
498 |
499 | exit(0);
500 | }
501 | */
502 | }
503 |
504 | public function add_content_security_policy() {
505 |
506 | if( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443 ){
507 |
508 | header("Content-Security-Policy: upgrade-insecure-requests");
509 | }
510 | }
511 |
512 | public function get_domains($loggingout=false){
513 |
514 | if($user = wp_get_current_user()){
515 |
516 | //get list of domains
517 |
518 | $domains = get_option( 'ussync_domain_list_'.$this -> key_num );
519 | $domains = explode( PHP_EOL, $domains );
520 |
521 | //get encrypted user name
522 |
523 | $user_name = $user->user_login;
524 | $user_name = $this->encrypt_uri($user_name);
525 |
526 | //get encrypted user email
527 |
528 | $user_email = $user->user_email;
529 | $user_email = $this->encrypt_uri($user_email);
530 |
531 | //get current domain
532 |
533 | $current_domain = get_site_url();
534 | $current_domain = rtrim($current_domain,'/');
535 | $current_domain = preg_replace("(^https?://)", "", $current_domain);
536 |
537 | //get encrypted user referer
538 |
539 | //$user_ref = $_SERVER['HTTP_HOST'];
540 | $user_ref = $current_domain;
541 | $user_ref = $this->encrypt_uri($user_ref);
542 |
543 | if(!empty($domains)){
544 |
545 | foreach($domains as $domain){
546 |
547 | $domain = trim($domain);
548 | $domain = rtrim($domain,'/');
549 | $domain = preg_replace("(^https?://)", "", $domain);
550 |
551 | if( $loggingout===true ){
552 |
553 | $url = $this -> proto . $domain . '/?ussync-token='.$user_email.'&ussync-key='.$this -> key_num.'&ussync-id='.$user_name.'&ussync-ref='.$user_ref.'&ussync-status=loggingout'.'&_' . time();
554 |
555 | $response = wp_remote_get( $url, array(
556 |
557 | 'timeout' => 5,
558 | 'user-agent' => $this -> user_agent,
559 | 'headers' => array(
560 |
561 | 'X-Forwarded-For' => $this->user_ip
562 | ),
563 | ));
564 | }
565 | elseif($current_domain != $domain){
566 |
567 | //output html
568 |
569 | //echo '
';
570 |
571 | echo'';
572 | }
573 | }
574 |
575 | if( $loggingout === true ){
576 |
577 | wp_logout();
578 |
579 | if(!empty($_GET['redirect_to'])){
580 |
581 | wp_safe_redirect( trim( $_GET['redirect_to'] ) );
582 | }
583 | else{
584 |
585 | wp_safe_redirect( wp_login_url() );
586 | }
587 |
588 | exit;
589 | }
590 | }
591 | }
592 | }
593 |
594 | private function get_secret_iv(){
595 |
596 | //$secret_iv = md5( $this->user_agent . $this->user_ip );
597 | //$secret_iv = md5( $this->user_ip );
598 | $secret_iv = md5( 'another-secret' );
599 |
600 | return $secret_iv;
601 | }
602 |
603 | private function encrypt_str($string){
604 |
605 | $output = false;
606 |
607 | $encrypt_method = "AES-256-CBC";
608 |
609 | $secret_key = md5( $this -> secret_key );
610 |
611 | $secret_iv = $this->get_secret_iv();
612 |
613 | // hash
614 | $key = hash('sha256', $secret_key);
615 |
616 | // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
617 | $iv = substr(hash('sha256', $secret_iv), 0, 16);
618 |
619 | $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
620 | $output = $this->base64_urlencode($output);
621 |
622 | return $output;
623 | }
624 |
625 | private function decrypt_str($string){
626 |
627 | $output = false;
628 |
629 | $encrypt_method = "AES-256-CBC";
630 |
631 | $secret_key = md5( $this->secret_key );
632 |
633 | $secret_iv = $this->get_secret_iv();
634 |
635 | // hash
636 | $key = hash( 'sha256', $secret_key);
637 |
638 | // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
639 | $iv = substr( hash( 'sha256', $secret_iv ), 0, 16);
640 |
641 | $output = openssl_decrypt($this->base64_urldecode($string), $encrypt_method, $key, 0, $iv);
642 |
643 | return $output;
644 | }
645 |
646 | private function encrypt_uri($uri,$len=250,$separator='/'){
647 |
648 | $uri = wordwrap($this->encrypt_str($uri),$len,$separator,true);
649 |
650 | return $uri;
651 | }
652 |
653 | private function decrypt_uri($uri,$separator='/'){
654 |
655 | $uri = $this->decrypt_str(str_replace($separator,'',$uri));
656 |
657 | return $uri;
658 | }
659 |
660 | private function base64_urlencode($inputStr=''){
661 |
662 | return strtr(base64_encode($inputStr), '+/=', '-_,');
663 | }
664 |
665 | private function base64_urldecode($inputStr=''){
666 |
667 | return base64_decode(strtr($inputStr, '-_,', '+/='));
668 | }
669 |
670 | /**
671 | * Wrapper function to register a new post type
672 | * @param string $post_type Post type name
673 | * @param string $plural Post type item plural name
674 | * @param string $single Post type item single name
675 | * @param string $description Description of post type
676 | * @return object Post type class object
677 | */
678 | public function register_post_type ( $post_type = '', $plural = '', $single = '', $description = '', $options = array() ) {
679 |
680 | if ( ! $post_type || ! $plural || ! $single ) return;
681 |
682 | $post_type = new User_Session_Synchronizer_Post_Type( $post_type, $plural, $single, $description, $options );
683 |
684 | return $post_type;
685 | }
686 |
687 | /**
688 | * Wrapper function to register a new taxonomy
689 | * @param string $taxonomy Taxonomy name
690 | * @param string $plural Taxonomy single name
691 | * @param string $single Taxonomy plural name
692 | * @param array $post_types Post types to which this taxonomy applies
693 | * @return object Taxonomy class object
694 | */
695 | public function register_taxonomy ( $taxonomy = '', $plural = '', $single = '', $post_types = array(), $taxonomy_args = array() ) {
696 |
697 | if ( ! $taxonomy || ! $plural || ! $single ) return;
698 |
699 | $taxonomy = new User_Session_Synchronizer_Taxonomy( $taxonomy, $plural, $single, $post_types, $taxonomy_args );
700 |
701 | return $taxonomy;
702 | }
703 |
704 | /**
705 | * Load frontend CSS.
706 | * @access public
707 | * @since 1.0.0
708 | * @return void
709 | */
710 | public function enqueue_styles () {
711 |
712 | wp_register_style( $this->_token . '-frontend', esc_url( $this->assets_url ) . 'css/frontend.css', array(), $this->_version );
713 | wp_enqueue_style( $this->_token . '-frontend' );
714 | } // End enqueue_styles ()
715 |
716 | /**
717 | * Load frontend Javascript.
718 | * @access public
719 | * @since 1.0.0
720 | * @return void
721 | */
722 | public function enqueue_scripts () {
723 | wp_register_script( $this->_token . '-frontend', esc_url( $this->assets_url ) . 'js/frontend' . $this->script_suffix . '.js', array( 'jquery' ), $this->_version );
724 | wp_enqueue_script( $this->_token . '-frontend' );
725 | } // End enqueue_scripts ()
726 |
727 | /**
728 | * Load admin CSS.
729 | * @access public
730 | * @since 1.0.0
731 | * @return void
732 | */
733 | public function admin_enqueue_styles ( $hook = '' ) {
734 | wp_register_style( $this->_token . '-admin', esc_url( $this->assets_url ) . 'css/admin.css', array(), $this->_version );
735 | wp_enqueue_style( $this->_token . '-admin' );
736 | } // End admin_enqueue_styles ()
737 |
738 | /**
739 | * Load admin Javascript.
740 | * @access public
741 | * @since 1.0.0
742 | * @return void
743 | */
744 | public function admin_enqueue_scripts ( $hook = '' ) {
745 | wp_register_script( $this->_token . '-admin', esc_url( $this->assets_url ) . 'js/admin' . $this->script_suffix . '.js', array( 'jquery' ), $this->_version );
746 | wp_enqueue_script( $this->_token . '-admin' );
747 | } // End admin_enqueue_scripts ()
748 |
749 | /**
750 | * Load plugin localisation
751 | * @access public
752 | * @since 1.0.0
753 | * @return void
754 | */
755 | public function load_localisation () {
756 | load_plugin_textdomain( 'user-session-synchronizer', false, dirname( plugin_basename( $this->file ) ) . '/lang/' );
757 | } // End load_localisation ()
758 |
759 | /**
760 | * Load plugin textdomain
761 | * @access public
762 | * @since 1.0.0
763 | * @return void
764 | */
765 | public function load_plugin_textdomain () {
766 | $domain = 'user-session-synchronizer';
767 |
768 | $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
769 |
770 | load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
771 | load_plugin_textdomain( $domain, false, dirname( plugin_basename( $this->file ) ) . '/lang/' );
772 | } // End load_plugin_textdomain ()
773 |
774 | /**
775 | * Main User_Session_Synchronizer Instance
776 | *
777 | * Ensures only one instance of User_Session_Synchronizer is loaded or can be loaded.
778 | *
779 | * @since 1.0.0
780 | * @static
781 | * @see User_Session_Synchronizer()
782 | * @return Main User_Session_Synchronizer instance
783 | */
784 | public static function instance ( $file = '', $version = '1.0.0' ) {
785 | if ( is_null( self::$_instance ) ) {
786 | self::$_instance = new self( $file, $version );
787 | }
788 | return self::$_instance;
789 | } // End instance ()
790 |
791 | /**
792 | * Cloning is forbidden.
793 | *
794 | * @since 1.0.0
795 | */
796 | public function __clone () {
797 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->_version );
798 | } // End __clone ()
799 |
800 | /**
801 | * Unserializing instances of this class is forbidden.
802 | *
803 | * @since 1.0.0
804 | */
805 | public function __wakeup () {
806 | _doing_it_wrong( __FUNCTION__, __( 'Cheatin’ huh?' ), $this->_version );
807 | } // End __wakeup ()
808 |
809 | /**
810 | * Installation. Runs on activation.
811 | * @access public
812 | * @since 1.0.0
813 | * @return void
814 | */
815 | public function install () {
816 | $this->_log_version_number();
817 | } // End install ()
818 |
819 | /**
820 | * Log the plugin version number.
821 | * @access public
822 | * @since 1.0.0
823 | * @return void
824 | */
825 | private function _log_version_number () {
826 | update_option( $this->_token . '_version', $this->_version );
827 | } // End _log_version_number ()
828 | }
829 |
--------------------------------------------------------------------------------
/includes/images/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/includes/images/menu.png
--------------------------------------------------------------------------------
/includes/images/right_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/includes/images/right_arrow.png
--------------------------------------------------------------------------------
/includes/images/send.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/includes/images/send.png
--------------------------------------------------------------------------------
/includes/images/time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/includes/images/time.png
--------------------------------------------------------------------------------
/includes/images/wrong_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/includes/images/wrong_arrow.png
--------------------------------------------------------------------------------
/includes/lib/class-user-session-synchronizer-admin-api.php:
--------------------------------------------------------------------------------
1 | ID, $field['id'], true );
42 |
43 | // Get data to display in field
44 | if ( isset( $option ) ) {
45 | $data = $option;
46 | }
47 |
48 | }
49 | else {
50 |
51 | // Get saved option
52 | $option_name .= $field['id'];
53 | $option = get_option( $option_name );
54 |
55 | // Get data to display in field
56 | if ( isset( $option ) ) {
57 | $data = $option;
58 | }
59 |
60 | }
61 |
62 | // Show default data if no option saved and default is supplied
63 | if ( $data === false && isset( $field['default'] ) ) {
64 | $data = $field['default'];
65 | } elseif ( $data === false ) {
66 | $data = '';
67 | }
68 |
69 | $html = '';
70 |
71 | switch( $field['type'] ) {
72 |
73 | case 'text':
74 | case 'url':
75 | case 'email':
76 | $html .= '' . "\n";
77 | break;
78 |
79 | case 'password':
80 | case 'number':
81 | case 'hidden':
82 | $min = '';
83 | if ( isset( $field['min'] ) ) {
84 | $min = ' min="' . esc_attr( $field['min'] ) . '"';
85 | }
86 |
87 | $max = '';
88 | if ( isset( $field['max'] ) ) {
89 | $max = ' max="' . esc_attr( $field['max'] ) . '"';
90 | }
91 | $html .= '' . "\n";
92 | break;
93 |
94 | case 'text_secret':
95 | $html .= '' . "\n";
96 | break;
97 |
98 | case 'textarea':
99 | $html .= '
'. "\n";
100 | break;
101 |
102 | case 'checkbox':
103 | $checked = '';
104 | if ( $data && 'on' == $data ) {
105 | $checked = 'checked="checked"';
106 | }
107 | $html .= '' . "\n";
108 | break;
109 |
110 | case 'checkbox_multi':
111 | foreach ( $field['options'] as $k => $v ) {
112 | $checked = false;
113 | if ( in_array( $k, (array) $data ) ) {
114 | $checked = true;
115 | }
116 | $html .= ' ';
117 | }
118 | break;
119 |
120 | case 'radio':
121 | foreach ( $field['options'] as $k => $v ) {
122 | $checked = false;
123 | if ( $k == $data ) {
124 | $checked = true;
125 | }
126 | $html .= ' ';
127 | }
128 | break;
129 |
130 | case 'select':
131 | $html .= ' ';
140 | break;
141 |
142 | case 'select_multi':
143 | $html .= ' ';
152 | break;
153 |
154 | case 'image':
155 | $image_thumb = '';
156 | if ( $data ) {
157 | $image_thumb = wp_get_attachment_thumb_url( $data );
158 | }
159 | $html .= '
' . "\n";
160 | $html .= '' . "\n";
161 | $html .= '' . "\n";
162 | $html .= '
' . "\n";
163 | break;
164 |
165 | case 'color':
166 | ?>
170 | ' . $field['description'] . '';
181 | break;
182 |
183 | default:
184 | if ( ! $post ) {
185 | $html .= '' . "\n";
192 | }
193 | break;
194 | }
195 |
196 | if ( ! $echo ) {
197 | return $html;
198 | }
199 |
200 | echo $html;
201 |
202 | }
203 |
204 | /**
205 | * Validate form field
206 | * @param string $data Submitted value
207 | * @param string $type Type of field to validate
208 | * @return string Validated value
209 | */
210 | public function validate_field ( $data = '', $type = 'text' ) {
211 |
212 | switch( $type ) {
213 | case 'text': $data = esc_attr( $data ); break;
214 | case 'url': $data = esc_url( $data ); break;
215 | case 'email': $data = is_email( $data ); break;
216 | }
217 |
218 | return $data;
219 | }
220 |
221 | /**
222 | * Add meta box to the dashboard
223 | * @param string $id Unique ID for metabox
224 | * @param string $title Display title of metabox
225 | * @param array $post_types Post types to which this metabox applies
226 | * @param string $context Context in which to display this metabox ('advanced' or 'side')
227 | * @param string $priority Priority of this metabox ('default', 'low' or 'high')
228 | * @param array $callback_args Any axtra arguments that will be passed to the display function for this metabox
229 | * @return void
230 | */
231 | public function add_meta_box ( $id = '', $title = '', $post_types = array(), $context = 'advanced', $priority = 'default', $callback_args = null ) {
232 |
233 | // Get post type(s)
234 | if ( ! is_array( $post_types ) ) {
235 | $post_types = array( $post_types );
236 | }
237 |
238 | // Generate each metabox
239 | foreach ( $post_types as $post_type ) {
240 | add_meta_box( $id, $title, array( $this, 'meta_box_content' ), $post_type, $context, $priority, $callback_args );
241 | }
242 | }
243 |
244 | /**
245 | * Display metabox content
246 | * @param object $post Post object
247 | * @param array $args Arguments unique to this metabox
248 | * @return void
249 | */
250 | public function meta_box_content ( $post, $args ) {
251 |
252 | $fields = apply_filters( $post->post_type . '_custom_fields', array(), $post->post_type );
253 |
254 | if ( ! is_array( $fields ) || 0 == count( $fields ) ) return;
255 |
256 | echo '' . "\n";
257 |
258 | foreach ( $fields as $field ) {
259 |
260 | if ( ! isset( $field['metabox'] ) ) continue;
261 |
262 | if ( ! is_array( $field['metabox'] ) ) {
263 | $field['metabox'] = array( $field['metabox'] );
264 | }
265 |
266 | if ( in_array( $args['id'], $field['metabox'] ) ) {
267 | $this->display_meta_box_field( $field, $post );
268 | }
269 |
270 | }
271 |
272 | echo '
' . "\n";
273 |
274 | }
275 |
276 | /**
277 | * Dispay field in metabox
278 | * @param array $field Field data
279 | * @param object $post Post object
280 | * @return void
281 | */
282 | public function display_meta_box_field ( $field = array(), $post ) {
283 |
284 | if ( ! is_array( $field ) || 0 == count( $field ) ) return;
285 |
286 | $field = '' . $this->display_field( $field, $post, false ) . '
' . "\n";
287 |
288 | echo $field;
289 | }
290 |
291 | /**
292 | * Save metabox fields
293 | * @param integer $post_id Post ID
294 | * @return void
295 | */
296 | public function save_meta_boxes ( $post_id = 0 ) {
297 |
298 | if( !$post_id || ( isset($_POST['_inline_edit']) && wp_verify_nonce($_POST['_inline_edit'],'inlineeditnonce') ) ) return;
299 |
300 | $post_type = get_post_type( $post_id );
301 |
302 | $fields = apply_filters( $post_type . '_custom_fields', array(), $post_type );
303 |
304 | if ( ! is_array( $fields ) || 0 == count( $fields ) ) return;
305 |
306 | foreach ( $fields as $field ) {
307 | if ( isset( $_REQUEST[ $field['id'] ] ) ) {
308 | update_post_meta( $post_id, $field['id'], $this->validate_field( $_REQUEST[ $field['id'] ], $field['type'] ) );
309 | } else {
310 | update_post_meta( $post_id, $field['id'], '' );
311 | }
312 | }
313 | }
314 |
315 | }
--------------------------------------------------------------------------------
/includes/lib/class-user-session-synchronizer-post-type.php:
--------------------------------------------------------------------------------
1 | post_type = $post_type;
53 | $this->plural = $plural;
54 | $this->single = $single;
55 | $this->description = $description;
56 | $this->options = $options;
57 |
58 | // Regsiter post type
59 | add_action( 'init' , array( $this, 'register_post_type' ) );
60 |
61 | // Display custom update messages for posts edits
62 | add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );
63 | add_filter( 'bulk_post_updated_messages', array( $this, 'bulk_updated_messages' ), 10, 2 );
64 | }
65 |
66 | /**
67 | * Register new post type
68 | * @return void
69 | */
70 | public function register_post_type () {
71 |
72 | $labels = array(
73 | 'name' => $this->plural,
74 | 'singular_name' => $this->single,
75 | 'name_admin_bar' => $this->single,
76 | 'add_new' => _x( 'Add New', $this->post_type , 'user-session-synchronizer' ),
77 | 'add_new_item' => sprintf( __( 'Add New %s' , 'user-session-synchronizer' ), $this->single ),
78 | 'edit_item' => sprintf( __( 'Edit %s' , 'user-session-synchronizer' ), $this->single ),
79 | 'new_item' => sprintf( __( 'New %s' , 'user-session-synchronizer' ), $this->single ),
80 | 'all_items' => sprintf( __( 'All %s' , 'user-session-synchronizer' ), $this->plural ),
81 | 'view_item' => sprintf( __( 'View %s' , 'user-session-synchronizer' ), $this->single ),
82 | 'search_items' => sprintf( __( 'Search %s' , 'user-session-synchronizer' ), $this->plural ),
83 | 'not_found' => sprintf( __( 'No %s Found' , 'user-session-synchronizer' ), $this->plural ),
84 | 'not_found_in_trash' => sprintf( __( 'No %s Found In Trash' , 'user-session-synchronizer' ), $this->plural ),
85 | 'parent_item_colon' => sprintf( __( 'Parent %s' ), $this->single ),
86 | 'menu_name' => $this->plural,
87 | );
88 |
89 | $args = array(
90 | 'labels' => apply_filters( $this->post_type . '_labels', $labels ),
91 | 'description' => $this->description,
92 | 'public' => true,
93 | 'publicly_queryable' => true,
94 | 'exclude_from_search' => false,
95 | 'show_ui' => true,
96 | 'show_in_menu' => true,
97 | 'show_in_nav_menus' => true,
98 | 'query_var' => true,
99 | 'can_export' => true,
100 | 'rewrite' => true,
101 | 'capability_type' => 'post',
102 | 'has_archive' => true,
103 | 'hierarchical' => true,
104 | 'show_in_rest' => true,
105 | 'rest_base' => $this->post_type,
106 | 'rest_controller_class' => 'WP_REST_Posts_Controller',
107 | 'supports' => array( 'title', 'editor', 'excerpt', 'comments', 'thumbnail' ),
108 | 'menu_position' => 5,
109 | 'menu_icon' => 'dashicons-admin-post',
110 | );
111 |
112 | $args = array_merge($args, $this->options);
113 |
114 | register_post_type( $this->post_type, apply_filters( $this->post_type . '_register_args', $args, $this->post_type ) );
115 | }
116 |
117 | /**
118 | * Set up admin messages for post type
119 | * @param array $messages Default message
120 | * @return array Modified messages
121 | */
122 | public function updated_messages ( $messages = array() ) {
123 | global $post, $post_ID;
124 |
125 | $messages[ $this->post_type ] = array(
126 | 0 => '',
127 | 1 => sprintf( __( '%1$s updated. %2$sView %3$s%4$s.' , 'user-session-synchronizer' ), $this->single, '', $this->single, '' ),
128 | 2 => __( 'Custom field updated.' , 'user-session-synchronizer' ),
129 | 3 => __( 'Custom field deleted.' , 'user-session-synchronizer' ),
130 | 4 => sprintf( __( '%1$s updated.' , 'user-session-synchronizer' ), $this->single ),
131 | 5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s.' , 'user-session-synchronizer' ), $this->single, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
132 | 6 => sprintf( __( '%1$s published. %2$sView %3$s%4s.' , 'user-session-synchronizer' ), $this->single, '', $this->single, '' ),
133 | 7 => sprintf( __( '%1$s saved.' , 'user-session-synchronizer' ), $this->single ),
134 | 8 => sprintf( __( '%1$s submitted. %2$sPreview post%3$s%4$s.' , 'user-session-synchronizer' ), $this->single, '', $this->single, '' ),
135 | 9 => sprintf( __( '%1$s scheduled for: %2$s. %3$sPreview %4$s%5$s.' , 'user-session-synchronizer' ), $this->single, '' . date_i18n( __( 'M j, Y @ G:i' , 'user-session-synchronizer' ), strtotime( $post->post_date ) ) . '', '', $this->single, '' ),
136 | 10 => sprintf( __( '%1$s draft updated. %2$sPreview %3$s%4$s.' , 'user-session-synchronizer' ), $this->single, '', $this->single, '' ),
137 | );
138 |
139 | return $messages;
140 | }
141 |
142 | /**
143 | * Set up bulk admin messages for post type
144 | * @param array $bulk_messages Default bulk messages
145 | * @param array $bulk_counts Counts of selected posts in each status
146 | * @return array Modified messages
147 | */
148 | public function bulk_updated_messages ( $bulk_messages = array(), $bulk_counts = array() ) {
149 |
150 | $bulk_messages[ $this->post_type ] = array(
151 | 'updated' => sprintf( _n( '%1$s %2$s updated.', '%1$s %3$s updated.', $bulk_counts['updated'], 'user-session-synchronizer' ), $bulk_counts['updated'], $this->single, $this->plural ),
152 | 'locked' => sprintf( _n( '%1$s %2$s not updated, somebody is editing it.', '%1$s %3$s not updated, somebody is editing them.', $bulk_counts['locked'], 'user-session-synchronizer' ), $bulk_counts['locked'], $this->single, $this->plural ),
153 | 'deleted' => sprintf( _n( '%1$s %2$s permanently deleted.', '%1$s %3$s permanently deleted.', $bulk_counts['deleted'], 'user-session-synchronizer' ), $bulk_counts['deleted'], $this->single, $this->plural ),
154 | 'trashed' => sprintf( _n( '%1$s %2$s moved to the Trash.', '%1$s %3$s moved to the Trash.', $bulk_counts['trashed'], 'user-session-synchronizer' ), $bulk_counts['trashed'], $this->single, $this->plural ),
155 | 'untrashed' => sprintf( _n( '%1$s %2$s restored from the Trash.', '%1$s %3$s restored from the Trash.', $bulk_counts['untrashed'], 'user-session-synchronizer' ), $bulk_counts['untrashed'], $this->single, $this->plural ),
156 | );
157 |
158 | return $bulk_messages;
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/includes/lib/class-user-session-synchronizer-taxonomy.php:
--------------------------------------------------------------------------------
1 | taxonomy = $taxonomy;
53 | $this->plural = $plural;
54 | $this->single = $single;
55 | if ( ! is_array( $post_types ) ) {
56 | $post_types = array( $post_types );
57 | }
58 | $this->post_types = $post_types;
59 | $this->taxonomy_args = $tax_args;
60 |
61 | // Register taxonomy
62 | add_action('init', array( $this, 'register_taxonomy' ) );
63 | }
64 |
65 | /**
66 | * Register new taxonomy
67 | * @return void
68 | */
69 | public function register_taxonomy () {
70 |
71 | $labels = array(
72 | 'name' => $this->plural,
73 | 'singular_name' => $this->single,
74 | 'menu_name' => $this->plural,
75 | 'all_items' => sprintf( __( 'All %s' , 'user-session-synchronizer' ), $this->plural ),
76 | 'edit_item' => sprintf( __( 'Edit %s' , 'user-session-synchronizer' ), $this->single ),
77 | 'view_item' => sprintf( __( 'View %s' , 'user-session-synchronizer' ), $this->single ),
78 | 'update_item' => sprintf( __( 'Update %s' , 'user-session-synchronizer' ), $this->single ),
79 | 'add_new_item' => sprintf( __( 'Add New %s' , 'user-session-synchronizer' ), $this->single ),
80 | 'new_item_name' => sprintf( __( 'New %s Name' , 'user-session-synchronizer' ), $this->single ),
81 | 'parent_item' => sprintf( __( 'Parent %s' , 'user-session-synchronizer' ), $this->single ),
82 | 'parent_item_colon' => sprintf( __( 'Parent %s:' , 'user-session-synchronizer' ), $this->single ),
83 | 'search_items' => sprintf( __( 'Search %s' , 'user-session-synchronizer' ), $this->plural ),
84 | 'popular_items' => sprintf( __( 'Popular %s' , 'user-session-synchronizer' ), $this->plural ),
85 | 'separate_items_with_commas' => sprintf( __( 'Separate %s with commas' , 'user-session-synchronizer' ), $this->plural ),
86 | 'add_or_remove_items' => sprintf( __( 'Add or remove %s' , 'user-session-synchronizer' ), $this->plural ),
87 | 'choose_from_most_used' => sprintf( __( 'Choose from the most used %s' , 'user-session-synchronizer' ), $this->plural ),
88 | 'not_found' => sprintf( __( 'No %s found' , 'user-session-synchronizer' ), $this->plural ),
89 | );
90 |
91 | $args = array(
92 | 'label' => $this->plural,
93 | 'labels' => apply_filters( $this->taxonomy . '_labels', $labels ),
94 | 'hierarchical' => true,
95 | 'public' => true,
96 | 'show_ui' => true,
97 | 'show_in_nav_menus' => true,
98 | 'show_tagcloud' => true,
99 | 'meta_box_cb' => null,
100 | 'show_admin_column' => true,
101 | 'update_count_callback' => '',
102 | 'show_in_rest' => true,
103 | 'rest_base' => $this->taxonomy,
104 | 'rest_controller_class' => 'WP_REST_Terms_Controller',
105 | 'query_var' => $this->taxonomy,
106 | 'rewrite' => true,
107 | 'sort' => '',
108 | );
109 |
110 | $args = array_merge($args, $this->taxonomy_args);
111 |
112 | register_taxonomy( $this->taxonomy, $this->post_types, apply_filters( $this->taxonomy . '_register_args', $args, $this->taxonomy, $this->post_types ) );
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/includes/views/demo_email.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Email Verification |
5 |
6 |
7 |
8 |
9 | Please Verify your email Account: |
10 |
11 |
12 | [ussyncemailverificationcode] |
13 |
14 |
15 |
16 |
17 | (c) 2000-2016 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/includes/views/email-setting.php:
--------------------------------------------------------------------------------
1 | activate_plugins_email();
19 |
20 | $email_title=get_option("ussync_email_conf_title");
21 | $email_sender=get_option("ussync_email_confemail");
22 | $email_content=get_option("ussync-email-header");
23 | }
24 | ?>
25 |
56 |
57 |
58 |
Email Verification Template Settings
59 | $value) {
62 | update_option($ussync_em_key, stripslashes($value));
63 | }
64 | echo "
Template Is saved
";
65 | }
66 | // echo do_shortcode("[ussyncemailverificationcode]");
67 | ?>
68 |
88 |
89 |
90 |
91 | [ussyncemailverificationcode]
");?>
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/includes/views/email-verification.php:
--------------------------------------------------------------------------------
1 |
32 |
57 |
58 |
User Email Verification
59 |
72 |
73 |
--------------------------------------------------------------------------------
/includes/views/logging-in.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Loading...
8 |
9 |
10 |
11 |
12 |
13 | get_domains(); ?>
14 |
15 | Loading...
16 |
17 |
18 |
19 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | \n"
13 | "Language-Team: LANGUAGE \n"
14 |
15 | #: classes/post-types/class-user-session-synchronizer-post_type.php:52
16 | #: includes/post-types/class-user-session-synchronizer-post_type.php:42
17 | msgctxt "post type general name"
18 | msgid "Post Type"
19 | msgstr ""
20 |
21 | #: classes/post-types/class-user-session-synchronizer-post_type.php:53
22 | #: includes/post-types/class-user-session-synchronizer-post_type.php:43
23 | msgctxt "post type singular name"
24 | msgid "Post Type"
25 | msgstr ""
26 |
27 | #: classes/post-types/class-user-session-synchronizer-post_type.php:55
28 | #: includes/post-types/class-user-session-synchronizer-post_type.php:45
29 | msgid "Add New %s"
30 | msgstr ""
31 |
32 | #: classes/post-types/class-user-session-synchronizer-post_type.php:55
33 | #: classes/post-types/class-user-session-synchronizer-post_type.php:56
34 | #: classes/post-types/class-user-session-synchronizer-post_type.php:57
35 | #: classes/post-types/class-user-session-synchronizer-post_type.php:59
36 | #: includes/post-types/class-user-session-synchronizer-post_type.php:45
37 | #: includes/post-types/class-user-session-synchronizer-post_type.php:46
38 | #: includes/post-types/class-user-session-synchronizer-post_type.php:47
39 | #: includes/post-types/class-user-session-synchronizer-post_type.php:49
40 | msgid "Post"
41 | msgstr ""
42 |
43 | #: classes/post-types/class-user-session-synchronizer-post_type.php:56
44 | #: includes/post-types/class-user-session-synchronizer-post_type.php:46
45 | msgid "Edit %s"
46 | msgstr ""
47 |
48 | #: classes/post-types/class-user-session-synchronizer-post_type.php:57
49 | #: includes/post-types/class-user-session-synchronizer-post_type.php:47
50 | msgid "New %s"
51 | msgstr ""
52 |
53 | #: classes/post-types/class-user-session-synchronizer-post_type.php:58
54 | #: includes/post-types/class-user-session-synchronizer-post_type.php:48
55 | msgid "All %s"
56 | msgstr ""
57 |
58 | #: classes/post-types/class-user-session-synchronizer-post_type.php:58
59 | #: classes/post-types/class-user-session-synchronizer-post_type.php:60
60 | #: classes/post-types/class-user-session-synchronizer-post_type.php:61
61 | #: classes/post-types/class-user-session-synchronizer-post_type.php:62
62 | #: includes/post-types/class-user-session-synchronizer-post_type.php:48
63 | #: includes/post-types/class-user-session-synchronizer-post_type.php:50
64 | #: includes/post-types/class-user-session-synchronizer-post_type.php:51
65 | #: includes/post-types/class-user-session-synchronizer-post_type.php:52
66 | msgid "Posts"
67 | msgstr ""
68 |
69 | #: classes/post-types/class-user-session-synchronizer-post_type.php:59
70 | #: includes/post-types/class-user-session-synchronizer-post_type.php:49
71 | msgid "View %s"
72 | msgstr ""
73 |
74 | #: classes/post-types/class-user-session-synchronizer-post_type.php:60
75 | #: includes/post-types/class-user-session-synchronizer-post_type.php:50
76 | msgid "Search %a"
77 | msgstr ""
78 |
79 | #: classes/post-types/class-user-session-synchronizer-post_type.php:61
80 | #: includes/post-types/class-user-session-synchronizer-post_type.php:51
81 | msgid "No %s Found"
82 | msgstr ""
83 |
84 | #: classes/post-types/class-user-session-synchronizer-post_type.php:62
85 | #: includes/post-types/class-user-session-synchronizer-post_type.php:52
86 | msgid "No %s Found In Trash"
87 | msgstr ""
88 |
89 | #: classes/post-types/class-user-session-synchronizer-post_type.php:64
90 | #: includes/post-types/class-user-session-synchronizer-post_type.php:54
91 | msgid "*Posts"
92 | msgstr ""
93 |
94 | #: classes/post-types/class-user-session-synchronizer-post_type.php:95
95 | #: classes/post-types/class-user-session-synchronizer-post_type.php:105
96 | #: includes/post-types/class-user-session-synchronizer-post_type.php:85
97 | #: includes/post-types/class-user-session-synchronizer-post_type.php:95
98 | msgid "Terms"
99 | msgstr ""
100 |
101 | #: classes/post-types/class-user-session-synchronizer-post_type.php:96
102 | #: includes/post-types/class-user-session-synchronizer-post_type.php:86
103 | msgid "Term"
104 | msgstr ""
105 |
106 | #: classes/post-types/class-user-session-synchronizer-post_type.php:97
107 | #: includes/post-types/class-user-session-synchronizer-post_type.php:87
108 | msgid "Search Terms"
109 | msgstr ""
110 |
111 | #: classes/post-types/class-user-session-synchronizer-post_type.php:98
112 | #: includes/post-types/class-user-session-synchronizer-post_type.php:88
113 | msgid "All Terms"
114 | msgstr ""
115 |
116 | #: classes/post-types/class-user-session-synchronizer-post_type.php:99
117 | #: includes/post-types/class-user-session-synchronizer-post_type.php:89
118 | msgid "Parent Term"
119 | msgstr ""
120 |
121 | #: classes/post-types/class-user-session-synchronizer-post_type.php:100
122 | #: includes/post-types/class-user-session-synchronizer-post_type.php:90
123 | msgid "Parent Term:"
124 | msgstr ""
125 |
126 | #: classes/post-types/class-user-session-synchronizer-post_type.php:101
127 | #: includes/post-types/class-user-session-synchronizer-post_type.php:91
128 | msgid "Edit Term"
129 | msgstr ""
130 |
131 | #: classes/post-types/class-user-session-synchronizer-post_type.php:102
132 | #: includes/post-types/class-user-session-synchronizer-post_type.php:92
133 | msgid "Update Term"
134 | msgstr ""
135 |
136 | #: classes/post-types/class-user-session-synchronizer-post_type.php:103
137 | #: includes/post-types/class-user-session-synchronizer-post_type.php:93
138 | msgid "Add New Term"
139 | msgstr ""
140 |
141 | #: classes/post-types/class-user-session-synchronizer-post_type.php:104
142 | #: includes/post-types/class-user-session-synchronizer-post_type.php:94
143 | msgid "New Term Name"
144 | msgstr ""
145 |
146 | #: classes/post-types/class-user-session-synchronizer-post_type.php:125
147 | #: includes/post-types/class-user-session-synchronizer-post_type.php:115
148 | msgid "Custom Field"
149 | msgstr ""
150 |
151 | #: classes/post-types/class-user-session-synchronizer-post_type.php:180
152 | #: includes/post-types/class-user-session-synchronizer-post_type.php:170
153 | msgid "Post updated. %sView post%s."
154 | msgstr ""
155 |
156 | #: classes/post-types/class-user-session-synchronizer-post_type.php:181
157 | #: includes/post-types/class-user-session-synchronizer-post_type.php:171
158 | msgid "Custom field updated."
159 | msgstr ""
160 |
161 | #: classes/post-types/class-user-session-synchronizer-post_type.php:182
162 | #: includes/post-types/class-user-session-synchronizer-post_type.php:172
163 | msgid "Custom field deleted."
164 | msgstr ""
165 |
166 | #: classes/post-types/class-user-session-synchronizer-post_type.php:183
167 | #: includes/post-types/class-user-session-synchronizer-post_type.php:173
168 | msgid "Post updated."
169 | msgstr ""
170 |
171 | #. translators: %s: date and time of the revision
172 |
173 | #: classes/post-types/class-user-session-synchronizer-post_type.php:185
174 | #: includes/post-types/class-user-session-synchronizer-post_type.php:175
175 | msgid "Post restored to revision from %s."
176 | msgstr ""
177 |
178 | #: classes/post-types/class-user-session-synchronizer-post_type.php:186
179 | #: includes/post-types/class-user-session-synchronizer-post_type.php:176
180 | msgid "Post published. %sView post%s."
181 | msgstr ""
182 |
183 | #: classes/post-types/class-user-session-synchronizer-post_type.php:187
184 | #: includes/post-types/class-user-session-synchronizer-post_type.php:177
185 | msgid "Post saved."
186 | msgstr ""
187 |
188 | #: classes/post-types/class-user-session-synchronizer-post_type.php:188
189 | #: includes/post-types/class-user-session-synchronizer-post_type.php:178
190 | msgid "Post submitted. %sPreview post%s."
191 | msgstr ""
192 |
193 | #: classes/post-types/class-user-session-synchronizer-post_type.php:189
194 | #: includes/post-types/class-user-session-synchronizer-post_type.php:179
195 | msgid "Post scheduled for: %1$s. %2$sPreview post%3$s."
196 | msgstr ""
197 |
198 | #: classes/post-types/class-user-session-synchronizer-post_type.php:189
199 | #: includes/post-types/class-user-session-synchronizer-post_type.php:179
200 | msgid "M j, Y @ G:i"
201 | msgstr ""
202 |
203 | #: classes/post-types/class-user-session-synchronizer-post_type.php:190
204 | #: includes/post-types/class-user-session-synchronizer-post_type.php:180
205 | msgid "Post draft updated. %sPreview post%s."
206 | msgstr ""
207 |
208 | #: classes/post-types/class-user-session-synchronizer-post_type.php:201
209 | #: includes/post-types/class-user-session-synchronizer-post_type.php:191
210 | msgid "Post Details"
211 | msgstr ""
212 |
213 | #: classes/post-types/class-user-session-synchronizer-post_type.php:295
214 | #: includes/post-types/class-user-session-synchronizer-post_type.php:285
215 | msgid "Enter the post title here"
216 | msgstr ""
217 |
218 | #: classes/post-types/class-user-session-synchronizer-post_type.php:308
219 | #: includes/post-types/class-user-session-synchronizer-post_type.php:298
220 | msgid "Custom field:"
221 | msgstr ""
222 |
223 | #: classes/post-types/class-user-session-synchronizer-post_type.php:309
224 | #: includes/post-types/class-user-session-synchronizer-post_type.php:299
225 | msgid "Description of this custom field."
226 | msgstr ""
227 |
228 | #: includes/class-user-session-synchronizer-settings.php:70
229 | #: includes/class-user-session-synchronizer-settings.php:405
230 | msgid "User Session Synchronizer"
231 | msgstr ""
232 |
233 | #: includes/class-user-session-synchronizer-settings.php:99
234 | msgid "Settings"
235 | msgstr ""
236 |
237 | #: includes/class-user-session-synchronizer-settings.php:111
238 | msgid "Standard"
239 | msgstr ""
240 |
241 | #: includes/class-user-session-synchronizer-settings.php:112
242 | msgid "These are fairly standard form input fields."
243 | msgstr ""
244 |
245 | #: includes/class-user-session-synchronizer-settings.php:116
246 | msgid "Some Text"
247 | msgstr ""
248 |
249 | #: includes/class-user-session-synchronizer-settings.php:117
250 | msgid "This is a standard text field."
251 | msgstr ""
252 |
253 | #: includes/class-user-session-synchronizer-settings.php:120
254 | #: includes/class-user-session-synchronizer-settings.php:128
255 | #: includes/class-user-session-synchronizer-settings.php:136
256 | msgid "Placeholder text"
257 | msgstr ""
258 |
259 | #: includes/class-user-session-synchronizer-settings.php:124
260 | msgid "A Password"
261 | msgstr ""
262 |
263 | #: includes/class-user-session-synchronizer-settings.php:125
264 | msgid "This is a standard password field."
265 | msgstr ""
266 |
267 | #: includes/class-user-session-synchronizer-settings.php:132
268 | msgid "Some Secret Text"
269 | msgstr ""
270 |
271 | #: includes/class-user-session-synchronizer-settings.php:133
272 | msgid "This is a secret text field - any data saved here will not be displayed after the page has reloaded, but it will be saved."
273 | msgstr ""
274 |
275 | #: includes/class-user-session-synchronizer-settings.php:140
276 | msgid "A Text Block"
277 | msgstr ""
278 |
279 | #: includes/class-user-session-synchronizer-settings.php:141
280 | msgid "This is a standard text area."
281 | msgstr ""
282 |
283 | #: includes/class-user-session-synchronizer-settings.php:144
284 | msgid "Placeholder text for this textarea"
285 | msgstr ""
286 |
287 | #: includes/class-user-session-synchronizer-settings.php:148
288 | msgid "An Option"
289 | msgstr ""
290 |
291 | #: includes/class-user-session-synchronizer-settings.php:149
292 | msgid "A standard checkbox - if you save this option as checked then it will store the option as 'on', otherwise it will be an empty string."
293 | msgstr ""
294 |
295 | #: includes/class-user-session-synchronizer-settings.php:155
296 | msgid "A Select Box"
297 | msgstr ""
298 |
299 | #: includes/class-user-session-synchronizer-settings.php:156
300 | msgid "A standard select box."
301 | msgstr ""
302 |
303 | #: includes/class-user-session-synchronizer-settings.php:163
304 | msgid "Some Options"
305 | msgstr ""
306 |
307 | #: includes/class-user-session-synchronizer-settings.php:164
308 | msgid "A standard set of radio buttons."
309 | msgstr ""
310 |
311 | #: includes/class-user-session-synchronizer-settings.php:171
312 | msgid "Some Items"
313 | msgstr ""
314 |
315 | #: includes/class-user-session-synchronizer-settings.php:172
316 | msgid "You can select multiple items and they will be stored as an array."
317 | msgstr ""
318 |
319 | #: includes/class-user-session-synchronizer-settings.php:181
320 | msgid "Extra"
321 | msgstr ""
322 |
323 | #: includes/class-user-session-synchronizer-settings.php:182
324 | msgid "These are some extra input fields that maybe aren't as common as the others."
325 | msgstr ""
326 |
327 | #: includes/class-user-session-synchronizer-settings.php:186
328 | msgid "A Number"
329 | msgstr ""
330 |
331 | #: includes/class-user-session-synchronizer-settings.php:187
332 | msgid "This is a standard number field - if this field contains anything other than numbers then the form will not be submitted."
333 | msgstr ""
334 |
335 | #: includes/class-user-session-synchronizer-settings.php:190
336 | msgid "42"
337 | msgstr ""
338 |
339 | #: includes/class-user-session-synchronizer-settings.php:194
340 | msgid "Pick a colour"
341 | msgstr ""
342 |
343 | #: includes/class-user-session-synchronizer-settings.php:195
344 | msgid "This uses WordPress' built-in colour picker - the option is stored as the colour's hex code."
345 | msgstr ""
346 |
347 | #: includes/class-user-session-synchronizer-settings.php:201
348 | msgid "An Image"
349 | msgstr ""
350 |
351 | #: includes/class-user-session-synchronizer-settings.php:202
352 | msgid "This will upload an image to your media library and store the attachment ID in the option field. Once you have uploaded an imge the thumbnail will display above these buttons."
353 | msgstr ""
354 |
355 | #: includes/class-user-session-synchronizer-settings.php:209
356 | msgid "A Multi-Select Box"
357 | msgstr ""
358 |
359 | #: includes/class-user-session-synchronizer-settings.php:210
360 | msgid "A standard multi-select box - the saved data is stored as an array."
361 | msgstr ""
362 |
363 | #: includes/class-user-session-synchronizer-settings.php:354
364 | msgid "Upload an image"
365 | msgstr ""
366 |
367 | #: includes/class-user-session-synchronizer-settings.php:354
368 | msgid "Use image"
369 | msgstr ""
370 |
371 | #: includes/class-user-session-synchronizer-settings.php:354
372 | msgid "Upload new image"
373 | msgstr ""
374 |
375 | #: includes/class-user-session-synchronizer-settings.php:355
376 | msgid "Remove image"
377 | msgstr ""
378 |
379 | #: includes/class-user-session-synchronizer-settings.php:410
380 | msgid "All"
381 | msgstr ""
382 |
383 | #: includes/class-user-session-synchronizer-settings.php:427
384 | msgid "Save Settings"
385 | msgstr ""
386 |
387 | #: includes/class-user-session-synchronizer-settings.php:458
388 | #: includes/class-user-session-synchronizer-settings.php:467
389 | #: includes/class-user-session-synchronizer.php:207
390 | #: includes/class-user-session-synchronizer.php:216
391 | msgid "Cheatin’ huh?"
392 | msgstr ""
393 | #. Plugin Name of the plugin/theme
394 | msgid "User Session Synchronizer"
395 | msgstr ""
396 |
397 | #. Plugin URI of the plugin/theme
398 | msgid "https://github.com/rafasashi/user-session-synchronizer/archive/master.zip"
399 | msgstr ""
400 |
401 | #. Author of the plugin/theme
402 | msgid "Hugh Lashbrooke"
403 | msgstr ""
404 |
405 | #. Author URI of the plugin/theme
406 | msgid "http://www.hugrafasashi.com/"
407 | msgstr ""
408 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === User Session Synchronizer ===
2 | Contributors: rafasashi
3 | Donate link: https://code.recuweb.com/get/user-session-synchronizer/
4 | Tags: user, session, synchronizer, cookie
5 | Requires at least: 4.3
6 | Tested up to: 6.2
7 | Stable tag: 1.4.0
8 | License: GPLv3 or later
9 | License URI: http://www.gnu.org/licenses/gpl-3.0.html
10 |
11 | Keep the user logged in from one wordpress to another by synchronizing user data and cookie session
12 |
13 | == Description ==
14 |
15 | User Session Synchronizer allows you to keep the user logged in from one wordpress to another by synchronizing user data and cookie session based on a verified email.
16 | The user email is encrypted based on the current user ip and a secret key shared by the synchronized wordpress installations.
17 |
18 | = Features =
19 |
20 | - Synchronize session between installations
21 | - Verify user email through new registration
22 | - Verify user email through manual admin action
23 | - Verify user email through email verification code
24 | - Prevent user form changing email
25 | - Display historical sessions
26 | - Auto add new subscriber if user doesn't exist
27 | - Destroy session everywhere on logging out
28 |
29 | = Upcoming =
30 |
31 | - Multiple secret keys & networks
32 | - Enable ajax cross-domain requests
33 |
34 | == Installation ==
35 |
36 | Installing "User Session Synchronizer" can be done either by searching for "User Session Synchronizer" via the "Plugins > Add New" screen in your WordPress dashboard, or by using the following steps:
37 |
38 | 1. Download the plugin via WordPress.org
39 | 2. Upload the ZIP file through the 'Plugins > Add New > Upload' screen in your WordPress dashboard
40 | 3. Activate the plugin through the 'Plugins' menu in WordPress
41 | 4. Set your first Secret Key throught the 'User Session Sync > Keys'
42 | 5. Repeat this installation process for every Wordpress you wish to sychnorize with the same Secret Key
43 |
44 | == Screenshots ==
45 |
46 | 1. https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/master/screenshot_1.png
47 | 2. https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/master/screenshot_2.png
48 | 3. https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/master/screenshot_3.png
49 | 4. https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/master/screenshot_4.png
50 |
51 | == Frequently Asked Questions ==
52 |
53 | = What is the plugin template for? =
54 |
55 | This plugin template is designed to Keep the user logged in from one wordpress to another by synchronizing user data and cookie session
56 |
57 | == Changelog ==
58 |
59 | = 1.3.8 =
60 |
61 | * 2017-05-26
62 | * logout bug fixed
63 |
64 | = 1.3.7 =
65 |
66 | * 2017-05-16
67 | * activate plugin email fixed
68 |
69 | = 1.3.6 =
70 |
71 | * 2017-03-14
72 | * Logout everywhere fixed
73 | * Infinit loop fixed on SSL auth
74 |
75 | = 1.3.5 =
76 |
77 | * 2017-02-09
78 | * Content-Security-Policy implementation
79 | * HTTPS supported
80 |
81 | = 1.3.4 =
82 |
83 | * 2017-01-27
84 | * User IP detection improved
85 | * Synchronization via iframe instead of image
86 |
87 | = 1.3.3 =
88 |
89 | * 2016-10-26
90 | * Resend validation email improved
91 |
92 | = 1.3.2 =
93 |
94 | * 2016-10-14
95 | * Issue regarding email validation corrected
96 |
97 | = 1.3.1 =
98 |
99 | * 2016-09-26
100 | * Multiple Logout issues corrected
101 |
102 | = 1.2 =
103 | * 2016-09-26
104 | * Multiple subfolders under same domain
105 |
106 | = 1.1 =
107 | * 2016-09-22
108 | * Theme footer hooked
109 |
110 | = 1.0 =
111 | * 2016-09-02
112 | * Initial release
113 |
114 | == Upgrade Notice ==
115 |
116 | = 1.0 =
117 | * 2016-09-02
118 | * Initial release
119 |
--------------------------------------------------------------------------------
/screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/screenshot_1.png
--------------------------------------------------------------------------------
/screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/screenshot_2.png
--------------------------------------------------------------------------------
/screenshot_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/screenshot_3.png
--------------------------------------------------------------------------------
/screenshot_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rafasashi/user-session-synchronizer/ebc2ba63e33266448b6954c0343243e8b4e14250/screenshot_4.png
--------------------------------------------------------------------------------
/uninstall.php:
--------------------------------------------------------------------------------
1 | ' . __( 'Donate', 'cleanlogin' ) . '' );
35 | $links = array_merge( $links, $new_links );
36 | }
37 | return $links;
38 | }
39 | add_filter('plugin_row_meta', 'user_session_synchronizer_row_meta', 10, 2);
40 |
41 | // Load plugin class files
42 | require_once( 'includes/class-user-session-synchronizer.php' );
43 | require_once( 'includes/class-user-session-synchronizer-email-verification.php' );
44 | require_once( 'includes/class-user-session-synchronizer-settings.php' );
45 | require_once( 'includes/class-user-session-synchronizer-session-control.php' );
46 |
47 | // Load plugin libraries
48 | require_once( 'includes/lib/class-user-session-synchronizer-admin-api.php' );
49 | require_once( 'includes/lib/class-user-session-synchronizer-post-type.php' );
50 | require_once( 'includes/lib/class-user-session-synchronizer-taxonomy.php' );
51 |
52 | /**
53 | * Returns the main instance of User_Session_Synchronizer to prevent the need to use globals.
54 | *
55 | * @since 1.0.0
56 | * @return object User_Session_Synchronizer
57 | */
58 | function User_Session_Synchronizer () {
59 |
60 | $instance = User_Session_Synchronizer::instance( __FILE__, '1.0.0' );
61 |
62 | if ( is_null( $instance->emailVerification ) ) {
63 | $instance->emailVerification = User_Session_Synchronizer_Email_Verification::instance( $instance );
64 | }
65 |
66 | if ( is_null( $instance->settings ) ) {
67 | $instance->settings = User_Session_Synchronizer_Settings::instance( $instance );
68 | }
69 |
70 | if ( is_null( $instance->sessionControl ) ) {
71 | $instance->sessionControl = User_Session_Synchronizer_Session_Control::instance( $instance );
72 | }
73 |
74 | return $instance;
75 | }
76 |
77 | User_Session_Synchronizer();
--------------------------------------------------------------------------------