PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / 3.1
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress v3.1
4.16.19 4.16.18 4.16.17 4.16.16 trunk 1.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5a 1.1.6 1.1.7 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4 1.4.1 1.4.2 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.7 1.7.1 1.7.2 1.8 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.1.9 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.2 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 3.0 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.13.4 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.15.0 4.15.1 4.15.10 4.15.11 4.15.12 4.15.13 4.15.14 4.15.15 4.15.16 4.15.17 4.15.18 4.15.19 4.15.2 4.15.20 4.15.20.1 4.15.21 4.15.22 4.15.23 4.15.24 4.15.25 4.15.3 4.15.4 4.15.5 4.15.6 4.15.7 4.15.8 4.15.9 4.16.0 4.16.1 4.16.10 4.16.11 4.16.12 4.16.13 4.16.14 4.16.15 4.16.2 4.16.3 4.16.4 4.16.5 4.16.6 4.16.7 4.16.8 4.16.9 4.2.0 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.7.0 4.8.0 4.9.0
wp-user-avatar / src / Themes / DragDrop / AbstractTheme.php
wp-user-avatar / src / Themes / DragDrop Last commit date
EditProfile 5 years ago Login 5 years ago MemberDirectory 5 years ago PasswordReset 5 years ago Registration 5 years ago UserProfile 5 years ago AbstractBuildScratch.php 5 years ago AbstractMemberDirectoryTheme.php 5 years ago AbstractTheme.php 5 years ago FieldListing.php 5 years ago MemberDirectoryListing.php 5 years ago ProfileFieldListing.php 5 years ago ThemeInterface.php 5 years ago ThemesRepository.php 5 years ago index.php 5 years ago
AbstractTheme.php
446 lines
1 <?php
2
3 namespace ProfilePress\Core\Themes\DragDrop;
4
5 use ProfilePress\Core\Base;
6 use ProfilePress\Core\Classes\ExtensionManager as EM;
7 use ProfilePress\Core\Classes\FormRepository as FR;
8
9 abstract class AbstractTheme implements ThemeInterface
10 {
11 public $form_id;
12
13 public $form_type;
14
15 public $tag_name;
16
17 public $metabox_settings;
18
19 public $asset_image_url;
20
21 public function __construct($form_id, $form_type)
22 {
23 $this->form_id = $form_id;
24 $this->form_type = $form_type;
25
26 $this->asset_image_url = PPRESS_ASSETS_URL . '/images';
27
28 $this->tag_name = 'login';
29
30 switch ($this->form_type) {
31 case FR::REGISTRATION_TYPE:
32 $this->tag_name = 'reg';
33 break;
34 case FR::EDIT_PROFILE_TYPE:
35 $this->tag_name = 'edit-profile';
36 break;
37 case FR::PASSWORD_RESET_TYPE:
38 $this->tag_name = 'reset';
39 break;
40 }
41
42 add_shortcode('pp-form-wrapper', [$this, 'form_wrapper_shortcode']);
43
44 add_filter('ppress_form_builder_meta_box_settings', [$this, 'metabox_settings'], 10, 3);
45
46 add_filter('ppress_form_builder_meta_box_submit_button_settings', [$this, 'submit_button_settings']);
47
48 add_filter('ppress_form_builder_meta_box_appearance_settings', [$this, 'appearance_settings']);
49
50 add_filter('ppress_form_builder_meta_box_colors_settings', [$this, 'color_settings']);
51
52 // add div wrapper to remember me checkbox
53 add_filter('ppress_form_field_listing_login-remember', [$this, 'remember_me_checkbox_wrapper'], 10, 2);
54 // when label is found in field settings, it is automatically added before the field so we are removing it.
55 add_filter('ppress_form_field_listing_setting_login-remember', [$this, 'remember_me_checkbox_remove_label']);
56 }
57
58 public function is_show_social_login()
59 {
60 return in_array($this->form_type, [FR::LOGIN_TYPE, FR::REGISTRATION_TYPE]) && EM::is_enabled(EM::SOCIAL_LOGIN);
61 }
62
63 /**
64 * Array of fields whose settings in form builder should not be modified. Should be as is.
65 */
66 public function disallowed_settings_fields()
67 {
68 return ['pp-custom-html', 'pp-recaptcha', 'pp-user-avatar', 'pp-user-cover-image'];
69 }
70
71 public function minified_form_css()
72 {
73 return ppress_minify_css($this->form_css());
74 }
75
76 public function get_meta($key)
77 {
78 $metabox_settings = FR::get_form_meta($this->form_id, $this->form_type, FR::METABOX_FORM_BUILDER_SETTINGS);
79
80 if (empty($metabox_settings)) $metabox_settings = [];
81
82 $default_metabox_settings = $this->default_metabox_settings();
83
84 return isset($metabox_settings[$key]) ? $metabox_settings[$key] : (isset($default_metabox_settings[$key]) ? $default_metabox_settings[$key] : '');
85 }
86
87 public function remember_me_checkbox_remove_label($field_setting)
88 {
89 unset($field_setting['label']);
90
91 return $field_setting;
92 }
93
94 public function remember_me_checkbox_wrapper($tag, $field_setting)
95 {
96 return sprintf(
97 '<div class="ppform-remember-me"><label class="ppform-remember-checkbox">%s <span class="ppform-remember-label">%s</span></label></div>',
98 $tag, $field_setting['label']
99 );
100 }
101
102 public function default_metabox_settings()
103 {
104 $button_text = esc_html__('Log In', 'wp-user-avatar');
105 $success_message = '';
106
107 switch ($this->form_type) {
108 case FR::REGISTRATION_TYPE:
109 $button_text = esc_html__('Register', 'wp-user-avatar');
110 $success_message = esc_html__('Registration successful.', 'wp-user-avatar');
111 break;
112 case FR::EDIT_PROFILE_TYPE:
113 $button_text = esc_html__('Update Profile', 'wp-user-avatar');
114 $success_message = esc_html__('Changes saved.', 'wp-user-avatar');
115 break;
116 case FR::PASSWORD_RESET_TYPE:
117 $button_text = esc_html__('Reset Password', 'wp-user-avatar');
118 $success_message = esc_html__('Check your email for further instruction.', 'wp-user-avatar');
119 break;
120 }
121
122 return [
123 'submit_button_text' => $button_text,
124 'submit_button_processing_label' => esc_html__('Processing', 'wp-user-avatar'),
125 FR::SUCCESS_MESSAGE => $success_message,
126 FR::REGISTRATION_USER_ROLE => 'subscriber'
127 ];
128 }
129
130 public function metabox_settings($settings, $form_type, $DragDropBuilderInstance)
131 {
132 return $settings;
133 }
134
135 public function submit_button_settings($settings)
136 {
137 return $settings;
138 }
139
140 public function appearance_settings($settings)
141 {
142 return $settings;
143 }
144
145 public function color_settings($settings)
146 {
147 return $settings;
148 }
149
150 /**
151 * Each fields default values.
152 *
153 * @return array
154 */
155 public function default_fields_settings()
156 {
157 $defaults = [
158 $this->tag_name . '-username' => [
159 'placeholder' => esc_html__('Username', 'wp-user-avatar')
160 ],
161 $this->tag_name . '-email' => [
162 'placeholder' => esc_html__('Email Address', 'wp-user-avatar')
163 ],
164 $this->tag_name . '-password' => [
165 'placeholder' => esc_html__('Password', 'wp-user-avatar')
166 ],
167 $this->tag_name . '-confirm-password' => [
168 'placeholder' => esc_html__('Confirm Password', 'wp-user-avatar')
169 ],
170 $this->tag_name . '-confirm-email' => [
171 'placeholder' => esc_html__('Confirm Email', 'wp-user-avatar')
172 ],
173 $this->tag_name . '-website' => [
174 'placeholder' => esc_html__('Website', 'wp-user-avatar')
175 ],
176 $this->tag_name . '-nickname' => [
177 'placeholder' => esc_html__('Nickname', 'wp-user-avatar')
178 ],
179 $this->tag_name . '-display-name' => [
180 'placeholder' => esc_html__('Display Name', 'wp-user-avatar')
181 ],
182 $this->tag_name . '-first-name' => [
183 'placeholder' => esc_html__('First Name', 'wp-user-avatar')
184 ],
185 $this->tag_name . '-last-name' => [
186 'placeholder' => esc_html__('Last Name', 'wp-user-avatar')
187 ],
188 $this->tag_name . '-bio' => [
189 'placeholder' => esc_html__('Biography', 'wp-user-avatar')
190 ],
191 $this->tag_name . '-avatar' => [],
192 $this->tag_name . '-password-meter' => [
193 'enforce' => true
194 ],
195 $this->tag_name . '-select-role' => ['options' => ''],
196
197 // edit profile only
198 'pp-user-avatar' => ['size' => 300],
199
200 // login form
201 'login-username' => [
202 'placeholder' => esc_html__('Username or Email', 'wp-user-avatar')
203 ],
204 'login-password' => [
205 'placeholder' => esc_html__('Password', 'wp-user-avatar')
206 ],
207 'login-remember' => [
208 'label' => esc_html__('Remember Me', 'wp-user-avatar')
209 ],
210
211 // password reset
212 'user-login' => [
213 'placeholder' => esc_html__('Username or Email', 'wp-user-avatar')
214 ],
215
216 // user profile
217 'profile-username' => [
218 'label' => esc_html__('Username', 'wp-user-avatar')
219 ],
220 'profile-email' => [
221 'label' => esc_html__('Email Address', 'wp-user-avatar')
222 ],
223 'profile-first-name' => [
224 'label' => esc_html__('First Name', 'wp-user-avatar')
225 ],
226 'profile-last-name' => [
227 'label' => esc_html__('Last Name', 'wp-user-avatar')
228 ],
229 'profile-website' => [
230 'label' => esc_html__('Website', 'wp-user-avatar')
231 ],
232 'profile-bio' => [
233 'label' => esc_html__('Bio', 'wp-user-avatar')
234 ],
235 ];
236
237 if ($this->form_type == FR::MEMBERS_DIRECTORY_TYPE) {
238 // user profile
239 $defaults['profile-username'] = [];
240 $defaults['profile-email'] = [];
241 $defaults['profile-first-name'] = [];
242 $defaults['profile-last-name'] = [];
243 $defaults['profile-website'] = [];
244 $defaults['profile-bio'] = [];
245 }
246
247 return $defaults;
248 }
249
250 public function form_wrapper_shortcode($atts, $content)
251 {
252 $form_id = $this->form_id;
253 $form_type = $this->form_type;
254
255 $atts = shortcode_atts(['class' => '', 'style' => ''], $atts);
256
257 $classes = ['pp-form-wrapper', "pp-$form_type", "pp-$form_type-$form_id"];
258 if (isset($atts['class']) && ! empty($atts['class'])) {
259 $classes[] = esc_attr($atts['class']);
260 }
261
262 return sprintf(
263 '<div id="%s" class="%s"%s>%s</div>',
264 "pp-$form_type-$form_id",
265 implode(' ', $classes),
266 ! empty($atts['style']) ? ' style="' . esc_attr($atts['style']) . '"' : '',
267 do_shortcode($content)
268 );
269 }
270
271 public function field_listing()
272 {
273 return (new FieldListing($this->form_id, $this->form_type))->defaults($this->default_fields_settings())->forge();
274 }
275
276 /**
277 * @return ProfileFieldListing
278 */
279 public function profile_listing()
280 {
281 return (new ProfileFieldListing($this->form_id))->defaults($this->default_fields_settings());
282 }
283
284 public function get_profile_field($field_key, $parse_shortcode = false)
285 {
286 if (empty($field_key)) return '';
287
288 $return = sprintf('[profile-cpf key=%s]', $field_key);
289
290 $standard_fields = array_keys(ppress_standard_fields_key_value_pair(true));
291
292 if (in_array($field_key, $standard_fields)) {
293
294 if ($field_key == 'first_last_names') {
295 $return = '[profile-first-name] [profile-last-name]';
296 } elseif ($field_key == 'last_first_names') {
297 $return = '[profile-last-name] [profile-first-name]';
298 } elseif ($field_key == 'registration_date') {
299 $return = '[profile-date-registered]';
300 } else {
301 $return = sprintf('[profile-%s]', $field_key);
302 }
303 }
304
305 return $parse_shortcode === true ? do_shortcode($return, true) : $return;
306 }
307
308 public function form_submit_button()
309 {
310 $submit_button_text = $this->get_meta('submit_button_text');
311 $processing_label = $this->get_meta('submit_button_processing_label');
312
313 return sprintf(
314 '[%s-submit class="ppform-submit-button" value="%s" processing_label="%s"]',
315 $this->tag_name, $submit_button_text, $processing_label
316 );
317 }
318
319 public function social_profile_icons()
320 {
321 if ( ! EM::is_enabled(EM::CUSTOM_FIELDS)) return false;
322
323 $facebook_url = $this->get_profile_field(Base::cif_facebook, true);
324 $twitter_url = $this->get_profile_field(Base::cif_twitter, true);
325 $linkedin_url = $this->get_profile_field(Base::cif_linkedin, true);
326 $github_url = $this->get_profile_field(Base::cif_github, true);
327 $instagram_url = $this->get_profile_field(Base::cif_instagram, true);
328 $youtube_url = $this->get_profile_field(Base::cif_youtube, true);
329 $vk_url = $this->get_profile_field(Base::cif_vk, true);
330
331 if (
332 empty($facebook_url) &&
333 empty($twitter_url) &&
334 empty($linkedin_url) &&
335 empty($github_url) &&
336 empty($instagram_url) &&
337 empty($youtube_url) &&
338 empty($vk_url)) {
339 return false;
340 }
341 ?>
342 <div class="ppress-pf-profile-connect">
343
344 <?php if ( ! empty($facebook_url)) : // ignore_html set to true to quicken the parsing ?>
345 <a href="<?= $facebook_url ?>" target="_blank" class="ppress-pf-social-icon dpf-facebook">
346 <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="48" height="48" viewBox="0 0 48 48" style=" fill:#000000;">
347 <path fill="#039be5" d="M24 5A19 19 0 1 0 24 43A19 19 0 1 0 24 5Z"></path>
348 <path fill="#fff" d="M26.572,29.036h4.917l0.772-4.995h-5.69v-2.73c0-2.075,0.678-3.915,2.619-3.915h3.119v-4.359c-0.548-0.074-1.707-0.236-3.897-0.236c-4.573,0-7.254,2.415-7.254,7.917v3.323h-4.701v4.995h4.701v13.729C22.089,42.905,23.032,43,24,43c0.875,0,1.729-0.08,2.572-0.194V29.036z"></path>
349 </svg>
350 </a>
351 <?php endif; ?>
352
353 <?php if ( ! empty($twitter_url)) : ?>
354 <a href="<?= $twitter_url ?>" target="_blank" class="ppress-pf-social-icon dpf-twitter">
355 <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="48" height="48" viewBox="0 0 48 48" style=" fill:#000000;">
356 <path fill="#03a9f4" d="M24 4A20 20 0 1 0 24 44A20 20 0 1 0 24 4Z"></path>
357 <path fill="#fff" d="M36,17.12c-0.882,0.391-1.999,0.758-3,0.88c1.018-0.604,2.633-1.862,3-3 c-0.951,0.559-2.671,1.156-3.793,1.372C31.311,15.422,30.033,15,28.617,15C25.897,15,24,17.305,24,20v2c-4,0-7.9-3.047-10.327-6 c-0.427,0.721-0.667,1.565-0.667,2.457c0,1.819,1.671,3.665,2.994,4.543c-0.807-0.025-2.335-0.641-3-1c0,0.016,0,0.036,0,0.057 c0,2.367,1.661,3.974,3.912,4.422C16.501,26.592,16,27,14.072,27c0.626,1.935,3.773,2.958,5.928,3c-1.686,1.307-4.692,2-7,2 c-0.399,0-0.615,0.022-1-0.023C14.178,33.357,17.22,34,20,34c9.057,0,14-6.918,14-13.37c0-0.212-0.007-0.922-0.018-1.13 C34.95,18.818,35.342,18.104,36,17.12"></path>
358 </svg>
359 </a>
360 <?php endif; ?>
361
362 <?php if ( ! empty($linkedin_url)) : ?>
363 <a href="<?= $linkedin_url ?>" target="_blank" class="ppress-pf-social-icon">
364 <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
365 width="48" height="48"
366 viewBox="0 0 48 48"
367 style="fill:#000000;">
368 <path fill="#0288d1" d="M24 4A20 20 0 1 0 24 44A20 20 0 1 0 24 4Z"></path>
369 <path fill="#fff" d="M14 19H18V34H14zM15.988 17h-.022C14.772 17 14 16.11 14 14.999 14 13.864 14.796 13 16.011 13c1.217 0 1.966.864 1.989 1.999C18 16.11 17.228 17 15.988 17zM35 24.5c0-3.038-2.462-5.5-5.5-5.5-1.862 0-3.505.928-4.5 2.344V19h-4v15h4v-8c0-1.657 1.343-3 3-3s3 1.343 3 3v8h4C35 34 35 24.921 35 24.5z"></path>
370 </svg>
371 </a>
372 <?php endif; ?>
373
374 <?php if ( ! empty($instagram_url)) : ?>
375 <a href="<?= $instagram_url ?>" target="_blank" class="ppress-pf-social-icon dpf-instagram">
376 <svg viewBox="0 0 128 128" width="35px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g>
377 <linearGradient gradientTransform="matrix(1 0 0 -1 594 633)" gradientUnits="userSpaceOnUse" id="SVGID_1_" x1="-566.7114" x2="-493.2875" y1="516.5693" y2="621.4296">
378 <stop offset="0" style="stop-color:#FFB900"/>
379 <stop offset="1" style="stop-color:#9100EB"/>
380 </linearGradient>
381 <circle cx="64" cy="64" fill="url(#SVGID_1_)" r="64"/>
382 </g>
383 <g>
384 <g>
385 <path d="M82.333,104H45.667C33.72,104,24,94.281,24,82.333V45.667C24,33.719,33.72,24,45.667,24h36.666 C94.281,24,104,33.719,104,45.667v36.667C104,94.281,94.281,104,82.333,104z M45.667,30.667c-8.271,0-15,6.729-15,15v36.667 c0,8.271,6.729,15,15,15h36.666c8.271,0,15-6.729,15-15V45.667c0-8.271-6.729-15-15-15H45.667z" fill="#FFFFFF"/>
386 </g>
387 <g>
388 <path d="M64,84c-11.028,0-20-8.973-20-20c0-11.029,8.972-20,20-20s20,8.971,20,20C84,75.027,75.028,84,64,84z M64,50.667c-7.352,0-13.333,5.981-13.333,13.333c0,7.353,5.981,13.333,13.333,13.333S77.333,71.353,77.333,64 C77.333,56.648,71.353,50.667,64,50.667z" fill="#FFFFFF"/>
389 </g>
390 <g>
391 <circle cx="85.25" cy="42.75" fill="#FFFFFF" r="4.583"/>
392 </g>
393 </g>
394 </svg>
395 </a>
396 <?php endif; ?>
397
398 <?php if ( ! empty($youtube_url)) : ?>
399 <a href="<?= $youtube_url ?>" target="_blank" class="ppress-pf-social-icon dpf-youtube">
400 <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
401 width="48" height="48"
402 viewBox="0 0 48 48"
403 style=" fill:#000000;">
404 <path fill="#f44336" d="M24 4A20 20 0 1 0 24 44A20 20 0 1 0 24 4Z"></path>
405 <path fill="#fff" d="M17,34l18-10L17,14V34z"></path>
406 </svg>
407 </a>
408 <?php endif; ?>
409
410 <?php if ( ! empty($vk_url)) : ?>
411 <a href="<?= $vk_url ?>" target="_blank" class="ppress-pf-social-icon dpf-vk">
412 <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
413 width="48" height="48"
414 viewBox="0 0 48 48"
415 style=" fill:#000000;">
416 <path fill="#1976d2" d="M24 4A20 20 0 1 0 24 44A20 20 0 1 0 24 4Z"></path>
417 <path fill="#fff" d="M35.937,18.041c0.046-0.151,0.068-0.291,0.062-0.416C35.984,17.263,35.735,17,35.149,17h-2.618 c-0.661,0-0.966,0.4-1.144,0.801c0,0-1.632,3.359-3.513,5.574c-0.61,0.641-0.92,0.625-1.25,0.625C26.447,24,26,23.786,26,23.199 v-5.185C26,17.32,25.827,17,25.268,17h-4.649C20.212,17,20,17.32,20,17.641c0,0.667,0.898,0.827,1,2.696v3.623 C21,24.84,20.847,25,20.517,25c-0.89,0-2.642-3-3.815-6.932C16.448,17.294,16.194,17,15.533,17h-2.643 C12.127,17,12,17.374,12,17.774c0,0.721,0.6,4.619,3.875,9.101C18.25,30.125,21.379,32,24.149,32c1.678,0,1.85-0.427,1.85-1.094 v-2.972C26,27.133,26.183,27,26.717,27c0.381,0,1.158,0.25,2.658,2c1.73,2.018,2.044,3,3.036,3h2.618 c0.608,0,0.957-0.255,0.971-0.75c0.003-0.126-0.015-0.267-0.056-0.424c-0.194-0.576-1.084-1.984-2.194-3.326 c-0.615-0.743-1.222-1.479-1.501-1.879C32.062,25.36,31.991,25.176,32,25c0.009-0.185,0.105-0.361,0.249-0.607 C32.223,24.393,35.607,19.642,35.937,18.041z"></path>
418 </svg>
419 </a>
420 <?php endif; ?>
421
422 <?php if ( ! empty($github_url)) : ?>
423 <a href="<?= $github_url ?>" target="_blank" class="ppress-pf-social-icon dpf-github">
424 <svg height="35" viewBox="0 0 16 16" version="1.1" width="35">
425 <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
426 </svg>
427 </a>
428 <?php endif; ?>
429
430 </div>
431 <?php
432 }
433
434 public static function get_instance($form_id, $form_type)
435 {
436 static $instance = false;
437
438 $class = get_called_class();
439
440 if ( ! $instance) {
441 $instance = new $class($form_id, $form_type);
442 }
443
444 return $instance;
445 }
446 }