Merge pull request #284 from roadster31/basemodulecontroller
Various improvements, and URL calculation fix
This commit is contained in:
@@ -206,7 +206,7 @@ class Order extends BaseAction implements EventSubscriberInterface
|
||||
$placedOrder->setInvoiceOrderAddressId($invoiceOrderAddress->getId());
|
||||
|
||||
$placedOrder->setStatusId(
|
||||
OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID)->getId()
|
||||
OrderStatusQuery::getNotPaidStatus()->getId()
|
||||
);
|
||||
|
||||
/* memorize discount */
|
||||
|
||||
@@ -266,9 +266,9 @@ class BaseAdminController extends BaseController
|
||||
/**
|
||||
* Redirect to à route ID related URL
|
||||
*
|
||||
* @param unknown $routeId the route ID, as found in Config/Resources/routing/admin.xml
|
||||
* @param array|\Thelia\Controller\Admin\unknown $urlParameters the URL parametrs, as a var/value pair array
|
||||
* @param array $routeParameters
|
||||
* @param string $routeId the route ID, as found in Config/Resources/routing/admin.xml
|
||||
* @param array $urlParameters the URL parameters, as a var/value pair array
|
||||
* @param array $routeParameters
|
||||
*/
|
||||
public function redirectToRoute($routeId, array $urlParameters = array(), array $routeParameters = array())
|
||||
{
|
||||
@@ -405,9 +405,9 @@ class BaseAdminController extends BaseController
|
||||
/**
|
||||
* Render the given template, and returns the result as an Http Response.
|
||||
*
|
||||
* @param $templateName the complete template name, with extension
|
||||
* @param array $args the template arguments
|
||||
* @param int $status http code status
|
||||
* @param string $templateName the complete template name, with extension
|
||||
* @param array $args the template arguments
|
||||
* @param int $status http code status
|
||||
* @return \Thelia\Core\HttpFoundation\Response
|
||||
*/
|
||||
protected function render($templateName, $args = array(), $status = 200)
|
||||
|
||||
@@ -138,7 +138,7 @@ class OrderEvent extends ActionEvent
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $status
|
||||
* @param int $status
|
||||
*/
|
||||
public function setStatus($status)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
|
||||
namespace Thelia\Install;
|
||||
|
||||
use Propel\Runtime\Connection\ConnectionInterface;
|
||||
use Propel\Runtime\Connection\ConnectionWrapper;
|
||||
use Propel\Runtime\Propel;
|
||||
use Propel\Runtime\ServiceContainer\ServiceContainerInterface;
|
||||
|
||||
/**
|
||||
* Class Database
|
||||
* @package Thelia\Install
|
||||
@@ -30,10 +35,34 @@ namespace Thelia\Install;
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
public $connection;
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
public function __construct(\PDO $connection)
|
||||
/**
|
||||
* Create a new instance, using the provided connection information, either none for
|
||||
* automatically a connection, a ConnectionWrapper instance (through ConnectionInterface) or a PDO connection.
|
||||
*
|
||||
* @param ConnectionInterface|\PDO|null $connection the connection object
|
||||
* @throws \InvalidArgumentException if $connection is not of the suitable type.
|
||||
*/
|
||||
public function __construct($connection = null)
|
||||
{
|
||||
// Get a connection from Propel if we don't have one
|
||||
if (null == $connection) {
|
||||
$connection = Propel::getConnection(ServiceContainerInterface::CONNECTION_WRITE);
|
||||
}
|
||||
|
||||
// Get the PDO connection from an
|
||||
if ($connection instanceof ConnectionWrapper) {
|
||||
$connection = $connection->getWrappedConnection();
|
||||
}
|
||||
|
||||
if (!$connection instanceof \PDO) {
|
||||
throw new \InvalidArgumentException("A PDO connection shoud be provided");
|
||||
}
|
||||
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
@@ -41,8 +70,8 @@ class Database
|
||||
* Insert all sql needed in database
|
||||
* Default insert /install/thelia.sql and /install/insert.sql
|
||||
*
|
||||
* @param string $dbName Database name
|
||||
* @param array $extraSqlFiles SQL Files uri to insert
|
||||
* @param string $dbName Database name
|
||||
* @param array $extraSqlFiles SQL Files uri to insert
|
||||
*/
|
||||
public function insertSql($dbName = null, array $extraSqlFiles = null)
|
||||
{
|
||||
@@ -67,13 +96,35 @@ class Database
|
||||
}
|
||||
}
|
||||
$size = count($sql);
|
||||
for ($i = 0; $i < $size; $i ++) {
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
if (!empty($sql[$i])) {
|
||||
$this->connection->query($sql[$i]);
|
||||
$this->execute($sql[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple wrapper around PDO::exec
|
||||
*
|
||||
* @param string $sql SQL query
|
||||
* @param array $args SQL request parameters (PDO style)
|
||||
* @throws \RuntimeException|\PDOException if something goes wrong.
|
||||
*/
|
||||
public function execute($sql, $args = array())
|
||||
{
|
||||
$stmt = $this->connection->prepare($sql);
|
||||
|
||||
if ($stmt === false) {
|
||||
throw new \RuntimeException("Failed to prepare statement for $sql: " . print_r($this->connection->errorInfo(), 1));
|
||||
}
|
||||
|
||||
$success = $stmt->execute($args);
|
||||
|
||||
if ($success === false || $stmt->errorCode() != 0) {
|
||||
throw new \RuntimeException("Failed to execute SQL '$sql', arguments:" . print_r($args,1).", error:".print_r($stmt->errorInfo(), 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Separate each sql instruction in an array
|
||||
*
|
||||
@@ -88,7 +139,7 @@ class Database
|
||||
|
||||
$tab = explode(";\n", $sql);
|
||||
$size = count($tab);
|
||||
for ($i=0; $i<$size; $i++) {
|
||||
for ($i = 0; $i < $size; $i++) {
|
||||
$queryTemp = str_replace("-CODE-", ";',", $tab[$i]);
|
||||
$queryTemp = str_replace("|", ";", $queryTemp);
|
||||
$query[] = $queryTemp;
|
||||
@@ -104,7 +155,7 @@ class Database
|
||||
*/
|
||||
public function createDatabase($dbName)
|
||||
{
|
||||
$this->connection->exec(
|
||||
$this->execute(
|
||||
sprintf(
|
||||
"CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8",
|
||||
$dbName
|
||||
|
||||
@@ -16,4 +16,26 @@ use Thelia\Model\Base\OrderStatusQuery as BaseOrderStatusQuery;
|
||||
*/
|
||||
class OrderStatusQuery extends BaseOrderStatusQuery
|
||||
{
|
||||
|
||||
public static function getNotPaidStatus() {
|
||||
return OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_NOT_PAID);
|
||||
}
|
||||
|
||||
public static function getPaidStatus() {
|
||||
return OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_PAID);
|
||||
}
|
||||
|
||||
public static function getProcessingStatus() {
|
||||
return OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_PROCESSING);
|
||||
}
|
||||
|
||||
public static function getSentStatus() {
|
||||
return OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_SENT);
|
||||
}
|
||||
|
||||
public static function getCancelledStatus() {
|
||||
return OrderStatusQuery::create()->findOneByCode(OrderStatus::CODE_CANCELED);
|
||||
}
|
||||
|
||||
|
||||
} // OrderStatusQuery
|
||||
|
||||
198
core/lib/Thelia/Module/BasePaymentModuleController.php
Normal file
198
core/lib/Thelia/Module/BasePaymentModuleController.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* */
|
||||
/* Thelia */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : info@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* This program is free software; you can redistribute it and/or modify */
|
||||
/* it under the terms of the GNU General Public License as published by */
|
||||
/* the Free Software Foundation; either version 3 of the License */
|
||||
/* */
|
||||
/* This program is distributed in the hope that it will be useful, */
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
||||
/* GNU General Public License for more details. */
|
||||
/* */
|
||||
/* You should have received a copy of the GNU General Public License */
|
||||
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
/* */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Module;
|
||||
|
||||
use Symfony\Component\Routing\Router;
|
||||
use Thelia\Controller\Front\BaseFrontController;
|
||||
use Thelia\Core\Event\Order\OrderEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
use Thelia\Core\HttpFoundation\Response;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Model\OrderQuery;
|
||||
use Thelia\Model\OrderStatus;
|
||||
use Thelia\Model\OrderStatusQuery;
|
||||
|
||||
/**
|
||||
* This class implement the minimum
|
||||
*
|
||||
* @package Paypal\Controller
|
||||
* @author Thelia <info@thelia.net>
|
||||
*/
|
||||
abstract class BasePaymentModuleController extends BaseFrontController
|
||||
{
|
||||
protected $log = null;
|
||||
|
||||
/**
|
||||
* Return a module identifier used to calculate the name of the log file,
|
||||
* and in the log messages.
|
||||
*
|
||||
* @return string the module code
|
||||
*/
|
||||
protected abstract function getModuleCode();
|
||||
|
||||
/**
|
||||
* Initialize a module-specific logger.
|
||||
*
|
||||
* @return Tlog a Tlog instance
|
||||
*/
|
||||
protected function getLog() {
|
||||
|
||||
if ($this->log == null) {
|
||||
$this->log = Tlog::getNewInstance();
|
||||
|
||||
$logFilePath = sprintf(THELIA_ROOT."log".DS."%s.log", strtolower($this->getModuleCode()));
|
||||
|
||||
$this->log->setPrefix("#LEVEL: #DATE #HOUR: ");
|
||||
$this->log->setDestinations("\\Thelia\\Log\\Destination\\TlogDestinationFile");
|
||||
$this->log->setConfig("\\Thelia\\Log\\Destination\\TlogDestinationFile", 0, $logFilePath);
|
||||
}
|
||||
|
||||
return $this->log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the confirmation of an order. This method should be called
|
||||
* once the module has performed the required checks to confirm a valid payment.
|
||||
*
|
||||
* @param int $order_id the order ID
|
||||
*/
|
||||
public function confirmPayment($order_id)
|
||||
{
|
||||
try {
|
||||
$order_id = intval($order_id);
|
||||
|
||||
if (null !== $order = $this->getOrder($order_id)) {
|
||||
|
||||
$this->getLog()->addInfo(
|
||||
$this->getTranslator()->trans("Processing confirmation of order ref. %ref, ID %id",
|
||||
array('%ref' => $order->getRef(), '%id' => $order->getId()))
|
||||
);
|
||||
|
||||
$event = new OrderEvent($order);
|
||||
|
||||
$event->setStatus(OrderStatusQuery::getPaidStatus()->getId());
|
||||
|
||||
$this->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
|
||||
|
||||
$this->getLog()->addInfo(
|
||||
$this->getTranslator()->trans("Order ref. %ref, ID %id has been successfully paid.",
|
||||
array('%ref' => $order->getRef(), '%id' => $order->getId()))
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (\Exception $ex) {
|
||||
$this->getLog()->addError(
|
||||
$this->getTranslator()->trans("Error occured while processing order ref. %ref, ID %id: %err",
|
||||
array(
|
||||
'%err' => $ex->getMessage(),
|
||||
'%ref' => ! isset($order) ? "?" : $order->getRef(),
|
||||
'%id' => ! isset($order) ? "?" : $order->getId()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the cancelation of a payment on the payment gateway. The order will go back to the
|
||||
* "not paid" status.
|
||||
*
|
||||
* @param int $order_id the order ID
|
||||
*/
|
||||
public function cancelPayment($order_id)
|
||||
{
|
||||
$order_id = intval($order_id);
|
||||
|
||||
if (null !== $order = $this->getOrder($order_id)) {
|
||||
$this->getLog()->addInfo(
|
||||
$this->getTranslator()->trans("Processing cancelation of payment for order ref. %ref",
|
||||
array('%ref' => $order->getRef()))
|
||||
);
|
||||
|
||||
$event = new OrderEvent($order);
|
||||
|
||||
$event->setStatus(OrderStatus::CODE_NOT_PAID);
|
||||
|
||||
$this->getLog()->addInfo(
|
||||
$this->getTranslator()->trans("Order ref. %ref is now unpaid.",
|
||||
array('%ref' => $order->getRef()))
|
||||
);
|
||||
|
||||
$this->dispatch(TheliaEvents::ORDER_UPDATE_STATUS, $event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order and issue a log message if not found.
|
||||
* @param $order_id
|
||||
* @return null|\Thelia\Model\Order
|
||||
*/
|
||||
protected function getOrder($order_id)
|
||||
{
|
||||
if (null == $order = OrderQuery::create()->findPk($order_id)) {
|
||||
$this->getLog()->addError($this->getTranslator()->trans("Unknown order ID: %id", array('%id' => $order_id)));
|
||||
}
|
||||
|
||||
return $order;
|
||||
}
|
||||
/**
|
||||
* Redirect the customer to the successful payment page.
|
||||
*
|
||||
* @param int $order_id the order ID
|
||||
*/
|
||||
public function redirectToSuccessPage($order_id) {
|
||||
|
||||
$this->getLog()->addInfo("Redirecting customer to payment success page");
|
||||
|
||||
$this->redirectToRoute(
|
||||
'order.placed',
|
||||
array(
|
||||
'order_id' => $order_id
|
||||
),
|
||||
Router::ABSOLUTE_PATH
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the customer to the failure payment page. if $message is null, a generic message is displayed.
|
||||
*
|
||||
* @param int $order_id the order ID
|
||||
* @param string|null $message an error message.
|
||||
*/
|
||||
public function redirectToFailurePage($order_id, $message = null) {
|
||||
|
||||
$this->getLog()->addInfo("Redirecting customer to payment failure page");
|
||||
|
||||
$this->redirectToRoute(
|
||||
'order.failed',
|
||||
array(
|
||||
'order_id' => $order_id,
|
||||
'message' => $message
|
||||
),
|
||||
Router::ABSOLUTE_PATH
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Rewriting\RewritingResolver;
|
||||
use Thelia\Rewriting\RewritingRetriever;
|
||||
@@ -32,9 +33,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
class URL
|
||||
{
|
||||
/** @var RewritingResolver $resolver */
|
||||
protected $resolver = null;
|
||||
|
||||
/** @var RewritingRetriever $retriever */
|
||||
protected $retriever = null;
|
||||
|
||||
/** @var RequestContext $requestContext */
|
||||
protected $requestContext;
|
||||
|
||||
const PATH_TO_FILE = true;
|
||||
@@ -42,10 +47,13 @@ class URL
|
||||
|
||||
protected static $instance = null;
|
||||
|
||||
/** @var string $baseUrlScheme a cache for the base URL scheme */
|
||||
private $baseUrlScheme = null;
|
||||
|
||||
public function __construct(ContainerInterface $container = null)
|
||||
{
|
||||
// Allow singleton style calls once intanciated.
|
||||
// For this to work, the URL service has to be instanciated very early. This is done manually
|
||||
// Allow singleton style calls once instantiated.
|
||||
// For this to work, the URL service has to be instantiated very early. This is done manually
|
||||
// in TheliaHttpKernel, by calling $this->container->get('thelia.url.manager');
|
||||
self::$instance = $this;
|
||||
|
||||
@@ -72,26 +80,34 @@ class URL
|
||||
* Return the base URL, either the base_url defined in Config, or the URL
|
||||
* of the current language, if 'one_domain_foreach_lang' is enabled.
|
||||
*
|
||||
* @param bool $scheme_only if true, only the scheme will be returned. If false, the complete base URL, including path, is returned.
|
||||
*
|
||||
* @return string the base URL, with a trailing '/'
|
||||
*/
|
||||
public function getBaseUrl()
|
||||
public function getBaseUrl($scheme_only = false)
|
||||
{
|
||||
if ($host = $this->requestContext->getHost()) {
|
||||
if (null === $this->baseUrlScheme) {
|
||||
|
||||
$scheme = $this->requestContext->getScheme();
|
||||
$scheme = "http";
|
||||
$port = 80;
|
||||
|
||||
$port = '';
|
||||
if ($host = $this->requestContext->getHost()) {
|
||||
|
||||
if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) {
|
||||
$port = ':'.$this->requestContext->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) {
|
||||
$port = ':'.$this->requestContext->getHttpsPort();
|
||||
$scheme = $this->requestContext->getScheme();
|
||||
|
||||
$port = '';
|
||||
|
||||
if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) {
|
||||
$port = ':'.$this->requestContext->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) {
|
||||
$port = ':'.$this->requestContext->getHttpsPort();
|
||||
}
|
||||
}
|
||||
|
||||
$schemeAuthority = "$scheme://$host"."$port";
|
||||
$this->baseUrlScheme = "$scheme://$host"."$port";
|
||||
}
|
||||
|
||||
return $schemeAuthority.$this->requestContext->getBaseUrl();
|
||||
return $scheme_only ? $this->baseUrlScheme : $this->baseUrlScheme . $this->requestContext->getBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,17 +135,25 @@ class URL
|
||||
// Already absolute ?
|
||||
if (substr($path, 0, 4) != 'http') {
|
||||
|
||||
$base_url = $this->getBaseUrl();
|
||||
// Prevent duplication of the subdirectory name when Thelia is installed in a subdirectory.
|
||||
// This happens when $path was calculated with Router::generate(), which returns an absolute URL,
|
||||
// starting at web server root. For example, if Thelia is installed in /thelia2, we got something like /thelia2/my/path
|
||||
// As base URL also contains /thelia2 (e.g. http://some.server.com/thelia2), we end up with
|
||||
// http://some.server.com/thelia2/thelia2/my/path, instead of http://some.server.com/thelia2/my/path
|
||||
// We have to compensate for this.
|
||||
$hasSubdirectory = 0 === strpos($path, $this->requestContext->getBaseUrl());
|
||||
|
||||
$base_url = $this->getBaseUrl($hasSubdirectory);
|
||||
|
||||
/* Seems no longer required
|
||||
// TODO fix this ugly patch
|
||||
if (strpos($path, "index_dev.php")) {
|
||||
$path = str_replace('index_dev.php', '', $path);
|
||||
}
|
||||
*/
|
||||
|
||||
// If only a path is requested, be sure to remove the script name (index.php or index_dev.php), if any.
|
||||
if ($path_only == self::PATH_TO_FILE) {
|
||||
|
||||
// As the base_url always ends with '/', if we don't find / at the end, we have a script.
|
||||
if (substr($base_url, -3) == 'php') $base_url = dirname($base_url);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user