1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This file contains all the administration functions for subscriptions. |
||
5 | * (and some more than that :P) |
||
6 | * |
||
7 | * Simple Machines Forum (SMF) |
||
8 | * |
||
9 | * @package SMF |
||
10 | * @author Simple Machines https://www.simplemachines.org |
||
11 | * @copyright 2020 Simple Machines and individual contributors |
||
12 | * @license https://www.simplemachines.org/about/smf/license.php BSD |
||
13 | * |
||
14 | * @version 2.1 RC2 |
||
15 | */ |
||
16 | |||
17 | if (!defined('SMF')) |
||
18 | die('No direct access...'); |
||
19 | |||
20 | /** |
||
21 | * The main entrance point for the 'Paid Subscription' screen, calling |
||
22 | * the right function based on the given sub-action. |
||
23 | * It defaults to sub-action 'view'. |
||
24 | * Accessed from ?action=admin;area=paidsubscribe. |
||
25 | * It requires admin_forum permission for admin based actions. |
||
26 | */ |
||
27 | function ManagePaidSubscriptions() |
||
28 | { |
||
29 | global $context, $txt, $modSettings; |
||
30 | |||
31 | // Load the required language and template. |
||
32 | loadLanguage('ManagePaid'); |
||
33 | loadTemplate('ManagePaid'); |
||
34 | |||
35 | if (!empty($modSettings['paid_enabled'])) |
||
36 | $subActions = array( |
||
37 | 'modify' => array('ModifySubscription', 'admin_forum'), |
||
38 | 'modifyuser' => array('ModifyUserSubscription', 'admin_forum'), |
||
39 | 'settings' => array('ModifySubscriptionSettings', 'admin_forum'), |
||
40 | 'view' => array('ViewSubscriptions', 'admin_forum'), |
||
41 | 'viewsub' => array('ViewSubscribedUsers', 'admin_forum'), |
||
42 | ); |
||
43 | else |
||
44 | $subActions = array( |
||
45 | 'settings' => array('ModifySubscriptionSettings', 'admin_forum'), |
||
46 | ); |
||
47 | |||
48 | // Default the sub-action to 'view subscriptions', but only if they have already set things up.. |
||
49 | $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (!empty($modSettings['paid_currency_symbol']) && !empty($modSettings['paid_enabled']) ? 'view' : 'settings'); |
||
50 | |||
51 | // Make sure you can do this. |
||
52 | isAllowedTo($subActions[$_REQUEST['sa']][1]); |
||
53 | |||
54 | $context['page_title'] = $txt['paid_subscriptions']; |
||
55 | |||
56 | // Tabs for browsing the different subscription functions. |
||
57 | $context[$context['admin_menu_name']]['tab_data'] = array( |
||
58 | 'title' => $txt['paid_subscriptions'], |
||
59 | 'help' => '', |
||
60 | 'description' => $txt['paid_subscriptions_desc'], |
||
61 | ); |
||
62 | if (!empty($modSettings['paid_enabled'])) |
||
63 | $context[$context['admin_menu_name']]['tab_data']['tabs'] = array( |
||
64 | 'view' => array( |
||
65 | 'description' => $txt['paid_subs_view_desc'], |
||
66 | ), |
||
67 | 'settings' => array( |
||
68 | 'description' => $txt['paid_subs_settings_desc'], |
||
69 | ), |
||
70 | ); |
||
71 | |||
72 | call_integration_hook('integrate_manage_subscriptions', array(&$subActions)); |
||
73 | |||
74 | // Call the right function for this sub-action. |
||
75 | call_helper($subActions[$_REQUEST['sa']][0]); |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Set any setting related to paid subscriptions, i.e. |
||
80 | * modify which payment methods are to be used. |
||
81 | * It requires the moderate_forum permission |
||
82 | * Accessed from ?action=admin;area=paidsubscribe;sa=settings. |
||
83 | * |
||
84 | * @param bool $return_config Whether or not to return the $config_vars array (used for admin search) |
||
85 | * @return void|array Returns nothing or returns the config_vars array if $return_config is true |
||
86 | */ |
||
87 | function ModifySubscriptionSettings($return_config = false) |
||
88 | { |
||
89 | global $context, $txt, $modSettings, $sourcedir, $smcFunc, $scripturl; |
||
90 | |||
91 | if (!empty($modSettings['paid_enabled'])) |
||
92 | { |
||
93 | // If the currency is set to something different then we need to set it to other for this to work and set it back shortly. |
||
94 | $modSettings['paid_currency'] = !empty($modSettings['paid_currency_code']) ? $modSettings['paid_currency_code'] : ''; |
||
95 | if (!empty($modSettings['paid_currency_code']) && !in_array($modSettings['paid_currency_code'], array('usd', 'eur', 'gbp', 'cad', 'aud'))) |
||
96 | $modSettings['paid_currency'] = 'other'; |
||
97 | |||
98 | // These are all the default settings. |
||
99 | $config_vars = array( |
||
100 | array( |
||
101 | 'check', |
||
102 | 'paid_enabled' |
||
103 | ), |
||
104 | '', |
||
105 | |||
106 | array( |
||
107 | 'select', |
||
108 | 'paid_email', |
||
109 | array( |
||
110 | 0 => $txt['paid_email_no'], |
||
111 | 1 => $txt['paid_email_error'], |
||
112 | 2 => $txt['paid_email_all'] |
||
113 | ), |
||
114 | 'subtext' => $txt['paid_email_desc'] |
||
115 | ), |
||
116 | array( |
||
117 | 'email', |
||
118 | 'paid_email_to', |
||
119 | 'subtext' => $txt['paid_email_to_desc'], |
||
120 | 'size' => 60 |
||
121 | ), |
||
122 | '', |
||
123 | |||
124 | 'dummy_currency' => array( |
||
125 | 'select', |
||
126 | 'paid_currency', |
||
127 | array( |
||
128 | 'usd' => $txt['usd'], |
||
129 | 'eur' => $txt['eur'], |
||
130 | 'gbp' => $txt['gbp'], |
||
131 | 'cad' => $txt['cad'], |
||
132 | 'aud' => $txt['aud'], |
||
133 | 'other' => $txt['other'] |
||
134 | ), |
||
135 | 'javascript' => 'onchange="toggleOther();"' |
||
136 | ), |
||
137 | array( |
||
138 | 'text', |
||
139 | 'paid_currency_code', |
||
140 | 'subtext' => $txt['paid_currency_code_desc'], |
||
141 | 'size' => 5, |
||
142 | 'force_div_id' => 'custom_currency_code_div' |
||
143 | ), |
||
144 | array( |
||
145 | 'text', |
||
146 | 'paid_currency_symbol', |
||
147 | 'subtext' => $txt['paid_currency_symbol_desc'], |
||
148 | 'size' => 8, |
||
149 | 'force_div_id' => 'custom_currency_symbol_div' |
||
150 | ), |
||
151 | array( |
||
152 | 'check', |
||
153 | 'paidsubs_test', |
||
154 | 'subtext' => $txt['paidsubs_test_desc'], |
||
155 | 'onclick' => 'return document.getElementById(\'paidsubs_test\').checked ? confirm(\'' . $txt['paidsubs_test_confirm'] . '\') : true;' |
||
156 | ), |
||
157 | ); |
||
158 | |||
159 | // Now load all the other gateway settings. |
||
160 | $gateways = loadPaymentGateways(); |
||
161 | foreach ($gateways as $gateway) |
||
162 | { |
||
163 | $gatewayClass = new $gateway['display_class'](); |
||
164 | $setting_data = $gatewayClass->getGatewaySettings(); |
||
165 | if (!empty($setting_data)) |
||
166 | { |
||
167 | $config_vars[] = array('title', $gatewayClass->title, 'text_label' => (isset($txt['paidsubs_gateway_title_' . $gatewayClass->title]) ? $txt['paidsubs_gateway_title_' . $gatewayClass->title] : $gatewayClass->title)); |
||
168 | $config_vars = array_merge($config_vars, $setting_data); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | $context['settings_message'] = $txt['paid_note']; |
||
173 | $context[$context['admin_menu_name']]['current_subsection'] = 'settings'; |
||
174 | $context['settings_title'] = $txt['settings']; |
||
175 | |||
176 | // We want javascript for our currency options. |
||
177 | addInlineJavaScript(' |
||
178 | function toggleOther() |
||
179 | { |
||
180 | var otherOn = document.getElementById("paid_currency").value == \'other\'; |
||
181 | var currencydd = document.getElementById("custom_currency_code_div_dd"); |
||
182 | |||
183 | if (otherOn) |
||
184 | { |
||
185 | document.getElementById("custom_currency_code_div").style.display = ""; |
||
186 | document.getElementById("custom_currency_symbol_div").style.display = ""; |
||
187 | |||
188 | if (currencydd) |
||
189 | { |
||
190 | document.getElementById("custom_currency_code_div_dd").style.display = ""; |
||
191 | document.getElementById("custom_currency_symbol_div_dd").style.display = ""; |
||
192 | } |
||
193 | } |
||
194 | else |
||
195 | { |
||
196 | document.getElementById("custom_currency_code_div").style.display = "none"; |
||
197 | document.getElementById("custom_currency_symbol_div").style.display = "none"; |
||
198 | |||
199 | if (currencydd) |
||
200 | { |
||
201 | document.getElementById("custom_currency_symbol_div_dd").style.display = "none"; |
||
202 | document.getElementById("custom_currency_code_div_dd").style.display = "none"; |
||
203 | } |
||
204 | } |
||
205 | } |
||
206 | toggleOther();', true); |
||
207 | } |
||
208 | else |
||
209 | { |
||
210 | $config_vars = array( |
||
211 | array('check', 'paid_enabled'), |
||
212 | ); |
||
213 | $context['settings_title'] = $txt['paid_subscriptions']; |
||
214 | } |
||
215 | |||
216 | // Just searching? |
||
217 | if ($return_config) |
||
218 | return $config_vars; |
||
219 | |||
220 | // Get the settings template fired up. |
||
221 | require_once($sourcedir . '/ManageServer.php'); |
||
222 | |||
223 | // Some important context stuff |
||
224 | $context['page_title'] = $txt['settings']; |
||
225 | $context['sub_template'] = 'show_settings'; |
||
226 | |||
227 | // Get the final touches in place. |
||
228 | $context['post_url'] = $scripturl . '?action=admin;area=paidsubscribe;save;sa=settings'; |
||
229 | |||
230 | // Saving the settings? |
||
231 | if (isset($_GET['save'])) |
||
232 | { |
||
233 | checkSession(); |
||
234 | |||
235 | $old = !empty($modSettings['paid_enabled']); |
||
236 | $new = !empty($_POST['paid_enabled']); |
||
237 | if ($old != $new) |
||
238 | { |
||
239 | // So we're changing this fundamental status. Great. |
||
240 | $smcFunc['db_query']('', ' |
||
241 | UPDATE {db_prefix}scheduled_tasks |
||
242 | SET disabled = {int:disabled} |
||
243 | WHERE task = {string:task}', |
||
244 | array( |
||
245 | 'disabled' => $new ? 0 : 1, |
||
246 | 'task' => 'paid_subscriptions', |
||
247 | ) |
||
248 | ); |
||
249 | |||
250 | // This may well affect the next trigger, whether we're enabling or not. |
||
251 | require_once($sourcedir . '/ScheduledTasks.php'); |
||
252 | CalculateNextTrigger('paid_subscriptions'); |
||
253 | } |
||
254 | |||
255 | // Check the email addresses were actually email addresses. |
||
256 | if (!empty($_POST['paid_email_to'])) |
||
257 | { |
||
258 | $email_addresses = array(); |
||
259 | foreach (explode(',', $_POST['paid_email_to']) as $email) |
||
260 | { |
||
261 | $email = trim($email); |
||
262 | if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) |
||
263 | $email_addresses[] = $email; |
||
264 | $_POST['paid_email_to'] = implode(',', $email_addresses); |
||
265 | } |
||
266 | } |
||
267 | |||
268 | // Can only handle this stuff if it's already enabled... |
||
269 | if (!empty($modSettings['paid_enabled'])) |
||
270 | { |
||
271 | // Sort out the currency stuff. |
||
272 | if ($_POST['paid_currency'] != 'other') |
||
273 | { |
||
274 | $_POST['paid_currency_code'] = $_POST['paid_currency']; |
||
275 | $_POST['paid_currency_symbol'] = $txt[$_POST['paid_currency'] . '_symbol']; |
||
276 | } |
||
277 | unset($config_vars['dummy_currency']); |
||
278 | } |
||
279 | |||
280 | saveDBSettings($config_vars); |
||
281 | $_SESSION['adm-save'] = true; |
||
282 | |||
283 | redirectexit('action=admin;area=paidsubscribe;sa=settings'); |
||
284 | } |
||
285 | |||
286 | // Prepare the settings... |
||
287 | prepareDBSettingContext($config_vars); |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * View a list of all the current subscriptions |
||
292 | * Requires the admin_forum permission. |
||
293 | * Accessed from ?action=admin;area=paidsubscribe;sa=view. |
||
294 | */ |
||
295 | function ViewSubscriptions() |
||
296 | { |
||
297 | global $context, $txt, $modSettings, $sourcedir, $scripturl; |
||
298 | |||
299 | // Not made the settings yet? |
||
300 | if (empty($modSettings['paid_currency_symbol'])) |
||
301 | fatal_lang_error('paid_not_set_currency', false, $scripturl . '?action=admin;area=paidsubscribe;sa=settings'); |
||
302 | |||
303 | // Some basic stuff. |
||
304 | $context['page_title'] = $txt['paid_subs_view']; |
||
305 | loadSubscriptions(); |
||
306 | |||
307 | $listOptions = array( |
||
308 | 'id' => 'subscription_list', |
||
309 | 'title' => $txt['subscriptions'], |
||
310 | 'items_per_page' => $modSettings['defaultMaxListItems'], |
||
311 | 'base_href' => $scripturl . '?action=admin;area=paidsubscribe;sa=view', |
||
312 | 'get_items' => array( |
||
313 | 'function' => function($start, $items_per_page) use ($context) |
||
314 | { |
||
315 | $subscriptions = array(); |
||
316 | $counter = 0; |
||
317 | $start++; |
||
318 | |||
319 | foreach ($context['subscriptions'] as $data) |
||
320 | { |
||
321 | if (++$counter < $start) |
||
322 | continue; |
||
323 | elseif ($counter == $start + $items_per_page) |
||
324 | break; |
||
325 | |||
326 | $subscriptions[] = $data; |
||
327 | } |
||
328 | return $subscriptions; |
||
329 | }, |
||
330 | ), |
||
331 | 'get_count' => array( |
||
332 | 'function' => function() use ($context) |
||
333 | { |
||
334 | return count($context['subscriptions']); |
||
335 | }, |
||
336 | ), |
||
337 | 'no_items_label' => $txt['paid_none_yet'], |
||
338 | 'columns' => array( |
||
339 | 'name' => array( |
||
340 | 'header' => array( |
||
341 | 'value' => $txt['paid_name'], |
||
342 | 'style' => 'width: 35%;', |
||
343 | ), |
||
344 | 'data' => array( |
||
345 | 'function' => function($rowData) use ($scripturl) |
||
346 | { |
||
347 | return sprintf('<a href="%1$s?action=admin;area=paidsubscribe;sa=viewsub;sid=%2$s">%3$s</a>', $scripturl, $rowData['id'], $rowData['name']); |
||
348 | }, |
||
349 | ), |
||
350 | ), |
||
351 | 'cost' => array( |
||
352 | 'header' => array( |
||
353 | 'value' => $txt['paid_cost'], |
||
354 | ), |
||
355 | 'data' => array( |
||
356 | 'function' => function($rowData) use ($txt) |
||
357 | { |
||
358 | return $rowData['flexible'] ? '<em>' . $txt['flexible'] . '</em>' : $rowData['cost'] . ' / ' . $rowData['length']; |
||
359 | }, |
||
360 | ), |
||
361 | ), |
||
362 | 'pending' => array( |
||
363 | 'header' => array( |
||
364 | 'value' => $txt['paid_pending'], |
||
365 | 'style' => 'width: 18%;', |
||
366 | 'class' => 'centercol', |
||
367 | ), |
||
368 | 'data' => array( |
||
369 | 'db_htmlsafe' => 'pending', |
||
370 | 'class' => 'centercol', |
||
371 | ), |
||
372 | ), |
||
373 | 'finished' => array( |
||
374 | 'header' => array( |
||
375 | 'value' => $txt['paid_finished'], |
||
376 | 'class' => 'centercol', |
||
377 | ), |
||
378 | 'data' => array( |
||
379 | 'db_htmlsafe' => 'finished', |
||
380 | 'class' => 'centercol', |
||
381 | ), |
||
382 | ), |
||
383 | 'total' => array( |
||
384 | 'header' => array( |
||
385 | 'value' => $txt['paid_active'], |
||
386 | 'class' => 'centercol', |
||
387 | ), |
||
388 | 'data' => array( |
||
389 | 'db_htmlsafe' => 'total', |
||
390 | 'class' => 'centercol', |
||
391 | ), |
||
392 | ), |
||
393 | 'is_active' => array( |
||
394 | 'header' => array( |
||
395 | 'value' => $txt['paid_is_active'], |
||
396 | 'class' => 'centercol', |
||
397 | ), |
||
398 | 'data' => array( |
||
399 | 'function' => function($rowData) use ($txt) |
||
400 | { |
||
401 | return '<span style="color: ' . ($rowData['active'] ? 'green' : 'red') . '">' . ($rowData['active'] ? $txt['yes'] : $txt['no']) . '</span>'; |
||
402 | }, |
||
403 | 'class' => 'centercol', |
||
404 | ), |
||
405 | ), |
||
406 | 'modify' => array( |
||
407 | 'data' => array( |
||
408 | 'function' => function($rowData) use ($txt, $scripturl) |
||
409 | { |
||
410 | return '<a href="' . $scripturl . '?action=admin;area=paidsubscribe;sa=modify;sid=' . $rowData['id'] . '">' . $txt['modify'] . '</a>'; |
||
411 | }, |
||
412 | 'class' => 'centercol', |
||
413 | ), |
||
414 | ), |
||
415 | 'delete' => array( |
||
416 | 'data' => array( |
||
417 | 'function' => function($rowData) use ($scripturl, $txt) |
||
418 | { |
||
419 | return '<a href="' . $scripturl . '?action=admin;area=paidsubscribe;sa=modify;delete;sid=' . $rowData['id'] . '">' . $txt['delete'] . '</a>'; |
||
420 | }, |
||
421 | 'class' => 'centercol', |
||
422 | ), |
||
423 | ), |
||
424 | ), |
||
425 | 'form' => array( |
||
426 | 'href' => $scripturl . '?action=admin;area=paidsubscribe;sa=modify', |
||
427 | ), |
||
428 | 'additional_rows' => array( |
||
429 | array( |
||
430 | 'position' => 'above_table_headers', |
||
431 | 'value' => '<input type="submit" name="add" value="' . $txt['paid_add_subscription'] . '" class="button">', |
||
432 | ), |
||
433 | array( |
||
434 | 'position' => 'below_table_data', |
||
435 | 'value' => '<input type="submit" name="add" value="' . $txt['paid_add_subscription'] . '" class="button">', |
||
436 | ), |
||
437 | ), |
||
438 | ); |
||
439 | |||
440 | require_once($sourcedir . '/Subs-List.php'); |
||
441 | createList($listOptions); |
||
442 | |||
443 | $context['sub_template'] = 'show_list'; |
||
444 | $context['default_list'] = 'subscription_list'; |
||
445 | } |
||
446 | |||
447 | /** |
||
448 | * Adding, editing and deleting subscriptions. |
||
449 | * Accessed from ?action=admin;area=paidsubscribe;sa=modify. |
||
450 | */ |
||
451 | function ModifySubscription() |
||
452 | { |
||
453 | global $context, $txt, $smcFunc; |
||
454 | |||
455 | $context['sub_id'] = isset($_REQUEST['sid']) ? (int) $_REQUEST['sid'] : 0; |
||
456 | $context['action_type'] = $context['sub_id'] ? (isset($_REQUEST['delete']) ? 'delete' : 'edit') : 'add'; |
||
457 | |||
458 | // Setup the template. |
||
459 | $context['sub_template'] = $context['action_type'] == 'delete' ? 'delete_subscription' : 'modify_subscription'; |
||
460 | $context['page_title'] = $txt['paid_' . $context['action_type'] . '_subscription']; |
||
461 | |||
462 | // Delete it? |
||
463 | if (isset($_POST['delete_confirm']) && isset($_REQUEST['delete'])) |
||
464 | { |
||
465 | checkSession(); |
||
466 | validateToken('admin-pmsd'); |
||
467 | |||
468 | // Before we delete the subscription we need to find out if anyone currently has said subscription. |
||
469 | $request = $smcFunc['db_query']('', ' |
||
470 | SELECT ls.id_member, ls.old_id_group, mem.id_group, mem.additional_groups |
||
471 | FROM {db_prefix}log_subscribed AS ls |
||
472 | INNER JOIN {db_prefix}members AS mem ON (ls.id_member = mem.id_member) |
||
473 | WHERE id_subscribe = {int:current_subscription} |
||
474 | AND status = {int:is_active}', |
||
475 | array( |
||
476 | 'current_subscription' => $context['sub_id'], |
||
477 | 'is_active' => 1, |
||
478 | ) |
||
479 | ); |
||
480 | $members = array(); |
||
481 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
482 | { |
||
483 | $id_member = array_shift($row); |
||
484 | $members[$id_member] = $row; |
||
485 | } |
||
486 | $smcFunc['db_free_result']($request); |
||
487 | |||
488 | // If there are any members with this subscription, we have to do some more work before we go any further. |
||
489 | if (!empty($members)) |
||
490 | { |
||
491 | $request = $smcFunc['db_query']('', ' |
||
492 | SELECT id_group, add_groups |
||
493 | FROM {db_prefix}subscriptions |
||
494 | WHERE id_subscribe = {int:current_subscription}', |
||
495 | array( |
||
496 | 'current_subscription' => $context['sub_id'], |
||
497 | ) |
||
498 | ); |
||
499 | $id_group = 0; |
||
500 | $add_groups = ''; |
||
501 | if ($smcFunc['db_num_rows']($request)) |
||
502 | list ($id_group, $add_groups) = $smcFunc['db_fetch_row']($request); |
||
503 | $smcFunc['db_free_result']($request); |
||
504 | |||
505 | $changes = array(); |
||
506 | |||
507 | // Is their group changing? This subscription may not have changed primary group. |
||
508 | if (!empty($id_group)) |
||
509 | { |
||
510 | foreach ($members as $id_member => $member_data) |
||
511 | { |
||
512 | // If their current primary group isn't what they had before the subscription, and their current group was |
||
513 | // granted by the sub, remove it. |
||
514 | if ($member_data['old_id_group'] != $member_data['id_group'] && $member_data['id_group'] == $id_group) |
||
515 | $changes[$id_member]['id_group'] = $member_data['old_id_group']; |
||
516 | } |
||
517 | } |
||
518 | |||
519 | // Did this subscription add secondary groups? |
||
520 | if (!empty($add_groups)) |
||
521 | { |
||
522 | $add_groups = explode(',', $add_groups); |
||
523 | foreach ($members as $id_member => $member_data) |
||
524 | { |
||
525 | // First let's get their groups sorted. |
||
526 | $current_groups = explode(',', $member_data['additional_groups']); |
||
527 | $new_groups = implode(',', array_diff($current_groups, $add_groups)); |
||
528 | if ($new_groups != $member_data['additional_groups']) |
||
529 | $changes[$id_member]['additional_groups'] = $new_groups; |
||
530 | } |
||
531 | } |
||
532 | |||
533 | // We're going through changes... |
||
534 | if (!empty($changes)) |
||
535 | foreach ($changes as $id_member => $new_values) |
||
536 | updateMemberData($id_member, $new_values); |
||
537 | } |
||
538 | |||
539 | // Delete the subscription |
||
540 | $smcFunc['db_query']('', ' |
||
541 | DELETE FROM {db_prefix}subscriptions |
||
542 | WHERE id_subscribe = {int:current_subscription}', |
||
543 | array( |
||
544 | 'current_subscription' => $context['sub_id'], |
||
545 | ) |
||
546 | ); |
||
547 | |||
548 | // And delete any subscriptions to it to clear the phantom data too. |
||
549 | $smcFunc['db_query']('', ' |
||
550 | DELETE FROM {db_prefix}log_subscribed |
||
551 | WHERE id_subscribe = {int:current_subscription}', |
||
552 | array( |
||
553 | 'current_subscription' => $context['sub_id'], |
||
554 | ) |
||
555 | ); |
||
556 | |||
557 | call_integration_hook('integrate_delete_subscription', array($context['sub_id'])); |
||
558 | |||
559 | redirectexit('action=admin;area=paidsubscribe;view'); |
||
560 | } |
||
561 | |||
562 | // Saving? |
||
563 | if (isset($_POST['save'])) |
||
564 | { |
||
565 | checkSession(); |
||
566 | |||
567 | // Some cleaning... |
||
568 | $isActive = isset($_POST['active']) ? 1 : 0; |
||
569 | $isRepeatable = isset($_POST['repeatable']) ? 1 : 0; |
||
570 | $allowpartial = isset($_POST['allow_partial']) ? 1 : 0; |
||
571 | $reminder = isset($_POST['reminder']) ? (int) $_POST['reminder'] : 0; |
||
572 | $emailComplete = strlen($_POST['emailcomplete']) > 10 ? trim($_POST['emailcomplete']) : ''; |
||
573 | $_POST['prim_group'] = !empty($_POST['prim_group']) ? (int) $_POST['prim_group'] : 0; |
||
574 | |||
575 | // Is this a fixed one? |
||
576 | if ($_POST['duration_type'] == 'fixed') |
||
577 | { |
||
578 | $_POST['span_value'] = !empty($_POST['span_value']) && is_numeric($_POST['span_value']) ? ceil($_POST['span_value']) : 0; |
||
579 | |||
580 | // There are sanity check limits on these things. |
||
581 | $limits = array( |
||
582 | 'D' => 90, |
||
583 | 'W' => 52, |
||
584 | 'M' => 24, |
||
585 | 'Y' => 5, |
||
586 | ); |
||
587 | if (empty($_POST['span_unit']) || empty($limits[$_POST['span_unit']]) || $_POST['span_value'] < 1) |
||
588 | fatal_lang_error('paid_invalid_duration', false); |
||
589 | |||
590 | if ($_POST['span_value'] > $limits[$_POST['span_unit']]) |
||
591 | fatal_lang_error('paid_invalid_duration_' . $_POST['span_unit'], false); |
||
592 | |||
593 | // Clean the span. |
||
594 | $span = $_POST['span_value'] . $_POST['span_unit']; |
||
595 | |||
596 | // Sort out the cost. |
||
597 | $cost = array('fixed' => sprintf('%01.2f', strtr($_POST['cost'], ',', '.'))); |
||
598 | |||
599 | // There needs to be something. |
||
600 | if ($cost['fixed'] == '0.00') |
||
601 | fatal_lang_error('paid_no_cost_value'); |
||
602 | } |
||
603 | // Flexible is harder but more fun ;) |
||
604 | else |
||
605 | { |
||
606 | $span = 'F'; |
||
607 | |||
608 | $cost = array( |
||
609 | 'day' => sprintf('%01.2f', strtr($_POST['cost_day'], ',', '.')), |
||
610 | 'week' => sprintf('%01.2f', strtr($_POST['cost_week'], ',', '.')), |
||
611 | 'month' => sprintf('%01.2f', strtr($_POST['cost_month'], ',', '.')), |
||
612 | 'year' => sprintf('%01.2f', strtr($_POST['cost_year'], ',', '.')), |
||
613 | ); |
||
614 | |||
615 | if ($cost['day'] == '0.00' && $cost['week'] == '0.00' && $cost['month'] == '0.00' && $cost['year'] == '0.00') |
||
616 | fatal_lang_error('paid_all_freq_blank'); |
||
617 | } |
||
618 | $cost = $smcFunc['json_encode']($cost); |
||
619 | |||
620 | // Having now validated everything that might throw an error, let's also now deal with the token. |
||
621 | validateToken('admin-pms'); |
||
622 | |||
623 | // Yep, time to do additional groups. |
||
624 | $addgroups = array(); |
||
625 | if (!empty($_POST['addgroup'])) |
||
626 | foreach ($_POST['addgroup'] as $id => $dummy) |
||
627 | $addgroups[] = (int) $id; |
||
628 | $addgroups = implode(',', $addgroups); |
||
629 | |||
630 | // Is it new?! |
||
631 | if ($context['action_type'] == 'add') |
||
632 | { |
||
633 | $id_subscribe = $smcFunc['db_insert']('', |
||
634 | '{db_prefix}subscriptions', |
||
635 | array( |
||
636 | 'name' => 'string-60', 'description' => 'string-255', 'active' => 'int', 'length' => 'string-4', 'cost' => 'string', |
||
637 | 'id_group' => 'int', 'add_groups' => 'string-40', 'repeatable' => 'int', 'allow_partial' => 'int', 'email_complete' => 'string', |
||
638 | 'reminder' => 'int', |
||
639 | ), |
||
640 | array( |
||
641 | $_POST['name'], $_POST['desc'], $isActive, $span, $cost, |
||
642 | $_POST['prim_group'], $addgroups, $isRepeatable, $allowpartial, $emailComplete, |
||
643 | $reminder, |
||
644 | ), |
||
645 | array('id_subscribe'), |
||
646 | 1 |
||
647 | ); |
||
648 | } |
||
649 | // Otherwise must be editing. |
||
650 | else |
||
651 | { |
||
652 | // Don't do groups if there are active members |
||
653 | $request = $smcFunc['db_query']('', ' |
||
654 | SELECT COUNT(*) |
||
655 | FROM {db_prefix}log_subscribed |
||
656 | WHERE id_subscribe = {int:current_subscription} |
||
657 | AND status = {int:is_active}', |
||
658 | array( |
||
659 | 'current_subscription' => $context['sub_id'], |
||
660 | 'is_active' => 1, |
||
661 | ) |
||
662 | ); |
||
663 | list ($disableGroups) = $smcFunc['db_fetch_row']($request); |
||
664 | $smcFunc['db_free_result']($request); |
||
665 | |||
666 | $smcFunc['db_query']('substring', ' |
||
667 | UPDATE {db_prefix}subscriptions |
||
668 | SET name = SUBSTRING({string:name}, 1, 60), description = SUBSTRING({string:description}, 1, 255), active = {int:is_active}, |
||
669 | length = SUBSTRING({string:length}, 1, 4), cost = {string:cost}' . ($disableGroups ? '' : ', id_group = {int:id_group}, |
||
670 | add_groups = {string:additional_groups}') . ', repeatable = {int:repeatable}, allow_partial = {int:allow_partial}, |
||
671 | email_complete = {string:email_complete}, reminder = {int:reminder} |
||
672 | WHERE id_subscribe = {int:current_subscription}', |
||
673 | array( |
||
674 | 'is_active' => $isActive, |
||
675 | 'id_group' => $_POST['prim_group'], |
||
676 | 'repeatable' => $isRepeatable, |
||
677 | 'allow_partial' => $allowpartial, |
||
678 | 'reminder' => $reminder, |
||
679 | 'current_subscription' => $context['sub_id'], |
||
680 | 'name' => $_POST['name'], |
||
681 | 'description' => $_POST['desc'], |
||
682 | 'length' => $span, |
||
683 | 'cost' => $cost, |
||
684 | 'additional_groups' => !empty($addgroups) ? $addgroups : '', |
||
685 | 'email_complete' => $emailComplete, |
||
686 | ) |
||
687 | ); |
||
688 | } |
||
689 | call_integration_hook('integrate_save_subscription', array(($context['action_type'] == 'add' ? $id_subscribe : $context['sub_id']), $_POST['name'], $_POST['desc'], $isActive, $span, $cost, $_POST['prim_group'], $addgroups, $isRepeatable, $allowpartial, $emailComplete, $reminder)); |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||
690 | |||
691 | redirectexit('action=admin;area=paidsubscribe;view'); |
||
692 | } |
||
693 | |||
694 | // Defaults. |
||
695 | if ($context['action_type'] == 'add') |
||
696 | { |
||
697 | $context['sub'] = array( |
||
698 | 'name' => '', |
||
699 | 'desc' => '', |
||
700 | 'cost' => array( |
||
701 | 'fixed' => 0, |
||
702 | ), |
||
703 | 'span' => array( |
||
704 | 'value' => '', |
||
705 | 'unit' => 'D', |
||
706 | ), |
||
707 | 'prim_group' => 0, |
||
708 | 'add_groups' => array(), |
||
709 | 'active' => 1, |
||
710 | 'repeatable' => 1, |
||
711 | 'allow_partial' => 0, |
||
712 | 'duration' => 'fixed', |
||
713 | 'email_complete' => '', |
||
714 | 'reminder' => 0, |
||
715 | ); |
||
716 | } |
||
717 | // Otherwise load up all the details. |
||
718 | else |
||
719 | { |
||
720 | $request = $smcFunc['db_query']('', ' |
||
721 | SELECT name, description, cost, length, id_group, add_groups, active, repeatable, allow_partial, email_complete, reminder |
||
722 | FROM {db_prefix}subscriptions |
||
723 | WHERE id_subscribe = {int:current_subscription} |
||
724 | LIMIT 1', |
||
725 | array( |
||
726 | 'current_subscription' => $context['sub_id'], |
||
727 | ) |
||
728 | ); |
||
729 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
730 | { |
||
731 | // Sort the date. |
||
732 | preg_match('~(\d*)(\w)~', $row['length'], $match); |
||
733 | if (isset($match[2])) |
||
734 | { |
||
735 | $_POST['span_value'] = $match[1]; |
||
736 | $span_unit = $match[2]; |
||
737 | } |
||
738 | else |
||
739 | { |
||
740 | $_POST['span_value'] = 0; |
||
741 | $span_unit = 'D'; |
||
742 | } |
||
743 | |||
744 | // Is this a flexible one? |
||
745 | if ($row['length'] == 'F') |
||
746 | $isFlexible = true; |
||
747 | else |
||
748 | $isFlexible = false; |
||
749 | |||
750 | $context['sub'] = array( |
||
751 | 'name' => $row['name'], |
||
752 | 'desc' => $row['description'], |
||
753 | 'cost' => $smcFunc['json_decode']($row['cost'], true), |
||
754 | 'span' => array( |
||
755 | 'value' => $_POST['span_value'], |
||
756 | 'unit' => $span_unit, |
||
757 | ), |
||
758 | 'prim_group' => $row['id_group'], |
||
759 | 'add_groups' => explode(',', $row['add_groups']), |
||
760 | 'active' => $row['active'], |
||
761 | 'repeatable' => $row['repeatable'], |
||
762 | 'allow_partial' => $row['allow_partial'], |
||
763 | 'duration' => $isFlexible ? 'flexible' : 'fixed', |
||
764 | 'email_complete' => $smcFunc['htmlspecialchars']($row['email_complete']), |
||
765 | 'reminder' => $row['reminder'], |
||
766 | ); |
||
767 | } |
||
768 | $smcFunc['db_free_result']($request); |
||
769 | |||
770 | // Does this have members who are active? |
||
771 | $request = $smcFunc['db_query']('', ' |
||
772 | SELECT COUNT(*) |
||
773 | FROM {db_prefix}log_subscribed |
||
774 | WHERE id_subscribe = {int:current_subscription} |
||
775 | AND status = {int:is_active}', |
||
776 | array( |
||
777 | 'current_subscription' => $context['sub_id'], |
||
778 | 'is_active' => 1, |
||
779 | ) |
||
780 | ); |
||
781 | list ($context['disable_groups']) = $smcFunc['db_fetch_row']($request); |
||
782 | $smcFunc['db_free_result']($request); |
||
783 | } |
||
784 | |||
785 | // Load up all the groups. |
||
786 | $request = $smcFunc['db_query']('', ' |
||
787 | SELECT id_group, group_name |
||
788 | FROM {db_prefix}membergroups |
||
789 | WHERE id_group != {int:moderator_group} |
||
790 | AND min_posts = {int:min_posts}', |
||
791 | array( |
||
792 | 'moderator_group' => 3, |
||
793 | 'min_posts' => -1, |
||
794 | ) |
||
795 | ); |
||
796 | $context['groups'] = array(); |
||
797 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
798 | $context['groups'][$row['id_group']] = $row['group_name']; |
||
799 | $smcFunc['db_free_result']($request); |
||
800 | |||
801 | // This always happens. |
||
802 | createToken($context['action_type'] == 'delete' ? 'admin-pmsd' : 'admin-pms'); |
||
803 | } |
||
804 | |||
805 | /** |
||
806 | * View all the users subscribed to a particular subscription. |
||
807 | * Requires the admin_forum permission. |
||
808 | * Accessed from ?action=admin;area=paidsubscribe;sa=viewsub. |
||
809 | * |
||
810 | * Subscription ID is required, in the form of $_GET['sid']. |
||
811 | */ |
||
812 | function ViewSubscribedUsers() |
||
813 | { |
||
814 | global $context, $txt, $scripturl, $smcFunc, $sourcedir, $modSettings; |
||
815 | |||
816 | // Setup the template. |
||
817 | $context['page_title'] = $txt['viewing_users_subscribed']; |
||
818 | |||
819 | // ID of the subscription. |
||
820 | $context['sub_id'] = (int) $_REQUEST['sid']; |
||
821 | |||
822 | // Load the subscription information. |
||
823 | $request = $smcFunc['db_query']('', ' |
||
824 | SELECT id_subscribe, name, description, cost, length, id_group, add_groups, active |
||
825 | FROM {db_prefix}subscriptions |
||
826 | WHERE id_subscribe = {int:current_subscription}', |
||
827 | array( |
||
828 | 'current_subscription' => $context['sub_id'], |
||
829 | ) |
||
830 | ); |
||
831 | // Something wrong? |
||
832 | if ($smcFunc['db_num_rows']($request) == 0) |
||
833 | fatal_lang_error('no_access', false); |
||
834 | // Do the subscription context. |
||
835 | $row = $smcFunc['db_fetch_assoc']($request); |
||
836 | $context['subscription'] = array( |
||
837 | 'id' => $row['id_subscribe'], |
||
838 | 'name' => $row['name'], |
||
839 | 'desc' => $row['description'], |
||
840 | 'active' => $row['active'], |
||
841 | ); |
||
842 | $smcFunc['db_free_result']($request); |
||
843 | |||
844 | // Are we searching for people? |
||
845 | $search_string = isset($_POST['ssearch']) && !empty($_POST['sub_search']) ? ' AND COALESCE(mem.real_name, {string:guest}) LIKE {string:search}' : ''; |
||
846 | $search_vars = empty($_POST['sub_search']) ? array() : array('search' => '%' . $_POST['sub_search'] . '%', 'guest' => $txt['guest']); |
||
847 | |||
848 | $listOptions = array( |
||
849 | 'id' => 'subscribed_users_list', |
||
850 | 'title' => sprintf($txt['view_users_subscribed'], $row['name']), |
||
851 | 'items_per_page' => $modSettings['defaultMaxListItems'], |
||
852 | 'base_href' => $scripturl . '?action=admin;area=paidsubscribe;sa=viewsub;sid=' . $context['sub_id'], |
||
853 | 'default_sort_col' => 'name', |
||
854 | 'get_items' => array( |
||
855 | 'function' => 'list_getSubscribedUsers', |
||
856 | 'params' => array( |
||
857 | $context['sub_id'], |
||
858 | $search_string, |
||
859 | $search_vars, |
||
860 | ), |
||
861 | ), |
||
862 | 'get_count' => array( |
||
863 | 'function' => 'list_getSubscribedUserCount', |
||
864 | 'params' => array( |
||
865 | $context['sub_id'], |
||
866 | $search_string, |
||
867 | $search_vars, |
||
868 | ), |
||
869 | ), |
||
870 | 'no_items_label' => $txt['no_subscribers'], |
||
871 | 'columns' => array( |
||
872 | 'name' => array( |
||
873 | 'header' => array( |
||
874 | 'value' => $txt['who_member'], |
||
875 | 'style' => 'width: 20%;', |
||
876 | ), |
||
877 | 'data' => array( |
||
878 | 'function' => function($rowData) use ($scripturl, $txt) |
||
879 | { |
||
880 | return $rowData['id_member'] == 0 ? $txt['guest'] : '<a href="' . $scripturl . '?action=profile;u=' . $rowData['id_member'] . '">' . $rowData['name'] . '</a>'; |
||
881 | }, |
||
882 | ), |
||
883 | 'sort' => array( |
||
884 | 'default' => 'name', |
||
885 | 'reverse' => 'name DESC', |
||
886 | ), |
||
887 | ), |
||
888 | 'status' => array( |
||
889 | 'header' => array( |
||
890 | 'value' => $txt['paid_status'], |
||
891 | 'style' => 'width: 10%;', |
||
892 | ), |
||
893 | 'data' => array( |
||
894 | 'db_htmlsafe' => 'status_text', |
||
895 | ), |
||
896 | 'sort' => array( |
||
897 | 'default' => 'status', |
||
898 | 'reverse' => 'status DESC', |
||
899 | ), |
||
900 | ), |
||
901 | 'payments_pending' => array( |
||
902 | 'header' => array( |
||
903 | 'value' => $txt['paid_payments_pending'], |
||
904 | 'style' => 'width: 15%;', |
||
905 | ), |
||
906 | 'data' => array( |
||
907 | 'db_htmlsafe' => 'pending', |
||
908 | ), |
||
909 | 'sort' => array( |
||
910 | 'default' => 'payments_pending', |
||
911 | 'reverse' => 'payments_pending DESC', |
||
912 | ), |
||
913 | ), |
||
914 | 'start_time' => array( |
||
915 | 'header' => array( |
||
916 | 'value' => $txt['start_date'], |
||
917 | 'style' => 'width: 20%;', |
||
918 | ), |
||
919 | 'data' => array( |
||
920 | 'db_htmlsafe' => 'start_date', |
||
921 | 'class' => 'smalltext', |
||
922 | ), |
||
923 | 'sort' => array( |
||
924 | 'default' => 'start_time', |
||
925 | 'reverse' => 'start_time DESC', |
||
926 | ), |
||
927 | ), |
||
928 | 'end_time' => array( |
||
929 | 'header' => array( |
||
930 | 'value' => $txt['end_date'], |
||
931 | 'style' => 'width: 20%;', |
||
932 | ), |
||
933 | 'data' => array( |
||
934 | 'db_htmlsafe' => 'end_date', |
||
935 | 'class' => 'smalltext', |
||
936 | ), |
||
937 | 'sort' => array( |
||
938 | 'default' => 'end_time', |
||
939 | 'reverse' => 'end_time DESC', |
||
940 | ), |
||
941 | ), |
||
942 | 'modify' => array( |
||
943 | 'header' => array( |
||
944 | 'style' => 'width: 10%;', |
||
945 | 'class' => 'centercol', |
||
946 | ), |
||
947 | 'data' => array( |
||
948 | 'function' => function($rowData) use ($scripturl, $txt) |
||
949 | { |
||
950 | return '<a href="' . $scripturl . '?action=admin;area=paidsubscribe;sa=modifyuser;lid=' . $rowData['id'] . '">' . $txt['modify'] . '</a>'; |
||
951 | }, |
||
952 | 'class' => 'centercol', |
||
953 | ), |
||
954 | ), |
||
955 | 'delete' => array( |
||
956 | 'header' => array( |
||
957 | 'style' => 'width: 4%;', |
||
958 | 'class' => 'centercol', |
||
959 | ), |
||
960 | 'data' => array( |
||
961 | 'function' => function($rowData) |
||
962 | { |
||
963 | return '<input type="checkbox" name="delsub[' . $rowData['id'] . ']">'; |
||
964 | }, |
||
965 | 'class' => 'centercol', |
||
966 | ), |
||
967 | ), |
||
968 | ), |
||
969 | 'form' => array( |
||
970 | 'href' => $scripturl . '?action=admin;area=paidsubscribe;sa=modifyuser;sid=' . $context['sub_id'], |
||
971 | ), |
||
972 | 'additional_rows' => array( |
||
973 | array( |
||
974 | 'position' => 'below_table_data', |
||
975 | 'value' => ' |
||
976 | <input type="submit" name="add" value="' . $txt['add_subscriber'] . '" class="button"> |
||
977 | <input type="submit" name="finished" value="' . $txt['complete_selected'] . '" data-confirm="' . $txt['complete_are_sure'] . '" class="button you_sure"> |
||
978 | <input type="submit" name="delete" value="' . $txt['delete_selected'] . '" data-confirm="' . $txt['delete_are_sure'] . '" class="button you_sure"> |
||
979 | ', |
||
980 | ), |
||
981 | array( |
||
982 | 'position' => 'top_of_list', |
||
983 | 'value' => ' |
||
984 | <div class="flow_auto"> |
||
985 | <input type="submit" name="ssearch" value="' . $txt['search_sub'] . '" class="button" style="margin-top: 3px;"> |
||
986 | <input type="text" name="sub_search" value="" class="floatright"> |
||
987 | </div> |
||
988 | ', |
||
989 | ), |
||
990 | ), |
||
991 | ); |
||
992 | |||
993 | require_once($sourcedir . '/Subs-List.php'); |
||
994 | createList($listOptions); |
||
995 | |||
996 | $context['sub_template'] = 'show_list'; |
||
997 | $context['default_list'] = 'subscribed_users_list'; |
||
998 | } |
||
999 | |||
1000 | /** |
||
1001 | * Returns how many people are subscribed to a paid subscription. |
||
1002 | * |
||
1003 | * @todo refactor away |
||
1004 | * |
||
1005 | * @param int $id_sub The ID of the subscription |
||
1006 | * @param string $search_string A search string |
||
1007 | * @param array $search_vars An array of variables for the search string |
||
1008 | * @return int The number of subscribed users matching the given parameters |
||
1009 | */ |
||
1010 | function list_getSubscribedUserCount($id_sub, $search_string, $search_vars = array()) |
||
1011 | { |
||
1012 | global $smcFunc; |
||
1013 | |||
1014 | // Get the total amount of users. |
||
1015 | $request = $smcFunc['db_query']('', ' |
||
1016 | SELECT COUNT(*) AS total_subs |
||
1017 | FROM {db_prefix}log_subscribed AS ls |
||
1018 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = ls.id_member) |
||
1019 | WHERE ls.id_subscribe = {int:current_subscription} ' . $search_string . ' |
||
1020 | AND (ls.end_time != {int:no_end_time} OR ls.payments_pending != {int:no_pending_payments})', |
||
1021 | array_merge($search_vars, array( |
||
1022 | 'current_subscription' => $id_sub, |
||
1023 | 'no_end_time' => 0, |
||
1024 | 'no_pending_payments' => 0, |
||
1025 | )) |
||
1026 | ); |
||
1027 | list ($memberCount) = $smcFunc['db_fetch_row']($request); |
||
1028 | $smcFunc['db_free_result']($request); |
||
1029 | |||
1030 | return $memberCount; |
||
1031 | } |
||
1032 | |||
1033 | /** |
||
1034 | * Return the subscribed users list, for the given parameters. |
||
1035 | * |
||
1036 | * @todo refactor outta here |
||
1037 | * |
||
1038 | * @param int $start The item to start with (for pagination purposes) |
||
1039 | * @param int $items_per_page How many items to show on each page |
||
1040 | * @param string $sort A string indicating how to sort the results |
||
1041 | * @param int $id_sub The ID of the subscription |
||
1042 | * @param string $search_string A search string |
||
1043 | * @param array $search_vars The variables for the search string |
||
1044 | * @return array An array of information about the subscribed users matching the given parameters |
||
1045 | */ |
||
1046 | function list_getSubscribedUsers($start, $items_per_page, $sort, $id_sub, $search_string, $search_vars = array()) |
||
1047 | { |
||
1048 | global $smcFunc, $txt; |
||
1049 | |||
1050 | $request = $smcFunc['db_query']('', ' |
||
1051 | SELECT ls.id_sublog, COALESCE(mem.id_member, 0) AS id_member, COALESCE(mem.real_name, {string:guest}) AS name, ls.start_time, ls.end_time, |
||
1052 | ls.status, ls.payments_pending |
||
1053 | FROM {db_prefix}log_subscribed AS ls |
||
1054 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = ls.id_member) |
||
1055 | WHERE ls.id_subscribe = {int:current_subscription} ' . $search_string . ' |
||
1056 | AND (ls.end_time != {int:no_end_time} OR ls.payments_pending != {int:no_payments_pending}) |
||
1057 | ORDER BY {raw:sort} |
||
1058 | LIMIT {int:start}, {int:max}', |
||
1059 | array_merge($search_vars, array( |
||
1060 | 'current_subscription' => $id_sub, |
||
1061 | 'no_end_time' => 0, |
||
1062 | 'no_payments_pending' => 0, |
||
1063 | 'guest' => $txt['guest'], |
||
1064 | 'sort' => $sort, |
||
1065 | 'start' => $start, |
||
1066 | 'max' => $items_per_page, |
||
1067 | )) |
||
1068 | ); |
||
1069 | $subscribers = array(); |
||
1070 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1071 | $subscribers[] = array( |
||
1072 | 'id' => $row['id_sublog'], |
||
1073 | 'id_member' => $row['id_member'], |
||
1074 | 'name' => $row['name'], |
||
1075 | 'start_date' => timeformat($row['start_time'], false), |
||
1076 | 'end_date' => $row['end_time'] == 0 ? 'N/A' : timeformat($row['end_time'], false), |
||
1077 | 'pending' => $row['payments_pending'], |
||
1078 | 'status' => $row['status'], |
||
1079 | 'status_text' => $row['status'] == 0 ? ($row['payments_pending'] == 0 ? $txt['paid_finished'] : $txt['paid_pending']) : $txt['paid_active'], |
||
1080 | ); |
||
1081 | $smcFunc['db_free_result']($request); |
||
1082 | |||
1083 | return $subscribers; |
||
1084 | } |
||
1085 | |||
1086 | /** |
||
1087 | * Edit or add a user subscription. |
||
1088 | * Accessed from ?action=admin;area=paidsubscribe;sa=modifyuser. |
||
1089 | */ |
||
1090 | function ModifyUserSubscription() |
||
1091 | { |
||
1092 | global $context, $txt, $modSettings, $smcFunc; |
||
1093 | |||
1094 | loadSubscriptions(); |
||
1095 | |||
1096 | $context['log_id'] = isset($_REQUEST['lid']) ? (int) $_REQUEST['lid'] : 0; |
||
1097 | $context['sub_id'] = isset($_REQUEST['sid']) ? (int) $_REQUEST['sid'] : 0; |
||
1098 | $context['action_type'] = $context['log_id'] ? 'edit' : 'add'; |
||
1099 | |||
1100 | // Setup the template. |
||
1101 | $context['sub_template'] = 'modify_user_subscription'; |
||
1102 | $context['page_title'] = $txt[$context['action_type'] . '_subscriber']; |
||
1103 | |||
1104 | // If we haven't been passed the subscription ID get it. |
||
1105 | if ($context['log_id'] && !$context['sub_id']) |
||
1106 | { |
||
1107 | $request = $smcFunc['db_query']('', ' |
||
1108 | SELECT id_subscribe |
||
1109 | FROM {db_prefix}log_subscribed |
||
1110 | WHERE id_sublog = {int:current_log_item}', |
||
1111 | array( |
||
1112 | 'current_log_item' => $context['log_id'], |
||
1113 | ) |
||
1114 | ); |
||
1115 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1116 | fatal_lang_error('no_access', false); |
||
1117 | list ($context['sub_id']) = $smcFunc['db_fetch_row']($request); |
||
1118 | $smcFunc['db_free_result']($request); |
||
1119 | } |
||
1120 | |||
1121 | if (!isset($context['subscriptions'][$context['sub_id']])) |
||
1122 | fatal_lang_error('no_access', false); |
||
1123 | $context['current_subscription'] = $context['subscriptions'][$context['sub_id']]; |
||
1124 | |||
1125 | // Searching? |
||
1126 | if (isset($_POST['ssearch'])) |
||
1127 | { |
||
1128 | return ViewSubscribedUsers(); |
||
1129 | } |
||
1130 | // Saving? |
||
1131 | elseif (isset($_REQUEST['save_sub'])) |
||
1132 | { |
||
1133 | checkSession(); |
||
1134 | |||
1135 | // Work out the dates... |
||
1136 | $starttime = mktime($_POST['hour'], $_POST['minute'], 0, $_POST['month'], $_POST['day'], $_POST['year']); |
||
1137 | $endtime = mktime($_POST['hourend'], $_POST['minuteend'], 0, $_POST['monthend'], $_POST['dayend'], $_POST['yearend']); |
||
1138 | |||
1139 | // Status. |
||
1140 | $status = $_POST['status']; |
||
1141 | |||
1142 | // New one? |
||
1143 | if (empty($context['log_id'])) |
||
1144 | { |
||
1145 | // Find the user... |
||
1146 | $request = $smcFunc['db_query']('', ' |
||
1147 | SELECT id_member, id_group |
||
1148 | FROM {db_prefix}members |
||
1149 | WHERE real_name = {string:name} |
||
1150 | LIMIT 1', |
||
1151 | array( |
||
1152 | 'name' => $_POST['name'], |
||
1153 | ) |
||
1154 | ); |
||
1155 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1156 | fatal_lang_error('error_member_not_found'); |
||
1157 | |||
1158 | list ($id_member, $id_group) = $smcFunc['db_fetch_row']($request); |
||
1159 | $smcFunc['db_free_result']($request); |
||
1160 | |||
1161 | // Ensure the member doesn't already have a subscription! |
||
1162 | $request = $smcFunc['db_query']('', ' |
||
1163 | SELECT id_subscribe |
||
1164 | FROM {db_prefix}log_subscribed |
||
1165 | WHERE id_subscribe = {int:current_subscription} |
||
1166 | AND id_member = {int:current_member}', |
||
1167 | array( |
||
1168 | 'current_subscription' => $context['sub_id'], |
||
1169 | 'current_member' => $id_member, |
||
1170 | ) |
||
1171 | ); |
||
1172 | if ($smcFunc['db_num_rows']($request) != 0) |
||
1173 | fatal_lang_error('member_already_subscribed'); |
||
1174 | $smcFunc['db_free_result']($request); |
||
1175 | |||
1176 | // Actually put the subscription in place. |
||
1177 | if ($status == 1) |
||
1178 | addSubscription($context['sub_id'], $id_member, 0, $starttime, $endtime); |
||
1179 | else |
||
1180 | { |
||
1181 | $smcFunc['db_insert']('', |
||
1182 | '{db_prefix}log_subscribed', |
||
1183 | array( |
||
1184 | 'id_subscribe' => 'int', 'id_member' => 'int', 'old_id_group' => 'int', 'start_time' => 'int', |
||
1185 | 'end_time' => 'int', 'status' => 'int', 'pending_details' => 'string-65534' |
||
1186 | ), |
||
1187 | array( |
||
1188 | $context['sub_id'], $id_member, $id_group, $starttime, |
||
1189 | $endtime, $status, $smcFunc['json_encode'](array()) |
||
1190 | ), |
||
1191 | array('id_sublog') |
||
1192 | ); |
||
1193 | |||
1194 | } |
||
1195 | } |
||
1196 | // Updating. |
||
1197 | else |
||
1198 | { |
||
1199 | $request = $smcFunc['db_query']('', ' |
||
1200 | SELECT id_member, status |
||
1201 | FROM {db_prefix}log_subscribed |
||
1202 | WHERE id_sublog = {int:current_log_item}', |
||
1203 | array( |
||
1204 | 'current_log_item' => $context['log_id'], |
||
1205 | ) |
||
1206 | ); |
||
1207 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1208 | fatal_lang_error('no_access', false); |
||
1209 | |||
1210 | list ($id_member, $old_status) = $smcFunc['db_fetch_row']($request); |
||
1211 | $smcFunc['db_free_result']($request); |
||
1212 | |||
1213 | // Pick the right permission stuff depending on what the status is changing from/to. |
||
1214 | if ($old_status == 1 && $status != 1) |
||
1215 | removeSubscription($context['sub_id'], $id_member); |
||
1216 | elseif ($status == 1 && $old_status != 1) |
||
1217 | { |
||
1218 | addSubscription($context['sub_id'], $id_member, 0, $starttime, $endtime); |
||
1219 | } |
||
1220 | else |
||
1221 | { |
||
1222 | $smcFunc['db_query']('', ' |
||
1223 | UPDATE {db_prefix}log_subscribed |
||
1224 | SET start_time = {int:start_time}, end_time = {int:end_time}, status = {int:status} |
||
1225 | WHERE id_sublog = {int:current_log_item}', |
||
1226 | array( |
||
1227 | 'start_time' => $starttime, |
||
1228 | 'end_time' => $endtime, |
||
1229 | 'status' => $status, |
||
1230 | 'current_log_item' => $context['log_id'], |
||
1231 | ) |
||
1232 | ); |
||
1233 | } |
||
1234 | } |
||
1235 | |||
1236 | // Done - redirect... |
||
1237 | redirectexit('action=admin;area=paidsubscribe;sa=viewsub;sid=' . $context['sub_id']); |
||
1238 | } |
||
1239 | // Deleting? |
||
1240 | elseif (isset($_REQUEST['delete']) || isset($_REQUEST['finished'])) |
||
1241 | { |
||
1242 | checkSession(); |
||
1243 | |||
1244 | // Do the actual deletes! |
||
1245 | if (!empty($_REQUEST['delsub'])) |
||
1246 | { |
||
1247 | $toDelete = array(); |
||
1248 | foreach ($_REQUEST['delsub'] as $id => $dummy) |
||
1249 | $toDelete[] = (int) $id; |
||
1250 | |||
1251 | $request = $smcFunc['db_query']('', ' |
||
1252 | SELECT id_subscribe, id_member |
||
1253 | FROM {db_prefix}log_subscribed |
||
1254 | WHERE id_sublog IN ({array_int:subscription_list})', |
||
1255 | array( |
||
1256 | 'subscription_list' => $toDelete, |
||
1257 | ) |
||
1258 | ); |
||
1259 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1260 | removeSubscription($row['id_subscribe'], $row['id_member'], isset($_REQUEST['delete'])); |
||
1261 | $smcFunc['db_free_result']($request); |
||
1262 | } |
||
1263 | redirectexit('action=admin;area=paidsubscribe;sa=viewsub;sid=' . $context['sub_id']); |
||
1264 | } |
||
1265 | |||
1266 | // Default attributes. |
||
1267 | if ($context['action_type'] == 'add') |
||
1268 | { |
||
1269 | $context['sub'] = array( |
||
1270 | 'id' => 0, |
||
1271 | 'start' => array( |
||
1272 | 'year' => (int) strftime('%Y', time()), |
||
1273 | 'month' => (int) strftime('%m', time()), |
||
1274 | 'day' => (int) strftime('%d', time()), |
||
1275 | 'hour' => (int) strftime('%H', time()), |
||
1276 | 'min' => (int) strftime('%M', time()) < 10 ? '0' . (int) strftime('%M', time()) : (int) strftime('%M', time()), |
||
1277 | 'last_day' => 0, |
||
1278 | ), |
||
1279 | 'end' => array( |
||
1280 | 'year' => (int) strftime('%Y', time()), |
||
1281 | 'month' => (int) strftime('%m', time()), |
||
1282 | 'day' => (int) strftime('%d', time()), |
||
1283 | 'hour' => (int) strftime('%H', time()), |
||
1284 | 'min' => (int) strftime('%M', time()) < 10 ? '0' . (int) strftime('%M', time()) : (int) strftime('%M', time()), |
||
1285 | 'last_day' => 0, |
||
1286 | ), |
||
1287 | 'status' => 1, |
||
1288 | ); |
||
1289 | $context['sub']['start']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['sub']['start']['month'] == 12 ? 1 : $context['sub']['start']['month'] + 1, 0, $context['sub']['start']['month'] == 12 ? $context['sub']['start']['year'] + 1 : $context['sub']['start']['year'])); |
||
1290 | $context['sub']['end']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['sub']['end']['month'] == 12 ? 1 : $context['sub']['end']['month'] + 1, 0, $context['sub']['end']['month'] == 12 ? $context['sub']['end']['year'] + 1 : $context['sub']['end']['year'])); |
||
1291 | |||
1292 | if (isset($_GET['uid'])) |
||
1293 | { |
||
1294 | $request = $smcFunc['db_query']('', ' |
||
1295 | SELECT real_name |
||
1296 | FROM {db_prefix}members |
||
1297 | WHERE id_member = {int:current_member}', |
||
1298 | array( |
||
1299 | 'current_member' => (int) $_GET['uid'], |
||
1300 | ) |
||
1301 | ); |
||
1302 | list ($context['sub']['username']) = $smcFunc['db_fetch_row']($request); |
||
1303 | $smcFunc['db_free_result']($request); |
||
1304 | } |
||
1305 | else |
||
1306 | $context['sub']['username'] = ''; |
||
1307 | } |
||
1308 | // Otherwise load the existing info. |
||
1309 | else |
||
1310 | { |
||
1311 | $request = $smcFunc['db_query']('', ' |
||
1312 | SELECT ls.id_sublog, ls.id_subscribe, ls.id_member, start_time, end_time, status, payments_pending, pending_details, |
||
1313 | COALESCE(mem.real_name, {string:blank_string}) AS username |
||
1314 | FROM {db_prefix}log_subscribed AS ls |
||
1315 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = ls.id_member) |
||
1316 | WHERE ls.id_sublog = {int:current_subscription_item} |
||
1317 | LIMIT 1', |
||
1318 | array( |
||
1319 | 'current_subscription_item' => $context['log_id'], |
||
1320 | 'blank_string' => '', |
||
1321 | ) |
||
1322 | ); |
||
1323 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1324 | fatal_lang_error('no_access', false); |
||
1325 | $row = $smcFunc['db_fetch_assoc']($request); |
||
1326 | $smcFunc['db_free_result']($request); |
||
1327 | |||
1328 | // Any pending payments? |
||
1329 | $context['pending_payments'] = array(); |
||
1330 | if (!empty($row['pending_details'])) |
||
1331 | { |
||
1332 | $pending_details = $smcFunc['json_decode']($row['pending_details'], true); |
||
1333 | foreach ($pending_details as $id => $pending) |
||
1334 | { |
||
1335 | // Only this type need be displayed. |
||
1336 | if ($pending[3] == 'payback') |
||
1337 | { |
||
1338 | // Work out what the options were. |
||
1339 | $costs = $smcFunc['json_decode']($context['current_subscription']['real_cost'], true); |
||
1340 | |||
1341 | if ($context['current_subscription']['real_length'] == 'F') |
||
1342 | { |
||
1343 | foreach ($costs as $duration => $cost) |
||
1344 | { |
||
1345 | if ($cost != 0 && $cost == $pending[1] && $duration == $pending[2]) |
||
1346 | $context['pending_payments'][$id] = array( |
||
1347 | 'desc' => sprintf($modSettings['paid_currency_symbol'], $cost . '/' . $txt[$duration]), |
||
1348 | ); |
||
1349 | } |
||
1350 | } |
||
1351 | elseif ($costs['fixed'] == $pending[1]) |
||
1352 | { |
||
1353 | $context['pending_payments'][$id] = array( |
||
1354 | 'desc' => sprintf($modSettings['paid_currency_symbol'], $costs['fixed']), |
||
1355 | ); |
||
1356 | } |
||
1357 | } |
||
1358 | } |
||
1359 | |||
1360 | // Check if we are adding/removing any. |
||
1361 | if (isset($_GET['pending'])) |
||
1362 | { |
||
1363 | foreach ($pending_details as $id => $pending) |
||
1364 | { |
||
1365 | // Found the one to action? |
||
1366 | if ($_GET['pending'] == $id && $pending[3] == 'payback' && isset($context['pending_payments'][$id])) |
||
1367 | { |
||
1368 | // Flexible? |
||
1369 | if (isset($_GET['accept'])) |
||
1370 | addSubscription($context['current_subscription']['id'], $row['id_member'], $context['current_subscription']['real_length'] == 'F' ? strtoupper(substr($pending[2], 0, 1)) : 0); |
||
1371 | unset($pending_details[$id]); |
||
1372 | |||
1373 | $new_details = $smcFunc['json_encode']($pending_details); |
||
1374 | |||
1375 | // Update the entry. |
||
1376 | $smcFunc['db_query']('', ' |
||
1377 | UPDATE {db_prefix}log_subscribed |
||
1378 | SET payments_pending = payments_pending - 1, pending_details = {string:pending_details} |
||
1379 | WHERE id_sublog = {int:current_subscription_item}', |
||
1380 | array( |
||
1381 | 'current_subscription_item' => $context['log_id'], |
||
1382 | 'pending_details' => $new_details, |
||
1383 | ) |
||
1384 | ); |
||
1385 | |||
1386 | // Reload |
||
1387 | redirectexit('action=admin;area=paidsubscribe;sa=modifyuser;lid=' . $context['log_id']); |
||
1388 | } |
||
1389 | } |
||
1390 | } |
||
1391 | } |
||
1392 | |||
1393 | $context['sub_id'] = $row['id_subscribe']; |
||
1394 | $context['sub'] = array( |
||
1395 | 'id' => 0, |
||
1396 | 'start' => array( |
||
1397 | 'year' => (int) strftime('%Y', $row['start_time']), |
||
1398 | 'month' => (int) strftime('%m', $row['start_time']), |
||
1399 | 'day' => (int) strftime('%d', $row['start_time']), |
||
1400 | 'hour' => (int) strftime('%H', $row['start_time']), |
||
1401 | 'min' => (int) strftime('%M', $row['start_time']) < 10 ? '0' . (int) strftime('%M', $row['start_time']) : (int) strftime('%M', $row['start_time']), |
||
1402 | 'last_day' => 0, |
||
1403 | ), |
||
1404 | 'end' => array( |
||
1405 | 'year' => (int) strftime('%Y', $row['end_time']), |
||
1406 | 'month' => (int) strftime('%m', $row['end_time']), |
||
1407 | 'day' => (int) strftime('%d', $row['end_time']), |
||
1408 | 'hour' => (int) strftime('%H', $row['end_time']), |
||
1409 | 'min' => (int) strftime('%M', $row['end_time']) < 10 ? '0' . (int) strftime('%M', $row['end_time']) : (int) strftime('%M', $row['end_time']), |
||
1410 | 'last_day' => 0, |
||
1411 | ), |
||
1412 | 'status' => $row['status'], |
||
1413 | 'username' => $row['username'], |
||
1414 | ); |
||
1415 | $context['sub']['start']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['sub']['start']['month'] == 12 ? 1 : $context['sub']['start']['month'] + 1, 0, $context['sub']['start']['month'] == 12 ? $context['sub']['start']['year'] + 1 : $context['sub']['start']['year'])); |
||
1416 | $context['sub']['end']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['sub']['end']['month'] == 12 ? 1 : $context['sub']['end']['month'] + 1, 0, $context['sub']['end']['month'] == 12 ? $context['sub']['end']['year'] + 1 : $context['sub']['end']['year'])); |
||
1417 | } |
||
1418 | |||
1419 | loadJavaScriptFile('suggest.js', array('defer' => false, 'minimize' => true), 'smf_suggest'); |
||
1420 | } |
||
1421 | |||
1422 | /** |
||
1423 | * Reapplies all subscription rules for each of the users. |
||
1424 | * |
||
1425 | * @param array $users An array of user IDs |
||
1426 | */ |
||
1427 | function reapplySubscriptions($users) |
||
1428 | { |
||
1429 | global $smcFunc; |
||
1430 | |||
1431 | // Make it an array. |
||
1432 | if (!is_array($users)) |
||
1433 | $users = array($users); |
||
1434 | |||
1435 | // Get all the members current groups. |
||
1436 | $groups = array(); |
||
1437 | $request = $smcFunc['db_query']('', ' |
||
1438 | SELECT id_member, id_group, additional_groups |
||
1439 | FROM {db_prefix}members |
||
1440 | WHERE id_member IN ({array_int:user_list})', |
||
1441 | array( |
||
1442 | 'user_list' => $users, |
||
1443 | ) |
||
1444 | ); |
||
1445 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1446 | { |
||
1447 | $groups[$row['id_member']] = array( |
||
1448 | 'primary' => $row['id_group'], |
||
1449 | 'additional' => explode(',', $row['additional_groups']), |
||
1450 | ); |
||
1451 | } |
||
1452 | $smcFunc['db_free_result']($request); |
||
1453 | |||
1454 | $request = $smcFunc['db_query']('', ' |
||
1455 | SELECT ls.id_member, ls.old_id_group, s.id_group, s.add_groups |
||
1456 | FROM {db_prefix}log_subscribed AS ls |
||
1457 | INNER JOIN {db_prefix}subscriptions AS s ON (s.id_subscribe = ls.id_subscribe) |
||
1458 | WHERE ls.id_member IN ({array_int:user_list}) |
||
1459 | AND ls.end_time > {int:current_time}', |
||
1460 | array( |
||
1461 | 'user_list' => $users, |
||
1462 | 'current_time' => time(), |
||
1463 | ) |
||
1464 | ); |
||
1465 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1466 | { |
||
1467 | // Specific primary group? |
||
1468 | if ($row['id_group'] != 0) |
||
1469 | { |
||
1470 | // If this is changing - add the old one to the additional groups so it's not lost. |
||
1471 | if ($row['id_group'] != $groups[$row['id_member']]['primary']) |
||
1472 | $groups[$row['id_member']]['additional'][] = $groups[$row['id_member']]['primary']; |
||
1473 | $groups[$row['id_member']]['primary'] = $row['id_group']; |
||
1474 | } |
||
1475 | |||
1476 | // Additional groups. |
||
1477 | if (!empty($row['add_groups'])) |
||
1478 | $groups[$row['id_member']]['additional'] = array_merge($groups[$row['id_member']]['additional'], explode(',', $row['add_groups'])); |
||
1479 | } |
||
1480 | $smcFunc['db_free_result']($request); |
||
1481 | |||
1482 | // Update all the members. |
||
1483 | foreach ($groups as $id => $group) |
||
1484 | { |
||
1485 | $group['additional'] = array_unique($group['additional']); |
||
1486 | foreach ($group['additional'] as $key => $value) |
||
1487 | if (empty($value)) |
||
1488 | unset($group['additional'][$key]); |
||
1489 | $addgroups = implode(',', $group['additional']); |
||
1490 | |||
1491 | $smcFunc['db_query']('', ' |
||
1492 | UPDATE {db_prefix}members |
||
1493 | SET id_group = {int:primary_group}, additional_groups = {string:additional_groups} |
||
1494 | WHERE id_member = {int:current_member} |
||
1495 | LIMIT 1', |
||
1496 | array( |
||
1497 | 'primary_group' => $group['primary'], |
||
1498 | 'current_member' => $id, |
||
1499 | 'additional_groups' => $addgroups, |
||
1500 | ) |
||
1501 | ); |
||
1502 | } |
||
1503 | } |
||
1504 | |||
1505 | /** |
||
1506 | * Add or extend a subscription of a user. |
||
1507 | * |
||
1508 | * @param int $id_subscribe The subscription ID |
||
1509 | * @param int $id_member The ID of the member |
||
1510 | * @param int|string $renewal 0 if we're forcing start/end time, otherwise a string indicating how long to renew the subscription for ('D', 'W', 'M' or 'Y') |
||
1511 | * @param int $forceStartTime If set, forces the subscription to start at the specified time |
||
1512 | * @param int $forceEndTime If set, forces the subscription to end at the specified time |
||
1513 | */ |
||
1514 | function addSubscription($id_subscribe, $id_member, $renewal = 0, $forceStartTime = 0, $forceEndTime = 0) |
||
1515 | { |
||
1516 | global $context, $smcFunc; |
||
1517 | |||
1518 | // Take the easy way out... |
||
1519 | loadSubscriptions(); |
||
1520 | |||
1521 | // Exists, yes? |
||
1522 | if (!isset($context['subscriptions'][$id_subscribe])) |
||
1523 | return; |
||
1524 | |||
1525 | $curSub = $context['subscriptions'][$id_subscribe]; |
||
1526 | |||
1527 | // Grab the duration. |
||
1528 | $duration = $curSub['num_length']; |
||
1529 | |||
1530 | // If this is a renewal change the duration to be correct. |
||
1531 | if (!empty($renewal)) |
||
1532 | { |
||
1533 | switch ($renewal) |
||
1534 | { |
||
1535 | case 'D': |
||
1536 | $duration = 86400; |
||
1537 | break; |
||
1538 | case 'W': |
||
1539 | $duration = 604800; |
||
1540 | break; |
||
1541 | case 'M': |
||
1542 | $duration = 2629743; |
||
1543 | break; |
||
1544 | case 'Y': |
||
1545 | $duration = 31556926; |
||
1546 | break; |
||
1547 | default: |
||
1548 | break; |
||
1549 | } |
||
1550 | } |
||
1551 | |||
1552 | // Firstly, see whether it exists, and is active. If so then this is meerly an extension. |
||
1553 | $request = $smcFunc['db_query']('', ' |
||
1554 | SELECT id_sublog, end_time, start_time |
||
1555 | FROM {db_prefix}log_subscribed |
||
1556 | WHERE id_subscribe = {int:current_subscription} |
||
1557 | AND id_member = {int:current_member} |
||
1558 | AND status = {int:is_active}', |
||
1559 | array( |
||
1560 | 'current_subscription' => $id_subscribe, |
||
1561 | 'current_member' => $id_member, |
||
1562 | 'is_active' => 1, |
||
1563 | ) |
||
1564 | ); |
||
1565 | |||
1566 | if ($smcFunc['db_num_rows']($request) != 0) |
||
1567 | { |
||
1568 | list ($id_sublog, $endtime, $starttime) = $smcFunc['db_fetch_row']($request); |
||
1569 | |||
1570 | // If this has already expired but is active, extension means the period from now. |
||
1571 | if ($endtime < time()) |
||
1572 | $endtime = time(); |
||
1573 | if ($starttime == 0) |
||
1574 | $starttime = time(); |
||
1575 | |||
1576 | // Work out the new expiry date. |
||
1577 | $endtime += $duration; |
||
1578 | |||
1579 | if ($forceEndTime != 0) |
||
1580 | $endtime = $forceEndTime; |
||
1581 | |||
1582 | // As everything else should be good, just update! |
||
1583 | $smcFunc['db_query']('', ' |
||
1584 | UPDATE {db_prefix}log_subscribed |
||
1585 | SET end_time = {int:end_time}, start_time = {int:start_time}, reminder_sent = {int:no_reminder_sent} |
||
1586 | WHERE id_sublog = {int:current_subscription_item}', |
||
1587 | array( |
||
1588 | 'end_time' => $endtime, |
||
1589 | 'start_time' => $starttime, |
||
1590 | 'current_subscription_item' => $id_sublog, |
||
1591 | 'no_reminder_sent' => 0, |
||
1592 | ) |
||
1593 | ); |
||
1594 | |||
1595 | return; |
||
1596 | } |
||
1597 | $smcFunc['db_free_result']($request); |
||
1598 | |||
1599 | // If we're here, that means we don't have an active subscription - that means we need to do some work! |
||
1600 | $request = $smcFunc['db_query']('', ' |
||
1601 | SELECT m.id_group, m.additional_groups |
||
1602 | FROM {db_prefix}members AS m |
||
1603 | WHERE m.id_member = {int:current_member}', |
||
1604 | array( |
||
1605 | 'current_member' => $id_member, |
||
1606 | ) |
||
1607 | ); |
||
1608 | |||
1609 | // Just in case the member doesn't exist. |
||
1610 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1611 | return; |
||
1612 | |||
1613 | list ($old_id_group, $additional_groups) = $smcFunc['db_fetch_row']($request); |
||
1614 | $smcFunc['db_free_result']($request); |
||
1615 | |||
1616 | // Prepare additional groups. |
||
1617 | $newAddGroups = explode(',', $curSub['add_groups']); |
||
1618 | $curAddGroups = explode(',', $additional_groups); |
||
1619 | |||
1620 | $newAddGroups = array_merge($newAddGroups, $curAddGroups); |
||
1621 | |||
1622 | // Simple, simple, simple - hopefully... id_group first. |
||
1623 | if ($curSub['prim_group'] != 0) |
||
1624 | { |
||
1625 | $id_group = $curSub['prim_group']; |
||
1626 | |||
1627 | // Ensure their old privileges are maintained. |
||
1628 | if ($old_id_group != 0) |
||
1629 | $newAddGroups[] = $old_id_group; |
||
1630 | } |
||
1631 | else |
||
1632 | $id_group = $old_id_group; |
||
1633 | |||
1634 | // Yep, make sure it's unique, and no empties. |
||
1635 | foreach ($newAddGroups as $k => $v) |
||
1636 | if (empty($v)) |
||
1637 | unset($newAddGroups[$k]); |
||
1638 | $newAddGroups = array_unique($newAddGroups); |
||
1639 | $newAddGroups = implode(',', $newAddGroups); |
||
1640 | |||
1641 | // Store the new settings. |
||
1642 | $smcFunc['db_query']('', ' |
||
1643 | UPDATE {db_prefix}members |
||
1644 | SET id_group = {int:primary_group}, additional_groups = {string:additional_groups} |
||
1645 | WHERE id_member = {int:current_member}', |
||
1646 | array( |
||
1647 | 'primary_group' => $id_group, |
||
1648 | 'current_member' => $id_member, |
||
1649 | 'additional_groups' => $newAddGroups, |
||
1650 | ) |
||
1651 | ); |
||
1652 | |||
1653 | // Now log the subscription - maybe we have a dorment subscription we can restore? |
||
1654 | $request = $smcFunc['db_query']('', ' |
||
1655 | SELECT id_sublog, end_time, start_time |
||
1656 | FROM {db_prefix}log_subscribed |
||
1657 | WHERE id_subscribe = {int:current_subscription} |
||
1658 | AND id_member = {int:current_member}', |
||
1659 | array( |
||
1660 | 'current_subscription' => $id_subscribe, |
||
1661 | 'current_member' => $id_member, |
||
1662 | ) |
||
1663 | ); |
||
1664 | |||
1665 | /** |
||
1666 | * @todo Don't really need to do this twice... |
||
1667 | */ |
||
1668 | if ($smcFunc['db_num_rows']($request) != 0) |
||
1669 | { |
||
1670 | list ($id_sublog, $endtime, $starttime) = $smcFunc['db_fetch_row']($request); |
||
1671 | |||
1672 | // If this has already expired but is active, extension means the period from now. |
||
1673 | if ($endtime < time()) |
||
1674 | $endtime = time(); |
||
1675 | if ($starttime == 0) |
||
1676 | $starttime = time(); |
||
1677 | |||
1678 | // Work out the new expiry date. |
||
1679 | $endtime += $duration; |
||
1680 | |||
1681 | if ($forceEndTime != 0) |
||
1682 | $endtime = $forceEndTime; |
||
1683 | |||
1684 | // As everything else should be good, just update! |
||
1685 | $smcFunc['db_query']('', ' |
||
1686 | UPDATE {db_prefix}log_subscribed |
||
1687 | SET start_time = {int:start_time}, end_time = {int:end_time}, old_id_group = {int:old_id_group}, status = {int:is_active}, reminder_sent = {int:no_reminder_sent} |
||
1688 | WHERE id_sublog = {int:current_subscription_item}', |
||
1689 | array( |
||
1690 | 'start_time' => $starttime, |
||
1691 | 'end_time' => $endtime, |
||
1692 | 'old_id_group' => $old_id_group, |
||
1693 | 'is_active' => 1, |
||
1694 | 'no_reminder_sent' => 0, |
||
1695 | 'current_subscription_item' => $id_sublog, |
||
1696 | ) |
||
1697 | ); |
||
1698 | |||
1699 | return; |
||
1700 | } |
||
1701 | $smcFunc['db_free_result']($request); |
||
1702 | |||
1703 | // Otherwise a very simple insert. |
||
1704 | $endtime = time() + $duration; |
||
1705 | if ($forceEndTime != 0) |
||
1706 | $endtime = $forceEndTime; |
||
1707 | |||
1708 | if ($forceStartTime == 0) |
||
1709 | $starttime = time(); |
||
1710 | else |
||
1711 | $starttime = $forceStartTime; |
||
1712 | |||
1713 | $smcFunc['db_insert']('', |
||
1714 | '{db_prefix}log_subscribed', |
||
1715 | array( |
||
1716 | 'id_subscribe' => 'int', 'id_member' => 'int', 'old_id_group' => 'int', 'start_time' => 'int', |
||
1717 | 'end_time' => 'int', 'status' => 'int', 'pending_details' => 'string', |
||
1718 | ), |
||
1719 | array( |
||
1720 | $id_subscribe, $id_member, $old_id_group, $starttime, |
||
1721 | $endtime, 1, '', |
||
1722 | ), |
||
1723 | array('id_sublog') |
||
1724 | ); |
||
1725 | } |
||
1726 | |||
1727 | /** |
||
1728 | * Removes a subscription from a user, as in removes the groups. |
||
1729 | * |
||
1730 | * @param int $id_subscribe The ID of the subscription |
||
1731 | * @param int $id_member The ID of the member |
||
1732 | * @param bool $delete Whether to delete the subscription or just disable it |
||
1733 | */ |
||
1734 | function removeSubscription($id_subscribe, $id_member, $delete = false) |
||
1735 | { |
||
1736 | global $context, $smcFunc; |
||
1737 | |||
1738 | loadSubscriptions(); |
||
1739 | |||
1740 | // Load the user core bits. |
||
1741 | $request = $smcFunc['db_query']('', ' |
||
1742 | SELECT m.id_group, m.additional_groups |
||
1743 | FROM {db_prefix}members AS m |
||
1744 | WHERE m.id_member = {int:current_member}', |
||
1745 | array( |
||
1746 | 'current_member' => $id_member, |
||
1747 | ) |
||
1748 | ); |
||
1749 | |||
1750 | // Just in case of errors. |
||
1751 | if ($smcFunc['db_num_rows']($request) == 0) |
||
1752 | { |
||
1753 | $smcFunc['db_query']('', ' |
||
1754 | DELETE FROM {db_prefix}log_subscribed |
||
1755 | WHERE id_member = {int:current_member}', |
||
1756 | array( |
||
1757 | 'current_member' => $id_member, |
||
1758 | ) |
||
1759 | ); |
||
1760 | return; |
||
1761 | } |
||
1762 | list ($id_group, $additional_groups) = $smcFunc['db_fetch_row']($request); |
||
1763 | $smcFunc['db_free_result']($request); |
||
1764 | |||
1765 | // Get all of the subscriptions for this user that are active - it will be necessary! |
||
1766 | $request = $smcFunc['db_query']('', ' |
||
1767 | SELECT id_subscribe, old_id_group |
||
1768 | FROM {db_prefix}log_subscribed |
||
1769 | WHERE id_member = {int:current_member} |
||
1770 | AND status = {int:is_active}', |
||
1771 | array( |
||
1772 | 'current_member' => $id_member, |
||
1773 | 'is_active' => 1, |
||
1774 | ) |
||
1775 | ); |
||
1776 | |||
1777 | // These variables will be handy, honest ;) |
||
1778 | $removals = array(); |
||
1779 | $allowed = array(); |
||
1780 | $old_id_group = 0; |
||
1781 | $new_id_group = -1; |
||
1782 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1783 | { |
||
1784 | if (!isset($context['subscriptions'][$row['id_subscribe']])) |
||
1785 | continue; |
||
1786 | |||
1787 | // The one we're removing? |
||
1788 | if ($row['id_subscribe'] == $id_subscribe) |
||
1789 | { |
||
1790 | $removals = explode(',', $context['subscriptions'][$row['id_subscribe']]['add_groups']); |
||
1791 | if ($context['subscriptions'][$row['id_subscribe']]['prim_group'] != 0) |
||
1792 | $removals[] = $context['subscriptions'][$row['id_subscribe']]['prim_group']; |
||
1793 | $old_id_group = $row['old_id_group']; |
||
1794 | } |
||
1795 | // Otherwise things we allow. |
||
1796 | else |
||
1797 | { |
||
1798 | $allowed = array_merge($allowed, explode(',', $context['subscriptions'][$row['id_subscribe']]['add_groups'])); |
||
1799 | if ($context['subscriptions'][$row['id_subscribe']]['prim_group'] != 0) |
||
1800 | { |
||
1801 | $allowed[] = $context['subscriptions'][$row['id_subscribe']]['prim_group']; |
||
1802 | $new_id_group = $context['subscriptions'][$row['id_subscribe']]['prim_group']; |
||
1803 | } |
||
1804 | } |
||
1805 | } |
||
1806 | $smcFunc['db_free_result']($request); |
||
1807 | |||
1808 | // Now, for everything we are removing check they definitely are not allowed it. |
||
1809 | $existingGroups = explode(',', $additional_groups); |
||
1810 | foreach ($existingGroups as $key => $group) |
||
1811 | if (empty($group) || (in_array($group, $removals) && !in_array($group, $allowed))) |
||
1812 | unset($existingGroups[$key]); |
||
1813 | |||
1814 | // Finally, do something with the current primary group. |
||
1815 | if (in_array($id_group, $removals)) |
||
1816 | { |
||
1817 | // If this primary group is actually allowed keep it. |
||
1818 | if (in_array($id_group, $allowed)) |
||
1819 | $existingGroups[] = $id_group; |
||
1820 | |||
1821 | // Either way, change the id_group back. |
||
1822 | if ($new_id_group < 1) |
||
1823 | { |
||
1824 | // If we revert to the old id-group we need to ensure it wasn't from a subscription. |
||
1825 | foreach ($context['subscriptions'] as $id => $group) |
||
1826 | // It was? Make them a regular member then! |
||
1827 | if ($group['prim_group'] == $old_id_group) |
||
1828 | $old_id_group = 0; |
||
1829 | |||
1830 | $id_group = $old_id_group; |
||
1831 | } |
||
1832 | else |
||
1833 | $id_group = $new_id_group; |
||
1834 | } |
||
1835 | |||
1836 | // Crazy stuff, we seem to have our groups fixed, just make them unique |
||
1837 | $existingGroups = array_unique($existingGroups); |
||
1838 | $existingGroups = implode(',', $existingGroups); |
||
1839 | |||
1840 | // Update the member |
||
1841 | $smcFunc['db_query']('', ' |
||
1842 | UPDATE {db_prefix}members |
||
1843 | SET id_group = {int:primary_group}, additional_groups = {string:existing_groups} |
||
1844 | WHERE id_member = {int:current_member}', |
||
1845 | array( |
||
1846 | 'primary_group' => $id_group, |
||
1847 | 'current_member' => $id_member, |
||
1848 | 'existing_groups' => $existingGroups, |
||
1849 | ) |
||
1850 | ); |
||
1851 | |||
1852 | // Disable the subscription. |
||
1853 | if (!$delete) |
||
1854 | $smcFunc['db_query']('', ' |
||
1855 | UPDATE {db_prefix}log_subscribed |
||
1856 | SET status = {int:not_active} |
||
1857 | WHERE id_member = {int:current_member} |
||
1858 | AND id_subscribe = {int:current_subscription}', |
||
1859 | array( |
||
1860 | 'not_active' => 0, |
||
1861 | 'current_member' => $id_member, |
||
1862 | 'current_subscription' => $id_subscribe, |
||
1863 | ) |
||
1864 | ); |
||
1865 | // Otherwise delete it! |
||
1866 | else |
||
1867 | $smcFunc['db_query']('', ' |
||
1868 | DELETE FROM {db_prefix}log_subscribed |
||
1869 | WHERE id_member = {int:current_member} |
||
1870 | AND id_subscribe = {int:current_subscription}', |
||
1871 | array( |
||
1872 | 'current_member' => $id_member, |
||
1873 | 'current_subscription' => $id_subscribe, |
||
1874 | ) |
||
1875 | ); |
||
1876 | } |
||
1877 | |||
1878 | /** |
||
1879 | * This just kind of caches all the subscription data. |
||
1880 | */ |
||
1881 | function loadSubscriptions() |
||
1882 | { |
||
1883 | global $context, $txt, $modSettings, $smcFunc; |
||
1884 | |||
1885 | if (!empty($context['subscriptions'])) |
||
1886 | return; |
||
1887 | |||
1888 | // Make sure this is loaded, just in case. |
||
1889 | loadLanguage('ManagePaid'); |
||
1890 | |||
1891 | $request = $smcFunc['db_query']('', ' |
||
1892 | SELECT id_subscribe, name, description, cost, length, id_group, add_groups, active, repeatable |
||
1893 | FROM {db_prefix}subscriptions', |
||
1894 | array( |
||
1895 | ) |
||
1896 | ); |
||
1897 | $context['subscriptions'] = array(); |
||
1898 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1899 | { |
||
1900 | // Pick a cost. |
||
1901 | $costs = $smcFunc['json_decode']($row['cost'], true); |
||
1902 | |||
1903 | if ($row['length'] != 'F' && !empty($modSettings['paid_currency_symbol']) && !empty($costs['fixed'])) |
||
1904 | $cost = sprintf($modSettings['paid_currency_symbol'], $costs['fixed']); |
||
1905 | else |
||
1906 | $cost = '???'; |
||
1907 | |||
1908 | // Do the span. |
||
1909 | preg_match('~(\d*)(\w)~', $row['length'], $match); |
||
1910 | if (isset($match[2])) |
||
1911 | { |
||
1912 | $num_length = $match[1]; |
||
1913 | $length = $match[1] . ' '; |
||
1914 | switch ($match[2]) |
||
1915 | { |
||
1916 | case 'D': |
||
1917 | $length .= $txt['paid_mod_span_days']; |
||
1918 | $num_length *= 86400; |
||
1919 | break; |
||
1920 | case 'W': |
||
1921 | $length .= $txt['paid_mod_span_weeks']; |
||
1922 | $num_length *= 604800; |
||
1923 | break; |
||
1924 | case 'M': |
||
1925 | $length .= $txt['paid_mod_span_months']; |
||
1926 | $num_length *= 2629743; |
||
1927 | break; |
||
1928 | case 'Y': |
||
1929 | $length .= $txt['paid_mod_span_years']; |
||
1930 | $num_length *= 31556926; |
||
1931 | break; |
||
1932 | } |
||
1933 | } |
||
1934 | else |
||
1935 | $length = '??'; |
||
1936 | |||
1937 | $context['subscriptions'][$row['id_subscribe']] = array( |
||
1938 | 'id' => $row['id_subscribe'], |
||
1939 | 'name' => $row['name'], |
||
1940 | 'desc' => $row['description'], |
||
1941 | 'cost' => $cost, |
||
1942 | 'real_cost' => $row['cost'], |
||
1943 | 'length' => $length, |
||
1944 | 'num_length' => $num_length, |
||
1945 | 'real_length' => $row['length'], |
||
1946 | 'pending' => 0, |
||
1947 | 'finished' => 0, |
||
1948 | 'total' => 0, |
||
1949 | 'active' => $row['active'], |
||
1950 | 'prim_group' => $row['id_group'], |
||
1951 | 'add_groups' => $row['add_groups'], |
||
1952 | 'flexible' => $row['length'] == 'F' ? true : false, |
||
1953 | 'repeatable' => $row['repeatable'], |
||
1954 | ); |
||
1955 | } |
||
1956 | $smcFunc['db_free_result']($request); |
||
1957 | |||
1958 | // Do the counts. |
||
1959 | $request = $smcFunc['db_query']('', ' |
||
1960 | SELECT COUNT(id_sublog) AS member_count, id_subscribe, status |
||
1961 | FROM {db_prefix}log_subscribed |
||
1962 | GROUP BY id_subscribe, status', |
||
1963 | array( |
||
1964 | ) |
||
1965 | ); |
||
1966 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1967 | { |
||
1968 | $ind = $row['status'] == 0 ? 'finished' : 'total'; |
||
1969 | |||
1970 | if (isset($context['subscriptions'][$row['id_subscribe']])) |
||
1971 | $context['subscriptions'][$row['id_subscribe']][$ind] = $row['member_count']; |
||
1972 | } |
||
1973 | $smcFunc['db_free_result']($request); |
||
1974 | |||
1975 | // How many payments are we waiting on? |
||
1976 | $request = $smcFunc['db_query']('', ' |
||
1977 | SELECT SUM(payments_pending) AS total_pending, id_subscribe |
||
1978 | FROM {db_prefix}log_subscribed |
||
1979 | GROUP BY id_subscribe', |
||
1980 | array( |
||
1981 | ) |
||
1982 | ); |
||
1983 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
1984 | { |
||
1985 | if (isset($context['subscriptions'][$row['id_subscribe']])) |
||
1986 | $context['subscriptions'][$row['id_subscribe']]['pending'] = $row['total_pending']; |
||
1987 | } |
||
1988 | $smcFunc['db_free_result']($request); |
||
1989 | } |
||
1990 | |||
1991 | /** |
||
1992 | * Load all the payment gateways. |
||
1993 | * Checks the Sources directory for any files fitting the format of a payment gateway, |
||
1994 | * loads each file to check it's valid, includes each file and returns the |
||
1995 | * function name and whether it should work with this version of SMF. |
||
1996 | * |
||
1997 | * @return array An array of information about available payment gateways |
||
1998 | */ |
||
1999 | function loadPaymentGateways() |
||
2000 | { |
||
2001 | global $sourcedir; |
||
2002 | |||
2003 | $gateways = array(); |
||
2004 | if ($dh = opendir($sourcedir)) |
||
2005 | { |
||
2006 | while (($file = readdir($dh)) !== false) |
||
2007 | { |
||
2008 | if (is_file($sourcedir . '/' . $file) && preg_match('~^Subscriptions-([A-Za-z\d]+)\.php$~', $file, $matches)) |
||
2009 | { |
||
2010 | // Check this is definitely a valid gateway! |
||
2011 | $fp = fopen($sourcedir . '/' . $file, 'rb'); |
||
2012 | $header = fread($fp, 4096); |
||
2013 | fclose($fp); |
||
2014 | |||
2015 | if (strpos($header, '// SMF Payment Gateway: ' . strtolower($matches[1])) !== false) |
||
2016 | { |
||
2017 | require_once($sourcedir . '/' . $file); |
||
2018 | |||
2019 | $gateways[] = array( |
||
2020 | 'filename' => $file, |
||
2021 | 'code' => strtolower($matches[1]), |
||
2022 | // Don't need anything snazzier than this yet. |
||
2023 | 'valid_version' => class_exists(strtolower($matches[1]) . '_payment') && class_exists(strtolower($matches[1]) . '_display'), |
||
2024 | 'payment_class' => strtolower($matches[1]) . '_payment', |
||
2025 | 'display_class' => strtolower($matches[1]) . '_display', |
||
2026 | ); |
||
2027 | } |
||
2028 | } |
||
2029 | } |
||
2030 | } |
||
2031 | closedir($dh); |
||
2032 | |||
2033 | return $gateways; |
||
2034 | } |
||
2035 | |||
2036 | ?> |