Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,340 @@
<?php
/**
* For the full copyright and license information, please view the
* docs/licenses/LICENSE.txt file that was distributed with this source code.
*/
use PrestaShop\PrestaShop\Adapter\Presenter\Order\OrderPresenter;
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagSettings;
use PrestaShop\PrestaShop\Core\FeatureFlag\FeatureFlagStateCheckerInterface;
use PrestaShop\PrestaShop\Core\Security\PasswordPolicyConfiguration;
use ZxcvbnPhp\Zxcvbn;
class OrderConfirmationControllerCore extends FrontController
{
/** @var bool */
public $ssl = true;
/** @var string */
public $php_self = 'order-confirmation';
/** @var int Cart ID */
public $id_cart;
public $id_module;
public $id_order;
public $secure_key;
/** @var Order Order object we found by cart ID */
protected $order;
/** @var Customer Customer object related to the cart */
protected $customer;
public $reference; // Deprecated
public $order_presenter; // Deprecated
/**
* Initialize order confirmation controller.
*
* @see FrontController::init()
*/
public function init(): void
{
// Test below to prevent unnecessary logs from "parent::init()"
$this->id_cart = (int) Tools::getValue('id_cart', 0);
if (!empty($this->context->cookie->id_cart) && $this->context->cookie->id_cart == $this->id_cart) {
$cart = new Cart($this->id_cart);
if ($cart->orderExists()) {
unset($this->context->cookie->id_cart);
}
}
parent::init();
/*
* There is a special case for free orders, when this page does more than just display
* the confirmation. It also creates the order if it is free. This is done if free_order
* parameter is passed to this page.
*
* After the order is created, we redirect to the same page without free_order parameter
* and display the confirmation as usual.
*/
if ((bool) Tools::getValue('free_order') === true) {
$this->checkFreeOrder();
}
/*
* Because of order splitting scenarios, we must get the data by id_cart parameter (not id_order),
* so we can display all orders made from this cart.
*
* It's not implemented yet, however, and probably won't be, because we are switching to a new
* logic of multiple shipments per order, which doesn't require splitting orders anymore.
*/
$this->id_order = Order::getIdByCartId((int) $this->id_cart);
if (empty($this->id_order)) {
Tools::redirect('pagenotfound');
}
// Now, load the order object and check validity
$this->order = new Order((int) $this->id_order);
if (!Validate::isLoadedObject($this->order)) {
Tools::redirect('pagenotfound');
}
/*
* Now, to prevent users from seeing other customers' order confirmations, we are using
* a secure key mechanism. The confirmation link contains a unique key which is also saved
* in database when the order is created. If the key from the URL doesn't match the one
* in database, we redirect to "page not found".
*/
$this->secure_key = Tools::getValue('key', false);
if (empty($this->secure_key) || $this->secure_key != $this->order->secure_key) {
Tools::redirect('pagenotfound');
}
// Last step, initialize some other data
$this->id_module = $this->order->module == 'free_order' ? -1 : Module::getModuleIdByName($this->order->module);
// This data is kept only for backward compatibility purposes
$this->reference = (string) $this->order->reference;
// If checks passed, initialize customer, we will need him anyway
$this->customer = new Customer((int) $this->order->id_customer);
}
/**
* Logic after submitting forms
*
* @see FrontController::postProcess()
*/
public function postProcess(): void
{
if (Tools::isSubmit('submitTransformGuestToCustomer')) {
// Only variable we need is the password
// There is no need to check other variables, because hacker would be kicked out in init(), if he tried to convert another customer
$password = Tools::getValue('password');
if (empty($password)) {
$this->errors[] = $this->trans(
'Enter a password to transform your guest account into a customer account.',
[],
'Shop.Forms.Help'
);
} else {
if (Validate::isAcceptablePasswordLength($password) === false) {
$this->errors[] = $this->translator->trans(
'Password must be between %d and %d characters long',
[
Configuration::get(PasswordPolicyConfiguration::CONFIGURATION_MINIMUM_LENGTH),
Configuration::get(PasswordPolicyConfiguration::CONFIGURATION_MAXIMUM_LENGTH),
],
'Shop.Notifications.Error'
);
}
if (Validate::isAcceptablePasswordScore($password) === false) {
$wordingsForScore = [
$this->translator->trans('Very weak', [], 'Shop.Theme.Global'),
$this->translator->trans('Weak', [], 'Shop.Theme.Global'),
$this->translator->trans('Average', [], 'Shop.Theme.Global'),
$this->translator->trans('Strong', [], 'Shop.Theme.Global'),
$this->translator->trans('Very strong', [], 'Shop.Theme.Global'),
];
$globalErrorMessage = $this->translator->trans(
'The minimum score must be: %s',
[
$wordingsForScore[(int) Configuration::get(PasswordPolicyConfiguration::CONFIGURATION_MINIMUM_SCORE)],
],
'Shop.Notifications.Error'
);
if ($this->context->shop->theme->get('global_settings.new_password_policy_feature') !== true) {
$zxcvbn = new Zxcvbn();
$result = $zxcvbn->passwordStrength($password);
if (!empty($result['feedback']['warning'])) {
$this->errors[] = $this->translator->trans(
$result['feedback']['warning'], [], 'Shop.Theme.Global'
);
} else {
$this->errors[] = $globalErrorMessage;
}
foreach ($result['feedback']['suggestions'] as $suggestion) {
$this->errors[] = $this->translator->trans($suggestion, [], 'Shop.Theme.Global');
}
} else {
$this->errors[] = $globalErrorMessage;
}
}
}
if (!empty($this->errors)) {
return;
}
// Prevent error
// A) either on page refresh
// B) if we already transformed him in other window or through backoffice
if ($this->customer->is_guest == 0) {
$this->errors[] = $this->trans(
'A customer account has already been created from this guest account. Please sign in.',
[],
'Shop.Notifications.Error'
);
// Check if a different customer with the same email was not already created in a different window or through backoffice
} elseif (Customer::customerExists($this->customer->email)) {
$this->errors[] = $this->trans(
'You can\'t transform your account into a customer account, because a registered customer with the same email already exists.',
[],
'Shop.Notifications.Error'
);
// Attempt to convert the customer
} elseif ($this->customer->transformToCustomer($this->context->language->id, $password)) {
$this->success[] = $this->trans(
'Your guest account has been successfully transformed into a customer account. You can now log in as a registered shopper.',
[],
'Shop.Notifications.Success'
);
} else {
$this->errors[] = $this->trans(
'An unexpected error occurred while creating your account.',
[],
'Shop.Notifications.Error'
);
}
}
}
/**
* Assign template vars related to page content.
*
* @see FrontController::initContent()
*/
public function initContent(): void
{
parent::initContent();
/** @var FeatureFlagStateCheckerInterface $featureFlagManager */
$featureFlagManager = $this->get(FeatureFlagStateCheckerInterface::class);
$this->context->smarty->assign([
'HOOK_ORDER_CONFIRMATION' => $this->displayOrderConfirmation($this->order),
'HOOK_PAYMENT_RETURN' => $this->displayPaymentReturn($this->order),
'order' => (new OrderPresenter())->present($this->order),
'order_customer' => $this->objectPresenter->present($this->customer),
'is_multishipment_enabled' => $featureFlagManager->isEnabled(FeatureFlagSettings::FEATURE_FLAG_IMPROVED_SHIPMENT),
'registered_customer_exists' => Customer::customerExists($this->customer->email),
]);
$this->setTemplate('checkout/order-confirmation');
// If logged in guest we clear the cookie for security reasons
if ($this->context->customer->is_guest) {
$this->context->customer->mylogout();
}
}
/**
* Execute the hook displayPaymentReturn. This hook should be used to display payment
* information on the order confirmation page. Payment status, instructions, QR code etc.
*/
public function displayPaymentReturn(Order $order)
{
// Check if we have a sensible module ID. Free orders have -1 as module ID
if (!Validate::isUnsignedId($this->id_module)) {
return false;
}
// Hook called only for the module concerned
return Hook::exec('displayPaymentReturn', ['order' => $order], $this->id_module);
}
/**
* Execute the hook displayOrderConfirmation.
*/
public function displayOrderConfirmation(Order $order)
{
return Hook::exec('displayOrderConfirmation', ['order' => $order]);
}
/**
* Check if an order is free and create it. After creation, we redirect to the same page
* which will display the order confirmation as usual.
*/
protected function checkFreeOrder(): void
{
/*
* Verify if this is not a faulty or duplicate call. If an order
* already exists for this cart, we do not create another one.
*/
if (!empty(Order::getIdByCartId((int) $this->id_cart))) {
return;
}
$cart = $this->context->cart;
if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0) {
Tools::redirect($this->context->link->getPageLink('order'));
}
$customer = new Customer($cart->id_customer);
if (!Validate::isLoadedObject($customer)) {
Tools::redirect($this->context->link->getPageLink('order'));
}
$total = (float) $cart->getOrderTotal(true, Cart::BOTH);
if ($total > 0) {
Tools::redirect($this->context->link->getPageLink('order'));
}
$order = new PaymentFree();
$order->validateOrder(
$cart->id,
(int) Configuration::get('PS_OS_PAYMENT'),
0,
$this->trans('Free order', [], 'Admin.Orderscustomers.Feature'),
null,
[],
null,
false,
$cart->secure_key
);
/*
* Redirect back to this page to display the order confirmation.
* Note the id_module parameter with value -1, it's only kept for
* backward compatibility, but not used anymore.
*/
Tools::redirect($this->context->link->getPageLink(
'order-confirmation',
null,
null,
[
'id_cart' => (int) $cart->id,
'id_module' => '-1',
'id_order' => (int) $order->currentOrder,
'key' => $cart->secure_key,
]
));
}
public function getBreadcrumbLinks(): array
{
$breadcrumb = parent::getBreadcrumbLinks();
$breadcrumb['links'][] = [
'title' => $this->trans('Order confirmation', [], 'Shop.Theme.Checkout'),
'url' => $this->context->link->getPageLink('order-confirmation'),
];
return $breadcrumb;
}
/**
* @return Order
*/
public function getOrder(): Order
{
return $this->order;
}
/**
* @return Customer
*/
public function getCustomer(): Customer
{
return $this->customer;
}
}