/**
  * Encrypt data.
  *
  * @param array $keys That must be an array that contains private and public keys.
  * @param mixed $data The data that has to be encrypted.
  *
  * @return mixed
  */
 public static function encrypt(array $keys, $data)
 {
     $chiper = new JCryptCipherRijndael256();
     $key = new JCryptKey("rijndael256", $keys["private"], $keys["public"]);
     $crypt = new JCrypt($chiper, $key);
     return $crypt->encrypt($data);
 }
 /**
  * Login authentication function.
  *
  * Username and encoded password are passed the onUserLogin event which
  * is responsible for the user validation. A successful validation updates
  * the current session record with the user's details.
  *
  * Username and encoded password are sent as credentials (along with other
  * possibilities) to each observer (authentication plugin) for user
  * validation.  Successful validation will update the current session with
  * the user details.
  *
  * @param   array  $credentials  Array('username' => string, 'password' => string)
  * @param   array  $options      Array('remember' => boolean)
  *
  * @return  boolean  True on success.
  *
  * @since   11.1
  */
 public function login($credentials, $options = array())
 {
     // Get the global JAuthentication object.
     jimport('joomla.user.authentication');
     $authenticate = JAuthentication::getInstance();
     $response = $authenticate->authenticate($credentials, $options);
     if ($response->status === JAuthentication::STATUS_SUCCESS) {
         // validate that the user should be able to login (different to being authenticated)
         // this permits authentication plugins blocking the user
         $authorisations = $authenticate->authorise($response, $options);
         foreach ($authorisations as $authorisation) {
             $denied_states = array(JAuthentication::STATUS_EXPIRED, JAuthentication::STATUS_DENIED);
             if (in_array($authorisation->status, $denied_states)) {
                 // Trigger onUserAuthorisationFailure Event.
                 $this->triggerEvent('onUserAuthorisationFailure', array((array) $authorisation));
                 // If silent is set, just return false.
                 if (isset($options['silent']) && $options['silent']) {
                     return false;
                 }
                 // Return the error.
                 switch ($authorisation->status) {
                     case JAuthentication::STATUS_EXPIRED:
                         return JError::raiseWarning('102002', JText::_('JLIB_LOGIN_EXPIRED'));
                         break;
                     case JAuthentication::STATUS_DENIED:
                         return JError::raiseWarning('102003', JText::_('JLIB_LOGIN_DENIED'));
                         break;
                     default:
                         return JError::raiseWarning('102004', JText::_('JLIB_LOGIN_AUTHORISATION'));
                         break;
                 }
             }
         }
         // Import the user plugin group.
         JPluginHelper::importPlugin('user');
         // OK, the credentials are authenticated and user is authorised.  Lets fire the onLogin event.
         $results = $this->triggerEvent('onUserLogin', array((array) $response, $options));
         /*
          * If any of the user plugins did not successfully complete the login routine
          * then the whole method fails.
          *
          * Any errors raised should be done in the plugin as this provides the ability
          * to provide much more information about why the routine may have failed.
          */
         if (!in_array(false, $results, true)) {
             // Set the remember me cookie if enabled.
             if (isset($options['remember']) && $options['remember']) {
                 // Create the encryption key, apply extra hardening using the user agent string.
                 $privateKey = self::getHash(@$_SERVER['HTTP_USER_AGENT']);
                 $key = new JCryptKey('simple', $privateKey, $privateKey);
                 $crypt = new JCrypt(new JCryptCipherSimple(), $key);
                 $rcookie = $crypt->encrypt(json_encode($credentials));
                 $lifetime = time() + 365 * 24 * 60 * 60;
                 // Use domain and path set in config for cookie if it exists.
                 $cookie_domain = $this->getCfg('cookie_domain', '');
                 $cookie_path = $this->getCfg('cookie_path', '/');
                 // Check for SSL connection
                 $secure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' || getenv('SSL_PROTOCOL_VERSION');
                 setcookie(self::getHash('JLOGIN_REMEMBER'), $rcookie, $lifetime, $cookie_path, $cookie_domain, $secure, true);
             }
             return true;
         }
     }
     // Trigger onUserLoginFailure Event.
     $this->triggerEvent('onUserLoginFailure', array((array) $response));
     // If silent is set, just return false.
     if (isset($options['silent']) && $options['silent']) {
         return false;
     }
     // If status is success, any error will have been raised by the user plugin
     if ($response->status !== JAuthentication::STATUS_SUCCESS) {
         JError::raiseWarning('102001', $response->error_message);
     }
     return false;
 }
