Version Description
- Initial Release
Download this release
Release Info
Developer | storeapps |
Plugin | Temporary Login Without Password |
Version | 1.0 |
Comparing to | |
See all releases |
Version 1.0
- admin/class-wp-temporary-login-without-password-admin.php +271 -0
- admin/css/wp-temporary-login-without-password-admin.css +81 -0
- admin/index.php +1 -0
- admin/js/clipboard.js +742 -0
- admin/js/clipboard.min.js +7 -0
- admin/js/wp-temporary-login-without-password-admin.js +38 -0
- includes/class-wp-temporary-login-without-password-common.php +442 -0
- includes/class-wp-temporary-login-without-password-i18n.php +17 -0
- includes/class-wp-temporary-login-without-password-layout.php +120 -0
- includes/class-wp-temporary-login-without-password-loader.php +48 -0
- includes/class-wp-temporary-login-without-password.php +88 -0
- includes/index.php +1 -0
- index.php +1 -0
- languages/wp-temporary-login-without-password.pot +246 -0
- license.txt +339 -0
- public/class-wp-temporary-login-without-password-public.php +92 -0
- public/index.php +1 -0
- readme.txt +45 -0
- screenshots/screenshot-1.png +0 -0
- screenshots/screenshot-2.png +0 -0
- templates/admin_settings.php +34 -0
- templates/list_temporary_logins.php +26 -0
- templates/new_login.php +41 -0
- temporary-login-without-password.php +29 -0
- uninstall.php +31 -0
admin/class-wp-temporary-login-without-password-admin.php
ADDED
@@ -0,0 +1,271 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Wp_Temporary_Login_Without_Password_Admin {
|
4 |
+
|
5 |
+
private $plugin_name;
|
6 |
+
private $version;
|
7 |
+
|
8 |
+
public function __construct($plugin_name, $version) {
|
9 |
+
|
10 |
+
$this->plugin_name = $plugin_name;
|
11 |
+
$this->version = $version;
|
12 |
+
}
|
13 |
+
|
14 |
+
public function enqueue_styles() {
|
15 |
+
wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/wp-temporary-login-without-password-admin.css', array(), $this->version, 'all');
|
16 |
+
}
|
17 |
+
|
18 |
+
public function enqueue_scripts() {
|
19 |
+
wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/wp-temporary-login-without-password-admin.js', array('jquery'), $this->version, false);
|
20 |
+
wp_enqueue_script('clipboardjs', plugin_dir_url(__FILE__) . 'js/clipboard.min.js', array('jquery'), $this->version, false);
|
21 |
+
}
|
22 |
+
|
23 |
+
public function admin_menu() {
|
24 |
+
$current_user_id = get_current_user_id();
|
25 |
+
if (!Wp_Temporary_Login_Without_Password_Common::is_valid_temporary_login($current_user_id)) {
|
26 |
+
add_users_page(__('Temporary Logins', Wp_Temporary_Login_Without_Password_i18n::$text_domain), __('Temporary Logins', Wp_Temporary_Login_Without_Password_i18n::$text_domain), apply_filters('tempadmin_user_cap', 'manage_options'), Wp_Temporary_Login_Without_Password_i18n::$text_domain, array(__class__, 'admin_settings'));
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
public static function admin_settings() {
|
31 |
+
$_template_file = WTLWP_PLUGIN_DIR . '/templates/admin_settings.php';
|
32 |
+
$wtlwp_generated_url = !empty($_REQUEST['wtlwp_generated_url']) ? $_REQUEST['wtlwp_generated_url'] : '';
|
33 |
+
$user_email = !empty($_REQUEST['user_email']) ? $_REQUEST['user_email'] : '';
|
34 |
+
include $_template_file;
|
35 |
+
}
|
36 |
+
|
37 |
+
public function create_user() {
|
38 |
+
|
39 |
+
if (empty($_POST['wtlwp_data']) || empty($_POST['wtlwp-nonce'])) {
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
|
43 |
+
$data = $_POST['wtlwp_data'];
|
44 |
+
$email = $data['user_email'];
|
45 |
+
$error = false;
|
46 |
+
|
47 |
+
$redirect_link = '';
|
48 |
+
if (false == Wp_Temporary_Login_Without_Password_Common::can_manage_wtlwp()) {
|
49 |
+
$result = array('status' => 'error', 'message' => 'unathorised_access');
|
50 |
+
$error = true;
|
51 |
+
}else if (!wp_verify_nonce($_POST['wtlwp-nonce'], 'wtlwp_generate_login_url')) {
|
52 |
+
$result = array('status' => 'error', 'message' => 'nonce_failed');
|
53 |
+
$error = true;
|
54 |
+
}else if (empty($data['user_email'])) {
|
55 |
+
$result = array('status' => 'error', 'message' => 'empty_email');
|
56 |
+
$error = true;
|
57 |
+
}else if (!is_email($email)) {
|
58 |
+
$result = array('status' => 'error', 'message' => 'not_valid_email');
|
59 |
+
$error = true;
|
60 |
+
}else if (!empty($data['user_email']) && email_exists($data['user_email'])) {
|
61 |
+
$result = array('status' => 'error', 'message' => 'email_is_in_use');
|
62 |
+
$error = true;
|
63 |
+
}
|
64 |
+
|
65 |
+
if (!$error) {
|
66 |
+
$user = Wp_Temporary_Login_Without_Password_Common::create_new_user($data);
|
67 |
+
if (!empty($user['error'])) {
|
68 |
+
$result = array('status' => 'error', 'message' => 'user_creation_failed');
|
69 |
+
} else {
|
70 |
+
$result = array('status' => 'success', 'message' => 'user_created');
|
71 |
+
$redirect_link = Wp_Temporary_Login_Without_Password_Common::get_redirect_link($result);
|
72 |
+
$redirect_link = add_query_arg('wtlwp_generated_url', Wp_Temporary_Login_Without_Password_Common::get_login_url($user), $redirect_link);
|
73 |
+
$redirect_link = add_query_arg('user_email', $email, $redirect_link);
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
if(empty($redirect_link)) {
|
78 |
+
$redirect_link = Wp_Temporary_Login_Without_Password_Common::get_redirect_link($result);
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
wp_redirect($redirect_link, 302);
|
83 |
+
exit();
|
84 |
+
}
|
85 |
+
|
86 |
+
public static function delete_user() {
|
87 |
+
|
88 |
+
if ((false === Wp_Temporary_Login_Without_Password_Common::can_manage_wtlwp()) || empty($_REQUEST['wtlwp_action']) || ($_REQUEST['wtlwp_action'] != 'delete') || empty($_REQUEST['user_id']) || (absint($_REQUEST['user_id']) == 0)) {
|
89 |
+
return;
|
90 |
+
}
|
91 |
+
|
92 |
+
$user_id = absint($_REQUEST['user_id']);
|
93 |
+
$nonce = $_REQUEST['manage-temporary-login'];
|
94 |
+
$redirect_url = '';
|
95 |
+
$error = false;
|
96 |
+
if (!wp_verify_nonce($nonce, 'manage-temporary-login_' . $user_id)) {
|
97 |
+
$result = array('status' => 'error', 'message' => 'nonce_failed');
|
98 |
+
$error = true;
|
99 |
+
} else if(!Wp_Temporary_Login_Without_Password_Common::is_valid_temporary_login($user_id, false)) {
|
100 |
+
$result = array('status' => 'error', 'message' => 'is_not_temporary_login');
|
101 |
+
$error = true;
|
102 |
+
}
|
103 |
+
|
104 |
+
if (!$error) {
|
105 |
+
$delete_user = wp_delete_user(absint($user_id), get_current_user_id());
|
106 |
+
if (!is_wp_error($delete_user)) {
|
107 |
+
$result = array('status' => 'success', 'message' => 'user_deleted');
|
108 |
+
} else {
|
109 |
+
$result = array('status' => 'error', 'message' => 'default_error_message');
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
$redirect_url = Wp_Temporary_Login_Without_Password_Common::get_redirect_link($result);
|
114 |
+
wp_redirect($redirect_url, 302);
|
115 |
+
exit();
|
116 |
+
}
|
117 |
+
|
118 |
+
public static function manage_temporary_login() {
|
119 |
+
|
120 |
+
if ((false === Wp_Temporary_Login_Without_Password_Common::can_manage_wtlwp()) || empty($_REQUEST['wtlwp_action']) || ($_REQUEST['wtlwp_action'] != 'disable' && $_REQUEST['wtlwp_action'] != 'enable') || empty($_REQUEST['user_id']) || (absint($_REQUEST['user_id']) == 0)) {
|
121 |
+
return;
|
122 |
+
}
|
123 |
+
|
124 |
+
$error = false;
|
125 |
+
$user_id = absint($_REQUEST['user_id']);
|
126 |
+
$action = $_REQUEST['wtlwp_action'];
|
127 |
+
$nonce = $_REQUEST['manage-temporary-login'];
|
128 |
+
|
129 |
+
$is_valid_temporary_user = Wp_Temporary_Login_Without_Password_Common::is_valid_temporary_login($user_id, false);
|
130 |
+
|
131 |
+
if (!$is_valid_temporary_user) {
|
132 |
+
$result = array('status' => 'error', 'message' => 'is_not_temporary_login');
|
133 |
+
$error = true;
|
134 |
+
} else if (!wp_verify_nonce($nonce, 'manage-temporary-login_' . $user_id)) {
|
135 |
+
$result = array('status' => 'error', 'message' => 'nonce_failed');
|
136 |
+
$error = true;
|
137 |
+
}
|
138 |
+
|
139 |
+
if(!$error) {
|
140 |
+
if ($action == 'disable') {
|
141 |
+
$disable_login = Wp_Temporary_Login_Without_Password_Common::manage_login(absint($user_id), 'disable');
|
142 |
+
if ($disable_login) {
|
143 |
+
$result = array('status' => 'success', 'message' => 'login_disabled');
|
144 |
+
} else {
|
145 |
+
$result = array('status' => 'error', 'message' => 'default_error_message');
|
146 |
+
$error = true;
|
147 |
+
}
|
148 |
+
} else if ($action == 'enable') {
|
149 |
+
$enable_login = Wp_Temporary_Login_Without_Password_Common::manage_login(absint($user_id), 'enable');
|
150 |
+
|
151 |
+
if ($enable_login) {
|
152 |
+
$result = array('status' => 'success', 'message' => 'login_enabled');
|
153 |
+
} else {
|
154 |
+
$result = array('status' => 'error', 'message' => 'default_error_message');
|
155 |
+
$error = true;
|
156 |
+
}
|
157 |
+
} else {
|
158 |
+
$result = array('status' => 'error', 'message' => 'invalid_action');
|
159 |
+
$error = true;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
$redirect_link = Wp_Temporary_Login_Without_Password_Common::get_redirect_link($result);
|
164 |
+
wp_redirect($redirect_link, 302);
|
165 |
+
exit();
|
166 |
+
}
|
167 |
+
|
168 |
+
public function display_admin_notices() {
|
169 |
+
|
170 |
+
if (empty($_REQUEST['page']) || (empty($_REQUEST['page']) && $_REQUEST['page'] !== 'wp-temporary-login-without-password') || !isset($_REQUEST['wtlwp_message']) || (!isset($_REQUEST['wtlwp_error']) && !isset($_REQUEST['wtlwp_success']))) {
|
171 |
+
return;
|
172 |
+
}
|
173 |
+
|
174 |
+
$class = $message = '';
|
175 |
+
$error = !empty($_REQUEST['wtlwp_error']) ? true : false;
|
176 |
+
$success = !empty($_REQUEST['wtlwp_success']) ? true : false;
|
177 |
+
if ($error) {
|
178 |
+
$message_type = !empty($_REQUEST['wtlwp_message']) ? $_REQUEST['wtlwp_message'] : 'default_error_message';
|
179 |
+
switch ($message_type) {
|
180 |
+
case 'user_creation_failed':
|
181 |
+
$message = __('User creation failed', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
182 |
+
break;
|
183 |
+
|
184 |
+
case 'unathorised_access':
|
185 |
+
$message = __('You do not have permission to create a temporary login', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
186 |
+
break;
|
187 |
+
|
188 |
+
case 'email_is_in_use':
|
189 |
+
$message = __('Email already is in use', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
190 |
+
break;
|
191 |
+
|
192 |
+
case 'empty_email':
|
193 |
+
$message = __('Please enter valid email address. Email field should not be empty', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
194 |
+
break;
|
195 |
+
|
196 |
+
case 'not_valid_email':
|
197 |
+
$message = __('Please enter valid email address', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
198 |
+
break;
|
199 |
+
|
200 |
+
case 'is_not_temporary_login':
|
201 |
+
$message = __('User you are trying to delete is not temporary', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
202 |
+
break;
|
203 |
+
|
204 |
+
case 'nonce_failed':
|
205 |
+
$message = __('Nonce failed', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
206 |
+
break;
|
207 |
+
|
208 |
+
case 'invalid_action':
|
209 |
+
$message = __('Invalid action', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
210 |
+
break;
|
211 |
+
|
212 |
+
case 'default_error_message':
|
213 |
+
default:
|
214 |
+
$message = __('Unknown error occured', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
215 |
+
break;
|
216 |
+
}
|
217 |
+
$class = 'error';
|
218 |
+
} else if ($success) {
|
219 |
+
$message_type = !empty($_REQUEST['wtlwp_message']) ? $_REQUEST['wtlwp_message'] : 'default_success_message';
|
220 |
+
switch ($message_type) {
|
221 |
+
case 'user_created':
|
222 |
+
$message = __('Login created successfully!', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
223 |
+
break;
|
224 |
+
|
225 |
+
case 'user_deleted':
|
226 |
+
$message = __('Login deleted successfully!', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
227 |
+
break;
|
228 |
+
|
229 |
+
case 'login_disabled':
|
230 |
+
$message = __('Login disabled successfully!', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
231 |
+
break;
|
232 |
+
|
233 |
+
case 'login_enabled':
|
234 |
+
$message = __('Login enabled successfully!', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
235 |
+
break;
|
236 |
+
|
237 |
+
default:
|
238 |
+
$message = __('Success!', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
239 |
+
break;
|
240 |
+
}
|
241 |
+
|
242 |
+
$class = 'updated';
|
243 |
+
}
|
244 |
+
|
245 |
+
|
246 |
+
$class .= ' notice notice-succe is-dismissible';
|
247 |
+
|
248 |
+
if (!empty($message)) {
|
249 |
+
$notice = '';
|
250 |
+
$notice .= '<div id="notice" class="' . $class . '">';
|
251 |
+
$notice .= '<p>' . esc_attr($message) . '</p>';
|
252 |
+
$notice .= '</div>';
|
253 |
+
|
254 |
+
echo $notice;
|
255 |
+
}
|
256 |
+
|
257 |
+
return;
|
258 |
+
}
|
259 |
+
|
260 |
+
public function disable_welcome_notification($blog_id, $user_id, $password, $title, $meta) {
|
261 |
+
|
262 |
+
if (!empty($user_id)) {
|
263 |
+
if (Wp_Temporary_Login_Without_Password_Common::is_valid_temporary_login($user_id)) {
|
264 |
+
return false;
|
265 |
+
}
|
266 |
+
}
|
267 |
+
|
268 |
+
return true;
|
269 |
+
}
|
270 |
+
|
271 |
+
}
|
admin/css/wp-temporary-login-without-password-admin.css
ADDED
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.new-wtlwp-form {
|
2 |
+
border: 1px solid;
|
3 |
+
padding: 10px;
|
4 |
+
background-color: white;
|
5 |
+
display: none;
|
6 |
+
}
|
7 |
+
|
8 |
+
.wtlwp-form-input {
|
9 |
+
width: 300px !important;
|
10 |
+
}
|
11 |
+
.widefat .wtlwp-status {
|
12 |
+
width: 40px;
|
13 |
+
}
|
14 |
+
|
15 |
+
.wtlwp-status-active {
|
16 |
+
color: #008000 !important;
|
17 |
+
}
|
18 |
+
|
19 |
+
.wtlwp-status-expired {
|
20 |
+
color: #FF0000 !important;
|
21 |
+
}
|
22 |
+
|
23 |
+
.wtlwp-status:after {
|
24 |
+
border-radius: 32px;
|
25 |
+
color: #fff;
|
26 |
+
display: block;
|
27 |
+
font-size: 11px;
|
28 |
+
font-weight: bold;
|
29 |
+
height: 16px;
|
30 |
+
line-height: 17px;
|
31 |
+
margin-left: 8px;
|
32 |
+
text-align: center;
|
33 |
+
width: 16px;
|
34 |
+
}
|
35 |
+
|
36 |
+
.wtlwp-status-active:after {
|
37 |
+
background: #008000 none repeat scroll 0 0;
|
38 |
+
content: "";
|
39 |
+
}
|
40 |
+
|
41 |
+
.wtlwp-status-expired:after {
|
42 |
+
background: #FF0000 none repeat scroll 0 0;
|
43 |
+
content: "";
|
44 |
+
}
|
45 |
+
|
46 |
+
.cancel-new-login-form {
|
47 |
+
cursor: pointer;
|
48 |
+
}
|
49 |
+
|
50 |
+
.wtlwp-wide-input {
|
51 |
+
width: 60%;
|
52 |
+
}
|
53 |
+
|
54 |
+
.generated-wtlwp-login-link {
|
55 |
+
border: 1px solid;
|
56 |
+
padding: 10px 10px 10px 10px;
|
57 |
+
}
|
58 |
+
|
59 |
+
.wtlwp-form-row {
|
60 |
+
padding-left: 20px !important;
|
61 |
+
}
|
62 |
+
|
63 |
+
.wtlwp-form-submit-button {
|
64 |
+
width: 115px;
|
65 |
+
}
|
66 |
+
|
67 |
+
.wtlwp-user-login {
|
68 |
+
font-size: 12px;
|
69 |
+
}
|
70 |
+
|
71 |
+
.wtlwp-copy-to-clipboard, .wtlwp-click-to-copy-btn {
|
72 |
+
cursor: pointer;
|
73 |
+
}
|
74 |
+
|
75 |
+
.wtlwp-copy-to-clipboard:hover {
|
76 |
+
color: #0073aa;
|
77 |
+
}
|
78 |
+
|
79 |
+
.copied-text-message {
|
80 |
+
padding: 20px;
|
81 |
+
}
|
admin/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
admin/js/clipboard.js
ADDED
@@ -0,0 +1,742 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* clipboard.js v1.5.12
|
3 |
+
* https://zenorocha.github.io/clipboard.js
|
4 |
+
*
|
5 |
+
* Licensed MIT © Zeno Rocha
|
6 |
+
*/
|
7 |
+
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
8 |
+
var matches = require('matches-selector')
|
9 |
+
|
10 |
+
module.exports = function (element, selector, checkYoSelf) {
|
11 |
+
var parent = checkYoSelf ? element : element.parentNode
|
12 |
+
|
13 |
+
while (parent && parent !== document) {
|
14 |
+
if (matches(parent, selector)) return parent;
|
15 |
+
parent = parent.parentNode
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
},{"matches-selector":5}],2:[function(require,module,exports){
|
20 |
+
var closest = require('closest');
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Delegates event to a selector.
|
24 |
+
*
|
25 |
+
* @param {Element} element
|
26 |
+
* @param {String} selector
|
27 |
+
* @param {String} type
|
28 |
+
* @param {Function} callback
|
29 |
+
* @param {Boolean} useCapture
|
30 |
+
* @return {Object}
|
31 |
+
*/
|
32 |
+
function delegate(element, selector, type, callback, useCapture) {
|
33 |
+
var listenerFn = listener.apply(this, arguments);
|
34 |
+
|
35 |
+
element.addEventListener(type, listenerFn, useCapture);
|
36 |
+
|
37 |
+
return {
|
38 |
+
destroy: function() {
|
39 |
+
element.removeEventListener(type, listenerFn, useCapture);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Finds closest match and invokes callback.
|
46 |
+
*
|
47 |
+
* @param {Element} element
|
48 |
+
* @param {String} selector
|
49 |
+
* @param {String} type
|
50 |
+
* @param {Function} callback
|
51 |
+
* @return {Function}
|
52 |
+
*/
|
53 |
+
function listener(element, selector, type, callback) {
|
54 |
+
return function(e) {
|
55 |
+
e.delegateTarget = closest(e.target, selector, true);
|
56 |
+
|
57 |
+
if (e.delegateTarget) {
|
58 |
+
callback.call(element, e);
|
59 |
+
}
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
module.exports = delegate;
|
64 |
+
|
65 |
+
},{"closest":1}],3:[function(require,module,exports){
|
66 |
+
/**
|
67 |
+
* Check if argument is a HTML element.
|
68 |
+
*
|
69 |
+
* @param {Object} value
|
70 |
+
* @return {Boolean}
|
71 |
+
*/
|
72 |
+
exports.node = function(value) {
|
73 |
+
return value !== undefined
|
74 |
+
&& value instanceof HTMLElement
|
75 |
+
&& value.nodeType === 1;
|
76 |
+
};
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Check if argument is a list of HTML elements.
|
80 |
+
*
|
81 |
+
* @param {Object} value
|
82 |
+
* @return {Boolean}
|
83 |
+
*/
|
84 |
+
exports.nodeList = function(value) {
|
85 |
+
var type = Object.prototype.toString.call(value);
|
86 |
+
|
87 |
+
return value !== undefined
|
88 |
+
&& (type === '[object NodeList]' || type === '[object HTMLCollection]')
|
89 |
+
&& ('length' in value)
|
90 |
+
&& (value.length === 0 || exports.node(value[0]));
|
91 |
+
};
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Check if argument is a string.
|
95 |
+
*
|
96 |
+
* @param {Object} value
|
97 |
+
* @return {Boolean}
|
98 |
+
*/
|
99 |
+
exports.string = function(value) {
|
100 |
+
return typeof value === 'string'
|
101 |
+
|| value instanceof String;
|
102 |
+
};
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Check if argument is a function.
|
106 |
+
*
|
107 |
+
* @param {Object} value
|
108 |
+
* @return {Boolean}
|
109 |
+
*/
|
110 |
+
exports.fn = function(value) {
|
111 |
+
var type = Object.prototype.toString.call(value);
|
112 |
+
|
113 |
+
return type === '[object Function]';
|
114 |
+
};
|
115 |
+
|
116 |
+
},{}],4:[function(require,module,exports){
|
117 |
+
var is = require('./is');
|
118 |
+
var delegate = require('delegate');
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Validates all params and calls the right
|
122 |
+
* listener function based on its target type.
|
123 |
+
*
|
124 |
+
* @param {String|HTMLElement|HTMLCollection|NodeList} target
|
125 |
+
* @param {String} type
|
126 |
+
* @param {Function} callback
|
127 |
+
* @return {Object}
|
128 |
+
*/
|
129 |
+
function listen(target, type, callback) {
|
130 |
+
if (!target && !type && !callback) {
|
131 |
+
throw new Error('Missing required arguments');
|
132 |
+
}
|
133 |
+
|
134 |
+
if (!is.string(type)) {
|
135 |
+
throw new TypeError('Second argument must be a String');
|
136 |
+
}
|
137 |
+
|
138 |
+
if (!is.fn(callback)) {
|
139 |
+
throw new TypeError('Third argument must be a Function');
|
140 |
+
}
|
141 |
+
|
142 |
+
if (is.node(target)) {
|
143 |
+
return listenNode(target, type, callback);
|
144 |
+
}
|
145 |
+
else if (is.nodeList(target)) {
|
146 |
+
return listenNodeList(target, type, callback);
|
147 |
+
}
|
148 |
+
else if (is.string(target)) {
|
149 |
+
return listenSelector(target, type, callback);
|
150 |
+
}
|
151 |
+
else {
|
152 |
+
throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Adds an event listener to a HTML element
|
158 |
+
* and returns a remove listener function.
|
159 |
+
*
|
160 |
+
* @param {HTMLElement} node
|
161 |
+
* @param {String} type
|
162 |
+
* @param {Function} callback
|
163 |
+
* @return {Object}
|
164 |
+
*/
|
165 |
+
function listenNode(node, type, callback) {
|
166 |
+
node.addEventListener(type, callback);
|
167 |
+
|
168 |
+
return {
|
169 |
+
destroy: function() {
|
170 |
+
node.removeEventListener(type, callback);
|
171 |
+
}
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Add an event listener to a list of HTML elements
|
177 |
+
* and returns a remove listener function.
|
178 |
+
*
|
179 |
+
* @param {NodeList|HTMLCollection} nodeList
|
180 |
+
* @param {String} type
|
181 |
+
* @param {Function} callback
|
182 |
+
* @return {Object}
|
183 |
+
*/
|
184 |
+
function listenNodeList(nodeList, type, callback) {
|
185 |
+
Array.prototype.forEach.call(nodeList, function(node) {
|
186 |
+
node.addEventListener(type, callback);
|
187 |
+
});
|
188 |
+
|
189 |
+
return {
|
190 |
+
destroy: function() {
|
191 |
+
Array.prototype.forEach.call(nodeList, function(node) {
|
192 |
+
node.removeEventListener(type, callback);
|
193 |
+
});
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Add an event listener to a selector
|
200 |
+
* and returns a remove listener function.
|
201 |
+
*
|
202 |
+
* @param {String} selector
|
203 |
+
* @param {String} type
|
204 |
+
* @param {Function} callback
|
205 |
+
* @return {Object}
|
206 |
+
*/
|
207 |
+
function listenSelector(selector, type, callback) {
|
208 |
+
return delegate(document.body, selector, type, callback);
|
209 |
+
}
|
210 |
+
|
211 |
+
module.exports = listen;
|
212 |
+
|
213 |
+
},{"./is":3,"delegate":2}],5:[function(require,module,exports){
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Element prototype.
|
217 |
+
*/
|
218 |
+
|
219 |
+
var proto = Element.prototype;
|
220 |
+
|
221 |
+
/**
|
222 |
+
* Vendor function.
|
223 |
+
*/
|
224 |
+
|
225 |
+
var vendor = proto.matchesSelector
|
226 |
+
|| proto.webkitMatchesSelector
|
227 |
+
|| proto.mozMatchesSelector
|
228 |
+
|| proto.msMatchesSelector
|
229 |
+
|| proto.oMatchesSelector;
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Expose `match()`.
|
233 |
+
*/
|
234 |
+
|
235 |
+
module.exports = match;
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Match `el` to `selector`.
|
239 |
+
*
|
240 |
+
* @param {Element} el
|
241 |
+
* @param {String} selector
|
242 |
+
* @return {Boolean}
|
243 |
+
* @api public
|
244 |
+
*/
|
245 |
+
|
246 |
+
function match(el, selector) {
|
247 |
+
if (vendor) return vendor.call(el, selector);
|
248 |
+
var nodes = el.parentNode.querySelectorAll(selector);
|
249 |
+
for (var i = 0; i < nodes.length; ++i) {
|
250 |
+
if (nodes[i] == el) return true;
|
251 |
+
}
|
252 |
+
return false;
|
253 |
+
}
|
254 |
+
},{}],6:[function(require,module,exports){
|
255 |
+
function select(element) {
|
256 |
+
var selectedText;
|
257 |
+
|
258 |
+
if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
|
259 |
+
element.focus();
|
260 |
+
element.setSelectionRange(0, element.value.length);
|
261 |
+
|
262 |
+
selectedText = element.value;
|
263 |
+
}
|
264 |
+
else {
|
265 |
+
if (element.hasAttribute('contenteditable')) {
|
266 |
+
element.focus();
|
267 |
+
}
|
268 |
+
|
269 |
+
var selection = window.getSelection();
|
270 |
+
var range = document.createRange();
|
271 |
+
|
272 |
+
range.selectNodeContents(element);
|
273 |
+
selection.removeAllRanges();
|
274 |
+
selection.addRange(range);
|
275 |
+
|
276 |
+
selectedText = selection.toString();
|
277 |
+
}
|
278 |
+
|
279 |
+
return selectedText;
|
280 |
+
}
|
281 |
+
|
282 |
+
module.exports = select;
|
283 |
+
|
284 |
+
},{}],7:[function(require,module,exports){
|
285 |
+
function E () {
|
286 |
+
// Keep this empty so it's easier to inherit from
|
287 |
+
// (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
|
288 |
+
}
|
289 |
+
|
290 |
+
E.prototype = {
|
291 |
+
on: function (name, callback, ctx) {
|
292 |
+
var e = this.e || (this.e = {});
|
293 |
+
|
294 |
+
(e[name] || (e[name] = [])).push({
|
295 |
+
fn: callback,
|
296 |
+
ctx: ctx
|
297 |
+
});
|
298 |
+
|
299 |
+
return this;
|
300 |
+
},
|
301 |
+
|
302 |
+
once: function (name, callback, ctx) {
|
303 |
+
var self = this;
|
304 |
+
function listener () {
|
305 |
+
self.off(name, listener);
|
306 |
+
callback.apply(ctx, arguments);
|
307 |
+
};
|
308 |
+
|
309 |
+
listener._ = callback
|
310 |
+
return this.on(name, listener, ctx);
|
311 |
+
},
|
312 |
+
|
313 |
+
emit: function (name) {
|
314 |
+
var data = [].slice.call(arguments, 1);
|
315 |
+
var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
|
316 |
+
var i = 0;
|
317 |
+
var len = evtArr.length;
|
318 |
+
|
319 |
+
for (i; i < len; i++) {
|
320 |
+
evtArr[i].fn.apply(evtArr[i].ctx, data);
|
321 |
+
}
|
322 |
+
|
323 |
+
return this;
|
324 |
+
},
|
325 |
+
|
326 |
+
off: function (name, callback) {
|
327 |
+
var e = this.e || (this.e = {});
|
328 |
+
var evts = e[name];
|
329 |
+
var liveEvents = [];
|
330 |
+
|
331 |
+
if (evts && callback) {
|
332 |
+
for (var i = 0, len = evts.length; i < len; i++) {
|
333 |
+
if (evts[i].fn !== callback && evts[i].fn._ !== callback)
|
334 |
+
liveEvents.push(evts[i]);
|
335 |
+
}
|
336 |
+
}
|
337 |
+
|
338 |
+
// Remove event from queue to prevent memory leak
|
339 |
+
// Suggested by https://github.com/lazd
|
340 |
+
// Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
|
341 |
+
|
342 |
+
(liveEvents.length)
|
343 |
+
? e[name] = liveEvents
|
344 |
+
: delete e[name];
|
345 |
+
|
346 |
+
return this;
|
347 |
+
}
|
348 |
+
};
|
349 |
+
|
350 |
+
module.exports = E;
|
351 |
+
|
352 |
+
},{}],8:[function(require,module,exports){
|
353 |
+
(function (global, factory) {
|
354 |
+
if (typeof define === "function" && define.amd) {
|
355 |
+
define(['module', 'select'], factory);
|
356 |
+
} else if (typeof exports !== "undefined") {
|
357 |
+
factory(module, require('select'));
|
358 |
+
} else {
|
359 |
+
var mod = {
|
360 |
+
exports: {}
|
361 |
+
};
|
362 |
+
factory(mod, global.select);
|
363 |
+
global.clipboardAction = mod.exports;
|
364 |
+
}
|
365 |
+
})(this, function (module, _select) {
|
366 |
+
'use strict';
|
367 |
+
|
368 |
+
var _select2 = _interopRequireDefault(_select);
|
369 |
+
|
370 |
+
function _interopRequireDefault(obj) {
|
371 |
+
return obj && obj.__esModule ? obj : {
|
372 |
+
default: obj
|
373 |
+
};
|
374 |
+
}
|
375 |
+
|
376 |
+
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
|
377 |
+
return typeof obj;
|
378 |
+
} : function (obj) {
|
379 |
+
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
380 |
+
};
|
381 |
+
|
382 |
+
function _classCallCheck(instance, Constructor) {
|
383 |
+
if (!(instance instanceof Constructor)) {
|
384 |
+
throw new TypeError("Cannot call a class as a function");
|
385 |
+
}
|
386 |
+
}
|
387 |
+
|
388 |
+
var _createClass = function () {
|
389 |
+
function defineProperties(target, props) {
|
390 |
+
for (var i = 0; i < props.length; i++) {
|
391 |
+
var descriptor = props[i];
|
392 |
+
descriptor.enumerable = descriptor.enumerable || false;
|
393 |
+
descriptor.configurable = true;
|
394 |
+
if ("value" in descriptor) descriptor.writable = true;
|
395 |
+
Object.defineProperty(target, descriptor.key, descriptor);
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
return function (Constructor, protoProps, staticProps) {
|
400 |
+
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
401 |
+
if (staticProps) defineProperties(Constructor, staticProps);
|
402 |
+
return Constructor;
|
403 |
+
};
|
404 |
+
}();
|
405 |
+
|
406 |
+
var ClipboardAction = function () {
|
407 |
+
/**
|
408 |
+
* @param {Object} options
|
409 |
+
*/
|
410 |
+
|
411 |
+
function ClipboardAction(options) {
|
412 |
+
_classCallCheck(this, ClipboardAction);
|
413 |
+
|
414 |
+
this.resolveOptions(options);
|
415 |
+
this.initSelection();
|
416 |
+
}
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Defines base properties passed from constructor.
|
420 |
+
* @param {Object} options
|
421 |
+
*/
|
422 |
+
|
423 |
+
|
424 |
+
ClipboardAction.prototype.resolveOptions = function resolveOptions() {
|
425 |
+
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
426 |
+
|
427 |
+
this.action = options.action;
|
428 |
+
this.emitter = options.emitter;
|
429 |
+
this.target = options.target;
|
430 |
+
this.text = options.text;
|
431 |
+
this.trigger = options.trigger;
|
432 |
+
|
433 |
+
this.selectedText = '';
|
434 |
+
};
|
435 |
+
|
436 |
+
ClipboardAction.prototype.initSelection = function initSelection() {
|
437 |
+
if (this.text) {
|
438 |
+
this.selectFake();
|
439 |
+
} else if (this.target) {
|
440 |
+
this.selectTarget();
|
441 |
+
}
|
442 |
+
};
|
443 |
+
|
444 |
+
ClipboardAction.prototype.selectFake = function selectFake() {
|
445 |
+
var _this = this;
|
446 |
+
|
447 |
+
var isRTL = document.documentElement.getAttribute('dir') == 'rtl';
|
448 |
+
|
449 |
+
this.removeFake();
|
450 |
+
|
451 |
+
this.fakeHandlerCallback = function () {
|
452 |
+
return _this.removeFake();
|
453 |
+
};
|
454 |
+
this.fakeHandler = document.body.addEventListener('click', this.fakeHandlerCallback) || true;
|
455 |
+
|
456 |
+
this.fakeElem = document.createElement('textarea');
|
457 |
+
// Prevent zooming on iOS
|
458 |
+
this.fakeElem.style.fontSize = '12pt';
|
459 |
+
// Reset box model
|
460 |
+
this.fakeElem.style.border = '0';
|
461 |
+
this.fakeElem.style.padding = '0';
|
462 |
+
this.fakeElem.style.margin = '0';
|
463 |
+
// Move element out of screen horizontally
|
464 |
+
this.fakeElem.style.position = 'absolute';
|
465 |
+
this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';
|
466 |
+
// Move element to the same position vertically
|
467 |
+
this.fakeElem.style.top = (window.pageYOffset || document.documentElement.scrollTop) + 'px';
|
468 |
+
this.fakeElem.setAttribute('readonly', '');
|
469 |
+
this.fakeElem.value = this.text;
|
470 |
+
|
471 |
+
document.body.appendChild(this.fakeElem);
|
472 |
+
|
473 |
+
this.selectedText = (0, _select2.default)(this.fakeElem);
|
474 |
+
this.copyText();
|
475 |
+
};
|
476 |
+
|
477 |
+
ClipboardAction.prototype.removeFake = function removeFake() {
|
478 |
+
if (this.fakeHandler) {
|
479 |
+
document.body.removeEventListener('click', this.fakeHandlerCallback);
|
480 |
+
this.fakeHandler = null;
|
481 |
+
this.fakeHandlerCallback = null;
|
482 |
+
}
|
483 |
+
|
484 |
+
if (this.fakeElem) {
|
485 |
+
document.body.removeChild(this.fakeElem);
|
486 |
+
this.fakeElem = null;
|
487 |
+
}
|
488 |
+
};
|
489 |
+
|
490 |
+
ClipboardAction.prototype.selectTarget = function selectTarget() {
|
491 |
+
this.selectedText = (0, _select2.default)(this.target);
|
492 |
+
this.copyText();
|
493 |
+
};
|
494 |
+
|
495 |
+
ClipboardAction.prototype.copyText = function copyText() {
|
496 |
+
var succeeded = undefined;
|
497 |
+
|
498 |
+
try {
|
499 |
+
succeeded = document.execCommand(this.action);
|
500 |
+
} catch (err) {
|
501 |
+
succeeded = false;
|
502 |
+
}
|
503 |
+
|
504 |
+
this.handleResult(succeeded);
|
505 |
+
};
|
506 |
+
|
507 |
+
ClipboardAction.prototype.handleResult = function handleResult(succeeded) {
|
508 |
+
if (succeeded) {
|
509 |
+
this.emitter.emit('success', {
|
510 |
+
action: this.action,
|
511 |
+
text: this.selectedText,
|
512 |
+
trigger: this.trigger,
|
513 |
+
clearSelection: this.clearSelection.bind(this)
|
514 |
+
});
|
515 |
+
} else {
|
516 |
+
this.emitter.emit('error', {
|
517 |
+
action: this.action,
|
518 |
+
trigger: this.trigger,
|
519 |
+
clearSelection: this.clearSelection.bind(this)
|
520 |
+
});
|
521 |
+
}
|
522 |
+
};
|
523 |
+
|
524 |
+
ClipboardAction.prototype.clearSelection = function clearSelection() {
|
525 |
+
if (this.target) {
|
526 |
+
this.target.blur();
|
527 |
+
}
|
528 |
+
|
529 |
+
window.getSelection().removeAllRanges();
|
530 |
+
};
|
531 |
+
|
532 |
+
ClipboardAction.prototype.destroy = function destroy() {
|
533 |
+
this.removeFake();
|
534 |
+
};
|
535 |
+
|
536 |
+
_createClass(ClipboardAction, [{
|
537 |
+
key: 'action',
|
538 |
+
set: function set() {
|
539 |
+
var action = arguments.length <= 0 || arguments[0] === undefined ? 'copy' : arguments[0];
|
540 |
+
|
541 |
+
this._action = action;
|
542 |
+
|
543 |
+
if (this._action !== 'copy' && this._action !== 'cut') {
|
544 |
+
throw new Error('Invalid "action" value, use either "copy" or "cut"');
|
545 |
+
}
|
546 |
+
},
|
547 |
+
get: function get() {
|
548 |
+
return this._action;
|
549 |
+
}
|
550 |
+
}, {
|
551 |
+
key: 'target',
|
552 |
+
set: function set(target) {
|
553 |
+
if (target !== undefined) {
|
554 |
+
if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {
|
555 |
+
if (this.action === 'copy' && target.hasAttribute('disabled')) {
|
556 |
+
throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
|
557 |
+
}
|
558 |
+
|
559 |
+
if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
|
560 |
+
throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
|
561 |
+
}
|
562 |
+
|
563 |
+
this._target = target;
|
564 |
+
} else {
|
565 |
+
throw new Error('Invalid "target" value, use a valid Element');
|
566 |
+
}
|
567 |
+
}
|
568 |
+
},
|
569 |
+
get: function get() {
|
570 |
+
return this._target;
|
571 |
+
}
|
572 |
+
}]);
|
573 |
+
|
574 |
+
return ClipboardAction;
|
575 |
+
}();
|
576 |
+
|
577 |
+
module.exports = ClipboardAction;
|
578 |
+
});
|
579 |
+
|
580 |
+
},{"select":6}],9:[function(require,module,exports){
|
581 |
+
(function (global, factory) {
|
582 |
+
if (typeof define === "function" && define.amd) {
|
583 |
+
define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory);
|
584 |
+
} else if (typeof exports !== "undefined") {
|
585 |
+
factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener'));
|
586 |
+
} else {
|
587 |
+
var mod = {
|
588 |
+
exports: {}
|
589 |
+
};
|
590 |
+
factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener);
|
591 |
+
global.clipboard = mod.exports;
|
592 |
+
}
|
593 |
+
})(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) {
|
594 |
+
'use strict';
|
595 |
+
|
596 |
+
var _clipboardAction2 = _interopRequireDefault(_clipboardAction);
|
597 |
+
|
598 |
+
var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);
|
599 |
+
|
600 |
+
var _goodListener2 = _interopRequireDefault(_goodListener);
|
601 |
+
|
602 |
+
function _interopRequireDefault(obj) {
|
603 |
+
return obj && obj.__esModule ? obj : {
|
604 |
+
default: obj
|
605 |
+
};
|
606 |
+
}
|
607 |
+
|
608 |
+
function _classCallCheck(instance, Constructor) {
|
609 |
+
if (!(instance instanceof Constructor)) {
|
610 |
+
throw new TypeError("Cannot call a class as a function");
|
611 |
+
}
|
612 |
+
}
|
613 |
+
|
614 |
+
function _possibleConstructorReturn(self, call) {
|
615 |
+
if (!self) {
|
616 |
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
617 |
+
}
|
618 |
+
|
619 |
+
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
620 |
+
}
|
621 |
+
|
622 |
+
function _inherits(subClass, superClass) {
|
623 |
+
if (typeof superClass !== "function" && superClass !== null) {
|
624 |
+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
625 |
+
}
|
626 |
+
|
627 |
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
628 |
+
constructor: {
|
629 |
+
value: subClass,
|
630 |
+
enumerable: false,
|
631 |
+
writable: true,
|
632 |
+
configurable: true
|
633 |
+
}
|
634 |
+
});
|
635 |
+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
636 |
+
}
|
637 |
+
|
638 |
+
var Clipboard = function (_Emitter) {
|
639 |
+
_inherits(Clipboard, _Emitter);
|
640 |
+
|
641 |
+
/**
|
642 |
+
* @param {String|HTMLElement|HTMLCollection|NodeList} trigger
|
643 |
+
* @param {Object} options
|
644 |
+
*/
|
645 |
+
|
646 |
+
function Clipboard(trigger, options) {
|
647 |
+
_classCallCheck(this, Clipboard);
|
648 |
+
|
649 |
+
var _this = _possibleConstructorReturn(this, _Emitter.call(this));
|
650 |
+
|
651 |
+
_this.resolveOptions(options);
|
652 |
+
_this.listenClick(trigger);
|
653 |
+
return _this;
|
654 |
+
}
|
655 |
+
|
656 |
+
/**
|
657 |
+
* Defines if attributes would be resolved using internal setter functions
|
658 |
+
* or custom functions that were passed in the constructor.
|
659 |
+
* @param {Object} options
|
660 |
+
*/
|
661 |
+
|
662 |
+
|
663 |
+
Clipboard.prototype.resolveOptions = function resolveOptions() {
|
664 |
+
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
665 |
+
|
666 |
+
this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
|
667 |
+
this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
|
668 |
+
this.text = typeof options.text === 'function' ? options.text : this.defaultText;
|
669 |
+
};
|
670 |
+
|
671 |
+
Clipboard.prototype.listenClick = function listenClick(trigger) {
|
672 |
+
var _this2 = this;
|
673 |
+
|
674 |
+
this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {
|
675 |
+
return _this2.onClick(e);
|
676 |
+
});
|
677 |
+
};
|
678 |
+
|
679 |
+
Clipboard.prototype.onClick = function onClick(e) {
|
680 |
+
var trigger = e.delegateTarget || e.currentTarget;
|
681 |
+
|
682 |
+
if (this.clipboardAction) {
|
683 |
+
this.clipboardAction = null;
|
684 |
+
}
|
685 |
+
|
686 |
+
this.clipboardAction = new _clipboardAction2.default({
|
687 |
+
action: this.action(trigger),
|
688 |
+
target: this.target(trigger),
|
689 |
+
text: this.text(trigger),
|
690 |
+
trigger: trigger,
|
691 |
+
emitter: this
|
692 |
+
});
|
693 |
+
};
|
694 |
+
|
695 |
+
Clipboard.prototype.defaultAction = function defaultAction(trigger) {
|
696 |
+
return getAttributeValue('action', trigger);
|
697 |
+
};
|
698 |
+
|
699 |
+
Clipboard.prototype.defaultTarget = function defaultTarget(trigger) {
|
700 |
+
var selector = getAttributeValue('target', trigger);
|
701 |
+
|
702 |
+
if (selector) {
|
703 |
+
return document.querySelector(selector);
|
704 |
+
}
|
705 |
+
};
|
706 |
+
|
707 |
+
Clipboard.prototype.defaultText = function defaultText(trigger) {
|
708 |
+
return getAttributeValue('text', trigger);
|
709 |
+
};
|
710 |
+
|
711 |
+
Clipboard.prototype.destroy = function destroy() {
|
712 |
+
this.listener.destroy();
|
713 |
+
|
714 |
+
if (this.clipboardAction) {
|
715 |
+
this.clipboardAction.destroy();
|
716 |
+
this.clipboardAction = null;
|
717 |
+
}
|
718 |
+
};
|
719 |
+
|
720 |
+
return Clipboard;
|
721 |
+
}(_tinyEmitter2.default);
|
722 |
+
|
723 |
+
/**
|
724 |
+
* Helper function to retrieve attribute value.
|
725 |
+
* @param {String} suffix
|
726 |
+
* @param {Element} element
|
727 |
+
*/
|
728 |
+
function getAttributeValue(suffix, element) {
|
729 |
+
var attribute = 'data-clipboard-' + suffix;
|
730 |
+
|
731 |
+
if (!element.hasAttribute(attribute)) {
|
732 |
+
return;
|
733 |
+
}
|
734 |
+
|
735 |
+
return element.getAttribute(attribute);
|
736 |
+
}
|
737 |
+
|
738 |
+
module.exports = Clipboard;
|
739 |
+
});
|
740 |
+
|
741 |
+
},{"./clipboard-action":8,"good-listener":4,"tiny-emitter":7}]},{},[9])(9)
|
742 |
+
});
|
admin/js/clipboard.min.js
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* clipboard.js v1.5.12
|
3 |
+
* https://zenorocha.github.io/clipboard.js
|
4 |
+
*
|
5 |
+
* Licensed MIT © Zeno Rocha
|
6 |
+
*/
|
7 |
+
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(r)return r(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n?n:t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(t,e,n){var o=t("matches-selector");e.exports=function(t,e,n){for(var i=n?t:t.parentNode;i&&i!==document;){if(o(i,e))return i;i=i.parentNode}}},{"matches-selector":5}],2:[function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function i(t,e,n,o){return function(n){n.delegateTarget=r(n.target,e,!0),n.delegateTarget&&o.call(t,n)}}var r=t("closest");e.exports=o},{closest:1}],3:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){var e=Object.prototype.toString.call(t);return"[object Function]"===e}},{}],4:[function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return i(t,e,n);if(c.nodeList(t))return r(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function r(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return s(document.body,t,e,n)}var c=t("./is"),s=t("delegate");e.exports=o},{"./is":3,delegate:2}],5:[function(t,e,n){function o(t,e){if(r)return r.call(t,e);for(var n=t.parentNode.querySelectorAll(e),o=0;o<n.length;++o)if(n[o]==t)return!0;return!1}var i=Element.prototype,r=i.matchesSelector||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector;e.exports=o},{}],6:[function(t,e,n){function o(t){var e;if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName)t.focus(),t.setSelectionRange(0,t.value.length),e=t.value;else{t.hasAttribute("contenteditable")&&t.focus();var n=window.getSelection(),o=document.createRange();o.selectNodeContents(t),n.removeAllRanges(),n.addRange(o),e=n.toString()}return e}e.exports=o},{}],7:[function(t,e,n){function o(){}o.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){i.off(t,o),e.apply(n,arguments)}var i=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,i=n.length;for(o;i>o;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],i=[];if(o&&e)for(var r=0,a=o.length;a>r;r++)o[r].fn!==e&&o[r].fn._!==e&&i.push(o[r]);return i.length?n[t]=i:delete n[t],this}},e.exports=o},{}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","select"],r);else if("undefined"!=typeof o)r(n,e("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=n(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},a=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),c=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return t.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action=e.action,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""},t.prototype.initSelection=function t(){this.text?this.selectFake():this.target&&this.selectTarget()},t.prototype.selectFake=function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px",this.fakeElem.style.top=(window.pageYOffset||document.documentElement.scrollTop)+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()},t.prototype.removeFake=function t(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)},t.prototype.selectTarget=function t(){this.selectedText=(0,i.default)(this.target),this.copyText()},t.prototype.copyText=function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(n){e=!1}this.handleResult(e)},t.prototype.handleResult=function t(e){e?this.emitter.emit("success",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)}):this.emitter.emit("error",{action:this.action,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})},t.prototype.clearSelection=function t(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()},t.prototype.destroy=function t(){this.removeFake()},a(t,[{key:"action",set:function t(){var e=arguments.length<=0||void 0===arguments[0]?"copy":arguments[0];if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==("undefined"==typeof e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=c})},{select:6}],9:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof o)r(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(t,e,n,o){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var l=i(e),u=i(n),f=i(o),d=function(t){function e(n,o){r(this,e);var i=a(this,t.call(this));return i.resolveOptions(o),i.listenClick(n),i}return c(e,t),e.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText},e.prototype.listenClick=function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})},e.prototype.onClick=function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})},e.prototype.defaultAction=function t(e){return s("action",e)},e.prototype.defaultTarget=function t(e){var n=s("target",e);return n?document.querySelector(n):void 0},e.prototype.defaultText=function t(e){return s("text",e)},e.prototype.destroy=function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)},e}(u.default);t.exports=d})},{"./clipboard-action":8,"good-listener":4,"tiny-emitter":7}]},{},[9])(9)});
|
admin/js/wp-temporary-login-without-password-admin.js
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function ($) {
|
2 |
+
'use strict';
|
3 |
+
|
4 |
+
jQuery(document).ready(function () {
|
5 |
+
//jQuery('#new-wtlwp-form').hide();
|
6 |
+
|
7 |
+
jQuery('#add-new-wtlwp-form-button').click(function () {
|
8 |
+
jQuery('#new-wtlwp-form').show();
|
9 |
+
});
|
10 |
+
|
11 |
+
jQuery('#cancel-new-login-form').click(function () {
|
12 |
+
jQuery('#new-wtlwp-form').hide();
|
13 |
+
});
|
14 |
+
|
15 |
+
if (jQuery('.wtlwp-click-to-copy-btn').get(0)) {
|
16 |
+
|
17 |
+
var clipboard = new Clipboard('.wtlwp-click-to-copy-btn');
|
18 |
+
|
19 |
+
clipboard.on('success', function (e) {
|
20 |
+
var elem = e.trigger;
|
21 |
+
var className = elem.getAttribute('class');
|
22 |
+
jQuery('#copied-text-message-' + className).text('Copied').fadeIn();
|
23 |
+
jQuery('#copied-text-message-' + className).fadeOut('slow');
|
24 |
+
});
|
25 |
+
}
|
26 |
+
|
27 |
+
if (jQuery('.wtlwp-copy-to-clipboard').get(0)) {
|
28 |
+
var clipboard_link = new Clipboard('.wtlwp-copy-to-clipboard');
|
29 |
+
|
30 |
+
clipboard_link.on('success', function (e) {
|
31 |
+
var elem = e.trigger;
|
32 |
+
var id = elem.getAttribute('id');
|
33 |
+
jQuery('#copied-' + id).text('Copied').fadeIn();
|
34 |
+
jQuery('#copied-' + id).fadeOut('slow');
|
35 |
+
});
|
36 |
+
}
|
37 |
+
});
|
38 |
+
})(jQuery);
|
includes/class-wp-temporary-login-without-password-common.php
ADDED
@@ -0,0 +1,442 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Wp_Temporary_Login_Without_Password_Common {
|
4 |
+
|
5 |
+
public static function create_username($data) {
|
6 |
+
|
7 |
+
$first_name = isset($data['user_first_name']) ? $data['user_first_name'] : '';
|
8 |
+
$last_name = isset($data['user_last_name']) ? $data['user_last_name'] : '';
|
9 |
+
$email = isset($data['user_email']) ? $data['user_email'] : '';
|
10 |
+
|
11 |
+
$name = '';
|
12 |
+
if (!empty($first_name) || !empty($last_name)) {
|
13 |
+
$name = str_replace(array('.', '+'), '', trim($first_name . $last_name));
|
14 |
+
} else {
|
15 |
+
if (!empty($email)) {
|
16 |
+
$explode = explode('@', $email);
|
17 |
+
$name = str_replace(array('.', '+'), '', $explode[0]);
|
18 |
+
}
|
19 |
+
}
|
20 |
+
|
21 |
+
if (username_exists($name)) {
|
22 |
+
$name = $name . substr(uniqid('', true), -6);
|
23 |
+
}
|
24 |
+
|
25 |
+
return sanitize_user($name, true);
|
26 |
+
}
|
27 |
+
|
28 |
+
public static function create_new_user($data) {
|
29 |
+
|
30 |
+
if (false === Wp_Temporary_Login_Without_Password_Common::can_manage_wtlwp()) {
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
|
34 |
+
$time = !empty($data['expiry']) ? $data['expiry'] : 'day';
|
35 |
+
|
36 |
+
$password = Wp_Temporary_Login_Without_Password_Common::generate_password();
|
37 |
+
$username = Wp_Temporary_Login_Without_Password_Common::create_username($data);
|
38 |
+
$first_name = isset($data['user_first_name']) ? sanitize_text_field($data['user_first_name']) : '';
|
39 |
+
$last_name = isset($data['user_last_name']) ? sanitize_text_field($data['user_last_name']) : '';
|
40 |
+
$email = isset($data['user_email']) ? sanitize_email($data['user_email']) : '';
|
41 |
+
$user_args = array(
|
42 |
+
'first_name' => $first_name,
|
43 |
+
'last_name' => $last_name,
|
44 |
+
'user_login' => $username,
|
45 |
+
'user_pass' => $password,
|
46 |
+
'user_email' => sanitize_email($email, true),
|
47 |
+
'role' => $data['role'],
|
48 |
+
);
|
49 |
+
|
50 |
+
$user_id = wp_insert_user($user_args);
|
51 |
+
|
52 |
+
if (is_wp_error($user_id)) {
|
53 |
+
$code = $user_id->get_error_code();
|
54 |
+
return array(
|
55 |
+
'error' => true,
|
56 |
+
'errcode' => $code,
|
57 |
+
'message' => $user_id->get_error_message($code)
|
58 |
+
);
|
59 |
+
}
|
60 |
+
|
61 |
+
update_user_meta($user_id, '_wtlwp_user', true);
|
62 |
+
update_user_meta($user_id, '_wtlwp_created', Wp_Temporary_Login_Without_Password_Common::get_current_gmt_timestamp());
|
63 |
+
update_user_meta($user_id, '_wtlwp_expire', Wp_Temporary_Login_Without_Password_Common::get_user_expire_time($time));
|
64 |
+
update_user_meta($user_id, '_wtlwp_token', Wp_Temporary_Login_Without_Password_Common::generate_wtlwp_token($user_id));
|
65 |
+
|
66 |
+
update_user_meta($user_id, 'show_welcome_panel', 0);
|
67 |
+
|
68 |
+
return $user_id;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* get the expiry duration
|
73 |
+
*
|
74 |
+
* @param type $key
|
75 |
+
* @return boolean|array
|
76 |
+
*/
|
77 |
+
public static function get_expiry_duration($key = '') {
|
78 |
+
|
79 |
+
$expiry_duration = array(
|
80 |
+
'3_days' => array(
|
81 |
+
'value' => DAY_IN_SECONDS * 3,
|
82 |
+
'label' => __('Three Days', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
83 |
+
),
|
84 |
+
'day' => array(
|
85 |
+
'value' => DAY_IN_SECONDS,
|
86 |
+
'label' => __('One Day', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
87 |
+
),
|
88 |
+
'3_hours' => array(
|
89 |
+
'value' => HOUR_IN_SECONDS * 3,
|
90 |
+
'label' => __('Three Hours', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
91 |
+
),
|
92 |
+
'hour' => array(
|
93 |
+
'value' => HOUR_IN_SECONDS,
|
94 |
+
'label' => __('One Hour', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
95 |
+
),
|
96 |
+
'week' => array(
|
97 |
+
'value' => WEEK_IN_SECONDS,
|
98 |
+
'label' => __('One Week', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
99 |
+
),
|
100 |
+
'month' => array(
|
101 |
+
'value' => DAY_IN_SECONDS * 30,
|
102 |
+
'label' => __('One Month', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
103 |
+
),
|
104 |
+
);
|
105 |
+
|
106 |
+
|
107 |
+
if (empty($key)) {
|
108 |
+
return $expiry_duration;
|
109 |
+
} elseif (isset($expiry_duration[$key])) {
|
110 |
+
return $expiry_duration[$key];
|
111 |
+
} else {
|
112 |
+
return;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
static function get_expiry_duration_html($selected = '') {
|
117 |
+
|
118 |
+
$p = '';
|
119 |
+
$r = '';
|
120 |
+
|
121 |
+
$expiry_duration = self::get_expiry_duration();
|
122 |
+
|
123 |
+
foreach ($expiry_duration as $key => $duration) {
|
124 |
+
$label = $duration['label'];
|
125 |
+
if ($selected == $key)
|
126 |
+
$p = "\n\t<option selected='selected' value='" . esc_attr($key) . "'>$label</option>";
|
127 |
+
else
|
128 |
+
$r .= "\n\t<option value='" . esc_attr($key) . "'>$label</option>";
|
129 |
+
}
|
130 |
+
|
131 |
+
echo $p . $r;
|
132 |
+
}
|
133 |
+
|
134 |
+
public static function generate_password() {
|
135 |
+
return wp_generate_password(absint(15), true, false);
|
136 |
+
}
|
137 |
+
|
138 |
+
public static function get_user_expire_time($time = '') {
|
139 |
+
$data = self::get_expiry_duration($time);
|
140 |
+
$range = !empty($data['value']) ? $data['value'] : DAY_IN_SECONDS;
|
141 |
+
|
142 |
+
return self::get_current_gmt_timestamp() + floatval($range);
|
143 |
+
}
|
144 |
+
|
145 |
+
public static function get_current_gmt_timestamp() {
|
146 |
+
return strtotime(gmdate('Y-m-d H:i:s', time()));
|
147 |
+
}
|
148 |
+
|
149 |
+
public static function get_temporary_logins() {
|
150 |
+
|
151 |
+
$args = array(
|
152 |
+
'fields' => 'all',
|
153 |
+
'meta_key' => '_wtlwp_expire',
|
154 |
+
'order' => 'DESC',
|
155 |
+
'orderby' => 'meta_value',
|
156 |
+
'meta_query' => array(
|
157 |
+
0 => array(
|
158 |
+
'key' => '_wtlwp_user',
|
159 |
+
'value' => 1
|
160 |
+
)
|
161 |
+
)
|
162 |
+
);
|
163 |
+
|
164 |
+
if (!empty($role)) {
|
165 |
+
$args['role'] = $role;
|
166 |
+
}
|
167 |
+
|
168 |
+
$users = new WP_User_Query($args);
|
169 |
+
|
170 |
+
if (!($users->results)) {
|
171 |
+
return false;
|
172 |
+
}
|
173 |
+
|
174 |
+
return $users->results;
|
175 |
+
}
|
176 |
+
|
177 |
+
public static function format_date_display($stamp = 0, $type = 'date_format') {
|
178 |
+
|
179 |
+
$type_format = 'date_format';
|
180 |
+
if ($type == 'date_format') {
|
181 |
+
$type_format = get_option('date_format');
|
182 |
+
} else if ($type == 'time_format') {
|
183 |
+
$type_format = get_option('time_format');
|
184 |
+
}
|
185 |
+
|
186 |
+
|
187 |
+
$timezone = get_option('timezone_string');
|
188 |
+
|
189 |
+
if (empty($timezone)) {
|
190 |
+
return date($type_format, $stamp);
|
191 |
+
}
|
192 |
+
|
193 |
+
$date = new DateTime('@' . $stamp);
|
194 |
+
|
195 |
+
$date->setTimezone(new DateTimeZone($timezone));
|
196 |
+
|
197 |
+
return $date->format($type_format);
|
198 |
+
}
|
199 |
+
|
200 |
+
public static function get_redirect_link($result = array()) {
|
201 |
+
|
202 |
+
if (empty($result)) {
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
|
206 |
+
$base_url = menu_page_url('wp-temporary-login-without-password', false);
|
207 |
+
|
208 |
+
if (empty($base_url)) {
|
209 |
+
return false;
|
210 |
+
}
|
211 |
+
|
212 |
+
$query_string = '';
|
213 |
+
if (!empty($result['status'])) {
|
214 |
+
if ($result['status'] == 'success') {
|
215 |
+
$query_string .= '&wtlwp_success=1';
|
216 |
+
} elseif ($result['status'] == 'error') {
|
217 |
+
$query_string .= '&wtlwp_error=1';
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
if (!empty($result['message'])) {
|
222 |
+
$query_string .= '&wtlwp_message=' . $result['message'];
|
223 |
+
}
|
224 |
+
|
225 |
+
$redirect_link = $base_url . $query_string;
|
226 |
+
|
227 |
+
return $redirect_link;
|
228 |
+
}
|
229 |
+
|
230 |
+
public static function can_manage_wtlwp($user_id = 0) {
|
231 |
+
|
232 |
+
if (empty($user_id)) {
|
233 |
+
$user_id = get_current_user_id();
|
234 |
+
}
|
235 |
+
|
236 |
+
if (empty($user_id)) {
|
237 |
+
return false;
|
238 |
+
}
|
239 |
+
|
240 |
+
$check = get_user_meta($user_id, '_wtlwp_user', true);
|
241 |
+
|
242 |
+
return !empty($check) ? false : true;
|
243 |
+
}
|
244 |
+
|
245 |
+
public static function is_login_expired($user_id = 0) {
|
246 |
+
|
247 |
+
if (empty($user_id)) {
|
248 |
+
$user_id = get_current_user_id();
|
249 |
+
}
|
250 |
+
|
251 |
+
if (empty($user_id)) {
|
252 |
+
return false;
|
253 |
+
}
|
254 |
+
|
255 |
+
$expire = get_user_meta($user_id, '_wtlwp_expire', true);
|
256 |
+
|
257 |
+
return !empty($expire) && self::get_current_gmt_timestamp() >= floatval($expire) ? true : false;
|
258 |
+
}
|
259 |
+
|
260 |
+
public static function generate_wtlwp_token($user_id) {
|
261 |
+
$str = $user_id . time() . uniqid('', true);
|
262 |
+
return md5($str);
|
263 |
+
}
|
264 |
+
|
265 |
+
public static function get_valid_user_based_on_wtlwp_token($token = '', $user_id = 0, $fields = 'all') {
|
266 |
+
$users_data = array();
|
267 |
+
if (empty($token)) {
|
268 |
+
return false;
|
269 |
+
}
|
270 |
+
|
271 |
+
$args = array(
|
272 |
+
'fields' => $fields,
|
273 |
+
'meta_key' => '_wtlwp_expire',
|
274 |
+
'order' => 'DESC',
|
275 |
+
'orderby' => 'meta_value',
|
276 |
+
'meta_query' => array(
|
277 |
+
0 => array(
|
278 |
+
'key' => '_wtlwp_token',
|
279 |
+
'value' => sanitize_text_field($token),
|
280 |
+
'compare' => '='
|
281 |
+
)
|
282 |
+
)
|
283 |
+
);
|
284 |
+
|
285 |
+
$users = new WP_User_Query($args);
|
286 |
+
|
287 |
+
if (empty($users->results)) {
|
288 |
+
return false;
|
289 |
+
}
|
290 |
+
|
291 |
+
$users_data = $users->results;
|
292 |
+
foreach ($users_data as $key => $user) {
|
293 |
+
$expire = get_user_meta($user->ID, '_wtlwp_expire', true);
|
294 |
+
if ($expire <= self::get_current_gmt_timestamp()) {
|
295 |
+
unset($users_data[$key]);
|
296 |
+
}
|
297 |
+
}
|
298 |
+
|
299 |
+
return $users_data;
|
300 |
+
}
|
301 |
+
|
302 |
+
public static function is_valid_temporary_login($user_id = 0, $check_expiry = true) {
|
303 |
+
|
304 |
+
if (empty($user_id)) {
|
305 |
+
return false;
|
306 |
+
}
|
307 |
+
|
308 |
+
$check = get_user_meta($user_id, '_wtlwp_user', true);
|
309 |
+
|
310 |
+
if(!empty($check) && $check_expiry) {
|
311 |
+
$check = !(self::is_login_expired($user_id));
|
312 |
+
}
|
313 |
+
|
314 |
+
return !empty($check) ? true : false;
|
315 |
+
}
|
316 |
+
|
317 |
+
public static function get_manage_login_url($user_id, $action = '') {
|
318 |
+
|
319 |
+
if (empty($user_id) || empty($action)) {
|
320 |
+
return;
|
321 |
+
}
|
322 |
+
|
323 |
+
$base_url = menu_page_url('wp-temporary-login-without-password', false);
|
324 |
+
$args = array();
|
325 |
+
|
326 |
+
switch($action) {
|
327 |
+
case 'disable';
|
328 |
+
$args = array('wtlwp_action' => 'disable','user_id' => $user_id);
|
329 |
+
break;
|
330 |
+
case 'enable';
|
331 |
+
$args = array('wtlwp_action' => 'enable','user_id' => $user_id);
|
332 |
+
break;
|
333 |
+
case 'delete';
|
334 |
+
$args = array('wtlwp_action' => 'delete','user_id' => $user_id);
|
335 |
+
break;
|
336 |
+
default:
|
337 |
+
break;
|
338 |
+
}
|
339 |
+
|
340 |
+
$manage_login_url = '';
|
341 |
+
if (!empty($args)) {
|
342 |
+
$base_url = add_query_arg($args, trailingslashit($base_url));
|
343 |
+
$manage_login_url = wp_nonce_url($base_url, 'manage-temporary-login_' . $user_id, 'manage-temporary-login');
|
344 |
+
}
|
345 |
+
|
346 |
+
return $manage_login_url;
|
347 |
+
}
|
348 |
+
|
349 |
+
public static function get_login_url($user_id) {
|
350 |
+
|
351 |
+
if (empty($user_id) ) {
|
352 |
+
return;
|
353 |
+
}
|
354 |
+
|
355 |
+
$is_valid_temporary_login = self::is_valid_temporary_login($user_id, false);
|
356 |
+
if (!$is_valid_temporary_login) {
|
357 |
+
return;
|
358 |
+
}
|
359 |
+
|
360 |
+
$wtlwp_token = get_user_meta($user_id, '_wtlwp_token', true);
|
361 |
+
if (empty($wtlwp_token)) {
|
362 |
+
return;
|
363 |
+
}
|
364 |
+
|
365 |
+
$login_url = add_query_arg('wtlwp_token', $wtlwp_token, trailingslashit(admin_url()));
|
366 |
+
|
367 |
+
return $login_url;
|
368 |
+
}
|
369 |
+
|
370 |
+
public static function manage_login($user_id = 0, $action = '') {
|
371 |
+
|
372 |
+
if (empty($user_id) || empty($action)) {
|
373 |
+
return;
|
374 |
+
}
|
375 |
+
|
376 |
+
$is_valid_temporary_login = self::is_valid_temporary_login($user_id, false);
|
377 |
+
if (!$is_valid_temporary_login) {
|
378 |
+
return;
|
379 |
+
}
|
380 |
+
|
381 |
+
$manage_login = false;
|
382 |
+
if ($action == 'disable') {
|
383 |
+
$manage_login = update_user_meta($user_id, '_wtlwp_expire', self::get_current_gmt_timestamp());
|
384 |
+
} elseif ($action == 'enable') {
|
385 |
+
$manage_login = update_user_meta($user_id, '_wtlwp_expire', self::get_user_expire_time());
|
386 |
+
}
|
387 |
+
|
388 |
+
if ($manage_login) {
|
389 |
+
return true;
|
390 |
+
}
|
391 |
+
|
392 |
+
return false;
|
393 |
+
}
|
394 |
+
|
395 |
+
public static function time_elapsed_string($time, $ago = false) {
|
396 |
+
|
397 |
+
if ($ago) {
|
398 |
+
$etime = self::get_current_gmt_timestamp() - $time;
|
399 |
+
} else {
|
400 |
+
$etime = $time - self::get_current_gmt_timestamp();
|
401 |
+
}
|
402 |
+
|
403 |
+
if ($etime < 1) {
|
404 |
+
return __('Expired', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
405 |
+
}
|
406 |
+
|
407 |
+
$a = array(365 * 24 * 60 * 60 => 'year',
|
408 |
+
30 * 24 * 60 * 60 => 'month',
|
409 |
+
24 * 60 * 60 => 'day',
|
410 |
+
60 * 60 => 'hour',
|
411 |
+
60 => 'minute',
|
412 |
+
1 => 'second'
|
413 |
+
);
|
414 |
+
|
415 |
+
$a_plural = array('year' => 'years',
|
416 |
+
'month' => 'months',
|
417 |
+
'day' => 'days',
|
418 |
+
'hour' => 'hours',
|
419 |
+
'minute' => 'minutes',
|
420 |
+
'second' => 'seconds'
|
421 |
+
);
|
422 |
+
|
423 |
+
foreach ($a as $secs => $str) {
|
424 |
+
$d = $etime / $secs;
|
425 |
+
if ($d >= 1) {
|
426 |
+
$r = round($d);
|
427 |
+
if ($ago) {
|
428 |
+
return __(sprintf('%d %s ago', $r, ($r > 1 ? $a_plural[$str] : $str)), Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
429 |
+
} else {
|
430 |
+
return __(sprintf('%d %s remaining', $r, ($r > 1 ? $a_plural[$str] : $str)), Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
431 |
+
}
|
432 |
+
}
|
433 |
+
}
|
434 |
+
}
|
435 |
+
|
436 |
+
public static function get_blocked_pages() {
|
437 |
+
$blocked_pages = array('wp-temporary-login-without-password', 'user-new.php', 'user-edit.php', 'profile.php');
|
438 |
+
$blocked_pages = apply_filters('wtlwp_restricted_pages_for_temporary_users', $blocked_pages);
|
439 |
+
return $blocked_pages;
|
440 |
+
}
|
441 |
+
|
442 |
+
}
|
includes/class-wp-temporary-login-without-password-i18n.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Define the internationalization functionality
|
5 |
+
*/
|
6 |
+
class Wp_Temporary_Login_Without_Password_i18n {
|
7 |
+
|
8 |
+
static $text_domain = 'wp-temporary-login-without-password';
|
9 |
+
|
10 |
+
public function load_plugin_textdomain() {
|
11 |
+
|
12 |
+
load_plugin_textdomain(
|
13 |
+
self::$text_domain, false, dirname(dirname(plugin_basename(__FILE__))) . '/languages/'
|
14 |
+
);
|
15 |
+
}
|
16 |
+
|
17 |
+
}
|
includes/class-wp-temporary-login-without-password-layout.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Wp_Temporary_Login_Without_Password_Layout {
|
4 |
+
|
5 |
+
public static function prepare_header_footer_row() {
|
6 |
+
|
7 |
+
$row = '';
|
8 |
+
|
9 |
+
$row .= '<th class="manage-column column-details" colspan="2">' . __('Users', Wp_Temporary_Login_Without_Password_i18n::$text_domain) . '</th>';
|
10 |
+
$row .= '<th class="manage-column column-email">' . __('Role', Wp_Temporary_Login_Without_Password_i18n::$text_domain) . '</th>';
|
11 |
+
$row .= '<th class="manage-column column-expired">' . __('Last Logged In', Wp_Temporary_Login_Without_Password_i18n::$text_domain) . '</th>';
|
12 |
+
$row .= '<th class="manage-column column-expired">' . __('Expiry', Wp_Temporary_Login_Without_Password_i18n::$text_domain) . '</th>';
|
13 |
+
$row .= '<th class="manage-column column-expired">' . __('Actions', Wp_Temporary_Login_Without_Password_i18n::$text_domain) . '</th>';
|
14 |
+
|
15 |
+
return $row;
|
16 |
+
}
|
17 |
+
|
18 |
+
public static function prepare_empty_user_row() {
|
19 |
+
|
20 |
+
$row = '';
|
21 |
+
|
22 |
+
$row .= '<tr class="tempadmin-single-user-row tempadmin-empty-users-row standard">';
|
23 |
+
$row .= '<td colspan="6">';
|
24 |
+
$row .= '<span class="description">' . __('You have not created any temporary logins yet.', Wp_Temporary_Login_Without_Password_i18n::$text_domain) . '</span>';
|
25 |
+
$row .= '</td>';
|
26 |
+
$row .= '</tr>';
|
27 |
+
|
28 |
+
return $row;
|
29 |
+
}
|
30 |
+
|
31 |
+
public static function prepare_single_user_row($user = OBJECT, $class = 'standard') {
|
32 |
+
global $wpdb;
|
33 |
+
if (is_numeric($user) && !is_object($user)) {
|
34 |
+
$user = get_user_by('id', $user);
|
35 |
+
}
|
36 |
+
|
37 |
+
$create = get_user_meta($user->ID, '_wtlwp_created', true);
|
38 |
+
$expire = get_user_meta($user->ID, '_wtlwp_expire', true);
|
39 |
+
$token = get_user_meta($user->ID, '_wtlwp_token', true);
|
40 |
+
$last_login_time = get_user_meta($user->ID, '_wtlwp_last_login', true);
|
41 |
+
|
42 |
+
$last_login_str = __('Not yet logged in', Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
43 |
+
if (!empty($last_login_time)) {
|
44 |
+
$last_login_str = Wp_Temporary_Login_Without_Password_Common::time_elapsed_string($last_login_time, true);
|
45 |
+
}
|
46 |
+
|
47 |
+
$wtlwp_status = "Active";
|
48 |
+
if (Wp_Temporary_Login_Without_Password_Common::is_login_expired($user->ID)) {
|
49 |
+
$wtlwp_status = "Expired";
|
50 |
+
}
|
51 |
+
|
52 |
+
$capabilities = $user->{$wpdb->prefix . 'capabilities'};
|
53 |
+
$wp_roles = new WP_Roles();
|
54 |
+
foreach ($wp_roles->role_names as $role => $name) {
|
55 |
+
if (array_key_exists($role, $capabilities)) {
|
56 |
+
$user_role = $name;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
$user_details = "<div><span>";
|
62 |
+
if ((esc_attr($user->first_name))) {
|
63 |
+
$user_details .= "<span>" . esc_attr($user->first_name) . "</span>";
|
64 |
+
}
|
65 |
+
|
66 |
+
if ((esc_attr($user->last_name))) {
|
67 |
+
$user_details .= "<span> " . esc_attr($user->last_name) . "</span>";
|
68 |
+
}
|
69 |
+
|
70 |
+
$user_details .= " (<span class='wtlwp-user-login'>" . esc_attr($user->user_login) . ")</span><br />";
|
71 |
+
|
72 |
+
if ((esc_attr($user->user_email))) {
|
73 |
+
$user_details .= "<span><b>" . esc_attr($user->user_email) . "</b></span> <br />";
|
74 |
+
}
|
75 |
+
|
76 |
+
$user_details .= "</span></div>";
|
77 |
+
|
78 |
+
$row = '';
|
79 |
+
|
80 |
+
$row .= '<tr id="single-user-' . absint($user->ID) . '" class="tempadmin-single-user-row">';
|
81 |
+
$row .= '<td class="email column-details" colspan="2">' . $user_details . '</td>';
|
82 |
+
$row .= '<td class="wtlwp-token column-role">' . esc_attr($user_role) . '</td>';
|
83 |
+
$row .= '<td class="wtlwp-token column-last-login">' . esc_attr($last_login_str) . '</td>';
|
84 |
+
|
85 |
+
$row .= '<td class="expired column-expired wtlwp-status-' . strtolower($wtlwp_status) . '">';
|
86 |
+
if (!empty($expire)) {
|
87 |
+
$row .= Wp_Temporary_Login_Without_Password_Common::time_elapsed_string($expire);
|
88 |
+
}
|
89 |
+
$row .= '</td>';
|
90 |
+
$row .= '<td class="wtlwp-token column-email">' . self::prepare_row_actions($user, $wtlwp_status) . '</td>';
|
91 |
+
$row .= '</tr>';
|
92 |
+
|
93 |
+
return $row;
|
94 |
+
}
|
95 |
+
|
96 |
+
public static function prepare_row_actions($user, $wtlwp_status) {
|
97 |
+
|
98 |
+
$action_row = '<div class="actions">';
|
99 |
+
|
100 |
+
$user_id = $user->ID;
|
101 |
+
|
102 |
+
$delete_login_url = Wp_Temporary_Login_Without_Password_Common::get_manage_login_url($user_id, 'delete');
|
103 |
+
$disable_login_url = Wp_Temporary_Login_Without_Password_Common::get_manage_login_url($user_id, 'disable');
|
104 |
+
$enable_login_url = Wp_Temporary_Login_Without_Password_Common::get_manage_login_url($user_id, 'enable');
|
105 |
+
|
106 |
+
if (strtolower($wtlwp_status) == 'expired') {
|
107 |
+
$action_row .= '<span class="enable"><a title="'. __('Reactivate for one day', Wp_Temporary_Login_Without_Password_i18n::$text_domain) .'" href="' . $enable_login_url . '"><span class="dashicons dashicons-lock"></a></span></span>';
|
108 |
+
} elseif (strtolower($wtlwp_status) == 'active') {
|
109 |
+
$action_row .= '<span class="disable"><a title="'. __('Disable', Wp_Temporary_Login_Without_Password_i18n::$text_domain) .'" href="' . $disable_login_url . '"><span class="dashicons dashicons-unlock"></span></a></span>';
|
110 |
+
}
|
111 |
+
|
112 |
+
$action_row .= '<span class="edit"><a title="'. __('Delete', Wp_Temporary_Login_Without_Password_i18n::$text_domain) .'" href="' . $delete_login_url . '"><span class="dashicons dashicons-no"></span></a></span>';
|
113 |
+
$action_row .= '<span class="edit"><span id="text-' . $user->ID . '" class="dashicons dashicons-admin-links wtlwp-copy-to-clipboard" title="'. __('Copy login link', Wp_Temporary_Login_Without_Password_i18n::$text_domain) .'" data-clipboard-text="' . Wp_Temporary_Login_Without_Password_Common::get_login_url($user->ID) . '"></span></span>';
|
114 |
+
$action_row .= '<span id="copied-text-' . $user->ID . '" class="copied-text-message"></span>';
|
115 |
+
$action_row .= '</div>';
|
116 |
+
|
117 |
+
return $action_row;
|
118 |
+
}
|
119 |
+
|
120 |
+
}
|
includes/class-wp-temporary-login-without-password-loader.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Register all actions and filters for the plugin
|
5 |
+
*/
|
6 |
+
class Wp_Temporary_Login_Without_Password_Loader {
|
7 |
+
|
8 |
+
protected $actions;
|
9 |
+
protected $filters;
|
10 |
+
|
11 |
+
public function __construct() {
|
12 |
+
$this->actions = array();
|
13 |
+
$this->filters = array();
|
14 |
+
}
|
15 |
+
|
16 |
+
public function add_action($hook, $component, $callback, $priority = 10, $accepted_args = 1) {
|
17 |
+
$this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args);
|
18 |
+
}
|
19 |
+
|
20 |
+
public function add_filter($hook, $component, $callback, $priority = 10, $accepted_args = 1) {
|
21 |
+
$this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args);
|
22 |
+
}
|
23 |
+
|
24 |
+
private function add($hooks, $hook, $component, $callback, $priority, $accepted_args) {
|
25 |
+
|
26 |
+
$hooks[] = array(
|
27 |
+
'hook' => $hook,
|
28 |
+
'component' => $component,
|
29 |
+
'callback' => $callback,
|
30 |
+
'priority' => $priority,
|
31 |
+
'accepted_args' => $accepted_args
|
32 |
+
);
|
33 |
+
|
34 |
+
return $hooks;
|
35 |
+
}
|
36 |
+
|
37 |
+
public function run() {
|
38 |
+
|
39 |
+
foreach ($this->filters as $hook) {
|
40 |
+
add_filter($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'], $hook['accepted_args']);
|
41 |
+
}
|
42 |
+
|
43 |
+
foreach ($this->actions as $hook) {
|
44 |
+
add_action($hook['hook'], array($hook['component'], $hook['callback']), $hook['priority'], $hook['accepted_args']);
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
}
|
includes/class-wp-temporary-login-without-password.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Wp_Temporary_Login_Without_Password {
|
4 |
+
|
5 |
+
protected $loader;
|
6 |
+
|
7 |
+
protected $plugin_name;
|
8 |
+
|
9 |
+
protected $version;
|
10 |
+
|
11 |
+
public function __construct() {
|
12 |
+
|
13 |
+
$this->plugin_name = 'wp-temporary-login-without-password';
|
14 |
+
$this->version = '1.0';
|
15 |
+
|
16 |
+
$this->load_dependencies();
|
17 |
+
$this->set_locale();
|
18 |
+
$this->define_admin_hooks();
|
19 |
+
$this->define_public_hooks();
|
20 |
+
}
|
21 |
+
|
22 |
+
public function define_constant($name, $value) {
|
23 |
+
if (!defined($name)) {
|
24 |
+
define($name, $value);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
private function load_dependencies() {
|
29 |
+
|
30 |
+
require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-wp-temporary-login-without-password-loader.php';
|
31 |
+
require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-wp-temporary-login-without-password-i18n.php';
|
32 |
+
require_once plugin_dir_path(dirname(__FILE__)) . 'admin/class-wp-temporary-login-without-password-admin.php';
|
33 |
+
require_once plugin_dir_path(dirname(__FILE__)) . 'public/class-wp-temporary-login-without-password-public.php';
|
34 |
+
|
35 |
+
require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-wp-temporary-login-without-password-common.php';
|
36 |
+
require_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-wp-temporary-login-without-password-layout.php';
|
37 |
+
|
38 |
+
$this->loader = new Wp_Temporary_Login_Without_Password_Loader();
|
39 |
+
}
|
40 |
+
|
41 |
+
private function set_locale() {
|
42 |
+
|
43 |
+
$plugin_i18n = new Wp_Temporary_Login_Without_Password_i18n();
|
44 |
+
|
45 |
+
$this->loader->add_action('plugins_loaded', $plugin_i18n, 'load_plugin_textdomain');
|
46 |
+
}
|
47 |
+
|
48 |
+
private function define_admin_hooks() {
|
49 |
+
|
50 |
+
$plugin_admin = new Wp_Temporary_Login_Without_Password_Admin($this->get_plugin_name(), $this->get_version());
|
51 |
+
|
52 |
+
$this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles');
|
53 |
+
$this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts');
|
54 |
+
|
55 |
+
$this->loader->add_action('admin_menu', $plugin_admin, 'admin_menu');
|
56 |
+
$this->loader->add_action('admin_init', $plugin_admin, 'create_user');
|
57 |
+
$this->loader->add_action('admin_init', $plugin_admin, 'delete_user');
|
58 |
+
$this->loader->add_action('admin_init', $plugin_admin, 'manage_temporary_login');
|
59 |
+
$this->loader->add_action('admin_notices', $plugin_admin, 'display_admin_notices');
|
60 |
+
|
61 |
+
$this->loader->add_filter('wpmu_welcome_notification', $plugin_admin, 'disable_welcome_notification', 10, 5);
|
62 |
+
}
|
63 |
+
|
64 |
+
private function define_public_hooks() {
|
65 |
+
|
66 |
+
$plugin_public = new Wp_Temporary_Login_Without_Password_Public($this->get_plugin_name(), $this->get_version());
|
67 |
+
|
68 |
+
$this->loader->add_action('init', $plugin_public, 'init_wtlwp');
|
69 |
+
$this->loader->add_filter('authenticate', $plugin_public, 'wtlwp_authenticate', 10, 3);
|
70 |
+
}
|
71 |
+
|
72 |
+
public function run() {
|
73 |
+
$this->loader->run();
|
74 |
+
}
|
75 |
+
|
76 |
+
public function get_plugin_name() {
|
77 |
+
return $this->plugin_name;
|
78 |
+
}
|
79 |
+
|
80 |
+
public function get_loader() {
|
81 |
+
return $this->loader;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function get_version() {
|
85 |
+
return $this->version;
|
86 |
+
}
|
87 |
+
|
88 |
+
}
|
includes/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
languages/wp-temporary-login-without-password.pot
ADDED
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Loco Gettext template
|
2 |
+
#, fuzzy
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"Project-Id-Version: WP Temporary Login Without Password\n"
|
6 |
+
"Report-Msgid-Bugs-To: \n"
|
7 |
+
"POT-Creation-Date: Tue Jul 26 2016 14:37:55 GMT+0530 (IST)\n"
|
8 |
+
"POT-Revision-Date: Wed Aug 03 2016 14:53:20 GMT+0530 (IST)\n"
|
9 |
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
10 |
+
"Last-Translator: \n"
|
11 |
+
"Language-Team: \n"
|
12 |
+
"Language: \n"
|
13 |
+
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n"
|
14 |
+
"MIME-Version: 1.0\n"
|
15 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
16 |
+
"Content-Transfer-Encoding: 8bit\n"
|
17 |
+
"X-Poedit-SourceCharset: UTF-8\n"
|
18 |
+
"X-Poedit-Basepath: .\n"
|
19 |
+
"X-Poedit-SearchPath-0: ..\n"
|
20 |
+
"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
|
21 |
+
"__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
|
22 |
+
"_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
|
23 |
+
"esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
|
24 |
+
"esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
|
25 |
+
"X-Generator: Loco - https://localise.biz/"
|
26 |
+
|
27 |
+
#. Name of the plugin
|
28 |
+
msgid "Temporary Login Without Password"
|
29 |
+
msgstr ""
|
30 |
+
|
31 |
+
#. URI of the plugin
|
32 |
+
msgid "http://storeapps.org"
|
33 |
+
msgstr ""
|
34 |
+
|
35 |
+
#. Description of the plugin
|
36 |
+
msgid ""
|
37 |
+
"Create a temporary login link for your developer with any role using which "
|
38 |
+
"they can access to your sytem without login and password for limited period "
|
39 |
+
"of time."
|
40 |
+
msgstr ""
|
41 |
+
|
42 |
+
#. Author of the plugin
|
43 |
+
msgid "StoreApps"
|
44 |
+
msgstr ""
|
45 |
+
|
46 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:26 ../admin/class-
|
47 |
+
#: wp-temporary-login-without-password-admin.php:26 ../templates/admin_settings.
|
48 |
+
#: php:3
|
49 |
+
msgid "Temporary Logins"
|
50 |
+
msgstr ""
|
51 |
+
|
52 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:181
|
53 |
+
msgid "User creation failed"
|
54 |
+
msgstr ""
|
55 |
+
|
56 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:185
|
57 |
+
msgid "You do not have permission to create a temporary login"
|
58 |
+
msgstr ""
|
59 |
+
|
60 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:189
|
61 |
+
msgid "Email already is in use"
|
62 |
+
msgstr ""
|
63 |
+
|
64 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:193
|
65 |
+
msgid "Please enter valid email address. Email field should not be empty"
|
66 |
+
msgstr ""
|
67 |
+
|
68 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:197
|
69 |
+
msgid "Please enter valid email address"
|
70 |
+
msgstr ""
|
71 |
+
|
72 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:201
|
73 |
+
msgid "User you are trying to delete is not temporary"
|
74 |
+
msgstr ""
|
75 |
+
|
76 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:205
|
77 |
+
msgid "Nonce failed"
|
78 |
+
msgstr ""
|
79 |
+
|
80 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:209
|
81 |
+
msgid "Invalid action"
|
82 |
+
msgstr ""
|
83 |
+
|
84 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:214
|
85 |
+
msgid "Unknown error occured"
|
86 |
+
msgstr ""
|
87 |
+
|
88 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:222
|
89 |
+
msgid "Login created successfully!"
|
90 |
+
msgstr ""
|
91 |
+
|
92 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:226
|
93 |
+
msgid "Login deleted successfully!"
|
94 |
+
msgstr ""
|
95 |
+
|
96 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:230
|
97 |
+
msgid "Login disabled successfully!"
|
98 |
+
msgstr ""
|
99 |
+
|
100 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:234
|
101 |
+
msgid "Login enabled successfully!"
|
102 |
+
msgstr ""
|
103 |
+
|
104 |
+
#: ../admin/class-wp-temporary-login-without-password-admin.php:238
|
105 |
+
msgid "Success!"
|
106 |
+
msgstr ""
|
107 |
+
|
108 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:82
|
109 |
+
msgid "Three Days"
|
110 |
+
msgstr ""
|
111 |
+
|
112 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:86
|
113 |
+
msgid "One Day"
|
114 |
+
msgstr ""
|
115 |
+
|
116 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:90
|
117 |
+
msgid "Three Hours"
|
118 |
+
msgstr ""
|
119 |
+
|
120 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:94
|
121 |
+
msgid "One Hour"
|
122 |
+
msgstr ""
|
123 |
+
|
124 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:98
|
125 |
+
msgid "One Week"
|
126 |
+
msgstr ""
|
127 |
+
|
128 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:102
|
129 |
+
msgid "One Month"
|
130 |
+
msgstr ""
|
131 |
+
|
132 |
+
#: ../includes/class-wp-temporary-login-without-password-common.php:404
|
133 |
+
msgid "Expired"
|
134 |
+
msgstr ""
|
135 |
+
|
136 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:9
|
137 |
+
msgid "Users"
|
138 |
+
msgstr ""
|
139 |
+
|
140 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:10 ..
|
141 |
+
#: /templates/new_login.php:19
|
142 |
+
msgid "Role"
|
143 |
+
msgstr ""
|
144 |
+
|
145 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:11
|
146 |
+
msgid "Last Logged In"
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:12 ..
|
150 |
+
#: /templates/new_login.php:27
|
151 |
+
msgid "Expiry"
|
152 |
+
msgstr ""
|
153 |
+
|
154 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:13
|
155 |
+
msgid "Actions"
|
156 |
+
msgstr ""
|
157 |
+
|
158 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:24
|
159 |
+
msgid "You have not created any temporary logins yet."
|
160 |
+
msgstr ""
|
161 |
+
|
162 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:42
|
163 |
+
msgid "Not yet logged in"
|
164 |
+
msgstr ""
|
165 |
+
|
166 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:107
|
167 |
+
msgid "Reactivate for one day"
|
168 |
+
msgstr ""
|
169 |
+
|
170 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:109
|
171 |
+
msgid "Disable"
|
172 |
+
msgstr ""
|
173 |
+
|
174 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:112
|
175 |
+
msgid "Delete"
|
176 |
+
msgstr ""
|
177 |
+
|
178 |
+
#: ../includes/class-wp-temporary-login-without-password-layout.php:113
|
179 |
+
msgid "Copy login link"
|
180 |
+
msgstr ""
|
181 |
+
|
182 |
+
#: ../public/class-wp-temporary-login-without-password-public.php:16
|
183 |
+
msgid "Token empty"
|
184 |
+
msgstr ""
|
185 |
+
|
186 |
+
#: ../public/class-wp-temporary-login-without-password-public.php:17
|
187 |
+
msgid "Authentication failed"
|
188 |
+
msgstr ""
|
189 |
+
|
190 |
+
#: ../public/class-wp-temporary-login-without-password-public.php:63
|
191 |
+
msgid "You don't have permission to access this page"
|
192 |
+
msgstr ""
|
193 |
+
|
194 |
+
#: ../public/class-wp-temporary-login-without-password-public.php:75
|
195 |
+
msgid "ERROR: Invalid username."
|
196 |
+
msgstr ""
|
197 |
+
|
198 |
+
#: ../public/class-wp-temporary-login-without-password-public.php:84
|
199 |
+
msgid "ERROR: User can't find."
|
200 |
+
msgstr ""
|
201 |
+
|
202 |
+
#: ../templates/admin_settings.php:3
|
203 |
+
msgid "Create New"
|
204 |
+
msgstr ""
|
205 |
+
|
206 |
+
#: ../templates/admin_settings.php:13
|
207 |
+
msgid "Here's a temporary login link"
|
208 |
+
msgstr ""
|
209 |
+
|
210 |
+
#: ../templates/admin_settings.php:15
|
211 |
+
msgid "Click To Copy"
|
212 |
+
msgstr ""
|
213 |
+
|
214 |
+
#: ../templates/admin_settings.php:17
|
215 |
+
msgid ""
|
216 |
+
"User can directly login to wordpress admin panel without username and "
|
217 |
+
"password by opening this link."
|
218 |
+
msgstr ""
|
219 |
+
|
220 |
+
#: ../templates/new_login.php:1
|
221 |
+
msgid "Create a new Temporary Login"
|
222 |
+
msgstr ""
|
223 |
+
|
224 |
+
#: ../templates/new_login.php:5
|
225 |
+
msgid "Email*"
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#: ../templates/new_login.php:10
|
229 |
+
msgid "First Name"
|
230 |
+
msgstr ""
|
231 |
+
|
232 |
+
#: ../templates/new_login.php:15
|
233 |
+
msgid "Last Name"
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#: ../templates/new_login.php:36
|
237 |
+
msgid "Submit"
|
238 |
+
msgstr ""
|
239 |
+
|
240 |
+
#: ../templates/new_login.php:36
|
241 |
+
msgid "or"
|
242 |
+
msgstr ""
|
243 |
+
|
244 |
+
#: ../templates/new_login.php:36
|
245 |
+
msgid "Cancel"
|
246 |
+
msgstr ""
|
license.txt
ADDED
@@ -0,0 +1,339 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
7 |
+
of this license document, but changing it is not allowed.
|
8 |
+
|
9 |
+
Preamble
|
10 |
+
|
11 |
+
The licenses for most software are designed to take away your
|
12 |
+
freedom to share and change it. By contrast, the GNU General Public
|
13 |
+
License is intended to guarantee your freedom to share and change free
|
14 |
+
software--to make sure the software is free for all its users. This
|
15 |
+
General Public License applies to most of the Free Software
|
16 |
+
Foundation's software and to any other program whose authors commit to
|
17 |
+
using it. (Some other Free Software Foundation software is covered by
|
18 |
+
the GNU Lesser General Public License instead.) You can apply it to
|
19 |
+
your programs, too.
|
20 |
+
|
21 |
+
When we speak of free software, we are referring to freedom, not
|
22 |
+
price. Our General Public Licenses are designed to make sure that you
|
23 |
+
have the freedom to distribute copies of free software (and charge for
|
24 |
+
this service if you wish), that you receive source code or can get it
|
25 |
+
if you want it, that you can change the software or use pieces of it
|
26 |
+
in new free programs; and that you know you can do these things.
|
27 |
+
|
28 |
+
To protect your rights, we need to make restrictions that forbid
|
29 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
30 |
+
These restrictions translate to certain responsibilities for you if you
|
31 |
+
distribute copies of the software, or if you modify it.
|
32 |
+
|
33 |
+
For example, if you distribute copies of such a program, whether
|
34 |
+
gratis or for a fee, you must give the recipients all the rights that
|
35 |
+
you have. You must make sure that they, too, receive or can get the
|
36 |
+
source code. And you must show them these terms so they know their
|
37 |
+
rights.
|
38 |
+
|
39 |
+
We protect your rights with two steps: (1) copyright the software, and
|
40 |
+
(2) offer you this license which gives you legal permission to copy,
|
41 |
+
distribute and/or modify the software.
|
42 |
+
|
43 |
+
Also, for each author's protection and ours, we want to make certain
|
44 |
+
that everyone understands that there is no warranty for this free
|
45 |
+
software. If the software is modified by someone else and passed on, we
|
46 |
+
want its recipients to know that what they have is not the original, so
|
47 |
+
that any problems introduced by others will not reflect on the original
|
48 |
+
authors' reputations.
|
49 |
+
|
50 |
+
Finally, any free program is threatened constantly by software
|
51 |
+
patents. We wish to avoid the danger that redistributors of a free
|
52 |
+
program will individually obtain patent licenses, in effect making the
|
53 |
+
program proprietary. To prevent this, we have made it clear that any
|
54 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
55 |
+
|
56 |
+
The precise terms and conditions for copying, distribution and
|
57 |
+
modification follow.
|
58 |
+
|
59 |
+
GNU GENERAL PUBLIC LICENSE
|
60 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
+
|
62 |
+
0. This License applies to any program or other work which contains
|
63 |
+
a notice placed by the copyright holder saying it may be distributed
|
64 |
+
under the terms of this General Public License. The "Program", below,
|
65 |
+
refers to any such program or work, and a "work based on the Program"
|
66 |
+
means either the Program or any derivative work under copyright law:
|
67 |
+
that is to say, a work containing the Program or a portion of it,
|
68 |
+
either verbatim or with modifications and/or translated into another
|
69 |
+
language. (Hereinafter, translation is included without limitation in
|
70 |
+
the term "modification".) Each licensee is addressed as "you".
|
71 |
+
|
72 |
+
Activities other than copying, distribution and modification are not
|
73 |
+
covered by this License; they are outside its scope. The act of
|
74 |
+
running the Program is not restricted, and the output from the Program
|
75 |
+
is covered only if its contents constitute a work based on the
|
76 |
+
Program (independent of having been made by running the Program).
|
77 |
+
Whether that is true depends on what the Program does.
|
78 |
+
|
79 |
+
1. You may copy and distribute verbatim copies of the Program's
|
80 |
+
source code as you receive it, in any medium, provided that you
|
81 |
+
conspicuously and appropriately publish on each copy an appropriate
|
82 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
83 |
+
notices that refer to this License and to the absence of any warranty;
|
84 |
+
and give any other recipients of the Program a copy of this License
|
85 |
+
along with the Program.
|
86 |
+
|
87 |
+
You may charge a fee for the physical act of transferring a copy, and
|
88 |
+
you may at your option offer warranty protection in exchange for a fee.
|
89 |
+
|
90 |
+
2. You may modify your copy or copies of the Program or any portion
|
91 |
+
of it, thus forming a work based on the Program, and copy and
|
92 |
+
distribute such modifications or work under the terms of Section 1
|
93 |
+
above, provided that you also meet all of these conditions:
|
94 |
+
|
95 |
+
a) You must cause the modified files to carry prominent notices
|
96 |
+
stating that you changed the files and the date of any change.
|
97 |
+
|
98 |
+
b) You must cause any work that you distribute or publish, that in
|
99 |
+
whole or in part contains or is derived from the Program or any
|
100 |
+
part thereof, to be licensed as a whole at no charge to all third
|
101 |
+
parties under the terms of this License.
|
102 |
+
|
103 |
+
c) If the modified program normally reads commands interactively
|
104 |
+
when run, you must cause it, when started running for such
|
105 |
+
interactive use in the most ordinary way, to print or display an
|
106 |
+
announcement including an appropriate copyright notice and a
|
107 |
+
notice that there is no warranty (or else, saying that you provide
|
108 |
+
a warranty) and that users may redistribute the program under
|
109 |
+
these conditions, and telling the user how to view a copy of this
|
110 |
+
License. (Exception: if the Program itself is interactive but
|
111 |
+
does not normally print such an announcement, your work based on
|
112 |
+
the Program is not required to print an announcement.)
|
113 |
+
|
114 |
+
These requirements apply to the modified work as a whole. If
|
115 |
+
identifiable sections of that work are not derived from the Program,
|
116 |
+
and can be reasonably considered independent and separate works in
|
117 |
+
themselves, then this License, and its terms, do not apply to those
|
118 |
+
sections when you distribute them as separate works. But when you
|
119 |
+
distribute the same sections as part of a whole which is a work based
|
120 |
+
on the Program, the distribution of the whole must be on the terms of
|
121 |
+
this License, whose permissions for other licensees extend to the
|
122 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
123 |
+
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
+
|
282 |
+
How to Apply These Terms to Your New Programs
|
283 |
+
|
284 |
+
If you develop a new program, and you want it to be of the greatest
|
285 |
+
possible use to the public, the best way to achieve this is to make it
|
286 |
+
free software which everyone can redistribute and change under these terms.
|
287 |
+
|
288 |
+
To do so, attach the following notices to the program. It is safest
|
289 |
+
to attach them to the start of each source file to most effectively
|
290 |
+
convey the exclusion of warranty; and each file should have at least
|
291 |
+
the "copyright" line and a pointer to where the full notice is found.
|
292 |
+
|
293 |
+
<one line to give the program's name and a brief idea of what it does.>
|
294 |
+
Copyright (C) <year> <name of author>
|
295 |
+
|
296 |
+
This program is free software; you can redistribute it and/or modify
|
297 |
+
it under the terms of the GNU General Public License as published by
|
298 |
+
the Free Software Foundation; either version 2 of the License, or
|
299 |
+
(at your option) any later version.
|
300 |
+
|
301 |
+
This program is distributed in the hope that it will be useful,
|
302 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
303 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
304 |
+
GNU General Public License for more details.
|
305 |
+
|
306 |
+
You should have received a copy of the GNU General Public License along
|
307 |
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
308 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
309 |
+
|
310 |
+
Also add information on how to contact you by electronic and paper mail.
|
311 |
+
|
312 |
+
If the program is interactive, make it output a short notice like this
|
313 |
+
when it starts in an interactive mode:
|
314 |
+
|
315 |
+
Gnomovision version 69, Copyright (C) year name of author
|
316 |
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
317 |
+
This is free software, and you are welcome to redistribute it
|
318 |
+
under certain conditions; type `show c' for details.
|
319 |
+
|
320 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
321 |
+
parts of the General Public License. Of course, the commands you use may
|
322 |
+
be called something other than `show w' and `show c'; they could even be
|
323 |
+
mouse-clicks or menu items--whatever suits your program.
|
324 |
+
|
325 |
+
You should also get your employer (if you work as a programmer) or your
|
326 |
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
327 |
+
necessary. Here is a sample; alter the names:
|
328 |
+
|
329 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
330 |
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
331 |
+
|
332 |
+
<signature of Ty Coon>, 1 April 1989
|
333 |
+
Ty Coon, President of Vice
|
334 |
+
|
335 |
+
This General Public License does not permit incorporating your program into
|
336 |
+
proprietary programs. If your program is a subroutine library, you may
|
337 |
+
consider it more useful to permit linking proprietary applications with the
|
338 |
+
library. If this is what you want to do, use the GNU Lesser General
|
339 |
+
Public License instead of this License.
|
public/class-wp-temporary-login-without-password-public.php
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Wp_Temporary_Login_Without_Password_Public {
|
4 |
+
|
5 |
+
private $plugin_name;
|
6 |
+
private $version;
|
7 |
+
|
8 |
+
public function __construct($plugin_name, $version) {
|
9 |
+
$this->plugin_name = $plugin_name;
|
10 |
+
$this->version = $version;
|
11 |
+
}
|
12 |
+
|
13 |
+
public static function get_error_messages($error_code) {
|
14 |
+
|
15 |
+
$error_messages = array(
|
16 |
+
'token' => __('Token empty', Wp_Temporary_Login_Without_Password_i18n::$text_domain),
|
17 |
+
'unauth' => __('Authentication failed', Wp_Temporary_Login_Without_Password_i18n::$text_domain)
|
18 |
+
);
|
19 |
+
|
20 |
+
if (!empty($error_code)) {
|
21 |
+
return (isset($error_messages[$error_code]) ? $error_messages[$error_code] : '');
|
22 |
+
}
|
23 |
+
|
24 |
+
return $error_messages;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function init_wtlwp() {
|
28 |
+
|
29 |
+
if (!is_user_logged_in() && !empty($_GET['wtlwp_token'])) {
|
30 |
+
|
31 |
+
$error_messages = array();
|
32 |
+
|
33 |
+
$wtlwp_token = $_GET['wtlwp_token'];
|
34 |
+
$users = Wp_Temporary_Login_Without_Password_Common::get_valid_user_based_on_wtlwp_token($wtlwp_token);
|
35 |
+
|
36 |
+
if (empty($users)) {
|
37 |
+
wp_safe_redirect(home_url());
|
38 |
+
} else {
|
39 |
+
$user = $users[0];
|
40 |
+
|
41 |
+
$user_id = $user->ID;
|
42 |
+
$user_login = $user->login;
|
43 |
+
update_user_meta($user_id, '_wtlwp_last_login', Wp_Temporary_Login_Without_Password_Common::get_current_gmt_timestamp());
|
44 |
+
wp_set_current_user($user_id, $user_login);
|
45 |
+
wp_set_auth_cookie($user_id);
|
46 |
+
|
47 |
+
do_action('wp_login', $user_login, $user);
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
if (is_user_logged_in()) {
|
52 |
+
$user_id = get_current_user_id();
|
53 |
+
if (!empty($user_id) && Wp_Temporary_Login_Without_Password_Common::is_valid_temporary_login($user_id, false)) {
|
54 |
+
if (Wp_Temporary_Login_Without_Password_Common::is_login_expired($user_id)) {
|
55 |
+
wp_logout();
|
56 |
+
wp_safe_redirect(home_url());
|
57 |
+
exit();
|
58 |
+
} else {
|
59 |
+
global $pagenow;
|
60 |
+
$bloked_pages = Wp_Temporary_Login_Without_Password_Common::get_blocked_pages();
|
61 |
+
$page = !empty($_GET['page']) ? $_GET['page'] : '';
|
62 |
+
if ((!empty($page) && in_array($page, $bloked_pages)) || (!empty($pagenow) && in_array($pagenow, $bloked_pages))) {
|
63 |
+
wp_die(__("You don't have permission to access this page", Wp_Temporary_Login_Without_Password_i18n::$text_domain));
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
function wtlwp_authenticate($user, $username, $password) {
|
71 |
+
|
72 |
+
$user_id = username_exists($username);
|
73 |
+
|
74 |
+
if (!$user_id) {
|
75 |
+
return new WP_Error('denied', __("ERROR: Invalid username."));
|
76 |
+
}
|
77 |
+
|
78 |
+
$check_expiry = false;
|
79 |
+
$is_valid_temporary_login = Wp_Temporary_Login_Without_Password_Common::is_valid_temporary_login($user_id, $check_expiry);
|
80 |
+
if ($is_valid_temporary_login) {
|
81 |
+
$is_login_expired = Wp_Temporary_Login_Without_Password_Common::is_login_expired($user_id);
|
82 |
+
update_user_meta($user_id, '_wtlwp_last_login', Wp_Temporary_Login_Without_Password_Common::get_current_gmt_timestamp());
|
83 |
+
if ($is_login_expired) {
|
84 |
+
$user = new WP_Error('denied', __("ERROR: User can't find."));
|
85 |
+
remove_action('authenticate', 'wp_authenticate_username_password', 20);
|
86 |
+
}
|
87 |
+
}
|
88 |
+
|
89 |
+
return $user;
|
90 |
+
}
|
91 |
+
|
92 |
+
}
|
public/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php // Silence is golden
|
readme.txt
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Temporary Login Without Password ===
|
2 |
+
Contributors: storeapps, niravmehta, malayladu
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CPTHCDC382KVA
|
4 |
+
Tags: admin, custom login, login, temporary login, wp admin, wordpress admin, access, expiration, user, login without password
|
5 |
+
Requires at least: 3.0.1
|
6 |
+
Tested up to: 4.5.3
|
7 |
+
Stable tag: 1.0
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
+
|
11 |
+
Create self-expiring, temporary admin accounts. Easily share direct login links (no need for username / password) with your developers or editors.
|
12 |
+
|
13 |
+
== Description ==
|
14 |
+
|
15 |
+
Create self-expiring, automatic login links for WordPress. Give them to developers when they ask for admin access to your site. Or an editor for a quick review of work done. Login works just by opening the link, no password needed.
|
16 |
+
|
17 |
+
Using "Temporary Login Without Password" plugin you can create a self expiring account for someone and give them a special link with which they can login to your WordPress without needing a username and password.
|
18 |
+
|
19 |
+
You can choose when the login expires, as well as the role of the temporary account.
|
20 |
+
|
21 |
+
Really useful when you need to give admin access to a developer for support or for performing routine tasks.
|
22 |
+
|
23 |
+
Use this plugin along with [WP Security Audit Log](https://wordpress.org/plugins/wp-security-audit-log/) plugin to track what the person does after loggin in.
|
24 |
+
|
25 |
+
|
26 |
+
**Spread The Word**
|
27 |
+
|
28 |
+
If you like Temporary Login Without Password, please leave a five star review on WordPress and also spread the word about it. That helps fellow website owners assess Temporary Login Without Password easily and benefit from it!
|
29 |
+
|
30 |
+
== Installation ==
|
31 |
+
|
32 |
+
1. Unzip downloaded folder and upload it to 'wp-content/plugins/' folder
|
33 |
+
2. Activate the plugin through the 'Plugins' menu in WordPress
|
34 |
+
3. Go to Users > Temporary Login section and create a new temporary login.
|
35 |
+
|
36 |
+
== Screenshots ==
|
37 |
+
|
38 |
+
1. Create a new temporary login.
|
39 |
+
2. List of all (Active/Expired) temporary logins.
|
40 |
+
|
41 |
+
== Changelog ==
|
42 |
+
|
43 |
+
= 1.0 =
|
44 |
+
|
45 |
+
- Initial Release
|
screenshots/screenshot-1.png
ADDED
Binary file
|
screenshots/screenshot-2.png
ADDED
Binary file
|
templates/admin_settings.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php ?>
|
2 |
+
<div class="wrap wtlwp-settings-wrap">
|
3 |
+
<h2> <?php echo __('Temporary Logins', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?> <span class="page-title-action" id="add-new-wtlwp-form-button"><?php _e('Create New', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></span> </h2>
|
4 |
+
<div class="wtlwp-settings">
|
5 |
+
<!-- Add New Form Start -->
|
6 |
+
<div class="wrap new-wtlwp-form" id="new-wtlwp-form">
|
7 |
+
<?php load_template(WTLWP_PLUGIN_DIR . '/templates/new_login.php'); ?>
|
8 |
+
</div>
|
9 |
+
|
10 |
+
<?php if(!empty($wtlwp_generated_url)) { ?>
|
11 |
+
|
12 |
+
<div class="wrap generated-wtlwp-login-link" id="generated-wtlwp-login-link">
|
13 |
+
<p><?php _e("Here's a temporary login link", Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></p>
|
14 |
+
<input id="wtlwp-click-to-copy-btn" type="text" class="wtlwp-wide-input" value="<?php echo $wtlwp_generated_url; ?>">
|
15 |
+
<button class="wtlwp-click-to-copy-btn" data-clipboard-action="copy" data-clipboard-target="#wtlwp-click-to-copy-btn"><?php echo __('Click To Copy', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></button>
|
16 |
+
<span id="copied-text-message-wtlwp-click-to-copy-btn"></span>
|
17 |
+
<p><?php _e("User can directly login to wordpress admin panel without username and password by opening this link.", Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
18 |
+
if(!empty($user_email)) {
|
19 |
+
echo __(sprintf(" <a href='mailto:%s'>Email</a> copied login link to user.", $user_email ), Wp_Temporary_Login_Without_Password_i18n::$text_domain);
|
20 |
+
}
|
21 |
+
?>
|
22 |
+
</p>
|
23 |
+
|
24 |
+
</div>
|
25 |
+
<?php } ?>
|
26 |
+
<!-- Add New Form End -->
|
27 |
+
|
28 |
+
<!-- List All Generated Logins Start -->
|
29 |
+
<div class="wrap list-wtlwp-logins" id="list-wtlwp-logins">
|
30 |
+
<?php load_template(WTLWP_PLUGIN_DIR . '/templates/list_temporary_logins.php'); ?>
|
31 |
+
</div>
|
32 |
+
<!-- List All Generated Logins End -->
|
33 |
+
</div>
|
34 |
+
</div>
|
templates/list_temporary_logins.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<table class="wp-list-table widefat fixed striped users">
|
2 |
+
<thead>
|
3 |
+
<?php echo Wp_Temporary_Login_Without_Password_Layout::prepare_header_footer_row(); ?>
|
4 |
+
</thead>
|
5 |
+
|
6 |
+
<tbody>
|
7 |
+
<?php
|
8 |
+
$users = Wp_Temporary_Login_Without_Password_Common::get_temporary_logins();
|
9 |
+
|
10 |
+
if (is_array($users) && count($users) > 0) {
|
11 |
+
|
12 |
+
foreach ($users as $user) {
|
13 |
+
echo Wp_Temporary_Login_Without_Password_Layout::prepare_single_user_row($user);
|
14 |
+
}
|
15 |
+
} else {
|
16 |
+
echo Wp_Temporary_Login_Without_Password_Layout::prepare_empty_user_row();
|
17 |
+
}
|
18 |
+
|
19 |
+
?>
|
20 |
+
|
21 |
+
</tbody>
|
22 |
+
|
23 |
+
<tfoot>
|
24 |
+
<?php echo Wp_Temporary_Login_Without_Password_Layout::prepare_header_footer_row(); ?>
|
25 |
+
</tfoot>
|
26 |
+
</table>
|
templates/new_login.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<h2> <?php echo __('Create a new Temporary Login', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></h2>
|
2 |
+
<form method="post">
|
3 |
+
<table class="form-table wtlwp-form">
|
4 |
+
<tr class="form-field form-required">
|
5 |
+
<th scope="row" class="wtlwp-form-row"> <label for="user_email"><?php echo __('Email*', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?> </label></th>
|
6 |
+
<td><input name="wtlwp_data[user_email]" type="text" id="user_email" value="" aria-required="true" autocapitalize="none" autocorrect="off" maxlength="60" class="wtlwp-form-input"/></td>
|
7 |
+
</tr>
|
8 |
+
|
9 |
+
<tr class="form-field form-required">
|
10 |
+
<th scope="row" class="wtlwp-form-row"> <label for="user_first_name"><?php echo __('First Name', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?> </label></th>
|
11 |
+
<td><input name="wtlwp_data[user_first_name]" type="text" id="user_first_name" value="" aria-required="true" autocapitalize="none" autocorrect="off" maxlength="60" class="wtlwp-form-input"/></td>
|
12 |
+
</tr>
|
13 |
+
|
14 |
+
<tr class="form-field form-required">
|
15 |
+
<th scope="row" class="wtlwp-form-row"> <label for="user_last_name"><?php echo __('Last Name', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?> </label></th>
|
16 |
+
<td><input name="wtlwp_data[user_last_name]" type="text" id="user_last_name" value="" aria-required="true" autocapitalize="none" autocorrect="off" maxlength="60" class="wtlwp-form-input"/></td>
|
17 |
+
</tr>
|
18 |
+
<tr class="form-field">
|
19 |
+
<th scope="row" class="wtlwp-form-row"><label for="adduser-role"><?php echo __('Role', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></label></th>
|
20 |
+
<td><select name="wtlwp_data[role]" id="user-role">
|
21 |
+
<?php wp_dropdown_roles('administrator'); ?>
|
22 |
+
</select>
|
23 |
+
</td>
|
24 |
+
</tr>
|
25 |
+
|
26 |
+
<tr class="form-field">
|
27 |
+
<th scope="row" class="wtlwp-form-row"><label for="adduser-role"><?php echo __('Expiry', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></label></th>
|
28 |
+
<td><select name="wtlwp_data[expiry]" id="user-expiry-time">
|
29 |
+
<?php Wp_Temporary_Login_Without_Password_Common::get_expiry_duration_html(); ?>
|
30 |
+
</select>
|
31 |
+
</td>
|
32 |
+
</tr>
|
33 |
+
|
34 |
+
<tr class="form-field">
|
35 |
+
<th scope="row" class="wtlwp-form-row"><label for="adduser-role"></label></th>
|
36 |
+
<td><p class="submit"><input type="submit" class="button button-primary wtlwp-form-submit-button" value="<?php _e('Submit', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?>" class="button button-primary" id="generatetemporarylogin" name="generate_temporary_login"> <?php _e('or', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?> <span class="cancel-new-login-form" id="cancel-new-login-form"><?php _e('Cancel', Wp_Temporary_Login_Without_Password_i18n::$text_domain); ?></span></p>
|
37 |
+
</td>
|
38 |
+
</tr>
|
39 |
+
<?php wp_nonce_field('wtlwp_generate_login_url', 'wtlwp-nonce', true, true); ?>
|
40 |
+
</table>
|
41 |
+
</form>
|
temporary-login-without-password.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Plugin Name: Temporary Login Without Password
|
5 |
+
* Plugin URI: http://storeapps.org
|
6 |
+
* Description: Create a temporary login link with any role using which one can access to your sytem without username and password for limited period of time.
|
7 |
+
* Version: 1.0
|
8 |
+
* Author: StoreApps
|
9 |
+
* Author URI: http://storeapps.org
|
10 |
+
* License: GPL-2.0+
|
11 |
+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
12 |
+
* Text Domain: wp-temporary-login-without-password
|
13 |
+
* Domain Path: /languages
|
14 |
+
*/
|
15 |
+
// If this file is called directly, abort.
|
16 |
+
if (!defined('WPINC')) {
|
17 |
+
die;
|
18 |
+
}
|
19 |
+
|
20 |
+
// Include main class file
|
21 |
+
require plugin_dir_path(__FILE__) . 'includes/class-wp-temporary-login-without-password.php';
|
22 |
+
|
23 |
+
function run_wp_temporary_login_without_password() {
|
24 |
+
$plugin = new Wp_Temporary_Login_Without_Password();
|
25 |
+
$plugin->define_constant('WTLWP_PLUGIN_DIR', dirname(__FILE__));
|
26 |
+
$plugin->run();
|
27 |
+
}
|
28 |
+
|
29 |
+
run_wp_temporary_login_without_password();
|
uninstall.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Fired when the plugin is uninstalled.
|
5 |
+
*
|
6 |
+
* When populating this file, consider the following flow
|
7 |
+
* of control:
|
8 |
+
*
|
9 |
+
* - This method should be static
|
10 |
+
* - Check if the $_REQUEST content actually is the plugin name
|
11 |
+
* - Run an admin referrer check to make sure it goes through authentication
|
12 |
+
* - Verify the output of $_GET makes sense
|
13 |
+
* - Repeat with other user roles. Best directly by using the links/query string parameters.
|
14 |
+
* - Repeat things for multisite. Once for a single site in the network, once sitewide.
|
15 |
+
*
|
16 |
+
* This file may be updated more in future version of the Boilerplate; however, this is the
|
17 |
+
* general skeleton and outline for how the file should work.
|
18 |
+
*
|
19 |
+
* For more information, see the following discussion:
|
20 |
+
* https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate/pull/123#issuecomment-28541913
|
21 |
+
*
|
22 |
+
* @link http://storeapps.org
|
23 |
+
* @since 1.0
|
24 |
+
*
|
25 |
+
* @package Wp_Temporary_Login_Without_Password
|
26 |
+
*/
|
27 |
+
|
28 |
+
// If uninstall not called from WordPress, then exit.
|
29 |
+
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
30 |
+
exit;
|
31 |
+
}
|