/** * Draws the user profile tab "Subscriptions" (if enabled, user is the profile owner, and something to display. * * @param UserTable $user * @param boolean $itsmyself * @param string $htmlSubscribed * @return string */ public function drawUserSomethings($user, $itsmyself, $htmlSubscribed) { global $_CB_framework, $ueConfig; $this->htmlSubscribed = $htmlSubscribed; $subscriptions = $this->_model; if (count($subscriptions) == 1) { $subTxt = CBPTXT::T(cbpaidApp::settingsParams()->get('subscription_name', 'subscription')); } else { $subTxt = CBPTXT::T(cbpaidApp::settingsParams()->get('subscriptions_name', 'subscriptions')); } if ($itsmyself) { $userName = null; } else { $userName = getNameFormat($user->name, $user->username, $ueConfig['name_format']); } if ($_CB_framework->getUi() == 1) { if ($itsmyself) { $this->htmlTabTitle = sprintf(CBPTXT::Th("Your current %s"), $subTxt); } else { $this->htmlTabTitle = sprintf(CBPTXT::Th("%s's current %s"), $userName, $subTxt); } } else { if ($itsmyself) { $this->htmlTabTitle = sprintf(CBPTXT::Th("Your current and past %s"), $subTxt); } else { $this->htmlTabTitle = sprintf(CBPTXT::Th("%s's current and past %s"), $userName, $subTxt); } } return $this->display(); }
/** * Returns text for button for upgrade, renewals, etc. * * @param string $type 'upgrade', 'pay', 'renew', 'reactivate', 'resubscribe', 'unsubscribe', 'delete', default is Apply * @return string translated button text (without htmlspecialchars, it will be applied on the returned text. */ public function buttonText( $type ) { switch ( $type ) { case 'upgrade': return CBPTXT::T("Buy"); case 'pay': return CBPTXT::T("Buy Now"); default: return parent::buttonText( $type ); } }
/** * Draws the plans upgrade proposals * * @param UserTable $user * @param int $plansDisplayed * @param string $htmlUpgrades * @param string $htmlspecialcharedBaseUrl * @param array $hiddenFlds * @param array $buttonTexts * @param string $buttonName * @return string */ public function drawUserUpgradePlans($user, $plansDisplayed, $htmlUpgrades, $htmlspecialcharedBaseUrl, $hiddenFlds, $buttonTexts, $buttonName) { $this->htmlUpgrades = $htmlUpgrades; $this->htmlspecialcharedBaseUrl = $htmlspecialcharedBaseUrl; $this->hiddenFlds = $hiddenFlds; $this->buttonName = $buttonName; $this->buttonText = implode(' / ', $buttonTexts); $subTxt = CBPTXT::T(cbpaidApp::settingsParams()->get('subscription_name', 'subscription')); if ($plansDisplayed == 1) { $this->htmlTitle = sprintf(CBPTXT::Th("Your current %s upgrade possibility:"), $subTxt); } else { $this->htmlTitle = sprintf(CBPTXT::Th("Your current %s upgrade possibilities:"), $subTxt); } return $this->display(); }
/** * Draws the user profile tab "Subscriptions" (if enabled, user is the profile owner, and something to display. * * @param string $htmlSubscriptionsAndUpgrades * @param string $htmlInvoicesLink * @param string $tabTitleText * @param string $htmlTabDescription * @return string */ public function drawTab($htmlSubscriptionsAndUpgrades, $htmlInvoicesLink, $tabTitleText, $htmlTabDescription) { global $ueConfig; $this->htmlSubscriptionsAndUpgrades = $htmlSubscriptionsAndUpgrades; $this->htmlInvoicesLink = $htmlInvoicesLink; $this->htmlTabDescription = $htmlTabDescription; $user = $this->_model; $title = cbReplaceVars(CBPTXT::Th(cbUnHtmlspecialchars($tabTitleText)), $user); if ($title) { $name = getNameFormat($user->name, $user->username, $ueConfig['name_format']); $title = sprintf($title, $name); } $this->htmlTabTitle = $title; return $this->display(); }
/** * Builds and sends e-mail * * @param UserTable $user * @param string $mailFrom_email * @param string $mailFrom_name * @param string $mailTo * @param string $mailSubject * @param string $mailBody * @param string $mailHtml * @param string $mailCC * @param string $mailBCC * @param string $mailAttachments * @param string[] $extraStrings * @return void */ protected function sendMail( $user, $mailFrom_email, $mailFrom_name, $mailTo, $mailSubject, $mailBody, $mailHtml, $mailCC, $mailBCC, $mailAttachments, $extraStrings ) { global $_CB_framework; cbimport( 'cb.tabs' ); $cbUser = CBuser::getInstance( $user->id ); if ( ! $cbUser ) { return; } $mailFrom_email = trim( $cbUser->replaceUserVars( $mailFrom_email, false, false, array(), false ) ); $mailFrom_name = trim( $cbUser->replaceUserVars( $mailFrom_name, false, false, array(), false ) ); $mailTo = trim( $cbUser->replaceUserVars( $mailTo, false, false, array(), false ) ); $mailCC = trim( $cbUser->replaceUserVars( $mailCC, false, false, array(), false ) ); $mailBCC = trim( $cbUser->replaceUserVars( $mailBCC, false, false, array(), false ) ); $mailSubject = trim( $cbUser->replaceUserVars( CBPTXT::T( $mailSubject ), false, false, $extraStrings, false ) ); $mailBody = trim( $cbUser->replaceUserVars( CBPTXT::T( $mailBody ), false, false, $extraStrings, false ) ); $mailAttachments = trim( $mailAttachments ); if ( $mailTo != '' ) { $mailTo = preg_split( '/ *, */', $mailTo ); } else { return; } if ( $mailCC != '' ) { $mailCC = preg_split( '/ *, */', $mailCC ); } else { $mailCC = null; } if ( $mailBCC != '' ) { $mailBCC = preg_split( '/ *, */', $mailBCC ); } else { $mailBCC = null; } if ( $mailAttachments != '' ) { $mailAttachments = preg_split( '/ *, */', $mailAttachments ); } else { $mailAttachments = null; } if ( $mailTo && ( $mailSubject || $mailBody ) ) { comprofilerMail( $mailFrom_email, $mailFrom_name, $mailTo, $_CB_framework->getCfg( 'sitename' ).' - '.$mailSubject, $mailBody, $mailHtml, $mailCC, $mailBCC, $mailAttachments ); } }
/** * Check for whether dependancies exist for this object in the db schema * * @param int $oid Optional key index * @return boolean TRUE: OK to delete, FALSE: not OK to delete, error in $this->_error */ public function canDelete($oid = null) { $k = $this->_tbl_key; if ($oid) { $this->{$k} = $oid; } $query = "SELECT COUNT(*)" . "\n FROM `#__cbsubs_subscriptions`" . "\n WHERE `plan_id` = " . (int) $this->{$k}; $this->_db->setQuery($query); $obj = null; $count = $this->_db->loadResult($obj); if ($count > 0) { $this->setError(CBPTXT::T("Subscriptions exist for this plan")); return false; } return parent::canDelete($oid); }
/** * Renders the currency symbol according to global settings * * @param string|null $currency * @param boolean $html * @return string */ public function renderCurrencySymbol( $currency, $html ) { $params = $this->params; if ( $currency === null ) { $currency = $params->get( 'currency_code', 'USD' ); } $priceCurrencyFormat = $params->get('price_currency_format', '%2$s %1$s' ); if ( $html ) { if ( strpos( $priceCurrencyFormat, '%3' ) !== false ) { $currencySymbols = array ( 'EUR' => '€', 'USD' => '$', 'GBP' => '£', 'JPY' => '¥', 'CHF' => 'Fr.', 'CAD' => 'C$', 'AUD' => '$', 'BRL' => 'R$', 'CNY' => '¥', 'DKK' => 'KR', 'ZAR' => 'R', 'SEK' => 'KR' ); //TBD: move to currency table $textHtmlSymbol = isset( $currencySymbols[$currency] ) ? $currencySymbols[$currency] : CBPTXT::Th( $currency ); } else { $textHtmlSymbol = CBPTXT::Th( $currency ); } $textHtmlSymbol = '<span class="cbregPcur">' . $textHtmlSymbol . '</span>'; } else { $textHtmlSymbol = CBPTXT::T( $currency ); } return $textHtmlSymbol; }
/** * Renders a $variable for an $output * * @param string $variable * @param string $output * @param boolean $rounded * @return string|null */ public function renderColumn($variable, $output = 'html', $rounded = false) { $html = $output == 'html'; switch ($variable) { case 'rate': $ret = $this->renderItemRate($html); break; case 'discount_amount': case 'tax_amount': $ret = $this->renderJustItemRates($variable, $html, $rounded); break; case 'first_rate': case 'first_discount_amount': case 'first_tax_amount': $ret = cbpaidMoney::getInstance()->renderPrice($this->{$variable}, $this->currency, $html, $rounded); break; case 'quantity': // removes insignifiant zeros after ., as well as the . itself if no decimals: $matches = null; $matched = preg_match("/^(.+?)[.]?[0]*\$/", $this->get($variable), $matches); $ret = $matched ? $matches[1] : null; break; case 'validity_period': if ($this->start_date && $this->stop_date && $this->start_date != '0000-00-00 00:00:00' && $this->stop_date != '0000-00-00 00:00:00') { $showTime = false; $startDate = cbFormatDate($this->start_date, 1, $showTime); $stopDate = cbFormatDate($this->stop_date, 1, $showTime); $ret = htmlspecialchars($startDate); if ($stopDate && $startDate != $stopDate) { $ret .= ($html ? ' - ' : ' - ') . htmlspecialchars($stopDate); } if ($this->second_stop_date && $this->second_stop_date != '0000-00-00 00:00:00') { $secondStartDate = cbFormatDate($this->_db->getUtcDateTime(cbpaidTimes::getInstance()->strToTime($this->stop_date) + 1), 1, $showTime); $secondStopDate = cbFormatDate($this->second_stop_date, 1, $showTime); $retsecond = htmlspecialchars($secondStartDate) . ($html ? ' - ' : ' - ') . htmlspecialchars($secondStopDate); $ret = sprintf($html ? CBPTXT::Th("%s, then %s") : CBPTXT::T("%s, then %s"), $ret, $retsecond); } } else { $ret = null; } break; case 'tax_rule_id': if ($this->tax_rule_id && is_callable(array('cbpaidTaxRule', 'getInstance'))) { $ret = cbpaidTaxRule::getInstance((int) $this->tax_rule_id)->getShortCode(); } else { $ret = null; } break; case 'original_rate': case 'first_original_rate': $ret = null; break; case 'ordering': case 'artnum': case 'description': case 'discount_text': default: $value = $this->get($variable); if ($value !== null) { $ret = htmlspecialchars($this->get($variable)); } else { $ret = null; } break; } return $ret; }
/** * When triggered, before starting to make changes this method should be called * Transition: -> E{$substate} * * @param string $substate * @return boolean TRUE: got lock to perform scheduled task, FALSE: no scheduling needed here (and no transition made) */ public function attemptScheduledTask( $substate = '' ) { if ( substr( $this->_baseObject->scheduler_state, 0, 1 ) == 'E' ) { // It was Executing: check for iterations before resetting to 'S' (with error log). if ( strlen( $this->_baseObject->scheduler_state ) == 1 ) { // Backwards compatibility: $this->_baseObject->scheduler_state .= '1'; } $iteration = (int) $this->_baseObject->scheduler_state[1]; if ( ++$iteration <= $this->maxExecWaitIterations ) { $this->_baseObject->scheduler_state[1] = (string) $iteration; $this->_baseObject->store(); } else { $this->_baseObject->scheduler_state = 'S'; cbpaidApp::setLogErrorMSG( 4, $this->_baseObject, CBPTXT::P("Scheduler for this basket has stayed in execution state for [NUMBER_OF_CRONS] cron cycles. Resetting execution state.", array( '[NUMBER_OF_CRONS]' => $this->maxExecWaitIterations ) ), null ); } } // Now normal case: if ( $this->_baseObject->scheduler_state == 'S' ) { // it was scheduled: $this->_baseObject->scheduler_state = 'E1' . $substate; // Executing return $this->_baseObject->store(); } return false; }
/** * Standard language loading method: * @todo add to CB API * * @param string $interface 'admin' to force-load admin languages */ public static function loadLang($interface = null) { global $_CB_framework; static $loaded = false; static $adminLoaded = false; if (!$loaded) { $path = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/language'; $myLanguageFolder = '-' . strtolower($_CB_framework->getCfg('lang_tag')); $myLanguageFile = 'language.php'; $file = $path . '/cbpaidsubscriptions' . $myLanguageFolder . '/' . $myLanguageFile; if (!file_exists($file)) { // Old method: $myLanguageFolder = $_CB_framework->getCfg('lang'); $myLanguageFile = $myLanguageFolder . '.php'; $file = $path . '/cbpaidsubscriptions' . $myLanguageFolder . '/' . $myLanguageFile; } if (file_exists($file)) { if (!$interface) { $CBstrings = array(); /** @noinspection PhpIncludeInspection */ include_once $file; // defines $CBstrings CBPTXT::addStrings($CBstrings); } if ($_CB_framework->getUi() == 2 || $interface == 'admin') { if (!$adminLoaded) { $file = $path . '/cbpaidsubscriptions' . $myLanguageFolder . '/admin_' . $myLanguageFile; if (file_exists($file)) { $CBstrings = array(); /** @noinspection PhpIncludeInspection */ include_once $file; // defines $CBstrings CBPTXT::addStrings($CBstrings); } $adminLoaded = true; } } } $loaded = true; } }
/** * store() function override, instead of storing it imports. * * @param boolean $updateNulls * @return boolean */ public function store($updateNulls = false) { $return = ''; // Check if file uploads are enabled if (!(bool) ini_get('file_uploads')) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("The importer can't continue before file uploads are enabled in PHP settings."); return false; } if (!$this->import_type) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No import type selected"); return false; } $fromFile = cbStartOfStringMatch($this->import_type, 'file_'); if ($fromFile) { $userfile = $_FILES['userfile']; if (!$userfile || $userfile == null) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No file selected"); return false; } if (isset($userfile['error']) && $userfile['error']) { $errors_array = array(1 => CBPTXT::T("The uploaded file exceeds the upload_max_filesize directive in php.ini."), 2 => CBPTXT::T("The uploaded file exceeds the maximum size allowed by this form."), 3 => CBPTXT::T("The uploaded file was only partially uploaded."), 4 => CBPTXT::T("No file was selected and uploaded."), 6 => CBPTXT::T("Missing a temporary folder in php.ini."), 7 => CBPTXT::T("Failed to write file to disk."), 8 => CBPTXT::T("File upload stopped by extension.")); if (in_array($userfile['error'], $errors_array)) { $fileErrorTxt = $errors_array[$userfile['error']]; } else { $fileErrorTxt = CBPTXT::T("File upload error number ") . htmlspecialchars($userfile['error']); } $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . $fileErrorTxt; return false; } if (!$userfile['tmp_name'] || !is_uploaded_file($userfile['tmp_name'])) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No temporary file name"); return false; } if ($userfile['size'] == 0) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("Empty file"); return false; } } else { $userfile = null; } if ($this->import_type == 'cms_acl') { if (!$this->usergroup) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No usergroup selected"); return false; } } if ($this->import_type == 'subscription') { if (!$this->from_plan) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No subscription plan selected"); return false; } if (!$this->from_sub_status) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No subscription status selected"); return false; } } if ($this->import_type != 'file_uid_plan_exp') { if (!$this->plan) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No plan selected"); return false; } if (!$this->state) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No subscription state selected"); return false; } if (!$this->date) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No subscription date selected"); return false; } } if ($fromFile) { $tmpName = $userfile['tmp_name']; $fileSize = (int) $userfile['size']; // $fileType = $userfile['type']; } else { $tmpName = null; $fileSize = null; } $planStateDate = array(); switch ($this->import_type) { case 'file_uid': $fp = fopen($tmpName, 'r'); $content = fread($fp, $fileSize); fclose($fp); unlink($tmpName); $userIdList = explode(',', trim($content)); break; case 'file_uid_plan_exp': $userIdList = array(); $fp = fopen($tmpName, 'r'); if ($fp) { $n = 0; while (!feof($fp)) { $line = trim(str_replace('"', '', fgets($fp, 256))); $n += 1; if (strlen($line) > 0) { $matches = null; if (preg_match('/([1-9][0-9]*),([1-9][0-9]*),([AXC]),([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9][0-9]:[0-9][0-9]:[0-9][0-9])/', $line, $matches)) { if (!in_array((int) $matches[1], $userIdList)) { $userIdList[] = (int) $matches[1]; } $planStateDate[(int) $matches[1]][] = array('plan' => (int) $matches[2], 'status' => $matches[3], 'date' => $matches[4]); } else { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . sprintf(CBPTXT::T("Line %s does not match the format userid,planid,status,date, e.g. 63,1,A,2009-01-01 00:00:00, and is instead: %s ."), $n, htmlspecialchars($line)); fclose($fp); unlink($tmpName); return false; } } } } fclose($fp); unlink($tmpName); break; case 'cms_acl': if (checkJversion() >= 2) { $sql = 'SELECT id FROM #__users u' . ' JOIN #__user_usergroup_map m ON ( u.id = m.user_id )' . ' WHERE m.group_id = ' . (int) $this->usergroup; } else { $sql = 'SELECT id FROM #__users' . ' WHERE gid = ' . (int) $this->usergroup; } $this->_db->setQuery($sql); $userIdList = $this->_db->loadResultArray(); break; case 'subscription': $statuses = $this->from_sub_status; foreach (array_keys($statuses) as $k) { $statuses[$k] = $this->_db->Quote($statuses[$k][0]); } $sql = 'SELECT s.user_id FROM #__cbsubs_subscriptions s' . ' JOIN #__users u ON ( u.id = s.user_id AND u.block = 0 )' . ' JOIN #__comprofiler c ON ( c.id = s.user_id AND c.confirmed = 1 AND c.approved = 1 )' . ' WHERE s.plan_id = ' . (int) $this->from_plan . ' AND s.status IN (' . implode(',', $statuses) . ')'; $this->_db->setQuery($sql); $userIdList = $this->_db->loadResultArray(); break; default: $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("Import type not implemented!"); return false; break; } if (count($userIdList) == 0) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("No user to import"); return false; } $plansMgr = cbpaidPlansMgr::getInstance(); if ($this->import_type != 'file_uid_plan_exp') { $plan = $plansMgr->loadPlan((int) $this->plan); $subscriptionTime = (int) $plan->strToTime($this->date); foreach ($userIdList as $key => $value) { if (!is_numeric($value)) { $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("non-numeric userid value: ") . str_replace("\n", ' ', htmlspecialchars($value)); return false; } $userIdList[$key] = (int) $value; } } else { $plan = null; $subscriptionTime = null; } $this->_db->setQuery("SELECT u.id, u.username FROM #__comprofiler c, #__users u WHERE c.id=u.id AND u.block = 0 AND c.approved = 1 AND c.confirmed = 1 AND c.id IN (" . implode(',', $userIdList) . ")"); $users = $this->_db->loadObjectList('id'); if (count($userIdList) != count($users)) { if (is_array($users)) { foreach ($users as $u) { $keys = array_keys($userIdList, $u->id); unset($userIdList[$keys[0]]); unset($planStateDate[(int) $u->id]); } } $idList = implode(', ', $userIdList); $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("Not all userId exist, are active (confirmed, approved and enabled) ! innexistant or inactive ids: ") . $idList; return false; } $this->_db->setQuery("SELECT DISTINCT user_id FROM #__cbsubs_subscriptions WHERE user_id IN (" . implode(',', $userIdList) . ")" . " ORDER BY user_id"); $usersSubscribed = $this->_db->loadResultArray(); $incompatibleUsersSubs = array(); if ($this->import_type != 'file_uid_plan_exp') { foreach ($users as $user) { @set_time_limit(60); $incompatible = false; if (in_array($user->id, $usersSubscribed)) { if ($plan->get('exclusive') && $plan->get('item_type') == 'usersubscription') { $paidUserExtension = cbpaidUserExtension::getInstance($user->id); $subscriptions = $paidUserExtension->getUserSubscriptions(null, false); foreach ($subscriptions as $s) { if ($s->parent_plan == $plan->get('parent') && $s->checkIfValid()) { $sPlan = $s->getPlan(); if ($sPlan->get('exclusive') && $sPlan->get('item_type') == 'usersubscription') { // check if any other exclusive subscription with same parent plan is active: $incompatible = true; break; } } } } } if (!$incompatible) { if ($plan->get('parent')) { $plansMgr = cbpaidPlansMgr::getInstance(); $parentPlan = $plansMgr->loadPlan($plan->get('parent')); $parentSub = $parentPlan->loadLatestSomethingOfUser($user->id, null); if (!$parentSub) { $incompatible = true; } } } if ($incompatible) { if (!in_array($user->id, $incompatibleUsersSubs)) { $incompatibleUsersSubs[] = $user->id; } continue; } if (!$this->dryrun) { $userFull = CBuser::getUserDataInstance($user->id); $this->createSomething($plan, $userFull, $this->state, $subscriptionTime); CBuser::unsetUsersNotNeeded(array((int) $user->id)); } } } else { $cbpaidTimes = cbpaidTimes::getInstance(); $systemTimeZone = new DateTimeZone($cbpaidTimes->systemTimeZone()); foreach ($users as $user) { @set_time_limit(60); foreach ($planStateDate[(int) $user->id] as $psd) { $plan = $plansMgr->loadPlan((int) $psd['plan']); $status = $psd['status']; if ($psd['date']) { $date = DateTime::createFromFormat('Y-m-d H:i:s', $psd['date'], $systemTimeZone); $subscriptionTime = $date->getTimestamp(); } else { $subscriptionTime = $cbpaidTimes->startTime(); } $incompatible = false; if (in_array($user->id, $usersSubscribed)) { if ($plan->get('exclusive') && $plan->get('item_type') == 'usersubscription') { $paidUserExtension = cbpaidUserExtension::getInstance($user->id); $subscriptions = $paidUserExtension->getUserSubscriptions(null, false); foreach ($subscriptions as $s) { if ($s->parent_plan == $plan->get('parent') && $s->checkIfValid()) { $sPlan = $s->getPlan(); if ($sPlan->get('exclusive') && $sPlan->get('item_type') == 'usersubscription') { // check if any other exclusive subscription with same parent plan is active: $incompatible = true; break; } } } } } if (!$incompatible) { if ($plan->get('parent')) { $plansMgr = cbpaidPlansMgr::getInstance(); $parentPlan = $plansMgr->loadPlan($plan->get('parent')); $parentSub = $parentPlan->loadLatestSomethingOfUser($user->id, null); if (!$parentSub) { $incompatible = true; } } } if ($incompatible) { if (!in_array($user->id, $incompatibleUsersSubs)) { $incompatibleUsersSubs[] = $user->id; } continue; } if (!$this->dryrun) { $userFull = CBuser::getUserDataInstance($user->id); $this->createSomething($plan, $userFull, $status, $subscriptionTime); CBuser::unsetUsersNotNeeded(array((int) $user->id)); } } } } if (count($userIdList) > 0 && count($incompatibleUsersSubs) == 0) { $resultText = CBPTXT::T("Success"); } elseif (count($userIdList) > count($incompatibleUsersSubs)) { $resultText = CBPTXT::T("Partial Success"); } elseif (count($userIdList) == count($incompatibleUsersSubs)) { $resultText = CBPTXT::T("Import failed"); } else { $resultText = CBPTXT::T("Unknown Result"); } $return .= '<h1>' . $resultText . ($this->dryrun ? ' [' . CBPTXT::T("DRY-RUN - NO REAL SUBSCRIPTION") . ']' : '') . ':</h1>'; if (count($incompatibleUsersSubs) > 0) { $idList = implode(', ', $incompatibleUsersSubs); $return .= '<p>' . CBPTXT::T("Some users have already subscriptions: user ids: ") . $idList . '</p>'; // $this->_error = CBPTXT::T("Importer") . ' - ' . CBPTXT::T("error:") . ' ' . CBPTXT::T("Some users have already subscriptions: user ids: ") . $idList; // return false; } if ($this->import_type != 'file_uid_plan_exp') { $return .= '<p>' . sprintf(CBPTXT::T("%d users subscribed to plan: %s , with state: %s"), count($userIdList) - count($incompatibleUsersSubs), $plan->get('name'), CBPTXT::T($this->_states[$this->state])) . '</p>'; if (count($userIdList) - count($incompatibleUsersSubs) > 0) { $return .= '<p>' . CBPTXT::T("Users subscribed (usernames):") . '</p>'; $return .= '<p>'; foreach ($users as $user) { if (!in_array($user->id, $incompatibleUsersSubs)) { $return .= $user->username . ' '; } } $return .= '</p>'; } } else { $return .= '<p>' . sprintf(CBPTXT::T("%d users subscribed"), count($userIdList) - count($incompatibleUsersSubs)) . '</p>'; if (count($userIdList) - count($incompatibleUsersSubs) > 0) { $return .= '<p>' . CBPTXT::T("Users subscribed (usernames):") . '</p>'; foreach ($users as $user) { if (!in_array($user->id, $incompatibleUsersSubs)) { $return .= '<p>' . $user->username . ' ' . CBPTXT::T("to") . ' '; foreach ($planStateDate[(int) $user->id] as $psd) { $plan = $plansMgr->loadPlan((int) $psd['plan']); $status = $psd['status']; $return .= sprintf(CBPTXT::T("plan: %s , with state: %s") . ' ', $plan->get('name'), CBPTXT::T($this->_states[$status])); } } } $return .= '</p>'; } } if (count($incompatibleUsersSubs) > 0) { $return .= '<p>' . CBPTXT::T("Following Users could not be subscribed (usernames) because either: (A) an exclusive active subscription exists that would conflict with the imported user subscription, or: (B) it is a children plan but the parent plan subscription does not exist:") . '</p>'; $return .= '<p>'; foreach ($incompatibleUsersSubs as $uid) { if (isset($users[$uid])) { $return .= $users[$uid]->username . ' '; } } $return .= '</p>'; } $this->_resultOfStore = $return; return true; }
/** * Returns formatted time period ( xxx weeks , or xxx years xxx months xxx days xxx hours xxx minutes xxx seconds * * @param string $varName 'validity' or 'fist_validity' * @param int $occurrences [default: 1] multiply period by the occurrences before displaying * @param boolean $displayOne [default: true] displays also if only 1 unit of something * @param boolean $displayCalendarYearStart [default: true] displays start of calendar year if not January 1st * @return string */ private function _renderPeriodOfValiditiy( $varName, $occurrences = 1, $displayOne = true, $displayCalendarYearStart = true ) { // $ycdhmsArray = $this->_timedObject->getValidity( $varName ); // $prefix = ( $this->_timedObject->isCalendarValidity( $varName ) ? CBPTXT::T("calendar ") : '' ); // return $this->_timedObject->renderPeriod( $ycdhmsArray, $occurrences, $displayOne, $prefix ); $ycdhmsArray = $this->getValidity( $varName ); $prefix = ( $this->isCalendarValidity( $varName ) ? CBPTXT::T("calendar ") : '' ); $text = $this->renderPeriod( $ycdhmsArray, $occurrences, $displayOne, $prefix ); $calStart = $this->calendarYearStart( $varName ); if ( $prefix && ( $calStart != '01-01' ) && $displayCalendarYearStart ) { list( $m, $d ) = explode( '-', $calStart ); $text .= ' ' . CBPTXT::T("starting") . ' ' . date( 'F j', mktime( 0, 0, 0, $m, $d, 2004 ) ); } return $text; }
/** * Renders the rate of $this payment item * * @param string $variable * @param boolean $output 'html', ... * @param boolean $rounded * @return string|null */ private function renderTotalRate($variable, $output, $rounded = false) { $renderedBasketPrice = null; $params = cbpaidApp::settingsParams(); if ($params->get('totalizer_description_' . 'grandtotal') == '[AUTOMATIC]') { list($recurring, , $period, $occurrences) = $this->_itemsProps($this->_paymentBasket->loadPaymentItems()); $renderedBasketPrice = $this->_paymentBasket->renderPrice(null, null, null, true); if ($recurring && ($this->_paymentBasket->period1 && $this->_paymentBasket->mc_amount1 != $this->_paymentBasket->mc_amount3)) { $then = $this->_paymentBasket->renderPrice($this->_paymentBasket->mc_amount3, $period, $occurrences, true); $renderedBasketPrice = sprintf(CBPTXT::Th("%s, then %s"), $renderedBasketPrice, $then); } } else { parent::renderColumn($variable, $output, $rounded); } return $renderedBasketPrice; }
/** * Finds file and returns absolute file path * * @param string $layout one word name * @param string $extension '.php' or '.css' * @return string|null */ protected function _file_path( $layout, $extension ) { global $_CB_framework; $saneLayout = ( $layout ? preg_replace( '/\W/', '', strtolower( $layout ) ) : 'default' ) . $extension; if ( $extension === '.php' ) { $absPrefix = $_CB_framework->getCfg( 'absolute_path' ); $chkPrefix = ''; $saneLayout = $this->viewName . '/' . $saneLayout; } else { $absPrefix = ''; $chkPrefix = $_CB_framework->getCfg( 'absolute_path' ); } $cmsTemplate = $this->_cmsCurrentTemplate(); $overrideFilePath = '/templates/' . $cmsTemplate . '/html/com_comprofiler/' . $this->_overrideSubFolder . '/'; if ( $cmsTemplate && file_exists( $chkPrefix . $absPrefix . $overrideFilePath . $saneLayout ) ) { $this->_tmplUsedPath = $overrideFilePath; return $absPrefix . $overrideFilePath . $saneLayout; } else { $internalFilePath = '/components/com_comprofiler/' . $this->_defaultTemplatePath . '/' . $this->templateToUse() . '/'; if ( file_exists( $chkPrefix . $absPrefix . $internalFilePath . $saneLayout ) ) { $this->_tmplUsedPath = $internalFilePath; return $absPrefix . $internalFilePath . $saneLayout; } else { $defaultInternalFilePath = '/components/com_comprofiler/' . $this->_defaultTemplatePath . '/' . 'default' . '/'; if ( ( $this->templateToUse() != 'default' ) && file_exists( $chkPrefix . $absPrefix . $defaultInternalFilePath . $saneLayout ) ) { $this->_tmplUsedPath = $defaultInternalFilePath; return $absPrefix . $defaultInternalFilePath . $saneLayout; } else { // $method = '_render' . $layout; // if ( is_callable( array( $this, $method ) ) ) { // $this->$method(); // } else { trigger_error( sprintf( CBPTXT::T("CB View %s Layout %s has no rendering file %s."), $this->viewName, $saneLayout, $absPrefix . $internalFilePath . $saneLayout ), E_USER_NOTICE ); // } } } } return null; }
/** * If table key (id) is NULL : inserts a new row * otherwise updates existing row in the database table * * Can be overridden or overloaded by the child class * * @param boolean $updateNulls TRUE: null object variables are also updated, FALSE: not. * @return boolean TRUE if successful otherwise FALSE */ public function store($updateNulls = false) { if (!cbpaidApp::authoriseAction('cbsubs.refunds')) { $this->setError(CBPTXT::T("Not authorized")); return false; } // 1) check: if (!in_array($this->payment_status, array('Completed', 'Pending', 'Partially-Refunded'))) { $this->setError(CBPTXT::T("This payment is not completed, pending or partially refunded.")); return false; } if ($this->txn_id == '') { $this->txn_id = 'None'; // needed for updatePayment to generate payment record. } $payment = new cbpaidPayment(); if (!$payment->load((int) $this->id)) { $this->setError(CBPTXT::T("This payment does not exist.")); return false; } $paymentBasket = new cbpaidPaymentBasket(); if (!$paymentBasket->load($this->payment_basket_id)) { $this->setError(CBPTXT::T("This payment has no associated payment basket and cannot be refunded from here. Maybe from your PSP online terminal ?")); return false; } if (!$this->gateway_account) { $this->setError(CBPTXT::T("This payment has no gateway associated so can not be refunded.")); return false; } $payAccount = cbpaidControllerPaychoices::getInstance()->getPayAccount($this->gateway_account); if (!$payAccount) { $this->setError(CBPTXT::T("This payment's payment basket's associated gateway account is not active, so can not be refunded from here.")); return false; } $payClass = $payAccount->getPayMean(); $returnText = null; $amount = sprintf('%.2f', (double) $this->refund_gross); if (is_callable(array($payClass, 'refundPayment'))) { $success = $payClass->refundPayment($paymentBasket, $payment, null, $this->refund_is_last, $amount, $this->refund_reason, $returnText); } else { $success = false; } $user = CBuser::getUserDataInstance($paymentBasket->user_id); $username = $user ? $user->username : '******'; $replacements = array('[REFUNDAMOUNT]' => $payment->mc_currency . ' ' . $amount, '[PAYMENTID]' => $payment->id, '[PAYMENTAMOUNT]' => $payment->mc_currency . ' ' . $payment->mc_gross, '[BASKETID]' => $paymentBasket->id, '[ORDERID]' => $paymentBasket->sale_id, '[FULLNAME]' => $paymentBasket->first_name . ' ' . $paymentBasket->last_name, '[USERNAME]' => $username, '[USERID]' => $paymentBasket->user_id, '[PAYMENTMETHOD]' => $payClass->getPayName(), '[TXNID]' => $payment->txn_id, '[AUTHID]' => $payment->auth_id, '[ERRORREASON]' => $paymentBasket->reason_code); if ($success) { // Success Message ? // $returnText = CBPTXT::P("Refunded [REFUNDAMOUNT] for payment id [PAYMENTID] of [PAYMENTAMOUNT] for basket id [BASKETID], Order id [ORDERID] of [FULLNAME] (username [USERNAME] - user id [USERID]) using [PAYMENTMETHOD] with txn_id [TXNID] and auth_id [AUTHID].", $replacements ); } else { $this->setError(CBPTXT::T($payClass->getErrorMSG()) . '. ' . CBPTXT::P("Refund request of [REFUNDAMOUNT] for payment id [PAYMENTID] of [PAYMENTAMOUNT] for basket id [BASKETID], Order id [ORDERID] of [FULLNAME] (username [USERNAME] - user id [USERID]) using [PAYMENTMETHOD] with txn_id [TXNID] and auth_id [AUTHID] failed for reason: [ERRORREASON].", $replacements)); return false; } return true; }
?> <button type="submit" class="button" name="addcouponcode" value="1" style="position:absolute;left:-9999px;top:-9999px;height:0;width:0;">Add</button> <div class="cbregCouponsInputed"> <ul class="cbregListOfCouponsInputed"> <?php foreach ( $this->couponsUsed as $coupon ) { ?> <li> <span class="cbregCouponCode"><?php echo $coupon->coupon_code; ?></span><span class="cbregCouponCodeSAeparator">:</span> <span class="cbregCouponName"><?php echo $coupon->name; ?></span> <span class="cb_button_wrapper_small cpay_button_couponcode_wrapper cbregCouponDelete"><button type="submit" class="button" name="deletecouponcode[<?php echo $coupon->id;?>]" value="1"><?php echo CBPTXT::Th( $this->couponRemoveButtonText ); ?></button></span> </li> <?php } ?> </ul> </div> <?php } ?> <div class="cbregCouponInput"> <label for="cbsubscouponcode"><span><?php echo CBPTXT::Th( $this->couponLabelText ); ?></span></label> <input name="couponcode" id="cbsubscouponcode" type="text" /> <span class="cb_button_wrapper_small cpay_button_couponcode_wrapper"><button type="submit" class="button" name="addcouponcode" value="1"><?php echo CBPTXT::Th( $this->couponAddButtonText ); ?></button></span> <span class="cbsubscouponInstructions"><?php echo CBPTXT::Th( $this->couponDescription ); ?></span> <?php if ( count( $this->couponDescriptionHints ) > 0 ) { ?> <div class="cbsubscouponsHints"> <?php foreach ( $this->couponDescriptionHints as $htmlDescription ) { ?> <div class="cbsubsCouponsHint"> <?php echo $htmlDescription; ?> </div> <?php } ?> </div> <?php } ?> </div> </div>
/** * Returns a cbpaidGatewaySelectorButton object parameters for rendering an HTML form with a visible button and hidden fields for the gateway * Or a string with HTML content instead (not recommended) * * @param cbpaidPaymentBasket $paymentBasket paymentBasket object * @param string $subMethod 'single', 'subscribe' or gateway-specific string (e.g. credit-card brand) * @param string $paymentType 'single' or 'subscribe' or for subscriptions 'cancel' * @return cbpaidGatewaySelectorButton or string with HTML */ protected function getPayButtonRecepie( $paymentBasket, $subMethod, $paymentType ) { // Settings for Free Trial and Order Now buttons are stored in global CBSubs settings: $params = cbpaidApp::settingsParams(); // Generate URLs for payment: $pspUrl = $this->pspUrl( $paymentBasket, ( $paymentType == 'subscribe' ) ); $requestParams = $this->getSinglePaymentRequstParams( $paymentBasket ); $customImage = $params->get( $this->_button . '_custom_image' ); $titleText = ( $this->_button == 'freetrial' ? CBPTXT::T("Subscribe to free trial period only") : CBPTXT::T("Confirm Order") ); $altText = ( $this->_button == 'freetrial' ? CBPTXT::T("Free Trial") : CBPTXT::T("Confirm Order") ); $butId = 'cbpaidButt' . strtolower( $this->_button ); if ( $customImage == '' ) { $customImage = $params->get( $this->_button . '_image', 'components/com_comprofiler/plugin/user/plug_cbpaidsubscriptions/icons/cards/' . ( $this->_button == 'freetrial' ? 'cc_big_orange_free_trial.gif' : 'cc_big_orange_confirm_order.gif' ) ); } $payNameForCssClass = $this->_button; return cbpaidGatewaySelectorButton::getPaymentButton( $this->getAccountParam( 'id' ), $subMethod, $paymentType, $pspUrl, $requestParams, $customImage, $altText, $titleText, $payNameForCssClass, $butId ); }
<?php /** * @version $Id: $ * @package CBSubs (TM) Community Builder Plugin for Paid Subscriptions (TM) * @subpackage Template for Paid Subscriptions * @copyright (C) 2007-2015 and Trademark of Lightning MultiCom SA, Switzerland - www.joomlapolis.com - and its licensors, all rights reserved * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU/GPL version 2 */ /** ensure this file is being included by a parent file */ if (!(defined('_VALID_CB') || defined('_JEXEC') || defined('_VALID_MOS'))) { die('Direct Access to this location is not allowed.'); } $tmplVersion = 1; // This is the template version that needs to match ?> <div class="contentheading" id="cbregInvoicesTitle"><?php echo $this->plansTitle; ?> </div> <div class="cbregLinkToInvoices"> <a href="<?php echo $this->invoicesListUrl; ?> "> <?php echo CBPTXT::Th("Click here to view the list of invoices"); ?> </a> </div>
/** * Utility function to return title with description as hover * * @param CBSimpleXMLElement $node * @return null|string */ function _title(&$node) { $description = $node->attributes('description'); if ($description) { $description = CBPTXT::T($description); $name = $node->attributes('name'); return ' title="' . htmlspecialchars($name . '|' . $description) . '"'; } return null; }
/** * Computes text for the title of the invoices list * * @param int $invoicesNumber array of cbpaidPaymentBasket of Completed and Pending baskets * @param UserTable $user reflecting the user being displayed (here null) * @param boolean $itsmyself user is logged in user * @param string $periodText if non-empty, text of the period showing invoices * @return string */ protected function _invoicesTitle($invoicesNumber, $user, $itsmyself, $periodText) { global $ueConfig; if ($itsmyself) { if ($periodText) { $plansTitle = sprintf(CBPTXT::Th("Your invoices of last %s"), htmlspecialchars($periodText)); } else { if ($invoicesNumber == 1) { $plansTitle = CBPTXT::Th("Your invoice"); } else { $plansTitle = CBPTXT::Th("Your invoices"); } } } else { if ($periodText) { $plansTitle = sprintf(CBPTXT::Th("%s's invoices of last %s"), getNameFormat($user->name, $user->username, $ueConfig['name_format']), htmlspecialchars($periodText)); } else { $plansTitle = sprintf(CBPTXT::Th("%s's invoices"), getNameFormat($user->name, $user->username, $ueConfig['name_format'])); } } return $plansTitle; }
/** * Saves record payment view * * @param int $paymentBasketId * @return null|string */ public static function saveRecordPayment($paymentBasketId) { cbpaidApp::loadLang('admin'); $paymentRecorder = new self(); $exists = $paymentBasketId && $paymentRecorder->load((int) $paymentBasketId); if ($exists) { if ($paymentRecorder->authoriseAction('cbsubs.recordpayments')) { $return = $paymentRecorder->saveRecordPaymentForm(); } else { $return = CBPTXT::T("You are not authorized to record payments."); } } else { $return = CBPTXT::T("No unpaid payment basket found."); } return $return; }
/** * Prepares ARB request (check outside of this that amount is in USD !!!! * * @param string $arbRequestType : 'CreateSubscription', 'UpdateSubscription', 'CancelSubscription' * @param array|null $card : $card['type'], $card['number'], $card['firstname'], $card['lastname'], $card['expmonth'], $card['expyear'], and optionally: $card['address'], $card['zip'], $card['country'] * @param cbpaidPaymentBasket $paymentBasket WARNING: Using mc_amount3 as price as it's a subscription, instead of mc_gross. * @param string $subscriptionId * @return mixed string of XML request */ private function _encodeArbXmlRequest( $arbRequestType, $card, &$paymentBasket, $subscriptionId = null ) { $authorize_login_id = $this->ISOtoUtf8( $this->getAccountParam( 'authorize_login_id' ) ); $authorize_transaction_key = $this->ISOtoUtf8( $this->getAccountParam( 'authorize_transaction_key' ) ); $refId = $this->ISOtoUtf8( $paymentBasket->id ); if ( $arbRequestType != 'CancelSubscription' ) { // CreateSubscription or UpdateSubscription: $cardNumber = substr( preg_replace ( '/[^0-9]+/', '', strval( $card['number'] ) ), 0, 16 ); $cardExpirationDate = substr( strval( intval( $card['expyear'] ) ), 0, 4 ) . '-' . substr( sprintf( '%02d', intval( $card['expmonth'] ) ), 0, 2 ); $firstName = $this->_cbp_utf8_substr( $this->ISOtoUtf8( $card['firstname'] ), 0, 50 ); $lastName = $this->_cbp_utf8_substr( $this->ISOtoUtf8( $card['lastname'] ), 0, 50 ); $email = $this->_cbp_utf8_substr( $this->ISOtoUtf8( $paymentBasket->payer_email ), 0, 255 ); $country = ( isset( $card['country'] ) ? $this->_cbp_utf8_substr( $this->ISOtoUtf8( $card['country'] ), 0, 60 ) : null ); $zip = ( isset( $card['zip'] ) ? $this->_cbp_utf8_substr( $this->ISOtoUtf8( $card['zip'] ), 0, 20 ) : null ); $address = ( isset( $card['address'] ) ? $this->_cbp_utf8_substr( $this->ISOtoUtf8( $card['address'] ), 0, 60 ) : null ); if ( $arbRequestType == 'CreateSubscription' ) { $subscriptionName = $this->_cbp_utf8_substr( $this->ISOtoUtf8( $paymentBasket->item_name ), 0, 20 ); $subscriptionDescription = $this->_cbp_utf8_substr( $this->ISOtoUtf8( $paymentBasket->item_name ), 0, 255 ); $subscriptionTiming = $this->_computeSubscriptionTiming( $paymentBasket, 'noUpfrontFirstCharge', $card ); if ( $subscriptionTiming['totalOccurrences'] == 0 ) { return array( CBPTXT::T("Credit card expiry too short for subscribing to any automatically re-occurrings payments at this time.") . ' ' . CBPTXT::T("Please renew from your subscriptions in time.") ); } $amount = sprintf( '%.2f', $paymentBasket->mc_amount3 ); $trialAmount = null; if ( $paymentBasket->mc_currency != 'USD' ) { trigger_error('Authorize.net ARB API handles only USD, not ' . $paymentBasket->mc_currency, E_USER_ERROR ); } //Build XML to post $content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" . "<ARBCreateSubscriptionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">\n" . " <merchantAuthentication>\n" . " <name>" . htmlspecialchars( $authorize_login_id ) . "</name>\n" . " <transactionKey>" . htmlspecialchars( $authorize_transaction_key ) . "</transactionKey>\n" . " </merchantAuthentication>\n" . " <refId>" . htmlspecialchars( $refId ) . "</refId>\n" . " <subscription>\n" . " <name>" . htmlspecialchars( $subscriptionName ) . "</name>\n" . " <paymentSchedule>\n" . " <interval>\n" . " <length>" . htmlspecialchars( $subscriptionTiming['intervalLength'] ) . "</length>\n" . " <unit>" . htmlspecialchars( $subscriptionTiming['intervalUnit'] ) . "</unit>\n" . " </interval>\n" . " <startDate>" . htmlspecialchars( $subscriptionTiming['startDate'] ) . "</startDate>\n" . " <totalOccurrences>". htmlspecialchars( $subscriptionTiming['totalOccurrences'] ) . "</totalOccurrences>\n"; if ( $trialAmount ) { $content .= " <trialOccurrences>". '1' . "</trialOccurrences>\n"; } $content .= " </paymentSchedule>\n" . " <amount>" . htmlspecialchars( $amount ) . "</amount>\n"; if ( $trialAmount ) { $content .= " <trialAmount>" . htmlspecialchars( $trialAmount ) . "</trialAmount>\n"; } $content .= " <payment>\n" . " <creditCard>\n" . " <cardNumber>" . htmlspecialchars( $cardNumber ) . "</cardNumber>\n" . " <expirationDate>". htmlspecialchars( $cardExpirationDate ) . "</expirationDate>\n" . " </creditCard>\n" . " </payment>\n" . " <order>\n" . " <invoiceNumber>" . htmlspecialchars( $paymentBasket->invoice ? $paymentBasket->invoice : $paymentBasket->id ) . "</invoiceNumber>\n" . " <description>" . htmlspecialchars( $subscriptionDescription ) . "</description>\n" . " </order>\n" . " <customer>\n" . " <id>" . htmlspecialchars( $paymentBasket->user_id ) . "</id>\n" . " <email>" . htmlspecialchars( $email ) . "</email>\n" . " </customer>\n" . " <billTo>\n" . " <firstName>" . htmlspecialchars( $firstName ) . "</firstName>\n" . " <lastName>" . htmlspecialchars( $lastName ) . "</lastName>\n" . ( $address !== null ? " <address>" . htmlspecialchars( $address ) . "</address>\n" : '' ) . ( $zip !== null ? " <zip>" . htmlspecialchars( $zip ) . "</zip>\n" : '' ) . ( $country !== null ? " <country>" . htmlspecialchars( $country ) . "</country>\n" : '' ) . " </billTo>\n" . " </subscription>\n" . "</ARBCreateSubscriptionRequest>\n"; } elseif ( $arbRequestType == 'UpdateSubscription' ) { //Build XML to post $content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" . "<ARBUpdateSubscriptionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">\n" . " <merchantAuthentication>\n" . " <name>" . htmlspecialchars( $authorize_login_id ) . "</name>\n" . " <transactionKey>" . htmlspecialchars( $authorize_transaction_key ) . "</transactionKey>\n" . " </merchantAuthentication>\n" . " <refId>" . htmlspecialchars( $refId ) . "</refId>\n" . " <subscriptionId>" . htmlspecialchars( $subscriptionId ) . "</subscriptionId>\n" . " <subscription>\n" . " <payment>\n" . " <creditCard>\n" . " <cardNumber>" . htmlspecialchars( $cardNumber ) . "</cardNumber>\n" . " <expirationDate>". htmlspecialchars( $cardExpirationDate ) . "</expirationDate>\n" . " </creditCard>\n" . " </payment>\n" . " <customer>\n" . " <id>" . htmlspecialchars( $paymentBasket->user_id ) . "</id>\n" . " <email>" . htmlspecialchars( $email ) . "</email>\n" . " </customer>\n" . " <billTo>\n" . " <firstName>" . htmlspecialchars( $firstName ) . "</firstName>\n" . " <lastName>" . htmlspecialchars( $lastName ) . "</lastName>\n" . ( $address !== null ? " <address>" . htmlspecialchars( $address ) . "</address>\n" : '' ) . ( $zip !== null ? " <zip>" . htmlspecialchars( $zip ) . "</zip>\n" : '' ) . ( $country !== null ? " <country>" . htmlspecialchars( $country ) . "</country>\n" : '' ) . " </billTo>\n" . " </subscription>\n" . "</ARBUpdateSubscriptionRequest>\n"; } else { $content = null; } } else { // 'CancelSubscription': //Build XML to post $content = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" . "<ARBCancelSubscriptionRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">\n" . " <merchantAuthentication>\n" . " <name>" . htmlspecialchars( $authorize_login_id ) . "</name>\n" . " <transactionKey>" . htmlspecialchars( $authorize_transaction_key ) . "</transactionKey>\n" . " </merchantAuthentication>\n" . " <refId>" . htmlspecialchars( $refId ) . "</refId>\n" . " <subscriptionId>" . htmlspecialchars( $subscriptionId ) . "</subscriptionId>\n" . "</ARBCancelSubscriptionRequest>\n"; } return $content; }
/** * Displays $text inside a standard CB div, and sets page title and pathway too * * @param string $text * @return string */ public static function displayWithTemplate($text) { global $_CB_framework; $regTitle = strip_tags(CBPTXT::T(cbpaidApp::settingsParams()->get('regTitle', "Subscriptions"))); outputCbTemplate(); $_CB_framework->setPageTitle($regTitle); $_CB_framework->appendPathWay($regTitle); $pre = '<div class="cbPageOuter"><div class="cbPageInner" id="cbregField">'; $post = '</div></div><div class="cbClr"> </div>'; return $pre . $text . $post; }
/** * Auxiliary function for replacing texts when extending XML * <replaces translate="yes"><replace attribute="label OR [DATA]" from="{source}" to="target" /> * * @param CBSimpleXMLElement|string|array $sourceData * @param CBSimpleXMLElement $sourceNode * @param CBSimpleXMLElement $destinationParentNode * @param CBObject $paramsView */ static function _substituteChildTexts( $sourceData, $sourceNode = null, $destinationParentNode = null, $paramsView = null ) { static $substitutions = array(); if ( is_array( $sourceData ) ) { // that is $source->attributes(): $return = array(); foreach ($sourceData as $k => $v ) { if ( isset( $substitutions[$k] ) ) { $v = str_replace( $substitutions[$k]['from'], $substitutions[$k]['to'], $v ); if ( $substitutions[$k]['translate'] ) { $v = CBPTXT::T( $v ); } } $return[$k] = $v; } } elseif ( is_string( $sourceData ) ) { // that is $source->data(): if ( isset( $substitutions['[DATA]'] ) ) { $k = '[DATA]'; $return = str_replace( $substitutions[$k]['from'], $substitutions[$k]['to'], $sourceData ); if ( $substitutions[$k]['translate'] ) { $return = CBPTXT::T( $return ); } } else { $return = $sourceData; } } elseif ( is_object( $sourceData ) ) { // initialize replacements: $substitutions = array(); foreach ($sourceData->children() as $replaceRule ) { $substitutions[$replaceRule->attributes( 'attribute' )]['from'][] = $replaceRule->attributes( 'from' ); $substitutions[$replaceRule->attributes( 'attribute' )]['to'][] = ( $replaceRule->attributes( 'type' ) == 'datavalue:string' ? $paramsView->get( $replaceRule->attributes( 'to' ) ) : $replaceRule->attributes( 'to' ) ); $substitutions[$replaceRule->attributes( 'attribute' )]['translate'] = $replaceRule->attributes( 'translate' ) === 'yes'; } $return = null; } return $return; }
/** * Returns substitution strings * * @see cbpaidSomething::substitutionStringsForItemDetailed() * * @param boolean $html HTML or TEXT return * @param string $reason 'N' new subscription, 'R' renewal, 'U'=update ) * @param boolean $autorecurring TRUE: is autorecurring, no real expiration date, FALSE: is not autorecurring * @return array */ public function substitutionStringsForItemDetailed( /** @noinspection PhpUnusedParameterInspection */ $html, $reason, $autorecurring ) { global $_CB_framework; $user = CBuser::getUserDataInstance( $this->user_id ); $prefixText = ''; $params =& cbpaidApp::settingsParams(); $extraStrings = array( 'ITEM_NAME' => $this->getPlan()->getPersonalized( 'name', $this->user_id, false ), // CBPTXT::T( $this->getText( 'name' ) ), 'ITEM_ALIAS' => CBPTXT::T( $this->getText( 'alias' ) ), 'ITEM_DESCRIPTION' => $this->getPlan()->getPersonalized( 'description', $this->user_id, false ), //strip_tags( CBPTXT::T( $this->getText( 'description' ) ) ), 'SITENAME' => $_CB_framework->getCfg( 'sitename' ), 'SITEURL' => $_CB_framework->getCfg( 'live_site' ), 'PLANS_TITLE' => strip_tags( CBPTXT::T( $params->get( 'regTitle' ) ) ), 'EMAILADDRESS' => $user->email, 'PREFIX_TEXT' => $prefixText ); return $extraStrings; }
/** * Gives links for maintenance of an invoice/basket in the list of invoices in frontend * * @return array of HTML links */ public function renderMaintenanceButtonsHtml( ) { $html = array(); if ( $this->authoriseAction( 'cbsubs.recordpayments' ) ) { if ( $this->payment_status == 'Pending') { $html[] = '<a href="' . cbpaidApp::getBaseClass()->getRecordPaymentUrl( $this ) . '" class="cbregLinkRecordPayment">' . CBPTXT::Th("Record offline payment") . '</a>'; } } return $html; }
/** * Get a correct display of the formatted validity of a plan * * @return string Formatted text giving validity of this subscription */ public function getFormattedValidityRemaining() { if ( ( $this->status == 'A' ) && ( $this->expiry_date == '0000-00-00 00:00:00' ) ) { $params =& cbpaidApp::settingsParams(); return CBPTXT::T( $params->get( 'regtextLifetime', 'Lifetime Subscription' ) ); } else { $occurrence = $this->regular_recurrings_used; if ( $occurrence > 0 ) { $reason = 'R'; } elseif ( $this->replaces_plan && $this->replaces_subscription ) { $reason = 'U'; } else { $reason = 'N'; } $varName = $this->getPlan()->getPlanVarName( $reason, $occurrence, 'validity' ); return $this->getPlan()->getFormattedValidity( $this->getPlan()->strToTime( $this->expiry_date ), $this->getPlan()->strToTime( $this->subscription_date ), $varName ); } }
/** * This is the handler for current version * * @return string */ public static function currentVersion( ){ $licenseMgr =& self::getInstance(); return CBPTXT::T("Version") . ' ' . $licenseMgr->version . ' ' . $licenseMgr->versionminor . '.'; }
/** * Redirects expired user to the re-subscription screen. * @access private * @param int $userId */ protected function _redirectExpiredMembership($userId) { global $_CB_framework; $params = cbpaidApp::settingsParams(); $paidUserExtension = cbpaidUserExtension::getInstance($userId); $expiredSubscriptions = $paidUserExtension->getUserSubscriptions('X'); // check if there is any expired extensions for the text if (count($expiredSubscriptions) > 0) { $textMessage = $params->get('subscriptionExpiredText', "Your membership has expired."); $expiredRedirectLink = $params->get('subscriptionExpiredRedirectLink'); } else { $textMessage = $params->get('subscriptionNeededText', "A membership is needed for access."); $expiredRedirectLink = $params->get('subscriptionNeededRedirectLink'); } if (!$expiredRedirectLink) { $baseClass = cbpaidApp::getBaseClass(); if ($baseClass) { $expiredRedirectLink = $baseClass->_getAbsURLwithParam(array('Itemid' => 0, 'account' => 'expired', 'user' => (int) $userId), 'pluginclass', false); } else { // without baseClass, as baseClass is not loaded in case of cbpaidsubsbot: $cbpPrefix = 'cbp'; $expiredRedirectLink = 'index.php?option=com_comprofiler&task=pluginclass&plugin=cbpaidsubscriptions&' . $cbpPrefix . 'account=expired&user='******'index.php?option=com_comprofiler&task=pluginclass&plugin=cbpaidsubscriptions&do=display_subscriptions'; // &Itemid= ??? } if ($userId) { $_SESSION['cbsubs']['expireduser'] = $userId; } } if ($_CB_framework->getRequestVar('option') != 'com_comprofiler' || $_CB_framework->getRequestVar('task') != 'pluginclass' || $_CB_framework->getRequestVar('plugin') != 'cbpaidsubscriptions') { cbRedirect(cbSef($expiredRedirectLink, false), CBPTXT::T($textMessage), 'warning'); } }
/** * gets the chosen plans from the form, and checks if they are allowed for that user * also gets the options of the plans * In detail: * gets an array of array of int as an array of int (removing first level), verifying that if index is not 0 the parent exists * In each plan object there is a ->_options variable with a Registry object with the option values of the plan * * @param UserTable $user Reflecting the user being registered or saved * @param string $name name of parameter in REQUEST URL * @param cbpaidProduct[] $allowedPlans array of cbpaidProduct which are allowed * @param boolean $isRegistration TRUE: Registration process (guest), or FALSE: upgrade-process (logged-in user) * @param string $reason Subscription reason: 'N'=new subscription (default), 'R'=renewal, 'U'=update * @param boolean $returnPlans TRUE: returns plan objects or FALSE: returns plan ids only. * @param string $postfix postfix for identifying multiple plans spaces (optional) * @return int[]|cbpaidProduct[]|string ARRAY of int|of cbpaidProducts : Plans which are selected within hierarchy (according to the post, to be rechecked !) or STRING: error message. */ protected function & _planGetAndCheckReqParamArray( &$user, $name, &$allowedPlans, $isRegistration, $reason, $returnPlans = false, $postfix = '' ) { global $_CB_framework, $_POST; $params =& cbpaidApp::settingsParams(); $enableFreeRegisteredUser = $params->get( 'enableFreeRegisteredUser', 1 ); $createAlsoFreeSubscriptions = $params->get( 'createAlsoFreeSubscriptions', 0 ); $ui = $_CB_framework->getUi(); if ( ! $isRegistration ) { if ( $ui == 1 ) { $userId = (int) cbGetParam( $_POST, 'user', 0 ); } else { $userId = (int) cbGetParam( $_POST, 'id', 0 ); } } else { $userId = null; } $selectedPlanIds = $this->_plangetReqParamArray( $name, $postfix ); /// $validSub = array(); // 1. checks that selected plans hierarchy is respected: $ok = true; $plansMgr = null; foreach ( $selectedPlanIds as $id ) { if ( $id != 0 ) { // ignore "None" plan in backend edit profile $ok = false; // foreach ( $allowedPlans as $planid => $p ) { if ( isset( $allowedPlans[(int) $id] ) ) { $p = $allowedPlans[(int) $id]; if ( $id == $p->id ) { $parentOk = true; $parentId = $p->get( 'parent' ); if ( $parentId != 0 ) { // the selected plan has a parent plan: check if parent plan is also chosen or already subscribed and active: $parentOk = false; foreach ($selectedPlanIds as $selPlanId ) { if ( $parentId == $selPlanId ) { $parentOk = true; break; } } if ( ( ! $isRegistration ) && ( ! $parentOk ) ) { // try to see if user is subscribed already to the parent plan: if ( $userId ) { if ( $plansMgr === null ) { $plansMgr =& cbpaidPlansMgr::getInstance(); } $plan = $plansMgr->loadPlan( $parentId ); /** @var $plan cbpaidProduct */ if ( $plan ) { // Check if allow free lifetime users without need to create such subscriptions: if ( $enableFreeRegisteredUser && ( ! $createAlsoFreeSubscriptions ) && $plan->isLifetimeValidity() && $plan->isFree() ) { $parentOk = true; } else { $sub = $plan->newSubscription(); /** @var $sub cbpaidSomething */ if ( $sub->loadValidUserSubscription( $userId ) ) { $parentOk = true; /// $validSub[$parentId] = $sub->id; } } } } } } if ( $parentOk ) { $ok = true; } break; } } if ( ! $ok ) { break; } } } if ( ! $ok ) { $selectedPlanIds = CBPTXT::T("Chosen plans combination is not allowed (you must choose coherent plans selection, e.g. parent subscriptions to a plan must be active)."); } else { // 2. Check that all exclusivities are respected: $plansMgr =& cbpaidPlansMgr::getInstance(); // 2.a. build array of exclusive [parent][plan]: $exclusiveChildren = array(); // 2.a.1. add the plans just selected now: foreach ($allowedPlans as $id => $p ) { if ( $p->get( 'exclusive' ) ) { $exclusiveChildren[$p->get( 'parent' )][$p->get( 'id' )] = ( in_array( $id, $selectedPlanIds ) ? 1 : 0 ); } } // 2.a.2. add the plans already subscribed with active subscription (if we are not just upgrading that level): $ValidUserPlans = array(); $validSubExists = array(); if ( ( ! $isRegistration ) && $userId ) { foreach ( $exclusiveChildren as $parentId => $exclPlansArray ) { if ( $parentId != 0 ) { $plan = $plansMgr->loadPlan( $parentId ); if ( $plan ) { $sub = $plan->newSubscription(); $ValidUserPlans[$parentId] = ( $sub->loadValidUserSubscription( $userId ) ); } else { $selectedPlanIds = CBPTXT::T("Chosen plan has a parent plan configured that doesn't exist anymore."); } } $numberOfSelected = array_sum( $exclPlansArray ); if ( $numberOfSelected == 0 ) { $firstFreeLifeTime = array(); // foreach ( $exclPlansArray as $childId => $selected ) foreach ( array_keys( $exclPlansArray ) as $childId ) { $plan = $plansMgr->loadPlan( $childId ); if ( ( ! isset( $firstFreeLifeTime[$parentId] ) ) && ( $enableFreeRegisteredUser && ( ! $createAlsoFreeSubscriptions ) && $plan->isLifetimeValidity() && $plan->isFree() ) ) { $firstFreeLifeTime[$parentId] = $plan->get( 'id' ); } if ( ! isset( $ValidUserPlans[$childId] ) ) { $sub = $plan->newSubscription(); $ValidUserPlans[$childId] = ( $sub->loadValidUserSubscription( $userId ) ); } if ( $ValidUserPlans[$childId] ) { $exclusiveChildren[$parentId][$childId] = 1; $validSubExists[$parentId] = 1; } } } } } // 2.b. check that exactly 1 exclusive plan is selected at each level (including still valid subscribed plans) which matters: if ( ! ( ( $ui == 2 ) && ( $selectedPlanIds == array( '0' ) ) ) ) { // ignore "None" plan in backend edit profile foreach ( $exclusiveChildren as $parentId => $exclPlansArray ) { $numberOfSelected = array_sum( $exclPlansArray ); if ( $numberOfSelected > 1 ) { $selectedPlanIds = CBPTXT::T("Chosen plans combination is not allowed (you can't choose more than one mandatory plan).") . $numberOfSelected; break; } elseif ( ( $numberOfSelected == 0 ) && ( ! isset( $validSubExists[$parentId] ) ) && ( ! isset( $firstFreeLifeTime[$parentId] ) ) ) { if ( ( $parentId == 0 ) || in_array( $parentId, $selectedPlanIds ) || ( isset( $ValidUserPlans[$parentId] ) && ( $ValidUserPlans[$parentId] == true ) ) ) { $selectedPlanIds = CBPTXT::T("Chosen plans combination is not allowed (you must choose coherent plans selection, e.g. mandatory subscription(s) must be active or mandatory plan(s) must be chosen)."); $names = array(); foreach ( array_keys( $exclPlansArray ) as $childId ) { $exclPlan =& $plansMgr->loadPlan( $childId ); /** @var $exclPlan cbpaidProduct */ $names[] = $exclPlan->get( 'name' ); } if ( $parentId ) { $parentPlan =& $plansMgr->loadPlan( $parentId ); /** @var $parentPlan cbpaidProduct */ $parentName = $parentPlan->get( 'name' ); $selectedPlanIds .= ' ' . CBPTXT::T( sprintf( "'%s' has mandatory options '%s' and none is selected." , $parentName, implode( "', '", $names ) ) ); } break; } } } } // 3. Checks that all selected plans' conditions are met: if ( is_array( $selectedPlanIds ) ) { foreach ( $selectedPlanIds as $id ) { if ( $id ) { $plan =& $plansMgr->loadPlan( $id ); if ( $plan ) { if ( ! $plan->checkActivateConditions( $user, $reason, $selectedPlanIds ) ) { // Error text will be in selectedPlanIds in case of error returning false: break; } } } } } // 4. Checks done: if ( $returnPlans && is_array( $selectedPlanIds ) && ( count( $selectedPlanIds ) > 0 ) ) { // if returning selected plans, sort them in same order and with same keys as corresponding allowed plans: global $_PLUGINS; $_PLUGINS->loadPluginGroup( 'user', 'cbsubs.' ); $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin'); $selectedPlans = array(); foreach ($allowedPlans as $id => $p ) { if ( in_array( $id, $selectedPlanIds ) ) { /** @var cbpaidProduct[] $selectedPlans */ $selectedPlans[(int) $id] = $allowedPlans[$id]; $selectionId = 'plan' . $id; $selectionName = 'plan' . ( $selectedPlans[$id]->get( 'exclusive' ) ? 'E' : 'N' ) . '[' . (int) $selectedPlans[$id]->parent . ']'; $selectionValue = $id; $view = $selectedPlans[$id]->getViewer(); $paramsOrString = $view->getOptions( $selectionId, $selectionName, $selectionValue, $reason ); if ( is_string( $paramsOrString ) ) { $selectedPlans = $paramsOrString; // error message break; } $selectedPlans[(int) $id]->_options = $paramsOrString; $selectedPlans[(int) $id]->_integrations = new Registry( '' ); $_PLUGINS->trigger( 'onCPayAfterPlanSelected', array( &$selectedPlans[(int) $id], &$selectedPlans[(int) $id]->_integrations , $reason ) ); if ( $_PLUGINS->is_errors() ) { $selectedPlans = $_PLUGINS->getErrorMSG(); break; } } } return $selectedPlans; } } return $selectedPlanIds; }