/** * returns HTML code to show the currently subscribed plans * @access private * * @param int $now Unix-time * @param UserTable $user Reflecting the user being displayed * @param cbpaidUsersubscriptionRecord[] $subscriptions array of cbpaidUsersubscriptionRecord : subscriptions already checked by getUpgradeAndRenewalPossibilities() * @param string $plansTitle * @param boolean $showRenewButtons Draw the Renew and Resubscribe buttons * @param boolean $showUnsubscribeButtons Draw the Unsubscribe button * @return string HTML for display */ protected function _getSubscribedPlans( /** @noinspection PhpUnusedParameterInspection */ $now, &$user, &$subscriptions, $plansTitle, $showRenewButtons, $showUnsubscribeButtons ) { //TBD: most of this belongs to subscriptionsMgr object global $_CB_framework, $_PLUGINS; $_PLUGINS->loadPluginGroup( 'user', 'cbsubs.' ); $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin'); $return = null; if ( count($subscriptions) > 0 ) { $now = $_CB_framework->now(); $return .= "\n<div class='regPlansList' id='cbregSubscr'>"; $subIds = array_reverse( array_keys( $subscriptions ) ); // get plans in reverse order to draw all children first $children = array(); foreach ( $subIds AS $id ) { if ( isset( $children[(int) $subscriptions[$id]->getPlanAttribute( 'id' )] ) ) { $childrenRendering = implode( "\n", $children[(int) $subscriptions[$id]->getPlanAttribute( 'id' )] ); unset( $children[(int) $subscriptions[$id]->getPlanAttribute( 'id' )] ); } else { $childrenRendering = null; } $controlButtons = $this->_drawSubscriptionButtons( $subscriptions[$id], $showRenewButtons, $showUnsubscribeButtons, $now, $user ); $_PLUGINS->trigger( 'onCPayBeforeDrawSomething', array( &$subscriptions[$id], &$childrenRendering, &$controlButtons, $showRenewButtons, $showUnsubscribeButtons, $now, $user ) ); $childrenRendering .= $controlButtons; $template = $subscriptions[$id]->getPlan()->getTemplateOutoutCss(); /** @var $view cbpaidSomethingView */ $view = cbpaidTemplateHandler::getViewer( $template, 'something' ); $view->setModel( $subscriptions[$id] ); $render = $view->drawSomethingNameDescription( $now, $childrenRendering ); $_PLUGINS->trigger( 'onCPayAfterDrawSomething', array( &$subscriptions[$id], &$render, $now, $user ) ); if ( ! isset( $children[(int) $subscriptions[$id]->getPlanAttribute( 'parent' )] ) ) { $children[(int) $subscriptions[$id]->getPlanAttribute( 'parent' )] = array(); } array_unshift( $children[(int) $subscriptions[$id]->getPlanAttribute( 'parent' )], $render ); } foreach ( array_keys( $children ) as $k ) { $children[$k] = implode( "\n", $children[$k] ); } $return .= implode( "\n", $children ) . "\n"; $return .= "</div>\n"; } return $return; }
/** * Outputs cbpaidsubscriptions registration template CSS file * * @param string $template Template to use (default is 'default') * @return void */ public function outputRegTemplate($template = '') { global $_CB_framework; static $dones = array(); if (!isset($dones[$template])) { $inBackend = $_CB_framework->getUi() == 2; if (!$inBackend || $template == '') { cbpaidTemplateHandler::getViewer($inBackend ? 'default' : $template, null)->outputTemplateCss('cbpaidsubscriptions'); if ($inBackend) { $_CB_framework->document->addHeadStyleSheet('/components/com_comprofiler/plugin/user/plug_cbpaidsubscriptions/templates/default/cbpaidsubscriptions.admin.css'); } } $dones[$template] = true; } }
/** * Displays user subscription and link to invoice HTML (if allowed) * * @param UserTable $user * @param string $htmlTabDescription * @return string */ public function displaySubscriptionsAndInvoicesLink( $user, $htmlTabDescription = null ) { global $_CB_framework; $return = ''; $params = $this->params; $itsmyself = ( $_CB_framework->myId() == $user->id ); $displayToMe = $itsmyself; if ( ! $itsmyself ) { $displayToMe = cbpaidApp::authoriseAction( 'cbsubs.usersubscriptionview' ); if ( $displayToMe ) { $itsmyself = cbpaidApp::authoriseAction( 'cbsubs.usersubscriptionmanage' ); } } if ( $user->id && $displayToMe ) { $basketsMgr =& cbpaidOrdersMgr::getInstance(); $basketsMgr->timeoutUnusedBaskets( $user->id ); $subscriptionsGUI = new cbpaidControllerUI(); $htmlSubscriptionsAndUpgrades = $subscriptionsGUI->getShowSubscriptionUpgrades( $user, $itsmyself ); $htmlInvoicesLink = null; $showInvoices = $params->get( 'show_invoices', 1 ); $invoicesShowPeriod = $params->get( 'invoices_show_period', '0000-06-00 00:00:00' ); if ( $showInvoices ) { $invoicesNumber = $this->_getInvoices( $user, $invoicesShowPeriod, true ); if ( $invoicesNumber > 0 ) { $invoicesListUrl = $this->getInvoicesListUrl( $user ); if ( $invoicesShowPeriod && ( $invoicesShowPeriod != '0000-00-00 00:00:00' ) ) { $cbpaidTimes =& cbpaidTimes::getInstance(); $periodText = $cbpaidTimes->renderPeriod( $invoicesShowPeriod, 1, false ); } else { $periodText = ''; } $htmlInvoicesLink = $subscriptionsGUI->showInvoicesListLink( $invoicesNumber, $invoicesListUrl, $user, $itsmyself, $periodText ); } } $tabTitleText = $params->get( 'profileTitle', "Your subscriptions" ); /** @var $viewer cbpaiduserprofilesubstabView */ $viewer = cbpaidTemplateHandler::getViewer( null, 'userprofilesubstab' ); $viewer->setModel( $user ); $return .= $viewer->drawTab( $htmlSubscriptionsAndUpgrades, $htmlInvoicesLink, $tabTitleText, $htmlTabDescription ); } return $return; }
/** * Render the payment possibilities as radios, buttons, or URL for redirect of browser * * @param cbpaidPaymentRadio[][] $payChoicesHtmlArray * @param cbpaidPaymentBasket $paymentBasket * @param string $redirectNow * @param string $chosenPaymentMethod * @param array $payChoicesHtmlRadiosArray OUT * @param cbpaidGatewaySelector|null $chosenPaymentSelector OUT * @return string */ private function _renderPayChoicesArray( $payChoicesHtmlArray, $paymentBasket, $redirectNow, $chosenPaymentMethod, &$payChoicesHtmlRadiosArray, &$chosenPaymentSelector ) { $ret = array(); $chosenPaymentSelector = null; if ( ( $redirectNow == 'redirect' ) || ( $redirectNow === true ) ) { foreach ( $payChoicesHtmlArray as $drawParams ) { if ( is_array( $drawParams ) ) { if ( is_string( $drawParams[0] ) ) { // Redirect is possible: Just return URL: $ret = $drawParams[0]; } else { // Redirect is wished but instead we got a button, as redirect was not possible (e.g. URL > 2k IE limit with Paypal encrypted payments): /** @var $renderer cbpaidBasketView */ $renderer = cbpaidTemplateHandler::getViewer( null, 'basket' ); $ret[] = $renderer->drawPaymentButton( $drawParams[0] ); } } } } elseif ( $redirectNow == 'radios' ) { $payment_method_radios_template = cbpaidApp::settingsParams()->get( 'payment_method_radios_template', '' ); /** @var $renderer cbpaidBasketView */ $renderer = cbpaidTemplateHandler::getViewer( $payment_method_radios_template, 'basket' ); $renderer->setModel( $paymentBasket ); foreach ( $payChoicesHtmlArray as $gatewaySubMethods ) { if ( is_array( $gatewaySubMethods ) ) { foreach ( $gatewaySubMethods as $radioPaymentSelector ) { /** @var $radioPaymentSelector cbpaidGatewaySelectorRadio */ $radioValue = $radioPaymentSelector->radioValue(); $selected = ( $chosenPaymentMethod === $radioValue ); if ( $selected ) { $chosenPaymentSelector = $radioPaymentSelector; } $payChoicesHtmlRadiosArray[] = array( $selected, $renderer->drawPaymentRadio( $radioPaymentSelector, $selected ) ); } } elseif ( is_string( $gatewaySubMethods ) ) { $ret[] = $gatewaySubMethods; } } } else { /** @var $renderer cbpaidBasketView */ $renderer = cbpaidTemplateHandler::getViewer( null, 'basket' ); $renderer->setModel( $paymentBasket ); foreach ( $payChoicesHtmlArray as $gatewaySubMethods ) { if ( is_array( $gatewaySubMethods ) ) { foreach ( $gatewaySubMethods as $paymentButton ) { $ret[] = $renderer->drawPaymentButton( $paymentButton ); } } elseif ( is_string( $gatewaySubMethods ) ) { $ret[] = $gatewaySubMethods; } } } return $ret; }
/** * Draws a subscription's name and description... * * @param int|null $now unix time for the expiration times (null: now) * @param string $insertAfterDescription HTML text to insert after this item as sub-items * @param boolean $showStateCheckMark * @return string */ public function drawSomethingNameDescription($now, $insertAfterDescription, $showStateCheckMark = true) { global $_CB_framework, $_PLUGINS; /** @var $subscription cbpaidUsersubscriptionRecord */ $subscription = $this->_model; $params = cbpaidApp::settingsParams(); $showtime = $params->get('showtime', '1') == '1'; $subTxt = CBPTXT::T($params->get('subscription_name', 'subscription')); $titlesTexts = array('A' => sprintf(CBPTXT::T("Active %s"), $subTxt), 'AA' => sprintf(CBPTXT::T("Active %s"), $subTxt), 'R' => sprintf(CBPTXT::T("%s not yet paid"), ucfirst($subTxt)), 'U' => sprintf(CBPTXT::T("Upgraded %s"), $subTxt), 'C' => sprintf(CBPTXT::T("Unsubscribed %s"), $subTxt), 'X' => sprintf(CBPTXT::T("Expired %s"), $subTxt), 'XX' => sprintf(CBPTXT::T("Inactive (parent %s not active)"), $subTxt), 'ZZ' => sprintf(CBPTXT::T("Unknown state of %s"), $subTxt)); // local state //TODO use getFormattedExpirationDateText() $stateTexts = array('A' => CBPTXT::T("Active"), 'AA' => CBPTXT::T("Active, expiring on %s"), 'R' => CBPTXT::T("Not yet paid"), 'U' => CBPTXT::T("Upgraded to higher plan on %s"), 'C' => CBPTXT::T("Unsubscribed on %s"), 'X' => CBPTXT::T("Expired %s"), 'XX' => sprintf(CBPTXT::T("Inactive (parent %s not active)"), $subTxt), 'ZZ' => sprintf(CBPTXT::T("Unknown state of %s"), $subTxt)); // local state $autoRenewingText = CBPTXT::T("%s, auto-renewing"); $autoRenewingXtimes = CBPTXT::T("%s, auto-renewing %s more times until %s"); // check if active and if parents are active: $realStatus = $subscription->realStatus($now); $subActive = $subscription->checkIfValid($now); $subAndParentsActive = $subscription->checkIfThisAndParentSubscriptionIsValid($now); if ($subActive && !$subAndParentsActive) { $status = 'XX'; } else { // compute local pseudo status, which is subscription status and 2 local states: AA and ZZ: $status = $realStatus; if (!array_key_exists($realStatus, $titlesTexts)) { $status = 'ZZ'; } if ($status == 'A' && !$subscription->isLifetimeValidity()) { $status = 'AA'; } } if ($status == 'ZZ' && $_CB_framework->getUi() == 1) { // if status is unknown, don't display it in frontend, only in backend ! return $insertAfterDescription; } $viewModel = new cbpaidSomethingViewModel(); $viewModel->subscription = $subscription; $viewModel->name = $subscription->getPlan()->getPersonalized('name', $subscription->user_id, true); $viewModel->description = $subscription->getPlan()->getPersonalized('description', $subscription->user_id, true); $viewModel->cssclass = $subscription->getPlanAttribute('cssclass'); $viewModel->active = $subAndParentsActive; $viewModel->validity = htmlspecialchars($subscription->getFormattedValidityRemaining()); $viewModel->title = htmlspecialchars($titlesTexts[$status]); // Prepare the exact description text for the status: if ($subscription->expiry_date && !($subscription->status == 'X' && $subActive)) { $expDate = cbFormatDate($subscription->expiry_date, 1, $showtime); } else { $expDate = ''; } $stateText = sprintf($stateTexts[$status], $expDate); // add information of auto-renewals if autorecurring and all autorecurrings are not yet done: if ($subscription->autorecurring_type > 0 && $status == 'AA' && ($subscription->regular_recurrings_total == 0 || $subscription->regular_recurrings_used < $subscription->regular_recurrings_total)) { if ($subscription->autorecurring_type == 2 && $subscription->regular_recurrings_total && $subscription->regular_recurrings_used < $subscription->regular_recurrings_total) { $occurrences = $subscription->regular_recurrings_total - $subscription->regular_recurrings_used; $finalExpTime = $subscription->computeExpiryTimeIfActivatedNow($now, 'R', $occurrences); $finalExpTxt = cbFormatDate($finalExpTime, 1, $showtime); // '%s, auto-renewing %s more times until %s' : $stateText = sprintf($autoRenewingXtimes, $stateText, $occurrences, $finalExpTxt); } else { // '%s, auto-renewing' : $stateText = sprintf($autoRenewingText, $stateText); } } $viewModel->stateText = htmlspecialchars($stateText); //TBD ???? $plan->displayPeriodPrice( 'R', $sub->getOccurrence() + 1, null, $plan->strToTime( $sub->expiry_date ), false ); $_PLUGINS->loadPluginGroup('user', 'cbsubs.'); $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin'); $insertBeforeValidity = implode('', $_PLUGINS->trigger('onCPayBeforeDrawSubscription', array(&$viewModel, &$subscription, &$insertAfterDescription))); /** @var $view cbpaidsomethingusersubscriptionView */ $view = cbpaidTemplateHandler::getViewer($this->templateToUse(), 'somethingusersubscription', 'html'); //TBD extend to any Something (merchandises, donations) $view->setModel($viewModel); return $view->drawSomething($insertBeforeValidity, $insertAfterDescription, $showStateCheckMark); }
/** * Generates the HTML to display the registration tab/area * * @param TabTable $tab the tab database entry * @param UserTable $user the user being displayed * @param int $ui 1 for front-end, 2 for back-end * @param array $postdata _POST data for saving edited tab content as generated with getEditTab * @return string|boolean Either string HTML for tab content, or false if ErrorMSG generated */ public function getDisplayRegistration( $tab, $user, $ui, $postdata ) { cbpaidErrorHandler::on(); $return = ''; $params = $this->params; $registrationPlansEnabled = $params->get('registrationPlansEnabled', 0); if ($registrationPlansEnabled) { $this->outputRegTemplate(); $subscriptionsGUI = new cbpaidControllerUI(); $plansTitle = CBPTXT::T( $this->params->get( 'regTitle', "Subscriptions" ) ); $htmlPlans = $subscriptionsGUI->getShowRegistrationPlans( $user, $plansTitle, 'N' ); /** @var $viewer cbpaiduserregistrationplansView */ $viewer = cbpaidTemplateHandler::getViewer( null, 'userregistrationplans' ); $viewer->setModel( $tab ); $return = $viewer->drawRegistrationPlans( $plansTitle, $htmlPlans ); } cbpaidErrorHandler::off(); return $return; }
/** * Cancels an existing recurring subscription * * @param cbpaidPaymentBasket $paymentBasket paymentBasket object * @param cbpaidPaymentItem[] $paymentItems redirect immediately instead of returning HTML for output * @return boolean|string TRUE if unsubscription done successfully, STRING if error */ protected function handleStopPaymentSubscription( $paymentBasket, $paymentItems ) { global $_CB_framework, $_CB_database; if ( $paymentBasket->mc_amount3 ) { // Recurring amount existing and if first amount existed it got payed OK: subscribe to an ARB: if ( $paymentBasket->subscr_id ) { if ( $this->hasPaypalApi() /* && ( substr( $paymentBasket->subscr_id, 0, 2 ) != 'S-' ) */ ) { // Only subscription ids starting with I- can be handled through API for unsubscription: S- subscriptions can not. // There is an API access, let's try to use it: $return = $this->getPaypalApi()->ManageRecurringPaymentsProfileStatus( $paymentBasket->subscr_id, 'cancel', null ); if ( $return ) { // Success! : $return is TRUE: $ipn = new cbpaidPaymentNotification( $_CB_database ); $ipn->payment_method = $this->getPayName(); $ipn->gateway_account = $this->getAccountParam( 'id' ); $ipn->log_type = '5'; $ipn->time_received = date( 'Y-m-d H:i:s', $_CB_framework->now() ); $ipn->raw_data = /* cbGetParam() not needed: we want raw info */ '$_GET=' . var_export( $_GET, true ) . ";\n"; $ipn->raw_data .= /* cbGetParam() not needed: we want raw info */ '$_POST=' . var_export( $_POST, true ) . ";\n"; $ipn->raw_data .= $this->getPaypalApi()->getRawLogData() . ";\n"; $ipn->ip_addresses = cbpaidRequest::getIPlist(); $ipn->payment_basket_id = $paymentBasket->id; $ipn->user_id = $paymentBasket->user_id; $_CB_database->insertObject( $ipn->getTableName(), $ipn, $ipn->getKeyName() ); } else { $this->setLogPaypalApiErrors( $paymentBasket ); $return = ''; } } else { $return = ''; } if ( ! $return ) { // No API, we can only render a button: (which is not displayed in case of upgrades): if ( ! is_string( $return ) ) { $return = ''; } $return .= CBPTXT::Th("You are currently using PayPal Recurring Payments to pay for your subscription. To unsubscribe and stop future payments, you must to do this from Paypal. Click on the button below to login into PayPal and follow the instructions there to unsubscribe. This will automatically stop your subscription on this site."); $paymentButton = $this->getPayButtonRecepie( $paymentBasket, 'subscribe', 'cancel' ); // Needed to post the button: $subscriptionsGUI = new cbpaidControllerUI(); $subscriptionsGUI->addcbpaidjsplugin(); /** @var $renderer cbpaidBasketView */ $renderer = cbpaidTemplateHandler::getViewer( null, 'basket' ); $renderer->setModel( $paymentBasket ); $return .= $renderer->drawPaymentButton( $paymentButton ); } } else { $this->_setLogErrorMSG( 3, null, 'Paypal autorecurring payment subscriptions: stopPaymentSubscription error: missing subscr_id in payment basket', CBPTXT::T("Submitted unsubscription didn't return an error but didn't complete.") ); $return = ''; } } else { $return = CBPTXT::T("Unsubscription from payment processor is not possible as this payment basket has no autorecurring amount."); } return $return; }
/** * Gets the viewer class for the rendering, keeps it in cache. * * @return cbpaidProductView */ public function & getViewer( ) { if ( ! isset( $this->_viewer ) ) { $template = $this->getTemplateOutoutCss(); $view = 'product' . $this->item_type; $output = 'html'; // For now... $this->_viewer = cbpaidTemplateHandler::getViewer( $template, $view, $output ); $this->_viewer->setModel( $this ); } return $this->_viewer; }
/** * parses regex match callback plan substitutions * * @param array $matches * @return string */ public function replacePlanSubstitutions( $matches ) { $planId = ( isset( $matches[1] ) ? (int) $matches[1] : null ); $text = ( isset( $matches[2] ) ? $matches[2] : null ); if ( $planId && $text ) { $user = cbUser::getMyUserDataInstance(); $plansMgr = cbpaidPlansMgr::getInstance(); $plan = $plansMgr->getPublishedPlan( $planId, $user ); if ( $plan ) { // Output CSS for displaying the plan properly: cbpaidTemplateHandler::getViewer( '', null )->outputTemplateCss( 'cbpaidsubscriptions' ); $plan->getTemplateOutoutCss(); // Get substitutions: return $plan->getPersonalized( $text, $user->id, true, true, null, false ); } } return null; }