Your IP : 216.73.216.224


Current Path : /var/www/html/administrator/components/com_osmembership/libraries/mpf/payment/
Upload File :
Current File : /var/www/html/administrator/components/com_osmembership/libraries/mpf/payment/common.php

<?php
/**
 * Part of the Ossolution Payment Package
 *
 * @copyright  Copyright (C) 2016 - 2016 Ossolution Team. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE
 */

use Joomla\CMS\Factory;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Table\Table;
use Joomla\CMS\Uri\Uri;
use OSSolution\MembershipPro\Admin\Event\Subscription\MembershipActive;

/**
 * Abstract Payment Class
 *
 * @since  1.0
 */
trait MPFPaymentCommon
{
	/**
	 * Flag to determine whether this payment method has payment processing fee
	 *
	 * @var bool
	 */
	public $paymentFee;

	/**
	 * The payment method icon Uri
	 *
	 * @var string
	 */
	public $iconUri;

	/**
	 * The parameters which will be passed to payment gateway for processing payment
	 *
	 * @var array
	 */
	protected $parameters = [];

	/**
	 * Notification data send from payment gateway back to the payment plugin.
	 *
	 * @var array
	 */
	protected $notificationData = [];

	/**
	 * Set data for a parameter
	 *
	 * @param   string  $name
	 * @param   string  $value
	 */
	protected function setParameter($name, $value)
	{
		$this->parameters[$name] = $value;
	}

	/**
	 * Get data for a parameter
	 *
	 * @param   string  $name
	 * @param   mixed   $default
	 *
	 * @return null
	 */
	protected function getParameter($name, $default = null)
	{
		return $this->parameters[$name] ?? $default;
	}

	/**
	 *  This method is called when payment for the registration is success, it needs to be used by all payment class
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   string                       $transactionId
	 */
	protected function onPaymentSuccess($row, $transactionId)
	{
		$config              = OSMembershipHelper::getConfig();
		$row->transaction_id = $transactionId;
		$row->payment_date   = gmdate('Y-m-d H:i:s');

		if ($row->act !== 'renew')
		{
			$row->published = $this->params->get('paid_payment_subscription_status', 1);
		}
		else
		{
			$row->published = 1;
		}

		$row->store();

		if ($row->act == 'upgrade')
		{
			OSMembershipHelper::callOverridableHelperMethod('Subscription', 'processUpgradeMembership', [$row]);
		}

		if (OSMembershipHelperSubscription::needToTriggerActiveEvent($row))
		{
			PluginHelper::importPlugin('osmembership');

			$event = new MembershipActive(['row' => $row]);

			Factory::getApplication()->getDispatcher()->dispatch($event->getName(), $event);
		}
		else
		{
			$row->active_event_triggered = 0;
			$row->store();
		}

		if ($row->process_payment_for_subscription)
		{
			$row->payment_method = $this->name;

			$rowPlan = OSMembershipHelperDatabase::getPlan($row->plan_id);

			if (str_starts_with($row->payment_method ?? '', 'os_offline')
				&& !(int) $rowPlan->expired_date)
			{
				$this->reCalculateSubscriptionDuration($row);
			}

			$row->store();
			OSMembershipHelperMail::sendSubscriptionPaymentEmail($row, $config);
		}
		else
		{
			OSMembershipHelperMail::sendEmails($row, $config);
		}
	}

	/**
	 * Recalculate subscription from_date and to_date for offline payment subscription when the subscription is approved
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 *
	 * @return void
	 */
	protected function reCalculateSubscriptionDuration($row)
	{
		$createdDate = Factory::getDate($row->created_date);
		$fromDate    = Factory::getDate($row->from_date);
		$toDate      = Factory::getDate($row->to_date);
		$todayDate   = Factory::getDate('now');
		$diff        = $createdDate->diff($todayDate);
		$fromDate->add($diff);
		$toDate->add($diff);
		$row->from_date = $fromDate->toSql();
		$row->to_date   = $toDate->toSql();
		$row->store();
	}

