first commit

This commit is contained in:
2025-03-12 17:06:23 +01:00
commit 2241f7131f
13185 changed files with 1692479 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
<?php
function st_paypal_checkout_express_add_link($namespace, Product $product) {
$config = stConfig::getInstance('stPaypal');
if ($config->get('express') && $config->get('configuration_verified')) {
$context = sfContext::getInstance();
st_theme_use_stylesheet('stPaypal.css');
if ($message = $context->getUser()->getAttribute('express_checkout_error', null, 'stPaypal')) {
$context->getUser()->setAttribute('express_checkout_error', null, 'stPaypal');
$errorContent = <<<ERROR
<div id="paypal_express_checkout_error">
{$message}.
</div>
ERROR;
}
if ($product->getPriceBrutto() <= 0 || !stBasket::isEnabled($product) || stBasket::isHidden($product)) {
$context->getUser()->setAttribute('express_checkout_error', null, 'stPaypal');
if (!empty($message))
return $errorContent;
else
return false;
}
$id = $product->getId();
$url = st_url_for('@stPaypalBuyProduct?product_id='.$id);
$image_url = 'https://www.paypal.com/' . stPaypal::getButtonLocaleByCulture($context->getUser()->getCulture()).'/i/btn/btn_xpressCheckout.gif';
$image_alt = __('Zapłać w systemie PayPal', null, 'stPaypalFrontend');
$content =<<< HTML
<div id="paypal_express_checkout">
<a id="{$namespace}_{$id}_paypal_checkout_express" href="$url">
<img src="$image_url" alt="$image_alt" />
</a>
</div>
<script type="text/javascript">
//<![CDATA[
jQuery(function($) {
$('#{$namespace}_{$id}_paypal_checkout_express').click(function() {
var quantity = $('#{$namespace}_{$id}_quantity');
if (quantity.length && quantity.val() == 0) {
quantity.val(quantity.get(0).defaultValue);
}
var quantity_value = quantity.length ? quantity.val() : {$product->getMinQty()};
var serialized = $('#{$namespace}_$id').serialize();
if (!serialized && $("#st_update_product_options_form").length > 0) {
serialized = 'option_list='+$.map($('#st_update_product_options_form').serializeArray(), function(option) { return option.value;}).join('-');
}
if (serialized) {
serialized += '&quantity='+quantity_value;
} else {
serialized += 'quantity='+quantity_value;
}
var link = $(this);
var href = link.attr('href')+'?'+serialized;
link.attr('href', href);
});
});
//]]>
</script>
HTML;
return $errorContent.$content;
}
return false;
}

View File

