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.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 / Admin / SettingsPages / GeneralSettings.php
wp-user-avatar / src / Admin / SettingsPages Last commit date
DragDropBuilder 5 years ago EmailSettings 5 years ago ShortcodeBuilder 5 years ago AbstractSettingsPage.php 5 years ago AddNewForm.php 5 years ago AdminFooter.php 5 years ago ExtensionsSettingsPage.php 5 years ago FormList.php 5 years ago Forms.php 5 years ago GeneralSettings.php 5 years ago IDUserColumn.php 5 years ago MemberDirectories.php 5 years ago MembersDirectoryList.php 5 years ago ToolsSettingsPage.php 5 years ago index.php 5 years ago
GeneralSettings.php
394 lines
1 <?php
2
3 namespace ProfilePress\Core\Admin\SettingsPages;
4
5 use ProfilePress\Core\Admin\SettingsPages\EmailSettings\EmailSettingsPage;
6 use ProfilePress\Core\Classes\FormRepository;
7 use ProfilePress\Custom_Settings_Page_Api;
8
9 class GeneralSettings extends AbstractSettingsPage
10 {
11 public function __construct()
12 {
13 $this->init_menu();
14 add_action('admin_menu', array($this, 'register_settings_page'));
15
16 // flush rewrite rule on save/persistence
17 add_action('wp_cspa_persist_settings', function () {
18 flush_rewrite_rules();
19 });
20 }
21
22 public function register_settings_page()
23 {
24 $hook = add_submenu_page(
25 PPRESS_SETTINGS_SLUG,
26 apply_filters('ppress_general_settings_admin_page_title', esc_html__('Settings', 'wp-user-avatar')) . ' - ProfilePress',
27 esc_html__('Settings', 'wp-user-avatar'),
28 'manage_options',
29 PPRESS_SETTINGS_SLUG,
30 array($this, 'settings_admin_page_callback')
31 );
32
33 add_action("load-$hook", [$this, 'screen_option']);
34 }
35
36 public function screen_option()
37 {
38 do_action('ppress_settings_page_screen_option');
39 }
40
41 public function settings_admin_page_callback()
42 {
43 if (isset($_GET['view']) && $_GET['view'] == 'email') {
44 return EmailSettingsPage::get_instance()->admin_page();
45 }
46
47 if (isset($_GET['view']) && $_GET['view'] == 'tools') {
48 return ToolsSettingsPage::get_instance()->admin_page();
49 }
50
51 $custom_page = apply_filters('ppress_general_settings_admin_page_short_circuit', false);
52
53 if (false !== $custom_page) return $custom_page;
54
55 $edit_profile_forms = array_reduce(FormRepository::get_forms(FormRepository::EDIT_PROFILE_TYPE),
56 function ($carry, $item) {
57 $carry[$item['form_id']] = $item['name'];
58
59 return $carry;
60 }, ['default' => esc_html__('My Account edit profile form (default)', 'wp-user-avatar')]);
61
62 $args = [
63 'global_settings' => apply_filters('ppress_global_settings_page', [
64 'tab_title' => esc_html__('Global', 'wp-user-avatar'),
65 'dashicon' => 'dashicons-admin-site-alt',
66 [
67 'section_title' => esc_html__('Global Settings', 'wp-user-avatar'),
68 'set_lost_password_url' => [
69 'type' => 'custom_field_block',
70 'label' => esc_html__('Password-reset Page', 'wp-user-avatar'),
71 'data' => $this->page_dropdown('set_lost_password_url'),
72 'description' => sprintf(
73 esc_html__('Select the page you wish to make WordPress default "Lost Password page". %3$s This should be the page that contains a %1$spassword reset form shortcode%2$s.', 'wp-user-avatar'),
74 '<a href="' . add_query_arg('form-type', 'password-reset', PPRESS_FORMS_SETTINGS_PAGE) . '"><strong>', '</strong></a>', '<br/>'),
75 ],
76 'set_login_url' => [
77 'type' => 'custom_field_block',
78 'label' => esc_html__('Login Page', 'wp-user-avatar'),
79 'data' => $this->page_dropdown('set_login_url'),
80 'description' => sprintf(
81 esc_html__('Select the page you wish to make WordPress default Login page. %3$s This should be the page that contains a %1$slogin form shortcode%2$s.', 'wp-user-avatar'),
82 '<a href="' . add_query_arg('form-type', 'login', PPRESS_FORMS_SETTINGS_PAGE) . '"><strong>', '</strong></a>', '<br/>'),
83 ],
84 'set_registration_url' => [
85 'type' => 'custom_field_block',
86 'label' => esc_html__('Registration Page', 'wp-user-avatar'),
87 'data' => $this->page_dropdown('set_registration_url'),
88 'description' => sprintf(
89 esc_html__('Select the page you wish to make WordPress default Registration page. %3$s This should be the page that contains a %1$sregistration form shortcode%2$s.', 'wp-user-avatar'),
90 '<a href="' . add_query_arg('form-type', 'registration', PPRESS_FORMS_SETTINGS_PAGE) . '"><strong>', '</strong></a>', '<br/>'),
91 ],
92 'edit_user_profile_url' => [
93 'type' => 'custom_field_block',
94 'label' => esc_html__('My Account Page', 'wp-user-avatar'),
95 'data' => $this->page_dropdown('edit_user_profile_url'),
96 'description' => sprintf(
97 esc_html__('Select a page that contains %3$s shortcode. You can also use an %1$sedit profile shortcode%2$s on the My Account page in case you want something custom.', 'wp-user-avatar'),
98 '<a href="' . add_query_arg('form-type', 'edit-profile', PPRESS_FORMS_SETTINGS_PAGE) . '"><strong>', '</strong></a>', '<code>[profilepress-my-account]</code>'),
99 ],
100 'disable_ajax_mode' => [
101 'type' => 'checkbox',
102 'label' => esc_html__('Disable Ajax Mode', 'wp-user-avatar'),
103 'value' => 'yes',
104 'checkbox_label' => esc_html__('Disable', 'wp-user-avatar'),
105 'description' => esc_html__('Check this box to disable ajax behaviour(whereby forms do not require page reload when submitted) in forms.', 'wp-user-avatar'),
106 ],
107 'remove_plugin_data' => [
108 'type' => 'checkbox',
109 'value' => 'yes',
110 'label' => esc_html__('Remove Data on Uninstall?', 'wp-user-avatar'),
111 'checkbox_label' => esc_html__('Delete', 'wp-user-avatar'),
112 'description' => esc_html__('Check this box if you would like ProfilePress to completely remove all of its data when the plugin is deleted.', 'wp-user-avatar'),
113 ]
114 ]
115 ]),
116 'registration_settings' => apply_filters('ppress_registration_settings_page', [
117 'tab_title' => esc_html__('Registration', 'wp-user-avatar'),
118 'dashicon' => 'dashicons-welcome-learn-more',
119 [
120 'section_title' => esc_html__('Registration Settings', 'wp-user-avatar'),
121 'set_auto_login_after_reg' => [
122 'type' => 'checkbox',
123 'label' => esc_html__('Auto-login after registration', 'wp-user-avatar'),
124 'checkbox_label' => esc_html__('Enable auto-login', 'wp-user-avatar'),
125 'value' => 'on',
126 'description' => esc_html__('Check this option to automatically login users after successful registration.', 'wp-user-avatar')
127 ]
128 ]
129 ]),
130 'login_settings' => apply_filters('ppress_login_settings_page', [
131 'tab_title' => esc_html__('Login', 'wp-user-avatar'),
132 'dashicon' => 'dashicons-universal-access-alt',
133 [
134 'section_title' => esc_html__('Login Settings', 'wp-user-avatar'),
135 'login_username_email_restrict' => [
136 'type' => 'select',
137 'options' => [
138 'both' => esc_html__('Email Address and Username (default)', 'wp-user-avatar'),
139 'email' => esc_html__('Email Address Only', 'wp-user-avatar'),
140 'username' => esc_html__('Username Only', 'wp-user-avatar')
141 ],
142 'value' => '',
143 'label' => esc_html__('Login with Email or Username', 'wp-user-avatar'),
144 'description' => esc_html__('By default, WordPress allows users to log in using either an email address or username. This setting allows you to restrict logins to only accept email addresses or usernames.', 'wp-user-avatar')
145 ],
146 ]
147 ]),
148 'my_account_settings' => apply_filters('ppress_my_account_settings_page', [
149 'tab_title' => esc_html__('My Account', 'wp-user-avatar'),
150 'section_title' => esc_html__('My Account Settings', 'wp-user-avatar'),
151 'dashicon' => 'dashicons-dashboard',
152 'redirect_default_edit_profile_to_custom' => [
153 'type' => 'checkbox',
154 'label' => esc_html__('Redirect Default Edit Profile', 'wp-user-avatar'),
155 'checkbox_label' => esc_html__('Activate', 'wp-user-avatar'),
156 'value' => 'yes',
157 'description' => sprintf(
158 __('Redirect <a target="_blank" href="%s">default WordPress profile</a> to My Account page.', 'wp-user-avatar'),
159 admin_url('profile.php')
160 )
161 ],
162 'myac_edit_account_endpoint' => [
163 'type' => 'text',
164 'value' => 'edit-profile',
165 'label' => esc_html__('Edit Account Endpoint', 'wp-user-avatar'),
166 'description' => __('Endpoint for the "My Account → Account Details" page.', 'wp-user-avatar'),
167 ],
168 'myac_change_password_endpoint' => [
169 'type' => 'text',
170 'value' => 'change-password',
171 'label' => esc_html__('Change Password Endpoint', 'wp-user-avatar'),
172 'description' => __('Endpoint for the "My Account → Change Password" page.', 'wp-user-avatar'),
173 ],
174 'myac_account_details_form' => [
175 'type' => 'select',
176 'options' => $edit_profile_forms,
177 'label' => esc_html__('Account Details Form', 'wp-user-avatar'),
178 'description' => esc_html__('Do you want to replace the default form in "My Account → Account Details" page? select an Edit Profile form that will replace it.', 'wp-user-avatar')
179 ],
180 ]),
181 'frontend_profile_settings' => apply_filters('ppress_frontend_profile_settings_page', [
182 'tab_title' => esc_html__('Frontend Profile', 'wp-user-avatar'),
183 'section_title' => esc_html__('Frontend Profile Settings', 'wp-user-avatar'),
184 'dashicon' => 'dashicons-admin-users',
185 'set_user_profile_shortcode' => [
186 'type' => 'custom_field_block',
187 'label' => esc_html__('Page with Profile Shortcode', 'wp-user-avatar'),
188 'data' => $this->page_dropdown('set_user_profile_shortcode'),
189 'description' => sprintf(__('Select the page that contains your <a href="%s">Frontend user profile shortcode</a>.', 'wp-user-avatar'), PPRESS_USER_PROFILES_SETTINGS_PAGE),
190 ],
191 'set_user_profile_slug' => [
192 'type' => 'text',
193 'value' => 'profile',
194 'label' => esc_html__('Profile Slug', 'wp-user-avatar'),
195 'description' => sprintf(__('Enter your preferred profile URL slug. Default to "profile" if empty. If slug is "profile", URL becomes %s where "john" is a user\'s username.', 'wp-user-avatar'), '<strong>' . home_url() . '/profile/john</strong>'),
196 ],
197 'disable_guests_can_view_profiles' => [
198 'type' => 'checkbox',
199 'label' => esc_html__('Disable Guests from Viewing Profiles', 'wp-user-avatar'),
200 'description' => esc_html__('Enable this option to stop disable guests or non-registered users from viewing users profiles.', 'wp-user-avatar'),
201 'value' => 'on'
202 ],
203 'disable_members_can_view_profiles' => [
204 'type' => 'checkbox',
205 'label' => esc_html__('Disable Members from Viewing Profiles', 'wp-user-avatar'),
206 'description' => esc_html__('Enable this option to stop members from viewing other users profiles. If enabled, users can only see their own profile.', 'wp-user-avatar'),
207 'value' => 'on'
208 ],
209 'comment_author_url_to_profile' => [
210 'type' => 'checkbox',
211 'label' => esc_html__('Comment Author URL to Profile', 'wp-user-avatar'),
212 'checkbox_label' => esc_html__('Enable option', 'wp-user-avatar'),
213 'value' => 'on',
214 'description' => sprintf(__("Change URL of comment authors to their ProfilePress front-end profile.", 'wp-user-avatar'))
215 ],
216 'author_slug_to_profile' => [
217 'type' => 'checkbox',
218 'label' => esc_html__('Authors Page to Profile', 'wp-user-avatar'),
219 'checkbox_label' => esc_html__('Enable option', 'wp-user-avatar'),
220 'value' => 'on',
221 'description' => sprintf(__("Change and redirect authors pages %s to their front-end profiles %s.", 'wp-user-avatar'), '<strong>(' . home_url() . '/author/admin)</strong>', '<strong>(' . home_url() . '/' . ppress_get_profile_slug() . '/admin)</strong>')
222 ],
223 ]
224 ),
225 'redirection_settings' => apply_filters('ppress_redirection_settings_page', [
226 'tab_title' => esc_html__('Redirection', 'wp-user-avatar'),
227 'section_title' => esc_html__('Redirection Settings', 'wp-user-avatar'),
228 'dashicon' => 'dashicons-redo',
229 'set_log_out_url' => [
230 'type' => 'custom_field_block',
231 'label' => esc_html__('Log out', 'wp-user-avatar'),
232 'data' => $this->page_dropdown('set_log_out_url',
233 [
234 ['key' => 'default', 'label' => esc_html__('Select...', 'wp-user-avatar')],
235 ['key' => 'current_view_page', 'label' => esc_html__('Currently viewed page', 'wp-user-avatar')]
236 ]
237 ) . $this->custom_text_input('custom_url_log_out'),
238 'description' => sprintf(
239 esc_html__('Select the page users will be redirected to after logout. To redirect to a custom URL instead of a selected page, enter the URL in input field directly above this description.', 'wp-user-avatar') . '%s' .
240 esc_html__('Leave the "custom URL" field empty to fallback to the selected page.', 'wp-user-avatar'),
241 '<br/>'
242 )
243 ],
244 'set_login_redirect' => [
245 'type' => 'custom_field_block',
246 'label' => esc_html__('Login', 'wp-user-avatar'),
247 'data' => $this->page_dropdown(
248 'set_login_redirect',
249 [
250 ['key' => 'current_page', 'label' => esc_html__('Currently viewed page', 'wp-user-avatar')],
251 ['key' => 'dashboard', 'label' => esc_html__('WordPress Dashboard', 'wp-user-avatar')]
252 ]
253 )
254 . $this->custom_text_input('custom_url_login_redirect'),
255 'description' => sprintf(
256 esc_html__('Select the page or custom URL users will be redirected to after login. To redirect to a custom URL instead of a selected page, enter the URL in input field directly above this description', 'wp-user-avatar') . '%s' .
257 esc_html__('Leave the "custom URL" field empty to fallback to the selected page.', 'wp-user-avatar'),
258 '<br/>'
259 )
260 ],
261 'set_password_reset_redirect' => [
262 'type' => 'custom_field_block',
263 'label' => esc_html__('Password Reset', 'wp-user-avatar'),
264 'data' => $this->page_dropdown(
265 'set_password_reset_redirect',
266 [],
267 [
268 'show_option_none' => esc_html__('Default..', 'wp-user-avatar'),
269 'option_none_value' => 'no_redirect',
270 ]
271 ) . $this->custom_text_input('custom_url_password_reset_redirect'),
272 'description' => sprintf(
273 esc_html__('Select the page or custom URL users will be redirected to after they successfully reset or change their password. To redirect to a custom URL instead of a selected page, enter the URL in input field directly above this description.', 'wp-user-avatar') . '%s' .
274 esc_html__('Leave the "custom URL" field empty to fallback to the selected page.', 'wp-user-avatar'),
275 '<br/>'
276 )
277 ]
278 ]),
279 'access_settings' => apply_filters('ppress_access_settings_page', [
280 'tab_title' => esc_html__('Access', 'wp-user-avatar'),
281 'section_title' => esc_html__('Access Settings', 'wp-user-avatar'),
282 'dashicon' => 'dashicons-products',
283 'global_site_access_notice' => [
284 'type' => 'arbitrary',
285 'data' => '',
286 'description' => sprintf(
287 '<div class="pp-settings-page-notice">' . esc_html__('%sNote:%s Access setting takes precedence over %sContent Protection rules%s.', 'wp-user-avatar'),
288 '<strong>', '</strong>', '<a target="_blank" href="' . PPRESS_CONTENT_PROTECTION_SETTINGS_PAGE . '">', '</a>'
289 )
290 ],
291 'global_site_access' => [
292 'type' => 'select',
293 'label' => esc_html__('Global Site Access', 'wp-user-avatar'),
294 'options' => [
295 'everyone' => esc_html__('Accessible to Everyone', 'wp-user-avatar'),
296 'login' => esc_html__('Accessible to Logged-in Users', 'wp-user-avatar')
297 ]
298 ],
299 'global_site_access_redirect_page' => [
300 'type' => 'custom_field_block',
301 'label' => esc_html__('Redirect Page', 'wp-user-avatar'),
302 'data' => $this->page_dropdown('global_site_access_redirect_page') . $this->custom_text_input('global_site_access_custom_redirect_page'),
303 'description' => esc_html__('Select the page or custom URL to redirect users that are not logged in to.', 'wp-user-avatar')
304 ],
305 'global_site_access_exclude_pages' => [
306 'type' => 'select2',
307 'label' => esc_html__('Pages to Exclude', 'wp-user-avatar'),
308 'options' => array_reduce(get_pages(), function ($carry, $item) {
309 $carry[$item->ID] = $item->post_title;
310
311 return $carry;
312 }, []),
313 'description' => esc_html__('Select the pages to exclude beside the redirect page that will be accessible by everyone.', 'wp-user-avatar')
314 ],
315 'global_site_access_allow_homepage' => [
316 'type' => 'checkbox',
317 'value' => 'yes',
318 'checkbox_label' => esc_html__('Enable', 'wp-user-avatar'),
319 'label' => esc_html__('Accessible Homepage', 'wp-user-avatar'),
320 'description' => esc_html__('Check to allow homepage to be accessible by everyone.', 'wp-user-avatar')
321 ],
322 'global_restricted_access_message' => [
323 'type' => 'wp_editor',
324 'value' => esc_html__('You are unauthorized to view this page.', 'wp-user-avatar'),
325 'label' => esc_html__('Global Restricted Access Message', 'wp-user-avatar'),
326 'description' => esc_html__('This is the message shown to users that do not have permission to view the content.', 'wp-user-avatar')
327 ],
328 ])
329 ];
330
331 if (class_exists('\BuddyPress')) {
332 $args['buddypress_settings'] = apply_filters('ppress_buddypress_settings_page', [
333 'tab_title' => esc_html__('BuddyPress', 'wp-user-avatar'),
334 'section_title' => esc_html__('BuddyPress Settings', 'wp-user-avatar'),
335 'dashicon' => 'dashicons-buddicons-buddypress-logo',
336 'redirect_bp_registration_page' => [
337 'type' => 'checkbox',
338 'value' => 'yes',
339 'label' => esc_html__('Registration Page', 'wp-user-avatar'),
340 'checkbox_label' => esc_html__('Check to enable', 'wp-user-avatar'),
341 'description' => sprintf(__('Check to redirect BuddyPress registration page to your selected %s', 'wp-user-avatar'), '<a href="#global_settings?set_registration_url_row">custom registration page</a>')
342 ],
343 'override_bp_avatar' => [
344 'type' => 'checkbox',
345 'label' => esc_html__('Override Avatar', 'wp-user-avatar'),
346 'value' => 'yes',
347 'checkbox_label' => esc_html__('Check to enable', 'wp-user-avatar'),
348 'description' => esc_html__('Check to override BuddyPress users uploaded avatars with that of ProfilePress.', 'wp-user-avatar')
349 ],
350 'override_bp_profile_url' => [
351 'type' => 'checkbox',
352 'value' => 'yes',
353 'label' => esc_html__('Override Profile URL', 'wp-user-avatar'),
354 'checkbox_label' => esc_html__('Check to enable', 'wp-user-avatar'),
355 'description' => esc_html__('Check to change the profile URL of BuddyPress users to ProfilePress front-end profile.', 'wp-user-avatar')
356 ]
357 ]
358 );
359 }
360
361 if (class_exists('\bbPress')) {
362 $args['bbpress_settings'] = apply_filters('ppress_bbpress_settings_page', [
363 'tab_title' => esc_html__('bbPress', 'wp-user-avatar'),
364 'section_title' => esc_html__('bbPress Settings', 'wp-user-avatar'),
365 'dashicon' => 'dashicons-buddicons-bbpress-logo',
366 'override_bbp_profile_url' => [
367 'type' => 'checkbox',
368 'value' => 'yes',
369 'label' => esc_html__('Override Profile URL', 'wp-user-avatar'),
370 'checkbox_label' => esc_html__('Check to enable', 'wp-user-avatar'),
371 'description' => esc_html__('Check to change bbPress profile URL to ProfilePress front-end profile.', 'wp-user-avatar')
372 ]
373 ]
374 );
375 }
376
377 $settings_args = apply_filters('ppress_settings_page_args', $args);
378 $instance = Custom_Settings_Page_Api::instance($settings_args, PPRESS_SETTINGS_DB_OPTION_NAME, esc_html__('General', 'wp-user-avatar'));
379 $this->register_core_settings($instance, true);
380 $instance->tab($this->settings_tab_args());
381 $instance->build_sidebar_tab_style();
382 }
383
384 public static function get_instance()
385 {
386 static $instance = null;
387
388 if (is_null($instance)) {
389 $instance = new self();
390 }
391
392 return $instance;
393 }
394 }