PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / 4.17.1
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress v4.17.1
4.17.1 4.17.0 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 / Admin / SettingsPages / Membership / PlansPage / SettingsPage.php
wp-user-avatar / src / Admin / SettingsPages / Membership / PlansPage Last commit date
PlanWPListTable.php 4 months ago SettingsPage.php 4 months ago index.php 4 years ago
SettingsPage.php
345 lines
1 <?php
2
3 namespace ProfilePress\Core\Admin\SettingsPages\Membership\PlansPage;
4
5 use ProfilePress\Core\Admin\SettingsPages\AbstractSettingsPage;
6 use ProfilePress\Core\Membership\CurrencyFormatter;
7 use ProfilePress\Core\Membership\Models\Customer\CustomerFactory;
8 use ProfilePress\Core\Membership\Models\Subscription\SubscriptionStatus;
9 use ProfilePress\Core\Membership\Repositories\SubscriptionRepository;
10 use ProfilePress\Custom_Settings_Page_Api;
11
12 class SettingsPage extends AbstractSettingsPage
13 {
14 public $error_bucket;
15
16 /** @var PlanWPListTable */
17 private $planListTable;
18
19 function __construct()
20 {
21 add_action('ppress_register_menu_page', [$this, 'register_cpf_settings_page']);
22 add_action('ppress_admin_settings_page_plans', [$this, 'settings_page_function']);
23
24 add_filter('set-screen-option', [__CLASS__, 'set_screen'], 10, 3);
25 add_filter('set_screen_option_rules_per_page', [__CLASS__, 'set_screen'], 10, 3);
26
27 if (ppressGET_var('page') == PPRESS_MEMBERSHIP_PLANS_SETTINGS_SLUG) {
28
29 add_action('admin_init', function () {
30 $this->save_changes();
31 });
32 }
33 }
34
35 public function default_header_menu()
36 {
37 return 'plans';
38 }
39
40 public function register_cpf_settings_page()
41 {
42 $hook = add_submenu_page(
43 PPRESS_DASHBOARD_SETTINGS_SLUG,
44 $this->admin_page_title() . ' - ProfilePress',
45 esc_html__('Membership Plans', 'wp-user-avatar'),
46 'manage_options',
47 PPRESS_MEMBERSHIP_PLANS_SETTINGS_SLUG,
48 array($this, 'admin_page_callback'));
49
50 add_action("load-$hook", array($this, 'add_options'));
51
52 do_action('ppress_membership_plans_settings_page_register', $hook);
53 }
54
55 public function header_menu_tabs()
56 {
57 $tabs = apply_filters('ppress_membership_plans_settings_page_tabs', [
58 5 => ['id' => $this->default_header_menu(), 'url' => PPRESS_MEMBERSHIP_SUBSCRIPTION_PLANS_SETTINGS_PAGE, 'label' => esc_html__('Plans', 'wp-user-avatar')],
59 10 => ['id' => 'groups', 'url' => PPRESS_MEMBERSHIP_GROUPS_SETTINGS_PAGE, 'label' => esc_html__('Groups', 'wp-user-avatar')],
60 15 => ['id' => 'coupons', 'url' => PPRESS_MEMBERSHIP_COUPONS_SETTINGS_PAGE, 'label' => esc_html__('Coupons', 'wp-user-avatar')]
61 ]);
62
63 ksort($tabs);
64
65 return $tabs;
66 }
67
68 public function admin_page_title()
69 {
70
71 $title = esc_html__('Plans', 'wp-user-avatar');
72
73 if (ppressGET_var('ppress_subp_action') == 'new') {
74 $title = esc_html__('Add Plan', 'wp-user-avatar');
75 }
76
77 if (ppressGET_var('ppress_subp_action') == 'edit') {
78 $title = esc_html__('Edit Plan', 'wp-user-avatar');
79 }
80
81 return apply_filters('ppress_membership_plans_settings_page_title', $title);
82 }
83
84 public function save_changes()
85 {
86 if ( ! isset($_POST['ppress_save_subscription_plan'])) return;
87
88 check_admin_referer('wp-csa-nonce', 'wp_csa_nonce');
89
90 if ( ! current_user_can('manage_options')) return;
91
92 $required_fields = [
93 'name' => esc_html__('Plan Name', 'wp-user-avatar'),
94 'price' => esc_html__('Price', 'wp-user-avatar'),
95 'billing_frequency' => esc_html__('Billing Frequency', 'wp-user-avatar'),
96 'subscription_length' => esc_html__('Subscription Length', 'wp-user-avatar')
97 ];
98
99 foreach ($required_fields as $field_id => $field_name) {
100 if (empty($_POST[$field_id])) {
101 return $this->error_bucket = sprintf(esc_html__('%s cannot be empty.', 'wp-user-avatar'), $field_name);
102 }
103 }
104
105 $plan = ppress_get_plan(absint(ppressGET_var('id')));
106
107 $current_role = $plan->user_role;
108 $new_role = sanitize_text_field($_POST['user_role']);
109
110 if ($new_role != 'create_new') {
111 $plan->user_role = $new_role;
112 }
113
114 $plan->name = stripslashes(sanitize_text_field($_POST['name']));
115 $plan->description = stripslashes(wp_kses_post($_POST['description']));
116 $plan->order_note = stripslashes(wp_kses_post($_POST['order_note']));
117 $plan->price = ppress_sanitize_amount($_POST['price']);
118 $plan->billing_frequency = sanitize_text_field($_POST['billing_frequency']);
119 $plan->subscription_length = sanitize_text_field($_POST['subscription_length']);
120 $plan->total_payments = absint($_POST['total_payments']);
121 if ($plan->subscription_length == 'renew_indefinitely') {
122 $plan->total_payments = 0;
123 }
124 $plan->signup_fee = ppress_sanitize_amount($_POST['signup_fee']);
125 $plan->free_trial = sanitize_text_field($_POST['free_trial']);
126 $plan_id = $plan->save();
127 $plan->id = $plan_id;
128
129 if (intval($plan_id) > 0) {
130
131 if ('create_new' == $new_role) {
132 $new_role = 'ppress_plan_' . $plan_id;
133 add_role($new_role, $plan->name, ['read' => true]);
134 $plan->user_role = $new_role;
135 $plan->save();
136 }
137
138 if ( ! empty($new_role) && $current_role != $new_role) {
139
140 $subs = SubscriptionRepository::init()->retrieveBy([
141 'plan_id' => $plan_id,
142 'status' => [
143 SubscriptionStatus::ACTIVE,
144 SubscriptionStatus::COMPLETED,
145 SubscriptionStatus::CANCELLED
146 ]
147 ]);
148
149 if ( ! empty($subs) && is_array($subs)) {
150 foreach ($subs as $sub) {
151 if ($sub->is_active()) {
152 $customer = CustomerFactory::fromId($sub->customer_id);
153 if ($customer->user_exists()) {
154 $customer->get_wp_user()->remove_role($current_role);
155 $customer->get_wp_user()->add_role($new_role);
156 }
157 }
158 }
159 }
160 }
161 }
162
163 $plan_extras = $plan->get_meta($plan::PLAN_EXTRAS);
164
165 if ( ! is_array($plan_extras) || empty($plan_extras)) {
166 $plan_extras = [];
167 }
168
169 $skip_props = array_map(function ($val) {
170 return $val->getName();
171 }, (new \ReflectionClass($plan))->getProperties());
172
173 array_push($skip_props, 'ppress_save_subscription_plan', 'wp_csa_nonce');
174
175 foreach ($_POST as $key => $value) {
176 if (in_array($key, $skip_props)) continue;
177 $plan_extras[$key] = ppress_clean($value);
178 }
179
180 $plan->update_meta('plan_extras', $plan_extras);
181
182 wp_safe_redirect(add_query_arg(['ppress_subp_action' => 'edit', 'id' => $plan_id, 'saved' => 'true'], PPRESS_MEMBERSHIP_SUBSCRIPTION_PLANS_SETTINGS_PAGE));
183 exit;
184 }
185
186 public static function set_screen($status, $option, $value)
187 {
188 return $value;
189 }
190
191 public function add_options()
192 {
193 $args = [
194 'label' => esc_html__('Membership Plans', 'wp-user-avatar'),
195 'default' => 10,
196 'option' => 'plans_per_page'
197 ];
198
199 add_screen_option('per_page', $args);
200
201 $this->planListTable = new PlanWPListTable();
202 }
203
204 public function admin_notices()
205 {
206 if ( ! isset($_GET['saved']) && ! isset($this->error_bucket)) return;
207
208 $status = 'updated';
209 $message = '';
210
211 if ( ! empty($this->error_bucket)) {
212 $message = $this->error_bucket;
213 $status = 'error';
214 }
215
216 if (isset($_GET['saved'])) {
217 $message = esc_html__('Changes saved.', 'wp-user-avatar');
218 }
219
220 printf('<div id="message" class="%s notice is-dismissible"><p>%s</strong></p></div>', $status, $message);
221 }
222
223 public function settings_page_function()
224 {
225 add_action('admin_footer', [$this, 'js_template']);
226 add_filter('wp_cspa_main_content_area', [$this, 'admin_settings_page_callback'], 10, 2);
227 add_action('wp_cspa_before_closing_header', [$this, 'add_new_button']);
228
229 $instance = Custom_Settings_Page_Api::instance();
230 $instance->option_name('ppview'); // adds ppview css class to #poststuff
231 $instance->page_header($this->admin_page_title());
232 $instance->build(true);
233 }
234
235 public function add_new_button()
236 {
237 if ( ! isset($_GET['ppress_subp_action']) || ppressGET_var('ppress_subp_action') == 'edit') {
238 $url = esc_url_raw(add_query_arg('ppress_subp_action', 'new', PPRESS_MEMBERSHIP_SUBSCRIPTION_PLANS_SETTINGS_PAGE));
239 echo "<a class=\"add-new-h2\" href=\"$url\">" . esc_html__('Add New Plan', 'wp-user-avatar') . '</a>';
240 }
241 }
242
243 public function admin_settings_page_callback()
244 {
245 if (in_array(ppressGET_var('ppress_subp_action'), ['new', 'edit'])) {
246 $this->admin_notices();
247 require_once dirname(dirname(__FILE__)) . '/views/add-edit-plan.php';
248
249 return;
250 }
251
252 $this->planListTable->prepare_items(); // has to be here.
253
254 $this->planListTable->views();
255 echo '<form method="post">';
256 $this->planListTable->display();
257 echo '</form>';
258
259 do_action('ppress_subscription_plan_wp_list_table_bottom');
260 }
261
262 public function js_template()
263 {
264 $currency_symbol = ppress_get_currency_symbol();
265 ?>
266 <script type="text/javascript">
267 var ppress_transform_plan_frequency = function (val) {
268 var bag = {
269 'monthly': '<?php esc_html_e('month', 'wp-user-avatar'); ?>',
270 'weekly': '<?php esc_html_e('week', 'wp-user-avatar'); ?>',
271 'daily': '<?php esc_html_e('day', 'wp-user-avatar'); ?>',
272 '3_month': '<?php esc_html_e('quarter', 'wp-user-avatar'); ?>',
273 '6_month': '<?php esc_html_e('every 6 months', 'wp-user-avatar'); ?>',
274 '1_year': '<?php esc_html_e('year', 'wp-user-avatar'); ?>',
275 'lifetime': '<?php esc_html_e('one-time', 'wp-user-avatar'); ?>',
276 };
277
278 return bag[val];
279 };
280
281 var ppress_transform_subscription_length = function (val) {
282 var bag = {
283 'monthly': '<?php esc_html_e('month', 'wp-user-avatar'); ?>',
284 'weekly': '<?php esc_html_e('week', 'wp-user-avatar'); ?>',
285 'daily': '<?php esc_html_e('day', 'wp-user-avatar'); ?>',
286 '3_month': '<?php esc_html_e('quarter', 'wp-user-avatar'); ?>',
287 '6_month': '<?php esc_html_e('every 6 months', 'wp-user-avatar'); ?>',
288 '1_year': '<?php esc_html_e('year', 'wp-user-avatar'); ?>',
289 'lifetime': '<?php esc_html_e('one-time', 'wp-user-avatar'); ?>',
290 };
291
292 return bag[val];
293 };
294
295 var ppress_transform_currency = function (price) {
296 var placeholder = '<?php echo (new CurrencyFormatter('54321012345'))->apply_symbol()->val(); ?>';
297 return placeholder.replace('54321012345', price);
298 };
299
300 </script>
301 <script type="text/html" id="tmpl-ppress-plan-summary">
302 <# var subscription_expiration_unit_map = {days: '<?= esc_html__('Days', 'wp-user-avatar') ?>',weeks: '<?= esc_html__('Weeks', 'wp-user-avatar') ?>',months: '<?= esc_html__('Months', 'wp-user-avatar') ?>',years: '<?= esc_html__('Years', 'wp-user-avatar') ?>'} #>
303 <# var total_payments = data.free_trial != 'disabled' ? data.total_payments - 1 : data.total_payments; #>
304 <# var billing_frequency_id = data.billing_frequency; #>
305 <# var billing_frequency = ppress_transform_plan_frequency(data.billing_frequency) #>
306 <# var billing_frequency_desc = data.billing_frequency == '6_month' ? 6*total_payments + " <?= __('months', 'wp-user-avatar') ?>" : total_payments+ ' '+billing_frequency+'s' #>
307 <# var total_payments_desc = billing_frequency_id != 'lifetime' && total_payments >= 1 ? ', <?= esc_html__('for', 'wp-user-avatar') ?> '+ billing_frequency_desc : ''; #>
308 <# var signup_fee_desc = billing_frequency_id != 'lifetime' && data.signup_fee > 0 ? '<?= sprintf(esc_html__(' and a %s signup fee', 'wp-user-avatar'), "'+ppress_transform_currency(data.signup_fee)+'") ?>' : ''; #>
309
310 <# var subscription_length_desc = data.subscription_length != 'fixed' ? '<?= esc_html__('Renews indefinitely', 'wp-user-avatar') ?>' : ''; #>
311 <# subscription_length_desc = billing_frequency_id == 'lifetime' ? '<?= esc_html__('Never expires', 'wp-user-avatar') ?>' : subscription_length_desc; #>
312
313 <# if (data.subscription_expiration_type == 'specific_date' && data.subscription_expiration_date) { #>
314 <# subscription_length_desc = '<?= esc_html__('Expires at', 'wp-user-avatar') ?> ' + data.subscription_expiration_date; #>
315 <# } else if (data.subscription_expiration_type == 'relative_date' && data.subscription_expiration_value && data.subscription_expiration_unit) { #>
316 <# var unit_label = subscription_expiration_unit_map[data.subscription_expiration_unit]; #>
317 <# subscription_length_desc = '<?= esc_html__('Expires after', 'wp-user-avatar') ?> ' + data.subscription_expiration_value + ' ' + unit_label; #>
318 <# } #>
319
320 <# var free_trial_desc = data.free_trial != 'disabled' ? '<?= sprintf(esc_html__('Includes a %s free trial', 'wp-user-avatar'), "'+data.free_trial+'") ?>' : ''; #>
321 <# free_trial_desc = free_trial_desc.replace('_', '-'); #>
322 <p>{{ ppress_transform_currency(data.price) }} / {{billing_frequency}}{{total_payments_desc}}{{{signup_fee_desc}}}</p>
323 <ul>
324 <# if(billing_frequency_id != 'lifetime' && '' !== free_trial_desc && 'disabled' !== free_trial_desc ) { #>
325 <li style="list-style:disc inside;">{{free_trial_desc}}</li>
326 <# } #>
327 <# if('' !== subscription_length_desc) { #>
328 <li style="list-style:disc inside;">{{subscription_length_desc}}</li>
329 <# } #>
330 </ul>
331 </script>
332 <?php
333 }
334
335 public static function get_instance()
336 {
337 static $instance = null;
338
339 if (is_null($instance)) {
340 $instance = new self();
341 }
342
343 return $instance;
344 }
345 }