@@ -0,0 +1,240 @@
<?php
class stPayPalExpressCheckout {
public function addOrder($response, Product $product) {
$config = stConfig::getInstance('stPaypal');
$custom = $response->getPaymentRequest_0_Custom();
if (!empty($custom)) $custom = json_decode($custom, true);
/**
* User
**/
$c = new Criteria();
$c->add(sfGuardUserPeer::USERNAME, $response->getEmail());
$user = sfGuardUserPeer::doSelectOne($c);
$billingUserData = $this->getUserDataFromResponse($response, new UserData());
$deliveryUserData = clone $billingUserData;
if (is_null($user)) {
$user = stUser::addUser($response->getEmail());
$billingUserData->setSfGuardUserId($user->getId());
$billingUserData->setIsDefault(1);
$billingUserData->setIsBilling(1);
$billingUserData->save();
$deliveryUserData->setSfGuardUserId($user->getId());
$deliveryUserData->setIsDefault(1);
$deliveryUserData->setIsBilling(0);
$deliveryUserData->save();
} else {
$c = new Criteria();
$c->add(UserDataPeer::SF_GUARD_USER_ID, $user->getId());
$c->add(UserDataPeer::IS_BILLING, 1);
$c->add(UserDataPeer::IS_DEFAULT, 1);
$defaultBillingUserData = UserDataPeer::doSelectOne($c);
$c = new Criteria();
$c->add(UserDataPeer::SF_GUARD_USER_ID, $user->getId());
$c->add(UserDataPeer::IS_BILLING, 0);
$c->add(UserDataPeer::IS_DEFAULT, 1);
$defaultDeliveryUserData = UserDataPeer::doSelectOne($c);
$stUser = sfContext::getInstance()->getUser();
if (!$stUser->thisSameUserDataObject($defaultBillingUserData, $billingUserData)) {
$billingUserData->setSfGuardUserId($user->getId());
$billingUserData->setIsBilling(1);
$billingUserData->save();
stUser::setDefaultUserData($billingUserData->getId(), 1, $user->getId());
}
if (!$stUser->thisSameUserDataObject($defaultDeliveryUserData, $deliveryUserData)) {
$deliveryUserData->setSfGuardUserId($user->getId());
$deliveryUserData->save();
stUser::setDefaultUserData($deliveryUserData->getId(), 0, $user->getId());
}
}
/**
* Order
**/
$order = new Order();
$order->setClientCulture(sfContext::getInstance()->getUser()->getCulture());
$order->setHost(sfContext::getInstance()->getRequest()->getHost());
$order->setOrderStatus(OrderStatusPeer::retrieveDefaultPendingStatus());
/**
* User billing and delivery data for order
**/
$order->setGuardUser($user);
$orderBilling = $this->mirrorUserData($order->getOrderUserDataBilling(), $billingUserData);
$orderDelivery = $this->mirrorUserData($order->getOrderUserDataDelivery(), $deliveryUserData);
/**
* Order currency
**/
$orderCurrency = $order->getOrderCurrency();
$c = new Criteria();
$c->add(CurrencyPeer::SHORTCUT, $response->getPaymentRequest_0_CurrencyCode());
$currency = CurrencyPeer::doSelectOne($c);
$orderCurrency->setName($currency->getName());
$orderCurrency->setExchange($currency->getExchange());
$orderCurrency->setFrontSymbol($currency->getFrontSymbol());
$orderCurrency->setBackSymbol($currency->getBackSymbol());
$orderCurrency->setShortcut($currency->getShortcut());
$orderProduct = new OrderProduct();
$orderProduct->setProductId($product->getId());
$orderProduct->setQuantity($response->getL_PaymentRequest_0_Qty0());
$orderProduct->setCode($product->getCode());
$orderProduct->setName($product->getName());
$orderProduct->setBasePriceBrutto($response->getL_PaymentRequest_0_Amt0());
$orderProduct->setImage($product->getOptImage());
$orderProduct->setTax($product->getTax());
$orderProduct->setPointsEarn($product->getPointsEarn());
$priceModifiers = $product->getPriceModifiers();
if ($priceModifiers)
{
foreach ($priceModifiers as $index => $price_modifier)
{
$priceModifiers[$index]['value'] = null;
if (isset($priceModifiers[$index]['custom']['label']))
{
$priceModifiers[$index]['label'] = $priceModifiers[$index]['custom']['label'];
}
}
$orderProduct->setPriceModifiers($priceModifiers);
}
$order->addOrderProduct($orderProduct);
/**
* Order delivery
**/
$delivery = DeliveryPeer::retrieveByPK($config->get('express_delivery'));
$orderDelivery = $order->getOrderDelivery();
$orderDelivery->setName($delivery->getName());
$orderDelivery->setTaxId($delivery->getTaxId());
$orderDelivery->setDeliveryId($delivery->getId());
$orderDelivery->setCostBrutto($response->getPaymentRequest_0_ShippingAmt()*$currency->getExchange());
$orderDelivery->setOptTax($delivery->getTax()->getVat());
/**
* Confirm order
**/
if (stUser::isFullAccount($user)) {
$order->setIsConfirmed(1);
}
/**
* Save order
**/
$order->save();
/**
* Generate order number
**/
$dateFormat = new sfDateFormat();
$orderConfig = stConfig::getInstance('stOrder');
$format = $orderConfig->get('number_format');
$date = $dateFormat->getDate($order->getCreatedAt(), 'd');
$number = str_replace(array('{NUMER}', '{DZIEN}', '{MIESIAC}', '{ROK}'), array($order->getId(), $date['mday'], $date['mon'], $date['year']), $format);
$order->setNumber($number);
$order->save();
/**
* Payment
**/
$c = new Criteria();
$c->add(PaymentTypePeer::MODULE_NAME, 'stPaypal');
$paymentType = PaymentTypePeer::doSelectOne($c);
$stPayment = new stPayment();
$paymentId = $stPayment->add($user->getId(), $paymentType->getId(), stPayment::getUnpayedAmountByOrder($order));
$stPayment->addPaymentForOrder($order->getId(), $paymentId);
/**
* Invoice
**/
stInvoiceListener::crateInvoiceProforma($order);
return $order;
}
protected function getUserDataFromResponse(stPaypalCallerResponse $r, UserData $u) {
$u->setFullName($r->getPaymentRequest_0_ShipToName());
$u->setAddress($r->getPaymentRequest_0_ShipToStreet());
$u->setCode($r->getPaymentRequest_0_ShipToZip());
$u->setTown($r->getPaymentRequest_0_ShipToCity());
$u->setRegion($r->getPaymentRequest_0_ShipToState());
$c = new Criteria();
$c->add(CountriesPeer::ISO_A2, $r->getPaymentRequest_0_ShipToCountryCode());
$country = CountriesPeer::doSelectOne($c);
$u->setCountriesId(is_null($country) ? '36' : $country->getId());
return $u;
}
protected function mirrorUserData($target, $source) {
$attributes = array('countries', 'full_name', 'address', 'region', 'code', 'town');
foreach($attributes as $attribute) {
$setter = 'set'.sfInflector::camelize($attribute);
$getter = 'get'.sfInflector::camelize($attribute);
$target->$setter($source->$getter());
}
}
public static function validateProduct(Product $product, $quantity) {
$context = sfContext::getInstance();
$i18n = $context->getI18n();
if ($product->getPriceBrutto() <= 0)
return self::returnValidareProductError($i18n->__('Cena produktu musi być większa niż 0'));
if (!is_numeric($quantity) || empty($quantity))
return self::returnValidareProductError($i18n->__('Podana wartość musi być liczbą całkowitą...', null, 'stBasket'));
$minAmount = stConfig::getInstance('stOrder')->get('min_amount', 0);
if ($minAmount > 0 && $minAmount > $product->getPriceBrutto())
return self::returnValidareProductError($i18n->__('Minimalna wartość zamówienia wynosi %min_amount%', array('%min_amount%' => st_price($min_amount, true, true)), 'stOrder'));
$maxQuantity = $product->getStock();
if ($product->getStock() == null || !$product->getIsStockValidated())
$maxQuantity = stConfig::getInstance('stBasket')->get('max_quantity', 0);
$productMaxQty = $product->getMaxQty();
$max = $productMaxQty && $productMaxQty < $maxQuantity ? $productMaxQty : $maxQuantity;
if ($max < $quantity)
return self::returnValidareProductError($i18n->__('Brak wymaganej ilości towaru w magazynie', null, 'stBasket'));
return true;
}
public static function returnValidareProductError($message) {
sfContext::getInstance()->getUser()->setAttribute('express_checkout_error', $message, 'stPaypal');
return false;
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* SOTESHOP/stPaypalPlugin
*
* Ten plik należy do aplikacji stPaypalPlugin opartej na licencji (Professional License SOTE).
* Nie zmieniaj tego pliku, jeśli chcesz korzystać z automatycznych aktualizacji oprogramowania.
* Jeśli chcesz wprowadzać swoje modyfikacje do programu, zapoznaj się z dokumentacją, jak zmieniać
* oprogramowanie bez zmiany kodu bazowego http://www.sote.pl/modifications
*
* @package stPaypalPlugin
* @subpackage libs
* @copyright SOTE (www.sote.pl)
* @license http://www.sote.pl/license/sote (Professional License SOTE)
* @version $Id: stPaypal.class.php 5933 2010-07-01 11:11:44Z marcin $
* @author Marcin Butlak <marcin.butlak@sote.pl>
*/
class stPaypal
{
public static function getButtonLocaleByCulture($culture)
{
$culture_to_locale = sfConfig::get('app_stPaypal_button_culture_locale');
return isset($culture_to_locale[$culture]) ? $culture_to_locale[$culture] : $culture_to_locale['default'];
}
public function checkPaymentConfiguration()
{
$config = stConfig::getInstance(null, 'stPaypal');
return $config->get('enabled') && $config->get('configuration_verified');
}
}

View File

@@ -0,0 +1,466 @@
<?php
/**
* SOTESHOP/stPaypalPlugin
*
* Ten plik należy do aplikacji stPaypalPlugin opartej na licencji (Professional License SOTE).
* Nie zmieniaj tego pliku, jeśli chcesz korzystać z automatycznych aktualizacji oprogramowania.
* Jeśli chcesz wprowadzać swoje modyfikacje do programu, zapoznaj się z dokumentacją, jak zmieniać
* oprogramowanie bez zmiany kodu bazowego http://www.sote.pl/modifications
*
* @package stPaypalPlugin
* @subpackage libs
* @copyright SOTE (www.sote.pl)
* @license http://www.sote.pl/license/sote (Professional License SOTE)
* @version $Id: $
* @author Marcin Butlak <marcin.butlak@sote.pl>
*/
/**
*
* Klasa obsługi wyjątków z stPaypalCallerService
*
* @package stPaypalPlugin
* @subpackage libs
*/
class stPaypalCallerException extends sfException
{
}
/**
*
* Podstawowa klasa upraszczająca tworzenie i pobieranie parametrów Paypal NVP API
*
* @package stPaypalPlugin
* @subpackage libs
*/
abstract class stPaypalCallerBase
{
protected $parameters = array('_ITEMS' => array());
public function __toString()
{
$tmp = array();
foreach($this->parameters as $name => $value)
{
if (is_array($value))
{
$tmp = array_merge($tmp, $value);
}
else
{
$tmp[] = strtoupper($name) . '=' . urlencode($value);
}
}
return implode('&', $tmp);
}
public function addItem(stPaypalCallerBase $item)
{
$this->parameters['_ITEMS'][] = $item;
}
public function getItems()
{
return $this->parameters['_ITEMS'];
}
public function setItems($items)
{
$this->parameters['_ITEMS'] = $items;
}
public function __set($name, $value)
{
$name = strtoupper($name);
$this->parameters[$name] = is_bool($value) ? intval($value) : $value;
}
public function __get($name)
{
$name = strtoupper($name);
return array_key_exists($name, $this->parameters) ? $this->parameters[$name] : null;
}
public function __call($name, $arguments)
{
if (strpos($name, 'set') === 0)
{
$name = substr($name, 3);
$this->$name = current($arguments);
return $this;
}
elseif (strpos($name, 'get') === 0)
{
$name = substr($name, 3);
return $this->$name;
}
}
}
/**
*
* Klasa upraszczająca definiowanie parametrów Paypal NVP API typu "List"
*
* @package stPaypalPlugin
* @subpackage libs
*/
class stPaypalCallerItem extends stPaypalCallerBase
{
private $id = 0;
public function __construct($id, $parameters = array())
{
$this->parameters = $parameters;
$this->id = $id;
}
public function setItemId($id)
{
$this->id = $id;
}
public function __toString()
{
$tmp = array();
foreach($this->parameters as $name => $value)
{
$tmp[] = 'L_' . strtoupper($name). $this->id . '=' . urlencode($value);
}
return implode('&', $tmp);
}
}
/**
*
* Klasa upraszczająca odbieranie odpowiedzi od Paypal NVP API
*
* @package stPaypalPlugin
* @subpackage libs
*/
class stPaypalCallerResponse extends stPaypalCallerBase
{
public function __construct($nvp)
{
$this->deformatNVP($nvp);
}
public function isSuccessful()
{
return $this->getAck() == 'Success' || $this->getAck() == 'SuccessWithWarning';
}
public function hasFailed()
{
return !$this->isSuccessful();
}
public function hasError($error_code)
{
foreach ($this->getItems() as $error)
{
if ($error->getErrorCode() == $error_code)
{
return true;
}
}
return false;
}
protected function deformatNVP($nvp)
{
$items = array();
$item_index = 0;
$parameters = explode('&', $nvp);
foreach ($parameters as $parameter)
{
list($name, $value) = explode('=', $parameter);
$tmp = array();
if (preg_match('/L_([A-Z]+)([0-9]+)/i', $name, $tmp))
{
if (isset($items[$item_index][$tmp[2]][$tmp[1]]) &&$tmp[2] == 0)
{
$item_index++;
}
$items[$item_index][$tmp[2]][$tmp[1]] = urldecode($value);
}
else
{
$this->parameters[$name] = urldecode($value);
}
}
foreach ($items as $item)
{
foreach ($item as $id => $params)
{
$this->addItem(new stPaypalCallerItem($id, $params));
}
}
unset($list_params);
}
}
/**
*
* Klasa upraszczająca tworzenie żądań do Paypal NVP API
*
* @package stPaypalPlugin
* @subpackage libs
*/
class stPaypalCallerRequest extends stPaypalCallerBase
{
public function __construct($parameters = array())
{
foreach($this->parameters as $name => $value)
{
if (is_array($value))
{
foreach ($value as $id => $params)
{
$this->addItem(new stPaypalCallerItem($id, $params));
}
}
else
{
$this->$name = $value;
}
}
}
}
/**
*
* Klasa upraszczająca kominukację z Paypal NVP API
*
* Przykład zapytania o aktualny bilans konta Paypal we wszystkich dostępnych walutach (zgodnie z specyfikacją ):
* $paypal = stPaypalCallerService::getInstance();
* $paypal->initialize('uzytkownik_api', 'haslo_api', 'podpis_api', 'sandbox|live');
* $request = new stPaypalCallerRequest();
* $request->setReturnAllCurrencies(1);
* $response = $paypal->getBalance($request);
* foreach ($response->getItems() as $item)
* {
* echo $item->getAmt() . " " . $item->getCurrencyCode() . "<br />";
* }
*
* @package stPaypalPlugin
* @subpackage libs
*/
class stPaypalCallerService
{
private $apiUsername = null;
private $apiPassword = null;
private $apiSignature = null;
private $apiEnvironment = self::ENV_LIVE;
private $apiVersion = null;
private $baseResponseClass = self::BASE_RESPONSE_CLASS;
protected static $instance = null;
const ENV_LIVE = 'live';
const ENV_SANDBOX = 'sandbox';
const BASE_RESPONSE_CLASS = 'stPaypalCallerResponse';
/**
*
* Pobiera instancję stPaypalCallerService
*
* @param string $base_caller_class Nazwy klasy rozszerzającej stPaypalCallerService (wymagane wyłącznie podczas rozszerzania stPaypalCallerService)
* @return stPaypalCallerService
*/
public static function getInstance($base_caller_class = null)
{
if (is_null(self::$instance))
{
$class = $base_caller_class ? $base_caller_class : __CLASS__;
self::$instance = new $class();
}
return self::$instance;
}
public function __construct()
{
$this->apiVersion = sfConfig::get('app_stPaypal_api_version');
}
public function initialize($username, $password, $signature, $params = array())
{
$this->apiUsername = $username;
$this->apiPassword = $password;
$this->apiSignature = $signature;
if (isset($params['environment']))
{
$this->apiEnvironment = $params['environment'];
}
if (isset($params['base_response_class']))
{
$this->baseResponseClass = $params['base_response_class'];
}
}
public function setApiUsername($username)
{
$this->apiUsername = $username;
}
public function setApiPassword($password)
{
$this->apiPassword = $password;
}
public function setApiSignature($signature)
{
$this->apiSignature = $signature;
}
public function setApiEnvironment($environment)
{
$this->apiEnvironment = $environment;
}
public function setApiVersion($apiVersion) {
$this->apiVersion = $apiVersion;
}
public function getExpressCheckoutUrl($token)
{
$urls = sfConfig::get('app_stPaypal_urls');
return $urls[$this->apiEnvironment] . '?cmd=_express-checkout&useraction=commit&token=' . $token;
}
/**
*
* Zmienia klase pełniącą rolę odpowiedzi od Paypal NVP API
*
* @param string $class_name Nazwa klasy
*/
public function setBaseResponseClass($class_name)
{
$this->baseResponseClass = $class_name;
}
/**
*
* Wykonuje żądanie za pośrednictwem Paypal NVP API
*
* @param string $method Nazwa metody Paypal API
* @param stPaypalCallerRequest $request Parametry żądania
* @return stPaypalCallerResponse
*/
public function __call($name, $arguments)
{
if (is_array($arguments[0]))
{
$request = new stPaypalCallerRequest($arguments[0]);
}
elseif (is_object($arguments[0]) && $arguments[0] instanceof stPaypalCallerRequest)
{
$request = clone $arguments[0];
}
else
{
throw new stPaypalCallerException('You must pass a stPaypalCallerRequest object or an array of Paypal parameters');
}
$request->setMethod($name);
$request->setUser($this->apiUsername);
$request->setPwd($this->apiPassword);
$request->setSignature($this->apiSignature);
$request->setVersion($this->apiVersion);
$endpoints = sfConfig::get('app_stPaypal_api_endpoints');
if (!isset($endpoints[$this->apiEnvironment]))
{
throw new stPaypalCallerException(sprintf('There is no "%s" environment, available enviroments: "%s"', $this->apiEnvironment, implode(", ",array_flip($endpoints))));
}
$response = self::curlCall($endpoints[$this->apiEnvironment], strval($request));
$responseObject = new $this->baseResponseClass($response);
if (sfConfig::get('sf_debug') && $responseObject->hasFailed())
{
sfLogger::getInstance()->err('{Paypal} '.var_export($responseObject->getItems(), true));
}
return $responseObject;
}
/**
*
* Metoda pomocnicza do obsługi żądań metodą POST
*
* @param string $url Adres żądania
* @param string $postfields Parametry POST żądania
* @return string Odpowiedź
*/
public static function curlCall($url, $postfields)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$response = curl_exec($ch);
if (curl_errno($ch))
{
throw new stPaypalCallerException(curl_error($ch), curl_errno($ch));
}
curl_close($ch);
return $response;
}
}