Your IP : 18.219.152.33
<?php
namespace Bitrix\Sale\PaySystem;
use Bitrix\Main\Application;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Event;
use Bitrix\Main\EventResult;
use Bitrix\Main\IO\Directory;
use Bitrix\Main\IO\File;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Request;
use Bitrix\Sale\Basket;
use Bitrix\Sale\Internals\EntityCollection;
use Bitrix\Sale\Internals\PaymentTable;
use Bitrix\Sale\Internals\PaySystemActionTable;
use Bitrix\Sale\Internals\PaySystemRestHandlersTable;
use Bitrix\Sale\Internals\ServiceRestrictionTable;
use Bitrix\Sale\Order;
use Bitrix\Sale\Payment;
use Bitrix\Sale\Services\PaySystem\Restrictions;
Loc::loadMessages(__FILE__);
/**
* Class PaySystemManager
* @package Bitrix\Sale\Payment
*/
final class Manager
{
const EVENT_ON_GET_HANDLER_DESC = 'OnSaleGetHandlerDescription';
const CACHE_ID = "BITRIX_SALE_INNER_PS_ID";
const TTL = 31536000;
/**
* @var array
*/
private static $handlerDirectories = array(
'CUSTOM' => '',
'LOCAL' => '/local/php_interface/include/sale_payment/',
'SYSTEM' => '/bitrix/modules/sale/handlers/paysystem/',
'SYSTEM_OLD' => '/bitrix/modules/sale/payment/'
);
/**
* @return array
*/
public static function getHandlerDirectories()
{
$handlerDirectories = self::$handlerDirectories;
$handlerDirectories['CUSTOM'] = Option::get("sale", "path2user_ps_files", BX_PERSONAL_ROOT."/php_interface/include/sale_payment/");
return $handlerDirectories;
}
/**
* @param array $params
* @return \Bitrix\Main\DB\Result
* @throws \Bitrix\Main\ArgumentException
*/
public static function getList(array $params = array())
{
return PaySystemActionTable::getList($params);
}
/**
* @param $id
* @return array|false
*/
public static function getById($id)
{
if ($id <= 0)
return false;
$params = array(
'select' => array('*'),
'filter' => array('ID' => $id)
);
$dbRes = self::getList($params);
return $dbRes->fetch();
}
/**
* @param $code
* @return array|bool
*/
public static function getByCode($code)
{
$params = array(
'select' => array('*'),
'filter' => array('CODE' => $code)
);
$dbRes = self::getList($params);
return $dbRes->fetch();
}
/**
* @param $primary
* @param array $data
* @return \Bitrix\Main\Entity\UpdateResult
* @throws \Exception
*/
public static function update($primary, array $data)
{
return PaySystemActionTable::update($primary, $data);
}
/**
* @param array $data
* @return \Bitrix\Main\Entity\AddResult
*/
public static function add(array $data)
{
return PaySystemActionTable::add($data);
}
/**
* @param Request $request
* @return array|false
*/
public static function searchByRequest(Request $request)
{
$documentRoot = Application::getDocumentRoot();
$items = self::getList(array('select' => array('*')));
while ($item = $items->fetch())
{
$name = $item['ACTION_FILE'];
foreach (self::getHandlerDirectories() as $type => $path)
{
$className = '';
if (File::isFileExists($documentRoot.$path.$name.'/handler.php'))
{
$className = static::getClassNameFromPath($item['ACTION_FILE']);
if (!class_exists($className))
require_once($documentRoot.$path.$name.'/handler.php');
}
else if (static::isRestHandler($name))
{
$className = '\Bitrix\Sale\PaySystem\RestHandler';
}
if (class_exists($className) && is_callable(array($className, 'isMyResponse')))
{
if ($className::isMyResponse($request, $item['ID']))
return $item;
}
}
}
return false;
}
/**
* @param string $className
* @return mixed|string
*/
public static function getFolderFromClassName($className)
{
$pos = strrpos($className, '\\');
if ($pos !== false)
$className = substr($className, $pos + 1);
$folder = str_replace('Handler', '', $className);
$folder = self::sanitize($folder);
$folder = ToLower($folder);
return $folder;
}
/**
* @param string $name
* @return mixed
*/
public static function sanitize($name)
{
return preg_replace("/[^a-z0-9._]/i", "", $name);
}
/**
* @param $paymentId
* @return array
* @throws \Bitrix\Main\ArgumentException
*/
public static function getIdsByPayment($paymentId)
{
if (empty($paymentId))
return array(0, 0);
$params = array(
'select' => array('ID', 'ORDER_ID'),
);
if (intval($paymentId).'|' == $paymentId.'|')
{
$params['filter']['ID'] = $paymentId;
}
else
{
$params['filter']['ACCOUNT_NUMBER'] = $paymentId;
}
$data = PaymentTable::getRow($params);
return array((int)$data['ORDER_ID'], (int)$data['ID']);
}
/**
* @return array
*/
public static function getConsumersList()
{
$result = array();
$items = self::getList();
while ($item = $items->fetch())
{
$data = self::getHandlerDescription($item['ACTION_FILE']);
$data['NAME'] = $item['NAME'];
$data['GROUP'] = 'PAYSYSTEM';
$data['PROVIDERS'] = array('VALUE', 'COMPANY', 'ORDER', 'USER', 'PROPERTY', 'PAYMENT');
$result['PAYSYSTEM_'.$item['ID']] = $data;
}
return $result;
}
/**
* @param $paySystemId
* @return string
*/
public static function getPsType($paySystemId)
{
$params = array(
'select' => array('IS_CASH'),
'filter' => array('ID' => $paySystemId)
);
$dbRes = self::getList($params);
$data = $dbRes->fetch();
return $data['IS_CASH'];
}
/**
* @param Payment $payment
* @param int $mode
* @return array
*/
public static function getListWithRestrictions(Payment $payment, $mode = Restrictions\Manager::MODE_CLIENT)
{
$result = array();
$dbRes = self::getList(array(
'filter' => array('ACTIVE' => 'Y'),
'order' => array('SORT' => 'ASC', 'NAME' => 'ASC')
));
while ($paySystem = $dbRes->fetch())
{
if ($mode == Restrictions\Manager::MODE_MANAGER)
{
$checkServiceResult = Restrictions\Manager::checkService($paySystem['ID'], $payment, $mode);
if ($checkServiceResult != Restrictions\Manager::SEVERITY_STRICT)
{
if ($checkServiceResult == Restrictions\Manager::SEVERITY_SOFT)
$paySystem['RESTRICTED'] = $checkServiceResult;
$result[$paySystem['ID']] = $paySystem;
}
}
else if ($mode == Restrictions\Manager::MODE_CLIENT)
{
if (Restrictions\Manager::checkService($paySystem['ID'], $payment, $mode) === Restrictions\Manager::SEVERITY_NONE)
$result[$paySystem['ID']] = $paySystem;
}
}
return $result;
}
/**
* @return array
* @throws \Bitrix\Main\IO\FileNotFoundException
*/
public static function getHandlerList()
{
$documentRoot = Application::getDocumentRoot();
$result = array(
'SYSTEM' => array(),
'USER' => array()
);
$oldHandlerList = array('yandex_3x', 'bill', 'bill_de', 'bill_ua', 'bill_en', 'bill_la', 'paymaster', 'assist', 'liqpay', 'qiwi', 'sberbank_new', 'sberbank', 'webmoney_web', 'money.mail', 'payment_forward_calc', 'payment_forward', 'roboxchange', 'cash');
foreach (self::getHandlerDirectories() as $type => $dir)
{
if (!Directory::isDirectoryExists($documentRoot.$dir))
continue;
$directory = new Directory($documentRoot.$dir);
foreach ($directory->getChildren() as $handler)
{
if (!$handler->isDirectory() || (in_array($handler->getName(), $oldHandlerList) && $type == 'SYSTEM_OLD'))
continue;
$isDescriptionExist = false;
/** @var Directory $handler */
foreach ($handler->getChildren() as $item)
{
if ($item->isFile())
{
$data = array();
$psTitle = '';
if (strpos($item->getName(), '.description') !== false)
{
$handlerName = $handler->getName();
include $item->getPath();
if (array_key_exists('NAME', $data))
{
$psTitle = $data['NAME'].' ('.$handlerName.')';
}
else
{
if ($psTitle == '')
$psTitle = $handlerName;
else
$psTitle .= ' ('.$handlerName.')';
$handlerName = str_replace($documentRoot, '', $handler->getPath());
}
$group = (strpos($type, 'SYSTEM') !== false) ? 'SYSTEM' : 'USER';
if (!isset($result[$group][$handlerName]))
{
if (array_key_exists('DOMAIN', $data))
{
if ((IsModuleInstalled('bitrix24') && $data['DOMAIN'] === 'BOX') ||
(!IsModuleInstalled('bitrix24') && $data['DOMAIN'] === 'CLOUD')
)
{
continue(2);
}
}
$result[$group][$handlerName] = $psTitle;
}
$isDescriptionExist = true;
continue;
}
}
}
if (!$isDescriptionExist)
{
$group = (strpos($type, 'SYSTEM') !== false) ? 'SYSTEM' : 'USER';
$handlerName = str_replace($documentRoot, '', $handler->getPath());
$result[$group][$handlerName] = $handler->getName();
}
}
}
$result['USER'] = array_merge(static::getRestHandlers(), $result['USER']);
return $result;
}
/**
* @param $path
* @return string
*/
public static function getClassNameFromPath($path)
{
$pos = strrpos($path, '/');
if ($pos == strlen($path))
{
$path = substr($path, 0, $pos - 1);
$pos = strrpos($path, '/');
}
if ($pos !== false)
$path = substr($path, $pos+1);
return "Sale\\Handlers\\PaySystem\\".$path.'Handler';
}
/**
* @param $handler
* @return array
*/
public static function getHandlerDescription($handler)
{
$service = new Service(array('ACTION_FILE' => $handler));
$data = $service->getHandlerDescription();
$eventParams = array('handler' => $handler);
$event = new Event('sale', self::EVENT_ON_GET_HANDLER_DESC, $eventParams);
$event->send();
foreach ($event->getResults() as $eventResult)
{
if($eventResult->getType() !== EventResult::ERROR)
$data['CODES'] = array_merge($data['CODES'], $eventResult->getParameters());
}
if (isset($data['CODES']) && is_array($data['CODES']))
uasort($data['CODES'], function ($a, $b) { return ($a['SORT'] < $b['SORT']) ? -1 : 1;});
return $data;
}
/**
* @param $folder
* @return null|string
*/
public static function getPathToHandlerFolder($folder)
{
$documentRoot = Application::getDocumentRoot();
if (strpos($folder, '/') !== false)
{
return $folder;
}
else
{
$dirs = self::getHandlerDirectories();
foreach ($dirs as $dir)
{
$path = $dir.$folder;
if (!Directory::isDirectoryExists($documentRoot.$path))
continue;
return $path;
}
}
return null;
}
/**
* @return int
*/
public static function getInnerPaySystemId()
{
$id = 0;
$cacheManager = Application::getInstance()->getManagedCache();
if($cacheManager->read(self::TTL, self::CACHE_ID))
$id = $cacheManager->get(self::CACHE_ID);
if ($id <= 0)
{
$data = PaySystemActionTable::getRow(
array(
'select' => array('ID'),
'filter' => array('ACTION_FILE' => 'inner')
)
);
if ($data === null)
$id = self::createInnerPaySystem();
else
$id = $data['ID'];
$cacheManager->set(self::CACHE_ID, $id);
}
return $id;
}
/**
* @return int
* @throws \Exception
*/
private static function createInnerPaySystem()
{
$paySystemSettings = array(
'NAME' => Loc::getMessage('SALE_PS_MANAGER_INNER_NAME'),
'PSA_NAME' => Loc::getMessage('SALE_PS_MANAGER_INNER_NAME'),
'ACTION_FILE' => 'inner',
'ACTIVE' => 'Y',
'NEW_WINDOW' => 'N'
);
$imagePath = Application::getDocumentRoot().'/bitrix/images/sale/sale_payments/inner.png';
if (File::isFileExists($imagePath))
{
$paySystemSettings['LOGOTIP'] = \CFile::MakeFileArray($imagePath);
$paySystemSettings['LOGOTIP']['MODULE_ID'] = "sale";
\CFile::SaveForDB($paySystemSettings, 'LOGOTIP', 'sale/paysystem/logotip');
}
$result = PaySystemActionTable::add($paySystemSettings);
if ($result->isSuccess())
return $result->getId();
return 0;
}
/**
* @param $id
* @return bool
*/
public static function isExist($id)
{
return (bool)self::getById($id);
}
/**
* @param $id
* @return Service|null
*/
public static function getObjectById($id)
{
if ($id <= 0)
return null;
$data = Manager::getById($id);
if (is_array($data) && $data)
return new Service($data);
return null;
}
/**
* @param $folder
* @param int $paySystemId
* @return array|mixed
*/
public static function getTariff($folder, $paySystemId = 0)
{
$documentRoot = Application::getDocumentRoot();
$result = array();
$path = self::getPathToHandlerFolder($folder);
if ($path !== null)
{
if (File::isFileExists($documentRoot.$path.'/handler.php'))
{
require_once $documentRoot.$path.'/handler.php';
$className = self::getClassNameFromPath($folder);
if (class_exists($className))
{
$interfaces = class_implements($className);
if (array_key_exists('Bitrix\Sale\PaySystem\IPayable', $interfaces))
$result = $className::getStructure($paySystemId);
}
}
}
else
{
$result = \CSalePaySystemsHelper::getPaySystemTarif($folder, $paySystemId);
}
return $result;
}
/**
* @return array
*/
public static function getBusValueGroups()
{
return array(
'CONNECT_SETTINGS_ALFABANK' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_ALFABANK'), 'SORT' => 100),
'CONNECT_SETTINGS_AUTHORIZE' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_AUTHORIZE'), 'SORT' => 100),
'CONNECT_SETTINGS_YANDEX' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_YANDEX'), 'SORT' => 100),
'CONNECT_SETTINGS_YANDEX_INVOICE' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_YANDEX_INVOICE'), 'SORT' => 100),
'CONNECT_SETTINGS_WEBMONEY' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_WEBMONEY'), 'SORT' => 100),
'CONNECT_SETTINGS_ASSIST' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_ASSIST'), 'SORT' => 100),
'CONNECT_SETTINGS_ROBOXCHANGE' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_ROBOXCHANGE'), 'SORT' => 100),
'CONNECT_SETTINGS_QIWI' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_QIWI'), 'SORT' => 100),
'CONNECT_SETTINGS_PAYPAL' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_PAYPAL'), 'SORT' => 100),
'CONNECT_SETTINGS_PAYMASTER' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_PAYMASTER'), 'SORT' => 100),
'CONNECT_SETTINGS_LIQPAY' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_LIQPAY'), 'SORT' => 100),
'CONNECT_SETTINGS_BILL' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_BILL'), 'SORT' => 100),
'CONNECT_SETTINGS_BILLDE' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_BILLDE'), 'SORT' => 100),
'CONNECT_SETTINGS_BILLEN' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_BILLEN'), 'SORT' => 100),
'CONNECT_SETTINGS_BILLUA' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_BILLUA'), 'SORT' => 100),
'CONNECT_SETTINGS_BILLLA' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_CONNECT_SETTINGS_BILLLA'), 'SORT' => 100),
'GENERAL_SETTINGS' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_GENERAL_SETTINGS'), 'SORT' => 100),
'COLUMN_SETTINGS' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_COLUMN'), 'SORT' => 100),
'VISUAL_SETTINGS' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_VISUAL'), 'SORT' => 100),
'PAYMENT' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_PAYMENT'), 'SORT' => 200),
'PAYSYSTEM' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_PAYSYSTEM'), 'SORT' => 500),
'PS_OTHER' => array('NAME' => Loc::getMessage('SALE_PS_MANAGER_GROUP_PS_OTHER'), 'SORT' => 10000)
);
}
/**
* @param $primary
* @return \Bitrix\Main\Entity\DeleteResult
*/
public static function delete($primary)
{
$paySystemInfo = array();
if ($primary)
{
$dbRes = PaySystemActionTable::getById($primary);
$paySystemInfo = $dbRes->fetch();
}
$result = PaySystemActionTable::delete($primary);
if ($result->isSuccess())
{
if ($paySystemInfo['LOGOTIP'])
\CFile::Delete($paySystemInfo['LOGOTIP']);
$restrictionList = Restrictions\Manager::getRestrictionsList($primary);
if ($restrictionList)
{
Restrictions\Manager::getClassesList();
foreach ($restrictionList as $restriction)
{
/** @var \Bitrix\Sale\Services\Base\Restriction $className */
$className = $restriction["CLASS_NAME"];
if (is_subclass_of($className, '\Bitrix\Sale\Services\Base\Restriction'))
{
$className::delete($restriction['ID'], $primary);
}
}
}
}
return $result;
}
/**
* @param $paySystemId
* @return array
* @throws \Bitrix\Main\ArgumentException
*/
public static function getPersonTypeIdList($paySystemId)
{
$data = array();
$dbRestriction = ServiceRestrictionTable::getList(array(
'filter' => array(
'SERVICE_ID' => $paySystemId,
'SERVICE_TYPE' => Restrictions\Manager::SERVICE_TYPE_PAYMENT,
'=CLASS_NAME' => '\Bitrix\Sale\Services\PaySystem\Restrictions\PersonType'
)
));
while ($restriction = $dbRestriction->fetch())
$data = array_merge($data, $restriction['PARAMS']['PERSON_TYPE_ID']);
return $data;
}
/**
* @param array $data
* @return null|EntityCollection|Payment
*/
public static function getPaymentObjectByData(array $data)
{
$context = Application::getInstance()->getContext();
/** @var Order $order */
$order = Order::create($context->getSite());
$order->setPersonTypeId($data['PERSON_TYPE_ID']);
$basket = Basket::create($context->getSite());
$order->setBasket($basket);
$collection = $order->getPaymentCollection();
if ($collection)
return $collection->createItem();
return null;
}
/**
* @return array
*/
public static function getDataRefundablePage()
{
$paySystemList = array();
$dbRes = static::getList();
while ($data = $dbRes->fetch())
{
$service = new Service($data);
if ($service->isRefundable())
$paySystemList[$data['ACTION_FILE']][] = $data;
}
$result = array();
foreach ($paySystemList as $handler => $data)
{
/* @var ServiceHandler $classHandler */
$classHandler = static::getClassNameFromPath($handler);
if (is_subclass_of($classHandler, '\Bitrix\Sale\PaySystem\ServiceHandler'))
{
$settings = $classHandler::findMyDataRefundablePage($data);
if ($settings)
$result = array_merge($settings, $result);
}
}
return $result;
}
/**
* @return array
*/
private static function getRestHandlers()
{
$result = array();
$dbRes = PaySystemRestHandlersTable::getList();
while ($item = $dbRes->fetch())
{
$result[$item['CODE']] = $item['NAME'].' ('.$item['CODE'].')';
}
return $result;
}
/**
* @param $handler
* @return bool
*/
public static function isRestHandler($handler)
{
$dbRes = PaySystemRestHandlersTable::getList(array('filter' => array('CODE' => $handler)));
return (bool)$dbRes->fetch();
}
}