/** * Gives translated offset-adjusted gmdate() * Right now only supports formats 'F' and 'j F' * * @param string $format Format like PHP's date() * @param int $timestamp Unix Timestamp * @return string */ public static function Tdate($format, $timestamp) { $monthNumber = cbpaidTimes::getInstance()->localDate('n', $timestamp); $monthName = self::T('UE_MONTHS_' . $monthNumber); if ($format == 'F') { return $monthName; } if ($format == 'j F') { $day = cbpaidTimes::getInstance()->localDate('j', $timestamp); return self::P("[DAY] [MONTHNAME]", array('[DAY]' => $day, '[MONTHNAME]' => $monthName)); } return 'UNHANDLED FORMAT IN CBPTxt::Tdate: ' . $format; }
/** * Get the most recent unpaid payment basket for that user * * @param int $userId * @return cbpaidPaymentBasket|boolean Basket or false = db_error */ public function loadCurrentUnpaidBasket( $userId ) { global $_CB_framework; $cbpaidTimes =& cbpaidTimes::getInstance(); $basket = $this->_tryLoadCurrentUnpaidBasket( $userId ); if ( $basket ) { $timeInitiated = $cbpaidTimes->strToTime( $basket->time_initiated ); $maxInitiatedTime = $_CB_framework->now() -10800; // NOW - 3 hours if ( $timeInitiated < $maxInitiatedTime ) { $this->timeoutUnusedBaskets( $userId ); $basket = null; } } return $basket; }
/** * WARNING: UNCHECKED ACCESS! On purpose unchecked access for M2M operations * Generates the HTML to display for a specific component-like page for the tab. WARNING: unchecked access ! * @param TabTable|null $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 mixed either string HTML for tab content, or false if ErrorMSG generated */ public function getTabComponent( /** @noinspection PhpUnusedParameterInspection */ $tab, $user, $ui, $postdata ) { global $_CB_database, $_CB_framework, $_POST; $return = ''; $paid = false; $oldignoreuserabort = ignore_user_abort(true); $allowHumanHtmlOutput = true; // this will be reverted in case of M2M server-to-server notifications $act = $this->base->_getReqParam( 'act' ); $actPosted = isset($_POST[$this->base->_getPagingParamName('act')]); if ( $act === null ) { $act = $this->base->input( 'act', null, GetterInterface::COMMAND ); $actPosted = $this->base->input( 'post/act', null, GetterInterface::COMMAND ) !== null; } $post_user_id = (int) cbGetParam( $_GET, 'user', 0 ); if ( $actPosted && ( $post_user_id > 0 ) ) { $access = false; $myId = $_CB_framework->myId(); if ( is_object( $user ) ) { if ( $myId == 0 ) { if ( in_array( $act, array( 'saveeditinvoiceaddress', 'saveeditbasketintegration', 'showbskt' ) ) ) { $access = true; } else { $paidsubsManager =& cbpaidSubscriptionsMgr::getInstance(); if ( ! $paidsubsManager->checkExpireMe( __FUNCTION__, $user->id, false ) ) { // expired subscriptions: we will allow limited access to: if ( in_array( $act, array( 'upgrade', 'pay', 'reactivate', 'resubscribe', 'display_subscriptions' ) ) ) { $access = true; } } } } else { if ( ( $ui == 1 && ( $user->id == $myId ) ) || ( cbpaidApp::authoriseAction( 'cbsubs.usersubscriptionmanage' ) ) ) { $access = true; } } } else { $return = CBPTXT::T("User does not exist") . '.'; } if ( ! $access ) { $return .= '<br />' . CBPTXT::T("Not authorized action") . '.'; return $return; } cbSpoofCheck( 'plugin' ); // anti-spoofing check // renew or upgrade subscription payment form: $params = $this->params; $now = $_CB_framework->now(); $subscriptionsGUI = new cbpaidControllerUI(); $subscriptionIds = $subscriptionsGUI->getEditPostedBoxes( 'id' ); if ( $subscriptionIds == array( 0 ) ) { $subscriptionIds = array(); } if ( $post_user_id && ( $user->id == $post_user_id ) ) { outputCbTemplate(); $this->base->outputRegTemplate(); outputCbJs(); switch ( $act ) { case 'upgrade': // upgrade an existing subscription // display basket and payment buttons or redirect for payment depending if multiple payment choices or intro text present: $chosenPlans = $subscriptionsGUI->getAndCheckChosenUpgradePlans( $postdata, $user, $now ); if ( ( ! is_array( $chosenPlans ) ) || ( count( $chosenPlans ) == 0 ) ) { $subTxt = CBPTXT::T( $params->get( 'subscription_name', 'subscription' ) ); $return .= ( is_string( $chosenPlans ) ? $chosenPlans . '<br />' : '' ) . sprintf( CBPTXT::Th("Please press back button and select the %s plan to which you would like to upgrade."), $subTxt ); break; } $introText = CBPTXT::Th( $params->get( 'intro_text_upgrade', null ) ); //TBD: check if already exists (reload protection): $paymentBasket = cbpaidControllerOrder::createSubscriptionsAndPayment( $user, $chosenPlans, $postdata, $subscriptionIds, null, 'R', CBPTXT::T("Upgrade"), 'U' ); if ( is_object( $paymentBasket ) ) { $return = cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } else { $return = $paymentBasket; // show messages as nothing to pay. } break; case 'pay': // pay for an unpaid subscription // display basket and payment buttons or redirect for payment depending if multiple payment choices or intro text present: $plan = $this->base->_getReqParam( 'plan' ); if ( ( ! $plan ) || ( ! isset( $subscriptionIds[$plan] ) ) || ( ! $subscriptionIds[$plan] ) ) { $subTxt = CBPTXT::T( $params->get( 'subscription_name', 'subscription' ) ); $return .= sprintf( CBPTXT::Th("Please press back button and select a %s plan."), $subTxt ); break; } $plansMgr =& cbpaidPlansMgr::getInstance(); $chosenPlans = array(); $chosenPlans[(int) $plan] = $plansMgr->loadPlan( (int) $plan ); $introText = CBPTXT::Th( $params->get( 'intro_text', null ) ); $paymentStatus = null; $return = cbpaidControllerOrder::showPaymentForm( $user, $chosenPlans, $introText, $subscriptionIds, $paymentStatus ); break; case 'renew': // renew a still valid subscription case 'reactivate': // reactivate an expired subscription case 'resubscribe': // resubscribe a cancelled subscription // display basket and payment buttons or redirect for payment depending if multiple payment choices or intro text present: $plan = $this->base->_getReqParam( 'plan' ); if ( ( ! $plan ) || ( ! isset( $subscriptionIds[$plan] ) ) || ( ! $subscriptionIds[$plan] ) ) { $subTxt = CBPTXT::T( $params->get( 'subscription_name', 'subscription' ) ); $return .= sprintf( CBPTXT::Th("Please press back button and select a %s plan."), $subTxt ); break; } $plansMgr =& cbpaidPlansMgr::getInstance(); $chosenPlans = array(); $chosenPlans[(int) $plan] = $plansMgr->loadPlan( (int) $plan ); $paidSomethingMgr =& cbpaidSomethingMgr::getInstance(); $subscription = $paidSomethingMgr->loadSomething( $subscriptionIds[$plan][0], $subscriptionIds[$plan][1] ); global $_PLUGINS; $_PLUGINS->loadPluginGroup( 'user', 'cbsubs.' ); $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin'); $_PLUGINS->trigger( 'onCPayAfterPlanRenewalSelected', array( &$chosenPlans[(int) $plan], &$subscription, $act ) ); if ( $_PLUGINS->is_errors() ) { $return .= $_PLUGINS->getErrorMSG(); break; } $introText = CBPTXT::Th( $params->get( 'intro_text_renew', null ) ); //TBD: check if already exists (reload protection): $paymentBasket = cbpaidControllerOrder::createSubscriptionsAndPayment( $user, $chosenPlans, $postdata, $subscriptionIds, null, null, CBPTXT::T("Renew"), 'R' ); if ( is_object( $paymentBasket ) ) { $return = cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } else { $return = $paymentBasket; // show messages as nothing to pay. } break; case 'unsubscribe': // request to unsubscribe an active subscription // display unsubscribe confirmation form: $plan = $this->base->_getReqParam( 'plan' ); if ( ( ! $plan ) || ( ! isset( $subscriptionIds[$plan] ) ) || ( ! $subscriptionIds[$plan] ) ) { $subTxt = CBPTXT::T( $params->get( 'subscription_name', 'subscription' ) ); $return .= sprintf( CBPTXT::Th("Please press back button and select a %s plan."), $subTxt ); break; } $introText = CBPTXT::Th( $params->get( 'unsubscribe_intro_text' , null ) ); $return = $subscriptionsGUI->showUnsubscribeForm( $user, $introText, (int) $plan, (int) $subscriptionIds[$plan][1] ); break; case 'confirm_unsubscribe': // confirm previous request to unsubscribe an active subscription // unsubscribe confirmed: $plan = $this->base->_getReqParam( 'plan' ); if ( ( ! $plan ) || ( ! isset( $subscriptionIds[$plan] ) ) || ( ! $subscriptionIds[$plan] ) ) { $subTxt = CBPTXT::T( $params->get( 'subscription_name', 'subscription' ) ); $return .= sprintf( CBPTXT::Th("Please press back button and select a %s plan."), $subTxt ); break; } if ( ( $plan ) && ( count( $subscriptionIds ) == 1 ) ) { $unsubscribeConfText = CBPTXT::Th( $params->get( 'unsubscribe_confirmation_text', null ) ); $return = cbpaidControllerOrder::doUnsubscribeConfirm( $user, $unsubscribeConfText, (int) $plan, (int) $subscriptionIds[$plan][1] ); } break; case 'display_subscriptions': // unsubscribe cancelled: display subscriptions: $return = $this->base->displayUserTab( $user ); break; case 'showinvoice': // shows a particular user invoice: if ( $params->get( 'show_invoices', 1 ) ) { $invoiceNo = $this->base->_getReqParam( 'invoice' ); $return = $this->showInvoice( $invoiceNo, $user ); } break; case 'saveeditinvoiceaddress': case 'editinvoiceaddress': // this is the case of reload of invoicing address $invoicingAddressQuery = $params->get( 'invoicing_address_query' ); if ( $invoicingAddressQuery > 0 ) { $basketId = $this->base->_getReqParam( 'basket', 0 ); $hashToCheck = $this->base->_getReqParam( 'bck' ); $paymentBasket = new cbpaidPaymentBasket( $_CB_database ); if ( $basketId && $paymentBasket->load( (int) $basketId ) && ( $paymentBasket->payment_status == 'NotInitiated' ) && ( $hashToCheck == $paymentBasket->checkHashUser( $hashToCheck ) ) ) { if ( ( $act == 'saveeditinvoiceaddress' ) && $this->base->input( 'actbutton', null, GetterInterface::COMMAND ) ) { // IE7-8 will return text instead of value and IE6 will return button all the time http://www.dev-archive.net/articles/forms/multiple-submit-buttons.html $return = $paymentBasket->saveInvoicingAddressForm( $user ); if ( $return === null ) { $paymentBasket->storeInvoicingDefaultAddress(); $introText = CBPTXT::Th( $params->get( 'intro_text', null ) ); $return .= cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } } else { // invoice has reloaded itself (e.g. for country change): $return = $paymentBasket->renderInvoicingAddressForm( $user ); } } else { $this->base->_setErrorMSG( CBPTXT::T("No unpaid payment basket found.") ); } } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } break; case 'saverecordpayment': case 'editrecordpayment': // this is the case of reload of the form $basketId = $this->base->_getReqParam( 'basket', 0 ); $hashToCheck = $this->base->_getReqParam( 'bck' ); $paymentBasket = new cbpaidPaymentBasket( $_CB_database ); if ( $basketId && $paymentBasket->load( (int) $basketId ) && ( $paymentBasket->payment_status != 'Completed' ) && ( $hashToCheck == $paymentBasket->checkHashUser( $hashToCheck ) ) ) { if ( $paymentBasket->authoriseAction( 'cbsubs.recordpayments' ) ) { if ( ( $act == 'saverecordpayment' ) && $this->base->input( 'actbutton', null, GetterInterface::COMMAND ) ) { // IE7-8 will return text instead of value and IE6 will return button all the time http://www.dev-archive.net/articles/forms/multiple-submit-buttons.html $return = cbpaidRecordBasketPayment::saveRecordPayment( $paymentBasket->id ); if ( $return === null ) { $return .= CBPTXT::T("Payment recorded.") . ' <a href="' . $_CB_framework->userProfileUrl( $paymentBasket->user_id, true ) . '">' . CBPTXT::Th("View user profile") . '</a>'; } } else { // invoice has reloaded itself (e.g. for country change): $return = cbpaidRecordBasketPayment::displayRecordPaymentForm( $paymentBasket->id ); } } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } } else { $this->base->_setErrorMSG( CBPTXT::T("No unpaid payment basket found.") ); } break; default: cbNotAuth(); return ''; break; } } } elseif ( $this->base->_getReqParam( 'account' ) && ( ( (int) cbGetParam( $_GET, 'user', 0 ) ) > 0 ) ) { $account = $this->base->_getReqParam( 'account' ); $post_user_id = (int) cbGetParam( $_GET, 'user', 0 ); $user = CBuser::getUserDataInstance( (int) $post_user_id ); if ( $user->id ) { if ( isset( $_SESSION['cbsubs']['expireduser'] ) && ( $_SESSION['cbsubs']['expireduser'] == $user->id ) ) { // expired subscriptions of membership: show possibilities: $subscriptionsGUI = new cbpaidControllerUI(); outputCbTemplate(); $this->base->outputRegTemplate(); outputCbJs(); switch ( $account ) { case 'expired': $paidsubsManager =& cbpaidSubscriptionsMgr::getInstance(); if ( ! $paidsubsManager->checkExpireMe( __FUNCTION__, $user->id, false ) ) { // no valid membership: $return = $subscriptionsGUI->getShowSubscriptionUpgrades( $user, true ); } break; default: break; } } else { $return = CBPTXT::Th("Browser cookies must be enabled."); } } } elseif ( in_array( $act, array( 'setbsktpmtmeth', 'setbsktcurrency' ) ) ) { cbSpoofCheck( 'plugin' ); // anti-spoofing check $params = $this->params; outputCbTemplate(); $this->base->outputRegTemplate(); outputCbJs(); $basketId = $this->base->_getReqParam( 'bskt', 0 ); $hashToCheck = $this->base->_getReqParam( 'bck' ); $paymentBasket = new cbpaidPaymentBasket( $_CB_database ); if ( $basketId && $paymentBasket->load( (int) $basketId ) && ( $paymentBasket->payment_status == 'NotInitiated' ) && ( $hashToCheck == $paymentBasket->checkHashUser( $hashToCheck ) ) ) { switch ( $act ) { case 'setbsktpmtmeth': if ( $params->get( 'payment_method_selection_type' ) == 'radios' ) { $chosenPaymentMethod = cbGetParam( $_POST, 'payment_method' ); $introText = CBPTXT::Th( $params->get( 'intro_text', null ) ); $return = $paymentBasket->saveBasketPaymentMethodForm( $user, $introText, $chosenPaymentMethod ); if ( $return === null ) { $return .= cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } break; case 'setbsktcurrency': if ( $params->get( 'allow_select_currency', '0' ) ) { $newCurrency = cbGetParam( $_POST, 'currency' ); if ( $newCurrency ) { if ( in_array( $newCurrency, cbpaidControllerPaychoices::getInstance()->getAllCurrencies() ) ) { $paymentBasket->changeCurrency( $newCurrency ); } else { $this->base->_setErrorMSG( CBPTXT::T("This currency is not allowed") ); } $introText = CBPTXT::Th( $params->get( 'intro_text', null ) ); $return .= cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } } else { $this->base->_setErrorMSG( CBPTXT::T("Changes of currency of orders are not authorized") ); } break; default: cbNotAuth(); return ''; break; } } else { $this->base->_setErrorMSG( CBPTXT::T("No unpaid payment basket found.") ); } } elseif ( $act == 'cbsubsclass' ) { $pluginName = $this->base->_getReqParam( 'class' ); if ( preg_match( '/^[a-z]+$/', $pluginName ) ) { $element = 'cbsubs.' . $pluginName; global $_PLUGINS; $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin', $element ); $loadedPlugins =& $_PLUGINS->getLoadedPluginGroup( 'user/plug_cbpaidsubscriptions/plugin' ); $params = $this->params; foreach ($loadedPlugins as $p ) { if ( $p->element == $element ) { $pluginId = $p->id; $args = array( &$user, &$params, &$postdata ); /** @noinspection PhpUndefinedCallbackInspection */ $return = $_PLUGINS->call( $pluginId, 'executeTask', 'getcbsubs' . $pluginName . 'Tab', $args, null ); break; } } } } elseif ( $act && ( ! in_array( $act, array( 'showbskt', 'setbsktpmtmeth' ) ) ) && ( ( (int) cbGetParam( $_GET, 'user', 0 ) ) > 0 ) ) { if ( ! is_object( $user ) ) { return CBPTXT::T("User does not exist."); } $params = $this->params; $post_user_id = (int) cbGetParam( $_GET, 'user', 0 ); if ( $post_user_id && ( ( $user->id == $post_user_id ) || ( cbpaidApp::authoriseAction( 'cbsubs.usersubscriptionmanage' ) ) ) ) { outputCbTemplate(); $this->base->outputRegTemplate(); outputCbJs(); switch ( $act ) { case 'showinvoice': if ( $params->get( 'show_invoices', 1 ) ) { $invoiceNo = $this->base->_getReqParam( 'invoice', 0 ); // This also checks for cbpaidApp::authoriseAction on cbsubs.sales or cbsubs.financial access permissions: $return = $this->showInvoice( $invoiceNo, $user ); } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } break; case 'showinvoiceslist': $showInvoices = $params->get( 'show_invoices', 1 ); $invoicesShowPeriod = $params->get( 'invoices_show_period', '0000-06-00 00:00:00' ); $itsmyself = ( $_CB_framework->myId() == $user->id ); if ( $showInvoices && ( $itsmyself || ( cbpaidApp::authoriseAction( 'cbsubs.sales' ) || cbpaidApp::authoriseAction( 'cbsubs.financial' ) ) ) ) { $subscriptionsGUI = new cbpaidControllerUI(); $invoices = $this->_getInvoices( $user, $invoicesShowPeriod, false ); if ( $invoicesShowPeriod && ( $invoicesShowPeriod != '0000-00-00 00:00:00' ) ) { $cbpaidTimes =& cbpaidTimes::getInstance(); $periodText = $cbpaidTimes->renderPeriod( $invoicesShowPeriod, 1, false ); } else { $periodText = ''; } $return .= $subscriptionsGUI->showInvoicesList( $invoices, $user, $itsmyself, $periodText ); } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } break; case 'editinvoiceaddress': // this is the case of the initial edit address link if ( $params->get( 'invoicing_address_query' ) > 0 ) { $basketId = $this->base->_getReqParam( 'basket', 0 ); $hashToCheck = $this->base->_getReqParam( 'bck' ); $paymentBasket = new cbpaidPaymentBasket( $_CB_database ); if ( $basketId && $paymentBasket->load( (int) $basketId ) && ( $paymentBasket->payment_status == 'NotInitiated' ) && ( $hashToCheck == $paymentBasket->checkHashUser( $hashToCheck ) ) ) { $return = $paymentBasket->renderInvoicingAddressForm( $user ); } else { $this->base->_setErrorMSG( CBPTXT::T("No unpaid payment basket found.") ); } } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } break; case 'showrecordpayment': $paymentBasketId = $this->base->_getReqParam( 'recordpayment', 0 ); if ( $paymentBasketId ) { $paymentBasket = new cbpaidPaymentBasket(); if ( $paymentBasket->load( (int) $paymentBasketId ) && $paymentBasket->authoriseAction( 'cbsubs.recordpayments' ) ) { // Auto-loads class: and authorization is checked inside: $return = cbpaidRecordBasketPayment::displayRecordPaymentForm( $paymentBasketId ); } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } break; default: $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); break; } } } elseif ( $act == 'showbskt' && ( ( ( (int) cbGetParam( $_GET, 'user', 0 ) ) > 0 ) ) || ( $this->base->_getReqParam( 'bskt', 0 ) && $this->base->_getReqParam( 'bck' ) ) ) { $basketId = $this->base->_getReqParam( 'bskt', 0 ); $hashToCheck = $this->base->_getReqParam( 'bck' ); // Basket integrations saving/editing url: if ( in_array($act, array( 'saveeditbasketintegration', 'editbasketintegration' ) ) ) { // edit is the case of edit or reload of integration form $integration = $this->base->_getReqParam( 'integration' ); $paymentBasket = new cbpaidPaymentBasket( $_CB_database ); if ( preg_match( '/^[a-z]+$/', $integration ) && $basketId && $paymentBasket->load( (int) $basketId ) && ( $paymentBasket->payment_status == 'NotInitiated' ) && ( $hashToCheck == $paymentBasket->checkHashUser( $hashToCheck ) ) ) { global $_PLUGINS; $element = 'cbsubs.' . $integration; $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin', $element ); $results = $_PLUGINS->trigger( 'onCPayEditBasketIntegration', array( $integration, $act, &$paymentBasket ) ); $return = null; foreach ( $results as $r ) { if ( $r ) { $return .= $r; } } if ( $act == 'editbasketintegration' ) { if ( $return !== null ) { return $return; } } } else { $this->base->_setErrorMSG( CBPTXT::T("No unpaid payment basket found.") ); } } $post_user_id = (int) cbGetParam( $_GET, 'user', 0 ); if ( $post_user_id && ! ( ( is_object( $user ) && ( $user->id == $post_user_id ) ) ) ) { return CBPTXT::T("User does not exist."); } outputCbTemplate(); $this->base->outputRegTemplate(); outputCbJs(); $params = $this->params; $paymentBasket = new cbpaidPaymentBasket( $_CB_database ); if ( $basketId && $paymentBasket->load( (int) $basketId ) && ( $paymentBasket->payment_status == 'NotInitiated' ) ) { if ( ! $post_user_id ) { $cbUser =& CBuser::getInstance( (int) $paymentBasket->user_id ); $user =& $cbUser->getUserData(); if ( ( ! is_object( $user ) ) || ! $user->id ) { return CBPTXT::T("User does not exist."); } } if ( ( $hashToCheck && $hashToCheck == $paymentBasket->checkHashUser( $hashToCheck ) ) || ( ( ! $hashToCheck ) && $paymentBasket->user_id && ( $paymentBasket->user_id == $_CB_framework->myId() ) ) ) { $introText = CBPTXT::Th( $params->get( 'intro_text', null ) ); $return .= cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } else { $this->base->_setErrorMSG( CBPTXT::T("Not authorized action") ); } } else { $this->base->_setErrorMSG( CBPTXT::T("No unpaid payment basket found.") ); } // } elseif ( isset($_REQUEST['result']) && isset( $_REQUEST['user'] ) && ( $_REQUEST['user'] > 0 ) ) { } elseif ( isset($_REQUEST['result']) && ( $this->base->_getReqParam('method') || $this->base->_getReqParam('gacctno') ) ) { // don't check license here so initiated payments can complete ! $params = $this->params; $method = $this->base->_getReqParam('method'); if ( ( $method == 'freetrial' ) || ( $method == 'cancelpay' ) ) { cbpaidApp::import( 'processors.freetrial.freetrial' ); cbpaidApp::import( 'processors.cancelpay.cancelpay' ); $className = 'cbpaidGatewayAccount' . $method; $payAccount = new $className( $_CB_database ); } else { $gateAccount = $this->base->_getReqParam('gacctno'); $payAccount = cbpaidControllerPaychoices::getInstance()->getPayAccount( $gateAccount ); if ( ! $payAccount ) { return ''; } } $payClass = $payAccount->getPayMean(); $paymentBasket = new cbpaidPaymentBasket($_CB_database); if ( $payClass && ( ( $this->base->_getReqParam('method') == $payClass->getPayName() ) || ( $this->base->_getReqParam('method') == null ) ) && $payClass->hashPdtBackCheck( $this->base->_getReqParam('pdtback') ) ) { // output for resultNotification: $return and $allowHumanHtmlOutput $return = $payClass->resultNotification( $paymentBasket, $postdata, $allowHumanHtmlOutput ); } if ( ! $paymentBasket->id ) { $this->base->_setErrorMSG(CBPTXT::T("No suitable basket found.")); } else { $user =& CBuser::getUserDataInstance( (int) $paymentBasket->user_id ); if ( $paymentBasket->payment_status == 'RegistrationCancelled' ) { // registration cancelled: delete payment basket and delete user after checking that he is not yet active: if ( $paymentBasket->load( (int) $paymentBasket->id ) ) { if ( $payClass->hashPdtBackCheck( $this->base->_getReqParam('pdtback') ) && ( ( $paymentBasket->payment_status == 'NotInitiated' ) || ( ( $paymentBasket->payment_status === 'Pending' ) && ( $paymentBasket->payment_method === 'offline' ) ) ) ) { $notification = new cbpaidPaymentNotification(); $notification->initNotification( $payClass, 0, 'P', $paymentBasket->payment_status, $paymentBasket->payment_type, null, $_CB_framework->now(), $paymentBasket->charset ); $payClass->updatePaymentStatus( $paymentBasket, 'web_accept', 'RegistrationCancelled', $notification, 0, 0, 0, true ); // This is a notification or a return to site after payment, we want to log any error happening in third-party stuff in case: cbpaidErrorHandler::keepTurnedOn(); } } } if ( $allowHumanHtmlOutput ) { // If frontend, we display result, otherwise, If Server-to-server notification: do not display any additional text here ! switch ( $paymentBasket->payment_status ) { case 'Completed': // PayPal recommends including the following information with the confirmation: // - Item name // - Amount paid // - Payer email // - Shipping address $newMsg = sprintf( CBPTXT::Th("Thank you for your payment of %s for the %s %s."), $paymentBasket->renderPrice(), $paymentBasket->item_name, htmlspecialchars( $payClass->getTxtUsingAccount( $paymentBasket ) ) ) // ' using your paypal account ' . $paymentBasket->payer_email . ' ' . $payClass->getTxtNextStep( $paymentBasket ); // . "Your transaction has been completed, and a receipt for your purchase has been emailed to you by PayPal. " // . "You may log into your account at www.paypal.com to view details of this transaction.</p>\n"; if ( $params->get( 'show_invoices' ) ) { $itsmyself = ( $_CB_framework->myId() == $user->id ); $subscriptionsGUI = new cbpaidControllerUI(); $newMsg .= '<p id="cbregviewinvoicelink">' . $subscriptionsGUI->getInvoiceShowAhtml( $paymentBasket, $user, $itsmyself, CBPTXT::Th("View printable invoice") ) . '</p>' ; } $paid = true; break; case 'Pending': $newMsg = sprintf( CBPTXT::Th("Thank you for initiating the payment of %s for the %s %s."), $paymentBasket->renderPrice(), $paymentBasket->item_name, htmlspecialchars( $payClass->getTxtUsingAccount( $paymentBasket ) ) ) // ' using your paypal account ' . $paymentBasket->payer_email . ' ' . $payClass->getTxtNextStep( $paymentBasket ); // . "Your payment is currently being processed. " // . "A receipt for your purchase will be emailed to you by PayPal once processing is complete. " // . "You may log into your account at www.paypal.com to view status details of this transaction.</p>\n"; break; case 'RegistrationCancelled': $newMsg = $payClass->getTxtNextStep( $paymentBasket ); break; case 'FreeTrial': $newMsg = CBPTXT::Th("Thank you for subscribing to") . ' ' . $paymentBasket->item_name . '.' . ' ' . $payClass->getTxtNextStep( $paymentBasket ); break; case null: $newMsg = CBPTXT::T("Payment basket does not exist."); break; case 'NotInitiated': $newMsg = ''; break; case 'RedisplayOriginalBasket': if ( $paymentBasket->load( (int) $paymentBasket->id ) && ( $paymentBasket->payment_status == 'NotInitiated' ) ) { $introText = CBPTXT::Th( $params->get( 'intro_text', null ) ); $return .= cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, $introText ); } $newMsg = ''; break; case 'Processed': case 'Denied': case 'Reversed': case 'Refunded': case 'Partially-Refunded': default: $newMsg = $payClass->getTxtNextStep( $paymentBasket ); // "<p>Your transaction is not cleared and has currently following status: <strong>" . $paymentBasket->payment_status . ".</strong></p>" // . "<p>You may log into your account at www.paypal.com to view status details of this transaction.</p>"; break; } if ( in_array( $paymentBasket->payment_status, array( 'Completed', 'Pending' ) ) ) { $subscriptions = $paymentBasket->getSubscriptions(); $texts = array(); // avoid repeating several times identical texts: if ( is_array( $subscriptions ) ) { foreach ( $subscriptions as $sub ) { /** @var $sub cbpaidSomething */ $thankYouParam = ( $paymentBasket->payment_status == 'Completed') ? 'thankyoutextcompleted' : 'thankyoutextpending'; $thankYouText = $sub->getPersonalized( $thankYouParam, true ); if ( $thankYouText && ! in_array( $thankYouText, $texts ) ) { $texts[] = $thankYouText; if ( strpos( $thankYouText, '<' ) === false ) { $msgTag = 'p'; } else { $msgTag = 'div'; } $newMsg .= '<' . $msgTag . ' class="cbregThanks" id="cbregThanks' . $sub->plan_id . '">' . $thankYouText . '</' . $msgTag . ">\n"; } } } } if ( $newMsg ) { $return .= '<div>' . $newMsg . '</div>'; } if ( $paid && ( $_CB_framework->myId() < 1 ) && ( cbGetParam( $_REQUEST, 'user', 0 ) == $paymentBasket->user_id ) ) { $_CB_database->setQuery( "SELECT * FROM #__comprofiler c, #__users u WHERE c.id=u.id AND c.id=".(int) $paymentBasket->user_id ); if ( $_CB_database->loadObject( $user ) && ( $user->lastvisitDate == '0000-00-00 00:00:00' ) ) { $return = '<p>' . implode( '', getActivationMessage( $user, 'UserRegistration' ) ) . '</p>' . $return; } } } } } else { cbNotAuth(); return ' ' . CBPTXT::T("No result."); } if ( $allowHumanHtmlOutput ) { $allErrorMsgs = $this->base->getErrorMSG( '</div><div class="error">' ); if ( $allErrorMsgs ) { $errorMsg = '<div class="error">' . $allErrorMsgs . '</div>'; } else { $errorMsg = null; } /** @var string $return */ if ( ( $return == '' ) && ( $errorMsg ) ) { $this->base->outputRegTemplate(); $return = $errorMsg . '<br /><br />' . $return; $return .= cbpaidControllerOrder::showBasketForPayment( $user, $paymentBasket, '' ); } else { $return = $errorMsg . $return; } } if ( ! is_null( $oldignoreuserabort ) ) { ignore_user_abort($oldignoreuserabort); } return $return; }
/** * Updates payment status of basket and of corresponding subscriptions if there is a change in status * * @param cbpaidPaymentBasket $paymentBasket Basket * @param string $eventType type of event (paypal type): 'web_accept', 'subscr_payment', 'subscr_signup', 'subscr_modify', 'subscr_eot', 'subscr_cancel', 'subscr_failed' * @param string $paymentStatus new status (Completed, RegistrationCancelled) * @param cbpaidPaymentNotification $notification notification object of the payment * @param int $occurrences renewal occurrences * @param int $autorecurring_type 0: not auto-recurring, 1: auto-recurring without payment processor notifications, 2: auto-renewing with processor notifications updating $expiry_date * @param int $autorenew_type 0: not auto-renewing (manual renewals), 1: asked for by user, 2: mandatory by configuration * @param boolean|string $txnIdMultiplePaymentDates FALSE: unique txn_id for each payment, TRUE: same txn_id can have multiple payment dates, additionally: 'SINGLEPAYMENT' will not look at txn_id at all * @param boolean $storePaymentRecord TRUE: normal case, create payment record if needed. FALSE: offline case where pending payment should not create a payment record. * @return void */ public function updatePaymentStatus($paymentBasket, $eventType, $paymentStatus, &$notification, $occurrences, $autorecurring_type, $autorenew_type, $txnIdMultiplePaymentDates, $storePaymentRecord = true) { global $_CB_framework, $_PLUGINS; $pluginsLoaded = false; $basketUpdateNulls = false; $previousUnifiedStatus = $this->mapPaymentStatus($paymentBasket->payment_status); $unifiedStatus = $this->mapPaymentStatus($paymentStatus); // get all related subscriptions being paid by this basket: $subscriptions = $paymentBasket->getSubscriptions(); $thisIsReferencePayment = false; $user = CBuser::getUserDataInstance((int) $paymentBasket->user_id); if ($paymentBasket->payment_status != $paymentStatus || $unifiedStatus == 'Partially-Refunded' || $autorecurring_type) { if ($paymentStatus && (in_array($eventType, array('web_accept', 'subscr_payment', 'subscr_signup')) || in_array($unifiedStatus, array('Reversed', 'Refunded', 'Partially-Refunded')))) { $paymentBasket->payment_status = $paymentStatus; } if (in_array($eventType, array('subscr_payment', 'subscr_signup'))) { $paymentBasket->recurring = 1; } if ($autorecurring_type == 0 && in_array($unifiedStatus, array('Completed', 'Processed', 'FreeTrial'))) { $paymentBasket->mc_amount1 = null; $paymentBasket->mc_amount3 = null; $paymentBasket->period1 = null; $paymentBasket->period3 = null; $basketUpdateNulls = true; } // if (count($subscriptions) >= 1) { $now = $_CB_framework->now(); $completed = false; $thisIsReferencePayment = false; $reason = null; switch ($unifiedStatus) { case 'FreeTrial': case 'Completed': case 'Processed': // this includes Canceled_Reversal !!! : if ($unifiedStatus == 'FreeTrial') { $paymentBasket->payment_status = 'Completed'; } if ($unifiedStatus == 'FreeTrial' || $unifiedStatus == 'Completed') { if ($notification->payment_date) { $time_completed = cbpaidTimes::getInstance()->gmStrToTime($notification->payment_date); } else { $time_completed = $now; } $paymentBasket->time_completed = Application::Database()->getUtcDateTime($time_completed); $completed = true; } if ($paymentStatus == 'Canceled_Reversal') { $paymentBasket->payment_status = 'Completed'; } if (is_object($notification) && isset($notification->txn_id)) { // real payment with transaction id: store as reference payment if not already stored: $thisIsReferencePayment = $this->_storePaymentOnce($paymentBasket, $notification, $now, $txnIdMultiplePaymentDates, 'Updating payment record because of new status of payment basket: ' . $unifiedStatus . ($paymentStatus != $unifiedStatus ? ' (new gateway-status: ' . $paymentStatus . ')' : '') . ' because of event received: ' . $eventType . '. Previous status was: ' . $previousUnifiedStatus); } else { // Free trials don't have a notification: $thisIsReferencePayment = true; } if ($thisIsReferencePayment) { // payment not yet processed: $autorenewed = $paymentBasket->recurring == 1 && $unifiedStatus == 'Completed' && $previousUnifiedStatus == 'Completed'; for ($i = 0, $n = count($subscriptions); $i < $n; $i++) { $reason = $autorenewed ? 'R' : $subscriptions[$i]->_reason; $subscriptions[$i]->activate($user, $now, $completed, $reason, $occurrences, $autorecurring_type, $autorenew_type, $autorenewed ? 1 : 0); } } break; case 'RegistrationCancelled': case 'Reversed': case 'Refunded': case 'Unsubscribed': if ($unifiedStatus == 'RegistrationCancelled') { if (!($previousUnifiedStatus == 'NotInitiated' || $previousUnifiedStatus === 'Pending' && $paymentBasket->payment_method === 'offline')) { return; } } for ($i = 0, $n = count($subscriptions); $i < $n; $i++) { $reason = $subscriptions[$i]->_reason; if ($reason != 'R' || in_array($unifiedStatus, array('Reversed', 'Refunded'))) { // Expired and Cancelled as well as Partially-Refunded are not reverted ! //TBD: really revert on refund everything ? a plan param would be nice here if (!in_array($previousUnifiedStatus, array('Pending', 'In-Progress', 'Denied', 'Reversed', 'Refunded')) && in_array($subscriptions[$i]->status, array('A', 'R', 'I')) && !$subscriptions[$i]->hasPendingPayment($paymentBasket->id)) { // not a cancelled or denied renewal: $subscriptions[$i]->revert($user, $unifiedStatus); } } } if ($unifiedStatus == 'RegistrationCancelled') { $paymentBasket->historySetMessage('Payment basket deleted because the subscriptions and payment got cancelled'); $paymentBasket->delete(); // deletes also payment_Items } $paidUserExtension = cbpaidUserExtension::getInstance($paymentBasket->user_id); $subscriptionsAnyAtAll = $paidUserExtension->getUserSubscriptions(''); $params = cbpaidApp::settingsParams(); $createAlsoFreeSubscriptions = $params->get('createAlsoFreeSubscriptions', 0); if (count($subscriptionsAnyAtAll) == 0 && !$createAlsoFreeSubscriptions) { $user = new UserTable(); $id = (int) cbGetParam($_GET, 'user'); $user->load((int) $id); if ($user->id && $user->block == 1) { $user->delete(null); } } break; case 'Denied': case 'Pending': if ($unifiedStatus == 'Denied') { // In fact when denied, it's the case as if the user attempted payment but failed it: He should be able to re-try: So just store the payment as denied for the records. if ($eventType == 'subscr_failed' || $eventType == 'subscr_cancel' && $autorecurring_type != 2) { // special case of a failed attempt: // or this is the final failed attempt of a basket with notifications: break; } } if ($previousUnifiedStatus == 'Completed') { return; // do not change a Completed payment as it cannot become Pending again. If we get "Pending" after "Completed", it is a messages chronological order mistake. } break; case 'In-Progress': case 'Partially-Refunded': default: break; } if ($eventType == 'subscr_cancel') { if (!in_array($unifiedStatus, array('Denied', 'Reversed', 'Refunded', 'Unsubscribed'))) { for ($i = 0, $n = count($subscriptions); $i < $n; $i++) { $subscriptions[$i]->autorecurring_cancelled($user, $unifiedStatus, $eventType); } } } for ($i = 0, $n = count($subscriptions); $i < $n; $i++) { $subscriptions[$i]->notifyPaymentStatus($unifiedStatus, $previousUnifiedStatus, $paymentBasket, $notification, $now, $user, $eventType, $paymentStatus, $occurrences, $autorecurring_type, $autorenew_type); } if (in_array($unifiedStatus, array('Denied', 'Reversed', 'Refunded', 'Partially-Refunded', 'Pending', 'In-Progress'))) { $thisIsReferencePayment = $this->_storePaymentOnce($paymentBasket, $notification, $now, $txnIdMultiplePaymentDates, 'Updating payment record because of new status of payment basket: ' . $unifiedStatus . ($paymentStatus != $unifiedStatus ? ' (new gateway-status: ' . $paymentStatus . ')' : '') . ' because of event received: ' . $eventType . '. Previous status was: ' . $previousUnifiedStatus); } // } foreach ($paymentBasket->loadPaymentTotalizers() as $totalizer) { $totalizer->notifyPaymentStatus($thisIsReferencePayment, $unifiedStatus, $previousUnifiedStatus, $paymentBasket, $notification, $now, $user, $eventType, $paymentStatus, $occurrences, $autorecurring_type, $autorenew_type, $txnIdMultiplePaymentDates); } if (!in_array($unifiedStatus, array('RegistrationCancelled'))) { if ($thisIsReferencePayment && in_array($unifiedStatus, array('Completed', 'Processed'))) { $paymentBasket->setPaidInvoiceNumber($reason); } $paymentBasket->historySetMessage('Updating payment basket ' . ($paymentStatus !== null ? 'status: ' . $unifiedStatus . ($paymentStatus != $unifiedStatus ? ' (new gateway-status: ' . $paymentStatus . ')' : '') : '') . ' because of event received: ' . $eventType . ($paymentStatus !== null ? '. Previous status was: ' . $previousUnifiedStatus : '')); $paymentBasket->store($basketUpdateNulls); } else { //TDB ? : $paymentBasket->delete(); in case of RegistrationCancelled done above, but should be done in case of FreeTrial ? (could be a param in future) } if (!in_array($unifiedStatus, array('Completed', 'Processed')) || $thisIsReferencePayment) { $_PLUGINS->loadPluginGroup('user', 'cbsubs.'); $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin'); $pluginsLoaded = true; $_PLUGINS->trigger('onCPayAfterPaymentStatusChange', array(&$user, &$paymentBasket, &$subscriptions, $unifiedStatus, $previousUnifiedStatus, $occurrences, $autorecurring_type, $autorenew_type)); } } if (!in_array($unifiedStatus, array('Completed', 'Processed')) || $thisIsReferencePayment) { if (!$pluginsLoaded) { $_PLUGINS->loadPluginGroup('user', 'cbsubs.'); $_PLUGINS->loadPluginGroup('user/plug_cbpaidsubscriptions/plugin'); } $_PLUGINS->trigger('onCPayAfterPaymentStatusUpdateEvent', array(&$user, &$paymentBasket, &$subscriptions, $unifiedStatus, $previousUnifiedStatus, $eventType, &$notification)); } }
/** * 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 ($this->time_paid && $this->time_paid != $this->_db->getNullDate()) { $time_paid = cbpaidTimes::getInstance()->strToTime($this->time_paid); // we do NOT use PHP strtotime, which is broken $dateDayHour = explode(' ', cbpaidTimes::getInstance()->localDate('Y-m-d w H o W', $time_paid)); $dateDayHour[1] += 1; // --> 1 = Sunday...7 = Saturday, ISO-8601 numeric representation of the day of the week, like MySQL $this->time_paid_date = $dateDayHour[0]; $this->time_paid_day_of_week = $dateDayHour[1]; $this->time_paid_yearweek = $dateDayHour[3] . '-W' . $dateDayHour[4]; $this->time_paid_yearmonth = substr($dateDayHour[0], 0, 7); $this->time_paid_hour = $dateDayHour[2]; } return parent::store($updateNulls); }
/** * Updates the payment item corresponding to this Something * * @param cbpaidPaymentItem $item * @param cbpaidPaymentBasket $paymentBasket * @param int $quantity Quantity * @param string $currency_code The currency of the payment basket (so the payment item must be converted into that currency * @return void */ public function updatePaymentItem(&$item, $paymentBasket, $quantity = null, $currency_code = null) { $item->callIntegrations('beforeUpdatePaymentItem', $this, $paymentBasket); if ($quantity === null) { $quantity = $item->quantity; } if ($currency_code === null) { $currency_code = $item->currency; } $reason = $item->reason; $tryAutorecurring = $item->autorecurring; $start_time = cbpaidTimes::getInstance()->strToTime($item->start_date); list($first_rate, , $rate, , $prorate_discount, , ) = $this->computeItemRatesAndValidity($quantity, $currency_code, $reason, $start_time, $tryAutorecurring); if ($first_rate !== false) { $item->quantity = $quantity; $item->currency = $currency_code; $item->first_rate = $first_rate; $item->rate = $rate; $item->prorate_discount = $prorate_discount; } $item->callIntegrations('afterUpdatePaymentItem', $this, $paymentBasket); }
/** * This is the frontend or backend method used directly * @see cbpaidPaymentBasket::store() * * 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) { global $_CB_framework, $_CB_database; // 1) check: if (!in_array($this->payment_status, array('Pending', 'Refunded', 'NotInitiated'))) { $this->setError(CBPTXT::T("This payment basket is not pending.")); return false; } if ($this->txn_id == '') { $this->txn_id = 'None'; // needed for updatePayment to generate payment record. } $paymentBasket = new cbpaidPaymentBasket($_CB_database); $paymentBasket->load($this->id); if (!$paymentBasket->gateway_account) { $this->setError(CBPTXT::T("This payment basket has no gateway associated so can not be paid manually.")); return false; } $ipn = new cbpaidPaymentNotification($_CB_database); $ipn->bindObjectToThisObject($paymentBasket, 'id'); $ipn->mc_currency = $this->mc_currency; $ipn->mc_gross = $this->mc_gross; if (!preg_match('/^[1-9][0-9]{3}-[01][0-9]-[0-3][0-9]/', $this->time_completed)) { $this->time_completed = Application::Database()->getUtcDateTime(); } $paymentBasket->time_completed = $this->time_completed; $ipn->payment_type = $this->payment_type; $paymentBasket->payment_type = $this->payment_type; $ipn->txn_id = $this->txn_id; $paymentBasket->txn_id = $this->txn_id; $ipn->payment_status = 'Completed'; $ipn->txn_type = 'web_accept'; $ipn->payment_method = $this->payment_method; $ipn->gateway_account = $this->gateway_account; $ipn->log_type = 'P'; $ipn->time_received = $_CB_database->getUtcDateTime(); $ipn->payment_date = gmdate('H:i:s M d, Y T', $this->time_completed ? cbpaidTimes::getInstance()->strToTime($this->time_completed) : cbpaidTimes::getInstance()->startTime()); // paypal-style //TBD FIXME: WE SHOULD CHANGE THIS OLD DATE STYLE ONCE WITH UTC timezone inputed $ipn->payment_basket_id = $this->id; $ipn->raw_result = 'manual'; $ipn->raw_data = ''; $ipn->ip_addresses = cbpaidRequest::getIPlist(); $ipn->user_id = Application::MyUser()->getUserId(); $ipn->txn_id = $this->txn_id; $ipn->payment_type = $this->payment_type; $ipn->charset = $_CB_framework->outputCharset(); //TBD /* $paymentBasket->first_name = $ipn->first_name = cbGetParam( $_POST, 'txtBTitle' ); $paymentBasket->first_name = $ipn->first_name = cbGetParam( $_POST, 'txtBFirstName' ); $paymentBasket->last_name = $ipn->last_name = cbGetParam( $_POST, 'txtBLastName' ); $paymentBasket->address_street = $ipn->address_street = cbGetParam( $_POST, 'txtBAddr1' ); $paymentBasket->address_zip = $ipn->address_zip = cbGetParam( $_POST, 'txtBZipCode' ); $paymentBasket->address_city = $ipn->address_city = cbGetParam( $_POST, 'txtBCity' ); $paymentBasket->address_country = $ipn->address_country = cbGetParam( $_POST, 'txtBCountry' ); //TBD? $paymentBasket->phone = $ipn->phone = cbGetParam( $_POST, 'txtBTel' ); //TBD? $paymentBasket->fax = $ipn->fax = cbGetParam( $_POST, 'txtBFax' ); $paymentBasket->payer_email = $ipn->payer_email = cbGetParam( $_POST, 'txtBEmail' ); */ if (!$_CB_database->insertObject($ipn->getTableName(), $ipn, $ipn->getKeyName())) { trigger_error('store error:' . htmlspecialchars($_CB_database->getErrorMsg()), E_USER_ERROR); //TBD also in paypal: error code 500 !!! } $payAccount = cbpaidControllerPaychoices::getInstance()->getPayAccount($paymentBasket->gateway_account); if (!$payAccount) { $this->setError(CBPTXT::T("This payment basket's associated gateway account is not active, so can not be paid manually.")); return false; } $payClass = $payAccount->getPayMean(); $payClass->updatePaymentStatus($paymentBasket, 'web_accept', 'Completed', $ipn, 1, 0, 0, 'singlepayment'); return true; }
/** * View for <param type="private" class="cbpaidParamsExt" method="checkcertificate">... * * @param string $value Stored Data of Model Value associated with the element * @param ParamsInterface $pluginParams Main settigns parameters of the plugin * @param string $name Name attribute * @param CBSimpleXMLElement $param This XML node * @param string $control_name Name of the control * @param string $control_name_name css id-encode of the names of the controls surrounding this node * @param boolean $view TRUE: view, FALSE: edit * @param cbpaidTable $modelOfData Data of the Model corresponding to this View * @param cbpaidTable[] $modelOfDataRows Displayed Rows if it is a table * @param int $modelOfDataRowsNumber Total Number of rows * @return null|string */ public function checkcertificate($value, &$pluginParams, $name, &$param, $control_name, $control_name_name, $view, &$modelOfData, &$modelOfDataRows, &$modelOfDataRowsNumber) { $return = ''; $default = $param->attributes('default'); $filePath = isset($modelOfData->{$default}) ? $modelOfData->{$default} : null; //->get( 'default' ); $ok = false; if ($filePath) { $readable = @file_exists($filePath) && @is_readable($filePath); if ($readable) { $certificate = @openssl_x509_read(file_get_contents($filePath)); if ($certificate !== false) { $details = @openssl_x509_parse($certificate, false); if ($details !== false) { /* foreach ( $details as $k => $v ) { $return .= $k . ': ' . $v . '<br />'; } $return .= var_export( $details, true ) . '<br />'; */ $return .= isset($details['name']) ? "Name: " . $details['name'] . '<br />' : ''; $return .= isset($details['validFrom_time_t']) ? "Valid from: " . cbpaidTimes::getInstance()->getUtcDateOfTime($details['validFrom_time_t']) . '<br />' : ''; $return .= isset($details['validTo_time_t']) ? "Valid until: " . cbpaidTimes::getInstance()->getUtcDateOfTime($details['validTo_time_t']) . '<br />' : ''; $ok = true; if (isset($details['validTo_time_t']) && $details['validTo_time_t'] < time()) { $return .= '<br /><span class="cbSmallWarning">' . "Certificate has expired !" . '</span>'; $ok = false; } elseif (isset($details['validFrom_time_t']) && $details['validFrom_time_t'] > time()) { $return .= '<br /><span class="cbSmallWarning">' . "Certificate is not yet valid !" . '</span>'; $ok = false; } else { $return .= "Certificate appears valid"; } } else { $return = "File is not a X509 certificate (public key)"; } } else { $return = sprintf("File %s is readable but can not be opened as a X509 certificate (openssl_x509_read failed on public key cert)", $filePath); } } else { $return = sprintf("File %s does not exist or is not readable", $filePath); } } else { $return = "Filename not set"; } return $this->_outputGreenRed('', $ok, $return, $return); }
/** * Renders a calendar or time-period validity period, e.g. Year 2007, March - May 2007, December 2006 - January 2007, etc. * * @param int|null $expiryTime Unix-time * @param int|null $startTime Unix-time * @param string $varName variable name ( 'validity' (default) or 'first_validity' ) * @param string $reason payment reason: 'N'=new subscription (default), 'R'=renewal, 'U'=update (needed only if $expiryTime is NULL) * @param int $occurrences number of occurrences (needed only if $expiryTime is NULL) * @param boolean $displayOne Display significant 1s also if it's 1: e.g. TRUE: 1 year, FALSE: year * @param boolean $html true: Display for html with non-breaking spaces * @param string $status status of subscription * @return string */ public function getFormattedValidity($expiryTime, $startTime, $varName, $reason = null, $occurrences = 1, $displayOne = true, $html = false, $status = 'I') { $this->fixVarName($varName); $text = ''; if ($this->isCalendarValidity($varName)) { $now = cbpaidTimes::getInstance()->startTime(); if ($startTime === null) { $startTime = $now; } if ($expiryTime === null) { $expiryTime = $this->getExpiryTime($startTime, $varName, $occurrences, $reason, $status); // WARNING: adjusts $startTime to the real Start-time, which is wanted here } $isValid = $now < $expiryTime; list($y, $c, $d, , , ) = $this->getValidity($varName); // = sscanf( substr( $this->get( $varName ), 2 ), '%d-%d-%d %d:%d:%d' ); list($yn, $cn, $dn) = sscanf(cbpaidTimes::getInstance()->localDate('Y-m-d', $now), '%d-%d-%d'); list($ys, $cs, $ds) = sscanf(cbpaidTimes::getInstance()->localDate('Y-m-d', $startTime), '%d-%d-%d'); list($ye, $ce, $de) = sscanf(cbpaidTimes::getInstance()->localDate('Y-m-d', $expiryTime), '%d-%d-%d'); $calStart = $this->calendarYearStart($varName); if ($y && $calStart == '01-01') { if ($y == 1 && $ye <= $ys + 1) { $text .= sprintf($this->_htmlNbsp(CBPTXT::T("Year %s"), $html), $ye); // 'Year 2007' if ($ye != $yn && $isValid) { $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } } else { $years = $ye - $ys + 1; if (!$isValid || $y == $years && $ys == $yn) { $text .= sprintf($this->_htmlNbsp(CBPTXT::T("Years %s - %s"), $html), $ys, $ye); // 'Years 2006 - 2007' } else { if ($y == $years) { $text .= sprintf($this->_htmlNbsp(CBPTXT::T("Years %s - %s"), $html), $ys, $ye); // 'Years 2007 - 2008' } else { $text .= sprintf($this->_htmlNbsp(CBPTXT::T("Years %s - %s"), $html), $ys + 1, $ye); // 'Years 2007 - 2008' } $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } } } elseif ($c || $y) { if ($calStart != '01-01' && !preg_match('/$..-01/', $calStart)) { // $text .= $calStart . date( 'Y-m-d H:i:s', $startTime ) .( $c + ( $y * 12 ) ) . '_' . ($ce - $cs + 1 + ( ( $ye - $ys ) * 12 )) . '_'; $text .= CBPTXT::Tdate('j F', $startTime) . ($ys != $ye ? $this->_htmlNbsp(' ', $html) . $ys : ''); // 'January' or 'December 2006' $text .= $this->_htmlNbsp(' - ', $html); // ' - ' $text .= CBPTXT::Tdate('j F', $expiryTime) . $this->_htmlNbsp(' ', $html) . $ye; // 'February 2007' if (($ys > $yn || $cs > $cn && $ys == $yn) && $isValid) { $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } } else { $months = $ce - $cs + 1 + ($ye - $ys) * 12; if ($c == 1 && $y == 0 || $months == 1) { $text .= CBPTXT::Tdate('F', $expiryTime) . $this->_htmlNbsp(' ', $html) . $ye; // 'January 2007' if ($ce != $cn && $isValid) { $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } } else { // if ( ( $c + ( $y * 12 ) ) == $months ) { $text .= CBPTXT::Tdate('F', $startTime) . ($ys != $ye ? $this->_htmlNbsp(' ', $html) . $ys : ''); // 'January' or 'December 2006' $text .= $this->_htmlNbsp(' - ', $html); // ' - ' $text .= CBPTXT::Tdate('F', $expiryTime) . $this->_htmlNbsp(' ', $html) . $ye; // 'February 2007' if (!($cs == $cn && $ys == $yn) && $isValid) { $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } // } else { //TBD: check if this else is still needed /* list($ynn, $cnn, $dnn, $hnn, $mnn, $snn) = sscanf( gmdate( 'Y-m-d H:i:s', $startTime ), '%d-%d-%d %d:%d:%d' ); $cnn += 2; $dnn = 0; $nextMonthTime = mktime($hnn, $mnn, $snn, $cnn, $dnn, $ynn); $text .= gmdate( 'F', $nextMonthTime) . ( ( $ynn != $ye ) ? $this->_htmlNbsp( ' ', $html ) . $ynn : '' ); // 'January' or 'December 2006' $text .= $this->_htmlNbsp( ' - ', $html ); // ' - ' $text .= gmdate( 'F', $expiryTime) . $this->_htmlNbsp( ' ', $html ) . $ye; // 'February 2007' if ( $isValid ) { $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } */ // } } } } elseif ($d) { if ($de == $dn) { $text .= CBPTXT::T("Today"); } elseif ($de == $dn + 1 || $de == 1 && $expiryTime - $now < 48 * 3600) { if ($d == 1) { $text .= CBPTXT::T("Tomorrow"); if ($isValid) { $text .= ' (' . CBPTXT::T("valid from now on") . ')'; } } else { $text .= CBPTXT::T("Today and tomorrow"); } } else { if ($isValid) { $days = (int) floor(($expiryTime - $now) / (24 * 3600)); if ($days < $d && $ds == $dn) { $t = CBPTXT::T("Today and next %d days"); if ($html) { $t = str_replace(' %d ', ' %d ', $t); } $text .= sprintf($t, $days); } else { $text .= sprintf($this->_htmlNbsp(CBPTXT::T("Next %d days"), $html), $days) . ' (' . CBPTXT::T("in addition of today, valid from now on") . ')'; } } else { $showtime = false; cbimport('cb.tabs'); // cbFormatDate is in comprofiler.class.php $expText = cbFormatDate($expiryTime, 0, $showtime); $startText = cbFormatDate($startTime, 0, $showtime); $text .= $startText; if ($startText != $expText) { $text .= $this->_htmlNbsp(' - ', $html) . $expText; } } } } } else { $text = $this->_htmlNbsp($this->renderPeriod($this->getValidity($varName), 1, $displayOne), $html); } return trim($text); }
/** * Compares $v1 to $v2 using $diffOperator and of $diffOperator is a duration-date (e.g. '-0000-00-01 00:00:00'), $diffLarger will give the underlying operator * @param string $v1 Value 1 * @param string $v2 Value 2 * @param string $diffOperator =,<,>,!=,E,!E,regexp,!regexp,birthday,+0000-00-01 00:00:00 * @param string $diffLarger * @return boolean */ private function _compareValuesWithOperator( $v1, $v2, $diffOperator, $diffLarger ) { global $_CB_database; switch ( $diffOperator ) { case '=': return ( $v1 == $v2 ); break; case '<': return ( $v1 < $v2 ); break; case '>': return ( $v1 > $v2 ); break; case '!=': return ( $v1 != $v2 ); break; case 'E': return ( stripos( $v1, $v2 ) !== false ); break; case '!E': return ( stripos( $v1, $v2 ) === false ); break; case 'regexp': return preg_match( $v1, $v2 ); break; case '!regexp': return ! preg_match( $v1, $v2 ); break; case 'birthday': return ( ( strlen( $v1 ) >= 10 ) && ( strlen( $v2 ) >= 10 ) ) && ( substr( $v1, 5, 5 ) == substr( $v2, 5, 5 ) ) // same month and day && ( substr( $v1, 0, 4 ) != substr( $v2, 0, 4 ) ); // but not same year break; default: if ( strlen($diffOperator ) == 20 ) { //TODO make it work for dates < 1970 !!!! AND for DATE without TIME if ( ( strlen( $v1 ) == 19 ) && ( $v1 != $_CB_database->getNullDate() ) ) { $t1 = cbpaidTimes::getInstance()->strToTime( $v1 ); } else { $t1 = 0; } if ( ( strlen( $v2 ) == 19 ) && ( $v2 != $_CB_database->getNullDate() ) ) { $t2 = $this->_timeAddSubDurationToDate( $diffOperator, $v2 ); } else { $t2 = 0; } return ( $diffLarger ? ( $t1 >= $t2 ) : ( $t1 <= $t2 ) ); } else { // no condition means this condition is OK: return true; } break; } }
/** * Returns formatted time period ( xxx weeks , or xxx years xxx months xxx days xxx hours xxx minutes xxx seconds * * @param int[] $ycdhmsArray = list( $years, $months, $days, $hours, $minutes, $seconds ) * @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 string $prefix text between number and period, e.g. 3 calendar months * @return string */ public function renderPeriod( $ycdhmsArray, $occurrences = 1, $displayOne = true, $prefix = '' ) { $cbpaidTimes =& cbpaidTimes::getInstance(); return $cbpaidTimes->renderPeriod( $ycdhmsArray, $occurrences, $displayOne, $prefix ); }
/** * Computes SQL DATETIME of next schedule based on $baseObject * * @param exampleScheduledClass $baseObject * @param boolean $justFailed * @return string */ public function computeMaturity($baseObject, $justFailed = false) { static $timeWords = array('S' => 'second', 'I' => 'minute', 'H' => 'hours', 'D' => 'day', 'W' => 'week', 'M' => 'month', 'Y' => 'year'); $nextMaturityTime = cbpaidTimes::getInstance()->gmStrToTime($baseObject->subscr_date); $recurrings = $baseObject->recur_times_used; // first period: if ($baseObject->period1) { $parray = explode(' ', $baseObject->period1); // e.g. '12 M' => array( '12', 'M' ) if (count($parray) == 2 && isset($timeWords[$parray[1]])) { // check format $nextMaturityTime = cbpaidTimes::getInstance()->gmStrToTime('+' . $parray[0] . ' ' . $timeWords[$parray[1]], $nextMaturityTime); // e.g. '+ 12 months' } } else { ++$recurrings; } // reoccuring period: if ($recurrings) { $parray = explode(' ', $baseObject->period3); // e.g. '12 M' => array( '12', 'M' ) if (count($parray) == 2 && isset($timeWords[$parray[1]])) { // Format is valid ? // Format is valid: $number = intval($parray[0]) * $recurrings; $nextMaturityTime = cbpaidTimes::getInstance()->gmStrToTime('+' . $number . ' ' . $timeWords[$parray[1]], $nextMaturityTime); // e.g. '+ 12 months' } } $nextMaturityTime += $baseObject->reattempts_tried * $this->retryInterval; if ($justFailed) { $tomorrow = cbpaidTimes::getInstance()->startTime() + $this->retryInterval; if ($tomorrow > $nextMaturityTime) { $nextMaturityTime = $tomorrow; } } return Application::Database()->getUtcDateTime($nextMaturityTime); }
/** * Checks if currency conversion of $this is up to date * * @param int $extraHoursOfValidity number of hours of extra-validity * @param string $renewalInterval strtotime relative time of validity (default: '+12 hours') * @return boolean TRUE: entry is up-to-date, FALSE: not up-to-date */ public function isUpToDate($extraHoursOfValidity = 0, $renewalInterval = '+12 hours') { global $_CB_framework; if ($this->last_renewed_date && $this->last_renewed_date != '0000-00-00 00:00:00') { $now = $_CB_framework->now(); $lastRenewedTime = cbpaidTimes::getInstance()->strToTime($this->last_renewed_date); $nextRenewalDue = cbpaidTimes::getInstance()->gmStrToTime($renewalInterval, $lastRenewedTime); $result = $now < $nextRenewalDue + $extraHoursOfValidity * 3600; } else { $result = false; } return $result; }
/** * Computes start time from $endTime for $showPeriod date * @param string $showPeriod SQL DATETIME formatted period of time * @param int $endTime End time * @return int|null Start-time or null for not computable */ private function _periodOfValidity($showPeriod, $endTime) { if (!$showPeriod || $showPeriod == '0000-00-00 00:00:00') { return null; } $duration = cbpaidTimes::getInstance()->dateInterval($showPeriod); $systemTimeZone = new DateTimeZone(cbpaidTimes::getInstance()->systemTimeZone()); $endDate = new DateTime('@' . $endTime, $systemTimeZone); $endDate->setTimezone($systemTimeZone); $startDate = $endDate->sub($duration); return $startDate->getTimestamp(); }
/** * Returns today's date in an array * * @return array array( year, month, day ) */ protected static function _getYearMonthDay() { return explode('-', cbpaidTimes::getInstance()->localDate('Y-m-d')); }
/** * Adds rate periods start and stop periods * * @param array $ratePeriods * @param cbpaidPaymentBasket $paymentBasket * @param int $paymentItemIndex * @param cbpaidsalestaxTotalizertype $taxRate * @param string $taxRate_stop_date * @param boolean $hasSecondPeriod * @param string $itemSecondStart */ private static function addRatePeriodJustStartDates( &$ratePeriods, $paymentBasket, $paymentItemIndex, $taxRate, $taxRate_stop_date, $hasSecondPeriod, $itemSecondStart ) { global $_CB_framework; $offset = (int) $_CB_framework->getCfg( 'offset' ) * 3600; $paymentBasketDay = date( 'Y-m-d', cbpaidTimes::getInstance()->strToTime( $paymentBasket->time_initiated ) + $offset ); $taxApplicableToFirstPeriod = ( $taxRate->start_date <= $paymentBasketDay ) && ( $taxRate_stop_date >= $paymentBasketDay ); $taxApplicableToSecondPeriod = $hasSecondPeriod && ( $taxRate->start_date <= $itemSecondStart ) && ( $taxRate_stop_date >= $itemSecondStart ); if ( $taxApplicableToFirstPeriod && $taxApplicableToSecondPeriod ) { $ratePeriods[0][0] = '0000-00-00'; $ratePeriods[0][1] = '0000-00-00'; $ratePeriods[0][2] = 'all'; $ratePeriods[0][3] = 0; $ratePeriods[0][4] = 0; $ratePeriods[0][5] = 0; $ratePeriods[0][6] = 0; $ratePeriods[0][7][] = $paymentItemIndex; } elseif ( $taxApplicableToFirstPeriod ) { $ratePeriods[] = array( $paymentBasketDay, $paymentBasketDay, 'first', 0, 0, 0, 0, array( $paymentItemIndex ) ); } elseif ( $taxApplicableToSecondPeriod ) { $ratePeriods[] = array( $itemSecondStart, $itemSecondStart, 'second', 0, 0, 0, 0, array( $paymentItemIndex ) ); } }
/** * Renders payments cycles with rate and validity for $this basket * * @param boolean $html * @param boolean $roundings TRUE: use settings roundings, FALSE: round to cents * @return string HTML text */ public function renderRatesValidtiy( $html, $roundings = true ) { if ( $this->period1 ) { if ( $this->recur_times ) { $tmpltext = CBPTXT::T("%s for the first %s, then %s for each %s, in %s installments"); } else { $tmpltext = CBPTXT::T("%s for the first %s, then %s each %s"); //TBD: alternate text: "&s, then, after %s, %s each %s" } } else { if ( $this->recur_times ) { $tmpltext = CBPTXT::T("%3\$s for each %4\$s, in %5\$s installments"); } else { $tmpltext = CBPTXT::T("%3\$s for each %4\$s"); } } $cbpaidMoney =& cbpaidMoney::getInstance(); $cbpaidTimes =& cbpaidTimes::getInstance(); if ( $this->period1 ) { $validity = $this->ymwdPeriodToTimePeriod( $this->period1 ); $first_validity_text = $cbpaidTimes->renderPeriod( $validity, 1 , false ); $first_rate_text = $cbpaidMoney->renderPrice( $this->mc_amount1, $this->mc_currency, $html, $roundings ); } else { $first_validity_text = null; $first_rate_text = null; } $validity = $this->ymwdPeriodToTimePeriod( $this->period3 ); $validity_text = $cbpaidTimes->renderPeriod( $validity, 1 , false ); $rate_text = $cbpaidMoney->renderPrice( $this->mc_amount3, $this->mc_currency, $html, $roundings ); $text = sprintf( $tmpltext, $first_rate_text, $first_validity_text, $rate_text, $validity_text, $this->recur_times ); return $text; }
/** * Checks all subscriptions of this plan for mass-expiries * * @param int $limit limit of number of users to expire ( 0 = no limit ) * @return int Count of subscriptions expired for this plan. */ public function checkAllSubscriptions($limit) { $now = cbpaidTimes::getInstance()->startTime(); $nowGraceTimeAgo = $this->substractValidityFromTime($this->get('graceperiod'), $now); $cutOffDate = $this->_db->getUtcDateTime($nowGraceTimeAgo); $fields = array('user_id'); $conditions = array('plan_id' => array('=', (int) $this->get('id')), 'status' => array('=', 'A'), 'expiry_date' => array('<', $cutOffDate), 'expiry_date ' => array('>', '0000-00-00 00:00:00')); $ordering = array(); $subscriptionLoader = $this->newSubscription(); $subscriptionLoader->setMatchingQuery($fields, $conditions, $ordering, 0, $limit); $expiredUsers = $this->_db->loadResultArray(); if (count($expiredUsers) > 0) { $deactivatedSub = null; foreach ($expiredUsers as $user_id) { $paidUserExtension = cbpaidUserExtension::getInstance($user_id); $paidUserExtension->checkUserSubscriptions(false, $deactivatedSub, 'X', true); } } return count($expiredUsers); }
/** * 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; }
/** * Updates the payment item corresponding to this Something * * @param cbpaidPaymentItem $item * @param cbpaidPaymentBasket $paymentBasket * @param int $quantity Quantity * @param string $currency_code The currency of the payment basket (so the payment item must be converted into that currency * @return void */ public function updatePaymentItem(&$item, $paymentBasket, $quantity = null, $currency_code = null) { $item->callIntegrations('beforeUpdatePaymentItem', $this, $paymentBasket); if ($quantity === null) { $quantity = $item->quantity; } if ($currency_code === null) { $currency_code = $item->currency; } $start_time = cbpaidTimes::getInstance()->strToTime($item->start_date); $rate = $this->getPriceOfNextPayment($currency_code, $start_time, $quantity, $item->reason); if ($rate === false) { $rate = 0; } $item->currency = $currency_code; $item->rate = $rate; $item->quantity = $quantity; $item->callIntegrations('afterUpdatePaymentItem', $this, $paymentBasket); }
/** * 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; }
/** * 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->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") . ' ' . CBPTXT::Tdate('F j', cbpaidTimes::getInstance()->localStrToTime((int) $m . '/' . (int) $d)); } return $text; }