Exemple #3
0
 /**
  * CURL-wrapper
  * 
  * @param string $url
  * @param string $type
  * @param array $arguments
  * @param boolean @run_bridge
  *                
  * @return string
  */
 public function getCURL($url, $type = 'get', $arguments = null, $runBridge = false)
 {
     // Load variables
     $httpHeaders = array();
     // Initialize CURL
     $handle = curl_init($url);
     if ($handle == false) {
         return null;
     }
     curl_setopt_array($handle, $this->getCurlDefaultArguments());
     $this->setCurlHeaders($handle);
     $this->setCurlHttpAuthentication($handle);
     // Forward cookies to Magento
     if ($runBridge == true) {
         $this->setCurlCookies($handle);
     }
     // Detect whether certain HTTP headers are set by the client
     foreach ($_SERVER as $header => $value) {
         if (!preg_match('/^http_/i', $header)) {
             continue;
         }
         $header = strtoupper(preg_replace('/http_/i', '', $header));
         if ($header == 'X_REQUESTED_WITH') {
             $httpHeaders[] = 'X-REQUESTED-WITH' . ': ' . $value;
         } else {
             if (preg_match('/^ACCEPT_/', $header)) {
                 $httpHeaders[] = str_replace('_', '-', $header) . ': ' . $value;
             }
         }
     }
     // Add proxy HTTP headers
     if (isset($_SERVER['REMOTE_ADDR'])) {
         $httpHeaders[] = 'X-REAL-IP: ' . $_SERVER['REMOTE_ADDR'];
     }
     if (isset($_SERVER['REMOTE_ADDR'])) {
         $httpHeaders[] = 'X-FORWARDED-FOR: ' . $_SERVER['REMOTE_ADDR'];
     }
     if (isset($_SERVER['SERVER_ADDR'])) {
         $httpHeaders[] = 'VIA: ' . $_SERVER['SERVER_ADDR'];
     }
     // Set SSL options
     $uri = JURI::getInstance();
     if ($uri->isSSL() == true) {
         $httpHeaders[] = 'FRONT-END-HTTPS: On';
     }
     if ($uri->isSSL() == true) {
         $httpHeaders[] = 'X-FORWARD-PROTO: https';
     }
     // Add some extra HTTP headers for HTTP Keep Alive
     if (MagebridgeModelConfig::load('keep_alive') == 0) {
         $httpHeaders[] = 'Connection: close';
     } else {
         $httpHeaders[] = 'Connection: keep-alive';
     }
     // Spoof the browser
     if (MagebridgeModelConfig::load('spoof_browser') == 1) {
         if ($runBridge == true && $this->app->isSite() == 1) {
             curl_setopt($handle, CURLOPT_REFERER, MageBridgeUrlHelper::getRequest());
             curl_setopt($handle, CURLOPT_USERAGENT, isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
         } else {
             curl_setopt($handle, CURLOPT_USERAGENT, $this->getUserAgentBySystem());
         }
     }
     // Automatically handle file uploads
     $tmp_files = $this->helper->upload();
     if (!empty($tmp_files)) {
         foreach ($tmp_files as $name => $tmp_file) {
             if (class_exists('CurlFile')) {
                 $arguments[$name] = new CurlFile($tmp_file['tmp_name'], $tmp_file['type']);
             } else {
                 $arguments[$name] = '@' . $tmp_file['tmp_name'];
             }
         }
     }
     // Set extra options when a POST is handled
     if ($type == 'post') {
         $arguments = is_array($arguments) && MagebridgeModelConfig::load('curl_post_as_array') == 0 ? http_build_query($arguments) : $arguments;
         curl_setopt($handle, CURLOPT_POST, true);
         curl_setopt($handle, CURLOPT_POSTFIELDS, $arguments);
         $httpHeaders[] = 'Expect:';
         //print_r($arguments);exit;
     }
     // Add the HTTP headers
     curl_setopt($handle, CURLOPT_HTTPHEADER, $httpHeaders);
     // Set encoding to zero
     curl_setopt($handle, CURLOPT_ENCODING, '');
     // Handle direct output and bridge output
     $this->debug->notice('CURL init: ' . $url . ' (' . (MageBridgeUrlHelper::getRequest() ? MageBridgeUrlHelper::getRequest() : 'no request') . ')');
     $this->handleFileDownloads($handle);
     $data = curl_exec($handle);
     $size = YireoHelper::strlen($data);
     if ($size > 1024) {
         $size = round($size / 1024, 2) . 'Kb';
     }
     $this->debug->profiler('CURL response size: ' . $size);
     // Cleanup the temporary uploads
     $this->helper->cleanup($tmp_files);
     // Separate the headers from the body
     $this->head['header_found'] = false;
     $this->head['last_url'] = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
     $this->head['http_code'] = curl_getinfo($handle, CURLINFO_HTTP_CODE);
     $this->head['size'] = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
     $this->head['info'] = curl_getinfo($handle);
     // Determine the separator
     $separator = null;
     if (strpos($data, "\r\n\r\n") > 0) {
         $separator = "\r\n\r\n";
     } elseif (strpos($data, "\n\n") > 0) {
         $separator = "\n\n";
     }
     // Split data into segments
     if (strpos($data, $separator) > 0) {
         $dataSegments = explode($separator, $data);
         $this->head['header_found'] = true;
         foreach ($dataSegments as $dataSegmentIndex => $dataSegment) {
             // Check for a segment that seems to contain HTTP-headers
             if (preg_match('/(Set-Cookie|Content-Type|Transfer-Encoding):/', $dataSegment)) {
                 // Get this segment
                 $this->head['headers'] = trim($dataSegment);
                 // Use the remaining segments for the body
                 unset($dataSegments[$dataSegmentIndex]);
                 $this->body = implode("\r\n", $dataSegments);
                 break;
             }
             // Only allow for a body after a header (and ignore double headers)
             unset($dataSegments[$dataSegmentIndex]);
         }
     }
     // Exit when no proper headers have been found
     if ($this->head['header_found'] == false) {
         $this->debug->warning('CURL contains no HTTP headers');
         return null;
     }
     if (empty($this->head['http_code'])) {
         $this->head['http_code'] = 200;
     }
     // Statistics
     $this->debug->profiler('CURL total time: ' . round(curl_getinfo($handle, CURLINFO_TOTAL_TIME), 4) . ' seconds');
     $this->debug->profiler('CURL connect time: ' . round(curl_getinfo($handle, CURLINFO_CONNECT_TIME), 4) . ' seconds');
     $this->debug->profiler('CURL DNS-time: ' . round(curl_getinfo($handle, CURLINFO_NAMELOOKUP_TIME), 4) . ' seconds');
     $this->debug->profiler('CURL download speed: ' . round(curl_getinfo($handle, CURLINFO_SPEED_DOWNLOAD * 8 / 1024), 4) . ' Kb/s');
     //$this->debug->trace( "CURL information", curl_getinfo($handle));
     //$this->debug->trace( "HTTP headers", $this->head );
     //$this->debug->trace( "HTTP body", $this->body );
     // Handle MageBridge HTTP-messaging
     if (preg_match_all('/X-MageBridge-(Notice|Error|Warning): ([^\\s]+)/', $this->head['headers'], $matches)) {
         foreach ($matches[0] as $index => $match) {
             $type = $matches[1][$index];
             $message = $matches[2][$index];
             if (!empty($type) && !empty($message)) {
                 $message = base64_decode($message);
                 $this->app->enqueueMessage($message, $type);
             }
         }
     }
     // Process the X-MageBridge-Customer header
     if ($this->getHeader('X-MageBridge-Customer') != null) {
         $value = $this->getHeader('X-MageBridge-Customer');
         MageBridgeModelBridge::getInstance()->addSessionData('customer/email', $value);
         MageBridgeModelUser::getInstance()->postlogin($value, null, true, true);
     }
     // Process the X-MageBridge-Form-Key header
     if ($this->getHeader('X-MageBridge-Form-Key') != null) {
         $value = $this->getHeader('X-MageBridge-Form-Key');
         MageBridgeModelBridge::getInstance()->addSessionData('form_key', $value);
     }
     // Log other Status Codes than 200
     if ($this->head['http_code'] != 200) {
         if ($this->head['http_code'] == 500) {
             $this->debug->error('CURL received HTTP status ' . $this->head['http_code']);
         } else {
             $this->debug->warning('CURL received HTTP status ' . $this->head['http_code']);
         }
     }
     // If we receive status 0, log it
     if ($this->head['http_code'] == 0) {
         $this->head['http_error'] = curl_error($handle);
         $this->debug->trace('CURL error', curl_error($handle));
     }
     // If we receive an exception, exit the bridge
     if ($this->head['http_code'] == 0 || $this->head['http_code'] == 500) {
         $this->init = self::CONNECTION_ERROR;
         $this->state = 'INTERNAL ERROR';
         curl_close($handle);
         return $this->body;
     }
     // If we receive a 404, log it
     if ($this->head['http_code'] == 404) {
         $this->init = self::CONNECTION_ERROR;
         $this->state = '404 NOT FOUND';
         curl_close($handle);
         if ($this->app->isSite() == 1 && MagebridgeModelConfig::load('enable_notfound') == 1) {
             JError::raiseError(404, JText::_('Page Not Found'));
             return null;
         } else {
             header('HTTP/1.0 404 Not Found');
             return $this->body;
         }
     }
     // If we have an empty body, log it
     if (empty($this->body)) {
         $this->debug->warning('CURL received empty body');
         if (!empty($this->head['headers'])) {
             $this->debug->trace('CURL headers', $this->head['headers']);
         }
     }
     // Define which cookies to spoof
     $cookies = MageBridgeBridgeHelper::getBridgableCookies();
     $defaultSessionName = ini_get('session.name');
     if (empty($defaultSessionName)) {
         $defaultSessionName = 'PHPSESSID';
     }
     $cookies[] = $defaultSessionName;
     // Add the default session for sake of badly written Magento extensions
     // Handle cookies
     if (MagebridgeModelConfig::load('bridge_cookie_all') == 1) {
         preg_match_all('/Set-Cookie: ([a-zA-Z0-9\\-\\_\\.]+)\\=(.*)/', $this->head['headers'], $matches);
     } else {
         preg_match_all('/Set-Cookie: (' . implode('|', $cookies) . ')\\=(.*)/', $this->head['headers'], $matches);
     }
     // Loop through the matches
     if (!empty($matches)) {
         $matchedCookies = array();
         foreach ($matches[0] as $index => $match) {
             // Extract the cookie-information
             $cookieName = $matches[1][$index];
             $cookieValue = $matches[2][$index];
             // Strip the meta-data from the cookie
             if (preg_match('/^([^\\;]+)\\;(.*)/', $cookieValue, $cookieValueMatch)) {
                 $cookieValue = $cookieValueMatch[1];
             }
             // Trim the cookie
             $cookieValue = trim($cookieValue);
             // Check if the cookie was dealt with or not
             if (in_array($cookieName, $matchedCookies)) {
                 continue;
             } else {
                 $matchedCookies[] = $cookieName;
             }
             // Set the cookie
             if (!headers_sent()) {
                 if ($cookieName == 'persistent_shopping_cart' && isset($matches[3][$index]) && preg_match('/expires=([^\\;]+)/', $matches[3][$index], $paramsMatch)) {
                     $expires = strtotime($paramsMatch[1]);
                 } else {
                     $expires = 0;
                 }
                 setcookie($cookieName, $cookieValue, $expires, '/', '.' . JURI::getInstance()->toString(array('host')));
                 $_COOKIE[$cookieName] = $cookieValue;
             }
             // Store this cookie also in the default Joomal! session (in case extra cookies are disabled)
             $session = JFactory::getSession();
             $session->set('magebridge.cookie.' . $cookieName, $cookieValue);
         }
     }
     // Handle the extra remember-me cookie
     $user = JFactory::getUser();
     if ($user->id > 0 && !empty($_COOKIE['persistent_shopping_cart'])) {
         $password = $user->password_clear;
         if (empty($password)) {
             $password = $this->input->getString('password');
         }
         if (empty($password)) {
             $password = $user->password;
         }
         if (!empty($password)) {
             $credentials = array('username' => $user->username, 'password' => $password);
             // Create the encryption key, apply extra hardening using the user agent string.
             $privateKey = JApplication::getHash(@$_SERVER['HTTP_USER_AGENT']);
             $key = new JCryptKey('simple', $privateKey, $privateKey);
             $crypt = new JCrypt(new JCryptCipherSimple(), $key);
             $rcookie = $crypt->encrypt(serialize($credentials));
             $lifetime = time() + 365 * 24 * 60 * 60;
             // Use domain and path set in config for cookie if it exists.
             $cookie_domain = JFactory::getConfig()->get('cookie_domain', '');
             $cookie_path = JFactory::getConfig()->get('cookie_path', '/');
             setcookie(JApplication::getHash('JLOGIN_REMEMBER'), $rcookie, $lifetime, $cookie_path, $cookie_domain);
         }
     }
     // Handle redirects
     preg_match('/^Location: ([^\\s]+)/m', $this->head['headers'], $matches);
     if ($this->allow_redirects && (preg_match('/^3([0-9]+)/', $this->head['http_code']) || !empty($matches))) {
         $originalLocation = trim(array_pop($matches));
         $location = $originalLocation;
         // Check for a location-override
         if ($this->getHeader('X-MageBridge-Location') != null) {
             // But only override the location, if there is no error present
             if (strstr($location, 'startcustomization=1') == false) {
                 $this->debug->notice('X-MageBridge-Location = ' . $this->getHeader('X-MageBridge-Location'));
                 $location = $this->getHeader('X-MageBridge-Location');
             }
         }
         // Check for a location-override if the customer is logged in
         if ($this->getHeader('X-MageBridge-Location-Customer') != null && $this->getHeader('X-MageBridge-Customer') != null) {
             MageBridgeModelUser::getInstance()->postlogin($this->getHeader('X-MageBridge-Customer'), null, true, true);
             $this->debug->notice('X-MageBridge-Location-Customer = ' . $this->getHeader('X-MageBridge-Location-Customer'));
             $location = $this->getHeader('X-MageBridge-Location-Customer');
         }
         // Check for the location in the CURL-information
         if (empty($location) && isset($this->head['info']['redirect_url'])) {
             $location = $this->head['info']['redirect_url'];
         }
         // No location could be found
         if (empty($location)) {
             $this->debug->trace('Redirect requested but no URL found', $this->head['headers']);
             return false;
         }
         // Check if the current location is the Magento homepage, and if so, override it with the Joomla!-stored referer instead
         $referer = $this->bridge->getHttpReferer();
         if ($location == $this->bridge->getJoomlaBridgeUrl()) {
             if (MagebridgeModelConfig::load('use_homepage_for_homepage_redirects') == 1) {
                 $location = JURI::base();
             } elseif (MagebridgeModelConfig::load('use_referer_for_homepage_redirects') == 1 && !empty($referer) && $referer != JURI::current()) {
                 $location = $referer;
             }
         }
         //$location = preg_replace('/magebridge\.php\//', '', $location);
         $this->debug->warning('Trying to redirect to new location ' . $location);
         header('X-MageBridge-Redirect: ' . $originalLocation);
         $this->setRedirect($location);
     }
     curl_close($handle);
     return $this->body;
 }
 /**
  * Encrypt a string
  *
  * @param   string  $s  String to encrypt
  *
  * @return  string
  *
  * @since   11.1
  * @deprecated  12.3  Use JCrypt instead.
  */
 public function encrypt($s)
 {
     return $this->_crypt->encrypt($s);
 }
Exemple #5
0
 /**
  * Process Subscription 
  *
  * @param array $data
  */
 function processSubscription($data)
 {
     jimport('joomla.user.helper');
     $db = JFactory::getDbo();
     $row = JTable::getInstance('OsMembership', 'Subscriber');
     $query = $db->getQuery(true);
     $config = OSMembershipHelper::getConfig();
     $user = JFactory::getUser();
     $userId = $user->get('id');
     $nullDate = $db->getNullDate();
     $fieldSuffix = OSMembershipHelper::getFieldSuffix();
     if (!$userId && $config->registration_integration) {
         //Store user account into Joomla users database
         if ($config->create_account_when_membership_active !== '1') {
             $userId = OSMembershipHelper::saveRegistration($data);
         } else {
             //Encrypt the password and store into  #__osmembership_subscribers table and create the account layout
             $privateKey = md5(JFactory::getConfig()->get('secret'));
             $key = new JCryptKey('simple', $privateKey, $privateKey);
             $crypt = new JCrypt(new JCryptCipherSimple(), $key);
             $data['user_password'] = $crypt->encrypt($data['password1']);
         }
     }
     $data['transaction_id'] = strtoupper(JUserHelper::genRandomPassword(16));
     $row->bind($data);
     $row->published = 0;
     $row->created_date = JFactory::getDate()->toSql();
     $row->user_id = $userId;
     while (true) {
         $subscriptionCode = JUserHelper::genRandomPassword(10);
         $query->select('COUNT(*)')->from('#__osmembership_subscribers')->where('subscription_code=' . $db->quote($subscriptionCode));
         $db->setQuery($query);
         $total = $db->loadResult();
         if (!$total) {
             break;
         }
     }
     $row->subscription_code = $subscriptionCode;
     $query->clear();
     $query->select('id')->from('#__osmembership_subscribers')->where("is_profile=1 AND ((user_id={$userId} AND user_id>0) OR email='{$row->email}')");
     $db->setQuery($query);
     $profileId = $db->loadResult();
     if ($profileId) {
         $row->is_profile = 0;
         $row->profile_id = $profileId;
     } else {
         $row->is_profile = 1;
     }
     $row->language = JFactory::getLanguage()->getTag();
     $query->clear();
     $query->select('*, title' . $fieldSuffix . ' AS title')->from('#__osmembership_plans')->where('id=' . (int) $data['plan_id']);
     $db->setQuery($query);
     $rowPlan = $db->loadObject();
     $rowFields = OSMembershipHelper::getProfileFields($row->plan_id, false);
     $form = new RADForm($rowFields);
     $form->setData($data)->bindData(true);
     $fees = OSMembershipHelper::calculateSubscriptionFee($rowPlan, $form, $data, $config, $row->payment_method);
     $action = $data['act'];
     if ($action == 'renew') {
         $renewOptionId = (int) $data['renew_option_id'];
         if ($renewOptionId == OSM_DEFAULT_RENEW_OPTION_ID) {
             $dateIntervalSpec = 'P' . $rowPlan->subscription_length . $rowPlan->subscription_length_unit;
         } else {
             $query->clear();
             $query->select('number_days')->from('#__osmembership_renewrates')->where('id=' . (int) $data['renew_option_id']);
             $db->setQuery($query);
             $numberDays = (int) $db->loadResult();
             $dateIntervalSpec = 'P' . $numberDays . 'D';
         }
     } elseif ($action == 'upgrade') {
         $dateIntervalSpec = 'P' . $rowPlan->subscription_length . $rowPlan->subscription_length_unit;
     } else {
         if ($rowPlan->recurring_subscription && $rowPlan->trial_duration) {
             $dateIntervalSpec = 'P' . $rowPlan->trial_duration . $rowPlan->trial_duration_unit;
         } else {
             $dateIntervalSpec = 'P' . $rowPlan->subscription_length . $rowPlan->subscription_length_unit;
         }
     }
     $maxDate = null;
     if ($row->user_id > 0) {
         //Subscriber, user existed
         $query->clear();
         $query->select('MAX(to_date)')->from('#__osmembership_subscribers')->where('user_id=' . $row->user_id . ' AND plan_id=' . $row->plan_id . ' AND (published=1 OR (published = 0 AND payment_method LIKE "os_offline%"))');
         $db->setQuery($query);
         $maxDate = $db->loadResult();
     }
     if ($maxDate) {
         $date = JFactory::getDate($maxDate);
         $row->from_date = $date->add(new DateInterval('P1D'))->toSql();
     } else {
         $date = JFactory::getDate();
         $row->from_date = $date->toSql();
     }
     if ($rowPlan->expired_date && $rowPlan->expired_date != $nullDate) {
         $expiredDate = JFactory::getDate($rowPlan->expired_date);
         $expiredDate->setTime(0, 0, 0);
         $startDate = clone $date;
         $startDate->setTime(0, 0, 0);
         if ($startDate >= $expiredDate) {
             $date->setDate($date->year + 1, $expiredDate->month, $expiredDate->day);
             $row->to_date = $date->toSql();
         } else {
             $row->to_date = $rowPlan->expired_date;
         }
     } else {
         if ($rowPlan->lifetime_membership) {
             $row->to_date = '2099-12-31 23:59:59';
         } else {
             $row->to_date = $date->add(new DateInterval($dateIntervalSpec))->toSql();
         }
     }
     $couponCode = JRequest::getVar('coupon_code', '');
     $couponId = 0;
     if ($couponCode && $fees['coupon_valid']) {
         $query->clear();
         $query->select('id')->from('#__osmembership_coupons')->where('code=' . $db->quote($couponCode));
         $db->setQuery($query);
         $couponId = (int) $db->loadResult();
         $query->clear();
         $query->update('#__osmembership_coupons')->set('used=used+1')->where('id=' . $couponId);
         $db->setQuery($query);
         $db->execute();
     }
     $row->amount = $fees['amount'];
     $row->discount_amount = $fees['discount_amount'];
     $row->tax_amount = $fees['tax_amount'];
     $row->payment_processing_fee = $fees['payment_processing_fee'];
     $row->coupon_id = $couponId;
     $row->gross_amount = $fees['gross_amount'];
     $row->store();
     if (!$row->profile_id) {
         $row->profile_id = $row->id;
         $row->store();
     }
     $data['amount'] = $fees['gross_amount'];
     //Store custom field data
     $form->storeData($row->id, $data);
     //Syncronize profile data for other records
     OSMembershipHelper::syncronizeProfileData($row, $data);
     JPluginHelper::importPlugin('osmembership');
     $dispatcher = JDispatcher::getInstance();
     $dispatcher->trigger('onAfterStoreSubscription', array($row));
     $data['regular_price'] = $fees['regular_gross_amount'];
     $data['trial_amount'] = $fees['trial_gross_amount'];
     if ($data['amount'] > 0 || $rowPlan->recurring_subscription) {
         switch ($action) {
             case 'renew':
                 $itemName = JText::_('OSM_PAYMENT_FOR_RENEW_SUBSCRIPTION');
                 $itemName = str_replace('[PLAN_TITLE]', $rowPlan->title, $itemName);
                 break;
             case 'upgrade':
                 $itemName = JText::_('OSM_PAYMENT_FOR_UPGRADE_SUBSCRIPTION');
                 $itemName = str_replace('[PLAN_TITLE]', $rowPlan->title, $itemName);
                 //Get from Plan Title
                 $query->clear();
                 $query->select('a.title')->from('#__osmembership_plans AS a')->innerJoin('#__osmembership_upgraderules AS b ON a.id=b.from_plan_id')->where('b.id=' . $row->upgrade_option_id);
                 $db->setQuery($query);
                 $fromPlanTitle = $db->loadResult();
                 $itemName = str_replace('[FROM_PLAN_TITLE]', $fromPlanTitle, $itemName);
                 break;
             default:
                 $itemName = JText::_('OSM_PAYMENT_FOR_SUBSCRIPTION');
                 $itemName = str_replace('[PLAN_TITLE]', $rowPlan->title, $itemName);
                 break;
         }
         $data['item_name'] = $itemName;
         $paymentMethod = $data['payment_method'];
         require_once JPATH_COMPONENT . '/plugins/' . $paymentMethod . '.php';
         $query->clear();
         $query->select('params, support_recurring_subscription')->from('#__osmembership_plugins')->where('name=' . $db->quote($paymentMethod));
         $db->setQuery($query);
         $plugin = $db->loadObject();
         $params = $plugin->params;
         $supportRecurring = $plugin->support_recurring_subscription;
         $params = new JRegistry($params);
         $paymentClass = new $paymentMethod($params);
         if ($rowPlan->recurring_subscription && $supportRecurring) {
             if ($paymentMethod == 'os_authnet') {
                 $paymentMethod = 'os_authnet_arb';
                 require_once JPATH_COMPONENT . '/plugins/' . $paymentMethod . '.php';
                 $paymentClass = new $paymentMethod($params);
             }
             $paymentClass->processRecurringPayment($row, $data);
         } else {
             $paymentClass->processPayment($row, $data);
         }
     } else {
         $Itemid = JRequest::getInt('Itemid');
         $row->published = 1;
         $row->store();
         if ($row->act == 'upgrade') {
             OSMembershipHelper::processUpgradeMembership($row);
         }
         OSMembershipHelper::sendEmails($row, $config);
         JPluginHelper::importPlugin('osmembership');
         $dispatcher = JDispatcher::getInstance();
         $dispatcher->trigger('onMembershipActive', array($row));
         $query->clear();
         $query->select('subscription_complete_url')->from('#__osmembership_plans')->where('id=' . $row->plan_id);
         //Get subscription complete UR
         $db->setQuery($query);
         $subscriptionCompleteURL = $db->loadResult();
         if ($subscriptionCompleteURL) {
             JFactory::getApplication()->redirect($subscriptionCompleteURL);
         } else {
             JFactory::getApplication()->redirect(JRoute::_('index.php?option=com_osmembership&view=complete&act=' . $row->act . '&subscription_code=' . $row->subscription_code . '&Itemid=' . $Itemid, false));
         }
     }
 }