/**
  * 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();
 }
Example #5
0
	/**
	 * 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);
 }
Example #7
0
	/**
	 * 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 ? '&nbsp;-&nbsp;' : ' - ') . 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 ? '&nbsp;-&nbsp;' : ' - ') . 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;
 }
Example #12
0
	/**
	 * 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;
 }
Example #16
0
?>
	<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;
 }
Example #24
0
	/**
	 * 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;
	}