tra('Member Payment'), 'documentation' => 'PluginMemberPayment', 'description' => tra('Receive payment from a member to extend membership to a group'), 'validate' => 'all', 'prefs' => [ 'wikiplugin_memberpayment', 'payment_feature' ], 'iconname' => 'money', 'introduced' => 5, 'params' => [ 'group' => [ 'required' => true, 'name' => tra('Group'), 'description' => tra('Name of the group for which the subscription should be added or extended.'), 'since' => '5.0', 'filter' => 'groupname', 'default' => '', ], 'price' => [ 'required' => true, 'name' => tra('Price'), 'description' => tr('Price per period (%0).', $prefs['payment_currency']), 'since' => '5.0', 'filter' => 'text', ], 'currentuser' => [ 'required' => false, 'name' => tra('Current User Member'), 'description' => tra('Membership only for the current user'), 'since' => '6.0', 'filter' => 'alpha', 'default' => 'n', 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'] ] ], 'inputtitle' => [ 'required' => false, 'name' => tra('Input Title'), 'description' => tra('Title of the initial input form.') . ' ' . tr('Use %0 for the group name, %1 for the price, %2 for the currency, %4 for the number of days and %5 for the number of years.') . ' ' . tra('Supports wiki syntax.'), 'since' => '6.0', 'filter' => 'text', 'default' => 'Membership to %0 for %1 (x%2)', ], 'inputtitleonly' => [ 'required' => false, 'name' => tra('Input Title Only'), 'description' => tr('Select Yes (%0y%1) to just show the title of the input form and not the period and cost information. Input Title must be set as well.', '', ''), 'since' => '11.0', 'filter' => 'alpha', 'default' => 'n', 'advanced' => true, 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'], ] ], 'howtitle' => [ 'required' => false, 'name' => tra('Initial Payment Form Title'), 'description' => tra('Add a title to the payment form when initially shown after clicking "Continue".') . ' ' . tra('Use %0 for the group name, %1 for the price, %2 for the currency, %4 for the number of days and %5 for the number of years.') . ' ' . tra('Supports wiki syntax'), 'since' => '6.0', 'filter' => 'text', 'default' => 'Membership to %0 for %1 (x%2)', ], 'howtitleonly' => [ 'required' => false, 'name' => tra('Payment Form Title Only'), 'description' => tr('Select Yes (%0y%1) to just show the title of the payment form. Initial Payment Form Title must be set as well.', '', ''), 'since' => '11.0', 'filter' => 'alpha', 'default' => 'n', 'advanced' => true, 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'], ] ], 'paytitle' => [ 'required' => false, 'name' => tra('Subsequent Payment Form Title'), 'description' => tra('Title of the payment form after the initial showing.') . ' ' . tra('Use %0 for the group name, %1 for the price, %2 for the currency, %4 for the number of days and %5 for the number of years.') . ' ' . tra('Supports wiki syntax'), 'since' => '11.0', 'filter' => 'text', 'default' => 'Membership to %0 for %1 (x%2)', ], 'paytitleonly' => [ 'required' => false, 'name' => tra('Subsequent Payment Form Title Only'), 'description' => tr('Select Yes (%0y%1) to just show the title of the payment form that shows after the initial viewing. Subsequent Payment Form Title must be set as well.', '', ''), 'since' => '11.0', 'filter' => 'alpha', 'default' => 'n', 'advanced' => true, 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'], ] ], 'preventdoublerequest' => [ 'required' => false, 'name' => tra('Prevent Double Request'), 'description' => tra('Prevent user from extended if there is already a pending request'), 'since' => '8.0', 'filter' => 'alpha', 'default' => 'n', 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'] ] ], 'freeperiods' => [ 'required' => false, 'name' => tra('Free Periods'), 'description' => tra('Give specified numbers of free periods, the first one could be prorated, in addition to those bought'), 'since' => '9.0', 'filter' => 'int', 'default' => 0, ], 'hideperiod' => [ 'required' => false, 'name' => tra('Hide Period'), 'description' => tra('Do not allow user to set period - use default of 1.'), 'since' => '11.0', 'filter' => 'alpha', 'default' => 'n', 'advanced' => true, 'options' => [ ['text' => '', 'value' => ''], ['text' => tra('Yes'), 'value' => 'y'], ['text' => tra('No'), 'value' => 'n'] ] ], 'periodslabel' => [ 'required' => false, 'name' => tra('Periods Label'), 'description' => tr('Customize the label for the periods input. No effect if Hide Period is set to Yes (%0y%1).', '', ''), 'since' => '9.1', 'filter' => 'text', 'default' => 'Number of periods:', ], 'returnurl' => [ 'required' => false, 'name' => tra('Return URL'), 'description' => tra('Page that payment service returns to after processing.'), 'since' => '11.0', 'filter' => 'url', 'default' => '', 'advanced' => true, ], ], ]; } function wikiplugin_memberpayment($data, $params, $offset) { global $prefs, $user; static $iPluginMemberpayment = 0; $userlib = TikiLib::lib('user'); $smarty = TikiLib::lib('smarty'); $iPluginMemberpayment++; $smarty->assign('iPluginMemberpayment', $iPluginMemberpayment); $smarty->assign('returnurl', ! empty($params['returnurl']) ? $params['returnurl'] : ''); $params['price'] = (float)$params['price']; $default = [ 'currentuser' => 'n', 'inputtitle' => '', 'inputtitleonly' => 'n', 'howtitle' => '', 'howtitleonly' => 'n', 'paytitle' => '', 'paytitleonly' => 'n', 'hideperiod' => 'n', 'periodslabel' => 'Number of periods:']; $params = array_merge($default, $params); $smarty->assign('hideperiod', $params['hideperiod']); $smarty->assign('periodslabel', $params['periodslabel']); //true if continue button has been hit $post = isset($_POST['wp_member_offset']); $oneuser = false; if (( $info = $userlib->get_group_info($params['group']) ) && ( $info['expireAfter'] > 0 || $info['anniversary'] > '')) { $attributelib = TikiLib::lib('attribute'); $paymentlib = TikiLib::lib('payment'); $tikilib = TikiLib::lib('tiki'); $smarty->assign('wp_member_offset', $offset); $smarty->assign('wp_member_price', $params['price']); if ($post) { $periods = (int) $_POST['wp_member_periods']; $freeperiods = 0; if ($periods && ! empty($params['freeperiods'])) { // give free periods (purchase of at least 1 full real period required) $freeperiods = (int) $params['freeperiods']; $periods += $freeperiods; } $smarty->assign('wp_member_postperiods', $periods); $oneuser = $params['currentuser'] == 'y' ? [$user] : explode('|', $_POST['wp_member_users']); $oneuser = count($oneuser) == 1 ? true : false; if ($oneuser) { $extendinfo = $userlib->get_extend_until_info($user, $params['group'], $periods); $paidterm = $extendinfo['interval']; } } if (! empty($info['expireAfter'])) { $smarty->assign('wp_member_expireafter', true); if ($info['expireAfter'] == 1) { $days = tra('day'); } elseif ($info['expireAfter'] > 1) { $days = tra('days'); } $info['termString'] = $info['expireAfter'] . ' ' . $days; //set up subscription parameters for paypal - interval (D, M or Y) and number of intervals are required if ($prefs['payment_system'] == 'paypal' && $oneuser) { if ($paidterm->y > 2 || ($paidterm->y <= 2 && $paidterm->y > 0 && $paidterm->m == 0)) { $ppinterval = 'Y'; $ppunits = $paidterm->y; //maximum number of days that can be specified in paypal is 90 for subscriptions } elseif ($paidterm->days > 90) { $ppinterval = 'M'; $ppunits = $paidterm->m + ($paidterm->y * 12); } else { $ppinterval = 'D'; $ppunits = $paidterm->days; } $beg = isset($extendinfo['new']) && $extendinfo['new'] === false ? tra('by') : tra('for'); $info['descString'] = $beg . ' ' . $info['expireAfter'] * $periods . ' ' . $days; } } $smarty->assign('wp_member_prorated', 0); // default if ($info['anniversary'] > '') { if (strlen($info['anniversary']) == 4) { $ann_month = substr($info['anniversary'], 0, 2); $ann_day = substr($info['anniversary'], 2, 2); $ppinterval = 'Y'; $fakedate = DateTime::createFromFormat('m-d', $ann_month . '-' . $ann_day); $info['termString'] = tr( 'Annual, commencing %0 %1 each year', tra($fakedate->format('M')), $fakedate->format('j') ); } elseif (strlen($info['anniversary']) == 2) { $ann_month = 0; $ann_day = $info['anniversary']; $ppinterval = 'M'; $info['termString'] = tr('Monthly, commencing on day %0 each month', $ann_day); } if ($oneuser) { $info['descString'] = 'to ' . $tikilib->get_short_date($extendinfo['timestamp'], $user); } $smarty->assign('wp_member_anniversary_month', $ann_month); $smarty->assign('wp_member_anniversary_day', $ann_day); if ($params['currentuser'] == 'y') { $extend_until_info = $userlib->get_extend_until_info($user, $params['group']); if ( ! empty($extend_until_info['ratio_prorated_first_period']) && $extend_until_info['ratio_prorated_first_period'] > 0 && $extend_until_info['ratio_prorated_first_period'] < 1 ) { $smarty->assign('wp_member_prorated', round($extend_until_info['ratio_prorated_first_period'] * $params['price'], 2)); } } } $smarty->assign('wp_member_group', $info); $smarty->assign('wp_member_currentuser', $params['currentuser']); // setup free period display if (! empty($params['freeperiods'])) { if ( isset($extendinfo['ratio_prorated_first_period']) && $extendinfo['ratio_prorated_first_period'] > 0 && $extendinfo['ratio_prorated_first_period'] < 1 ) { $smarty->assign('wp_member_freeperiods', $params['freeperiods'] - 1); $smarty->assign('wp_member_freeprorated', 1); } else { $smarty->assign('wp_member_freeperiods', $params['freeperiods']); $smarty->assign('wp_member_freeprorated', 0); } } else { $smarty->assign('wp_member_freeperiods', 0); $smarty->assign('wp_member_freeprorated', 0); } $smarty->assign('wp_member_requestpending', 'n'); $smarty->assign('wp_member_title', $params['inputtitle']); $smarty->assign('wp_member_titleonly', $params['inputtitleonly']); $smarty->assign('wp_member_paymentid', 0); if (isset($params['currentuser']) && $params['currentuser'] == 'y' && ! empty($params['preventdoublerequest']) && $params['preventdoublerequest'] == 'y') { $attname = 'tiki.memberextend.' . $info['id']; $attributes = $attributelib->get_attributes('user', $user); if (isset($attributes[$attname])) { $smarty->assign('wp_member_requestpending', 'y'); $smarty->assign('wp_member_paymentid', $attributes[$attname]); if (! empty($params['paytitle'])) { $smarty->assign('wp_member_title', $params['paytitle']); $smarty->assign('wp_member_titleonly', $params['paytitleonly']); } } } if (isset($_POST['wp_member_offset']) && $_POST['wp_member_offset'] == $offset && ! empty($_POST['wp_member_periods'])) { $users = $params['currentuser'] == 'y' ? [$user] : explode('|', $_POST['wp_member_users']); $users = array_map('trim', $users); $users = array_filter($users, [ $userlib, 'user_exists' ]); $users = array_filter($users); $smarty->assign('wp_member_users', count($users)); if (! empty($params['preventdoublerequest']) && $params['preventdoublerequest'] == 'y') { foreach ($users as $u) { $attname = 'tiki.memberextend.' . $info['id']; $attributes = $attributelib->get_attributes('user', $u); if (isset($attributes[$attname])) { return '{REMARKSBOX(type=warning, title=Plugin Memberpayment Error)}' . tra('The user ') . $u . tra(' already has a pending extension request payment invoice ') . $attributes[$attname] . '{REMARKSBOX}'; } } } if ($prefs['payment_system'] == 'paypal' && $oneuser) { $rounded = round($periods); if ( ($ppinterval == 'Y' && $rounded <= 5) || ($ppinterval == 'M' && $rounded <= 24) || ($ppinterval == 'D' && $rounded <= 90) ) { $smarty->assign('wp_member_subscribeok', 'y'); if (isset($ppunits)) { $smarty->assign('wp_member_periodset', $ppunits); } else { $smarty->assign('wp_member_periodset', round($periods)); } if (isset($ppinterval)) { $smarty->assign('wp_member_interval', $ppinterval); } //when parameters don't fit within paypal limits } else { $smarty->assign('wp_member_subscribeok', 'n'); } } if (count($users) == 1) { $mem = isset($extendinfo['new']) && $extendinfo['new'] === false ? 'Extend membership' : 'Membership'; $term = ! empty($info['descString']) ? ' ' . $info['descString'] : ''; $desc = tr('%0 to %1 %2 for %3', $mem, $params['group'], $term, reset($users)); } else { $perplural = $periods > 1 ? tra('periods') : tra('period'); $desc = tr( 'Membership to %0 for %1 users for %2 %3', $params['group'], count($users), $periods, $perplural ); } //calculate cost $cost = 0; if (! empty($info['expireAfter'])) { $cost = round(count($users) * ($periods - $freeperiods) * $params['price'], 2); } if ($info['anniversary'] > '') { foreach ($users as $u) { $extendinfo = $userlib->get_extend_until_info($u, $params['group'], $periods); $extendinfo['freeperiods'] = $freeperiods; if ( ! empty($extendinfo['ratio_prorated_first_period']) && $extendinfo['ratio_prorated_first_period'] > 0 && $extendinfo['ratio_prorated_first_period'] < 1 ) { $smarty->assign('wp_member_prorated', round($extendinfo['ratio_prorated_first_period'] * $params['price'], 2)); } if ( $extendinfo['freeperiods'] > 0 && $extendinfo['ratio_prorated_first_period'] < 1 && $extendinfo['ratio_prorated_first_period'] > 0 ) { $extendinfo['ratio'] = $extendinfo['ratio'] - $extendinfo['ratio_prorated_first_period']; $extendinfo['freeperiods']--; } $cost += ($extendinfo['ratio'] - $extendinfo['freeperiods']) * $params['price']; } $cost = round($cost, 2); } $id = $paymentlib->request_payment($desc, $cost, $prefs['payment_default_delay']); $paymentlib->register_behavior($id, 'complete', 'extend_membership', [ $users, $params['group'], $periods, $info['id'] ]); foreach ($users as $u) { $attributelib->set_attribute('user', $u, 'tiki.memberextend.' . $info['id'], $id); } $paymentlib->register_behavior($id, 'cancel', 'cancel_membership_extension', [ $users, $info['id'] ]); $smarty->assign('wp_member_title', $params['howtitle']); $smarty->assign('wp_member_titleonly', $params['howtitleonly']); require_once 'lib/smarty_tiki/function.payment.php'; return '^~np~' . smarty_function_payment([ 'id' => $id ], $smarty->getEmptyInternalTemplate()) . '~/np~^'; } elseif ($prefs['payment_system'] == 'cclite' && isset($_POST['cclite_payment_amount']) && isset($_POST['invoice'])) { require_once 'lib/smarty_tiki/function.payment.php'; return '^~np~' . smarty_function_payment([ 'id' => $_POST['invoice'] ], $smarty->getEmptyInternalTemplate()) . '~/np~^'; } return '~np~' . $smarty->fetch('wiki-plugins/wikiplugin_memberpayment.tpl') . '~/np~'; } elseif ($info['expireAfter'] == 0 && $params['group'] == $info['groupName']) { return '{REMARKSBOX(type=warning, title=Plugin Memberpayment Error)}' . tra('The group ') . '' . $info['groupName'] . '' . tra(' does not have a membership term.') . tra(' Go to ') . '' . tra('Admin > Groups') . '' . tra(' to specify a term for this group by automatically unassigning users after a certain number of days.') . '{REMARKSBOX}'; } else { return '{REMARKSBOX(type=warning, title=Plugin Memberpayment Error)}' . tra('The group ') . '' . $params['group'] . '' . tra(' does not exist') . '{REMARKSBOX}'; } }