	/**
	 * Process renew recurring subscription after receiving payment
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   string                       $subscriptionId
	 * @param   string                       $transactionId
	 *
	 * @return void
	 */
	protected function processRenewRecurringSubscription($row, $subscriptionId, $transactionId)
	{
		/* @var OSMembershipModelApi $model */
		$model               = MPFModel::getInstance('Api', 'OSMembershipModel', ['ignore_request' => true]);
		$renewedSubscription = $model->renewRecurringSubscription($row->id, $subscriptionId, $transactionId);

		// Set payment_method for the renewed subscription in case it is lost for some reason
		if (!$renewedSubscription->payment_method)
		{
			$renewedSubscription->payment_method = $this->getName();
			$renewedSubscription->store();
		}

		$rowPlan = OSMembershipHelperDatabase::getPlan($row->plan_id);

		if ($rowPlan->number_payments > 0 && $rowPlan->number_payments <= ($row->payment_made + 1))
		{
			if ($rowPlan->last_payment_action == 1)
			{
				$renewedSubscription->to_date = '2099-12-31 23:59:59';
				$renewedSubscription->store();
			}
			elseif ($rowPlan->last_payment_action == 2
				&& $rowPlan->extend_duration > 0
				&& $rowPlan->extend_duration_unit)
			{
				$date = Factory::getDate($renewedSubscription->to_date);
				$date->add(new DateInterval('P' . $rowPlan->extend_duration . $rowPlan->extend_duration_unit));
				$renewedSubscription->to_date = $date->toSql();
				$renewedSubscription->store();
			}
		}
	}

	/**
	 * Method to check if payment plugin support cancel recurring subscription
	 *
	 * @return bool
	 */
	public function supportCancelRecurringSubscription()
	{
		return method_exists($this, 'cancelSubscription');
	}

	/**
	 * Method to check if payment plugin support refund payment
	 *
	 * @return bool
	 */
	public function supportRefundPayment()
	{
		return method_exists($this, 'refund');
	}

	/**
	 * Method to check whether we need to show card type on form for this payment method. From now on, we don't have to
	 * show card type on form because it can be detected from card number. Keep it here for B/C reason only
	 *
	 * @return bool|int
	 */
	public function getCardType()
	{
		return 0;
	}

	/**
	 * Method to check whether we need to show card holder name in the form
	 *
	 * @return bool|int
	 */
	public function getCardHolderName()
	{
		return $this->type;
	}

	/**
	 * Method to check whether we need to show card cvv input on form
	 *
	 * @return bool|int
	 */
	public function getCardCvv()
	{
		return $this->type;
	}

	/**
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   int                          $Itemid
	 * @param   string                       $queryString
	 *
	 * @return string
	 */
	protected function getPaymentNotifyUrl($row, $Itemid = 0, $queryString = ''): string
	{
		$url = Uri::root() . 'index.php?option=com_osmembership&task=payment_confirm&payment_method='
			. $this->getName();

		if ($queryString)
		{
			$url .= '&' . $queryString;
		}

		if ($Itemid > 0)
		{
			$url .= '&Itemid=' . $Itemid;
		}

		$url .= OSMembershipHelper::getLangLink();

		return $url;
	}

	/**
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   int                          $Itemid
	 *
	 * @return string
	 */
	protected function getRecurringPaymentNotifyUrl($row, $Itemid = 0): string
	{
		$url = Uri::root() . 'index.php?option=com_osmembership&task=recurring_payment_confirm&payment_method='
			. $this->getName();

		if ($Itemid > 0)
		{
			$url .= '&Itemid=' . $Itemid;
		}

		$url .= OSMembershipHelper::getLangLink();

		return $url;
	}

	/**
	 * Get SEF return URL after processing payment
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   int                          $Itemid
	 * @param   bool                         $absolute
	 *
	 * @return string
	 */
	protected function getPaymentCompleteUrl($row, $Itemid, $absolute = false)
	{
		$langLink = OSMembershipHelper::getLangLink();

		if ($row->process_payment_for_subscription)
		{
			$Itemid = OSMembershipHelperRoute::getViewRoute('payment', $Itemid);

			$url = 'index.php?option=com_osmembership&view=payment&layout=complete&subscription_code='
				. $row->subscription_code . '&Itemid=' . $Itemid . $langLink;
		}
		else
		{
			$url = OSMembershipHelperRoute::getViewRoute('complete', $Itemid)
				. '&subscription_code=' . $row->subscription_code . $langLink;
		}

		return Route::_($url, false, 0, $absolute);
	}

	/**
	 * Get payment failure URL
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   int                          $Itemid
	 * @param   bool                         $absolute
	 *
	 * @return string
	 */
	protected function getPaymentFailureUrl($row, $Itemid, $absolute = false): string
	{
		$url = 'index.php?option=com_osmembership&view=failure&Itemid=' . $Itemid;

		return Route::_($url, false, 0, $absolute);
	}

	/**
	 * Get payment failure URL
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   int                          $Itemid
	 * @param   bool                         $absolute
	 *
	 * @return string
	 */
	protected function getPaymentCancelUrl($row, $Itemid, $absolute = false): string
	{
		$url = 'index.php?option=com_osmembership&view=cancel&layout=default&id=' . $row->id . '&Itemid=' . $Itemid;

		return Route::_($url, false, 0, $absolute);
	}

	/**
	 * Store payment error message into session to have it displayed on payment failure page
	 *
	 * @param   string  $error
	 *
	 * @return void
	 */
	protected function setPaymentErrorMessage($error): void
	{
		Factory::getApplication()->getSession()->set('omnipay_payment_error_reason', $error);
	}

	/**
	 * Method to check if the payment success process for this transaction already processed
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   string                       $transactionId
	 *
	 * @return bool
	 */
	protected function transactionProcessed($row, $transactionId = ''): bool
	{
		// Make sure each transaction is only processed once
		if ($transactionId && OSMembershipHelper::isTransactionProcessed($transactionId))
		{
			return true;
		}

		if ($row->published)
		{
			return true;
		}

		return false;
	}

	/**
	 * Method to get a table class from Membership Pro
	 *
	 * @param   string  $name
	 *
	 * @return bool|Table
	 */
	protected function getTable($name)
	{
		$className = 'OSMembershipTable' . ucfirst($name);

		$db = Factory::getContainer()->get('db');

		return new $className($db);
	}

	/**
	 * Method to get Subscriber table object
	 *
	 * @return bool|OSMembershipTableSubscriber
	 */
	protected function getSubscriberTable()
	{
		return $this->getTable('Subscriber');
	}

	/**
	 * Handle payment error. Store the error message in the session and redirect user to payment
	 * failure page
	 *
	 * @param   OSMembershipTableSubscriber  $row
	 * @param   int                          $Itemid
	 * @param   string                       $message
	 *
	 * @return void
	 */
	protected function handlePaymentError($row, $Itemid, $message)
	{
		$url = $this->getPaymentFailureUrl($row, $Itemid);
		$this->setPaymentErrorMessage($message);
		Factory::getApplication()->redirect($url);
	}

	/**
	 * Get payment plugin layout
	 *
	 * @param   string  $layout
	 *
	 * @return string
	 */
	protected function getLayoutPath($layout = 'form')
	{
		/* @var \Joomla\CMS\Application\CMSApplication $app */
		$app      = Factory::getApplication();
		$template = $app->getTemplate();

		// Remove os_ from plugin name and remove any _ characters to get folder name
		$name = str_replace(
			'_',
			'',
			substr($this->getName(), 3)
		);

		if (is_file(
			JPATH_THEMES . '/' . $template . '/html/com_osmembership/plugins/' . $name . '/' . $layout . '.php'
		))
		{
			return JPATH_THEMES . '/' . $template . '/html/com_osmembership/plugins/' . $name . '/' . $layout . '.php';
		}

		return JPATH_ROOT . '/components/com_osmembership/plugins/' . $name . '/tmpl/' . $layout . '.php';
	}

	/***
	 * Log the notification data
	 *
	 * @param   string  $extraData  a string contain the extra data which you want to log
	 *
	 * @return void
	 */
	protected function logNotificationData($extraData = null)
	{
		if (!$this->params->get('ipn_log'))
		{
			return;
		}

		$app = Factory::getApplication();

		$logPath = $app->get('log_path');

		if (!$logPath)
		{
			return;
		}

		$logCategory = 'membershippro_ipn_' . $this->getName();

		Log::addLogger(
			[
				'text_file'         => 'ipn_' . $this->getName() . '.php',
				'text_file_path'    => $logPath,
				'text_entry_format' => "{DATE} {TIME}\t" . "{MESSAGE}",
			],
			Log::ALL,
			[$logCategory]
		);

		$message = '';

		if (is_array($this->notificationData))
		{
			$message = $this->arrayToString($this->notificationData);
		}

		$message .= $extraData;

		try
		{
			Log::add(
				$message,
				'INFO',
				$logCategory,
				Factory::getDate('now', $app->get('offset'))->format('Y-m-d H:i:s', true)
			);
		}
		catch (\Exception $e)
		{
			// Do-nothing
		}
	}

	/**
	 * Method to convert array to string in key=value format
	 *
	 * @param   array  $array
	 *
	 * @return string
	 */
	private function arrayToString(array $array): string
	{
		$stringData = '';

		foreach ($array as $key => $value)
		{
			if (is_array($value))
			{
				$stringData .= self::arrayToString($value) . ',';
			}
			else
			{
				$stringData .= $key . '=' . $value . ',';
			}
		}

		return rtrim($stringData, ',');
	}
}