Add .gitignore and .htaccess for security
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.sublime-*
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Node (if any build tools)
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Composer dev dependencies (if installed locally)
|
||||||
|
vendor/
|
||||||
10
.htaccess
Normal file
10
.htaccess
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Apache 2.2
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
Order deny,allow
|
||||||
|
Deny from all
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Apache 2.4
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
Require all denied
|
||||||
|
</IfModule>
|
||||||
20
composer.json
Normal file
20
composer.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "myprestarocks/prestashop-compatibility",
|
||||||
|
"description": "Shared compatibility traits for PrestaShop modules - AJAX responses, templates, and core fixes",
|
||||||
|
"type": "library",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "mypresta.rocks",
|
||||||
|
"email": "info@mypresta.rocks"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"MyPrestaRocks\\Compatibility\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
147
src/AjaxResponseTrait.php
Normal file
147
src/AjaxResponseTrait.php
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ajax Response Trait - Standardized JSON responses for PrestaShop modules
|
||||||
|
*
|
||||||
|
* Provides consistent AJAX response methods with proper headers and hook integration.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* use MyPrestaRocks\Compatibility\AjaxResponseTrait;
|
||||||
|
*
|
||||||
|
* class YourModule extends Module {
|
||||||
|
* use AjaxResponseTrait;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author mypresta.rocks <info@mypresta.rocks>
|
||||||
|
* @copyright Copyright (c) mypresta.rocks
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MyPrestaRocks\Compatibility;
|
||||||
|
|
||||||
|
if (!defined('_PS_VERSION_')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait AjaxResponseTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Send a JSON response and exit
|
||||||
|
*
|
||||||
|
* Primary method for AJAX responses. Parameters ordered by frequency of use:
|
||||||
|
* - success: always needed
|
||||||
|
* - data: usually needed
|
||||||
|
* - message: optional, only when you need to show user feedback
|
||||||
|
*
|
||||||
|
* @param bool $success Whether the operation succeeded
|
||||||
|
* @param array $data Additional data to return
|
||||||
|
* @param string|null $message Optional message for user feedback
|
||||||
|
* @return void (exits)
|
||||||
|
*/
|
||||||
|
public function ajaxResponse($success, $data = [], $message = null)
|
||||||
|
{
|
||||||
|
$response = [
|
||||||
|
'success' => $success,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($message !== null) {
|
||||||
|
$response['message'] = $message;
|
||||||
|
$response['confirmations'] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($data)) {
|
||||||
|
$response = array_merge($response, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->outputJsonResponse($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a success response
|
||||||
|
*
|
||||||
|
* @param array $data Data to return
|
||||||
|
* @param string|null $message Optional success message
|
||||||
|
* @return void (exits)
|
||||||
|
*/
|
||||||
|
public function ajaxSuccess($data = [], $message = null)
|
||||||
|
{
|
||||||
|
$this->ajaxResponse(true, $data, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an error response
|
||||||
|
*
|
||||||
|
* @param string|null $message Error message
|
||||||
|
* @param array $data Additional error data
|
||||||
|
* @return void (exits)
|
||||||
|
*/
|
||||||
|
public function ajaxError($message = null, $data = [])
|
||||||
|
{
|
||||||
|
$this->ajaxResponse(false, $data, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render standardized JSON response for AJAX calls
|
||||||
|
*
|
||||||
|
* @deprecated Use ajaxResponse(), ajaxSuccess(), or ajaxError() instead
|
||||||
|
* Kept for backward compatibility with existing code
|
||||||
|
*
|
||||||
|
* @param string $message Message to display
|
||||||
|
* @param bool $success Whether the operation succeeded
|
||||||
|
* @param array $data Additional data to return
|
||||||
|
* @return void (exits)
|
||||||
|
*/
|
||||||
|
public function renderMessage($message, $success = true, $data = [])
|
||||||
|
{
|
||||||
|
$this->ajaxResponse($success, $data, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output JSON response with proper headers and hooks
|
||||||
|
*
|
||||||
|
* @param array $response Response array to encode
|
||||||
|
* @return void (exits)
|
||||||
|
*/
|
||||||
|
protected function outputJsonResponse($response)
|
||||||
|
{
|
||||||
|
$jsonResponse = json_encode($response);
|
||||||
|
|
||||||
|
$controller = get_class($this);
|
||||||
|
$method = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)[2]['function'] ?? 'unknown';
|
||||||
|
|
||||||
|
\Hook::exec('actionAjaxDieBefore', ['controller' => $controller, 'method' => $method, 'value' => $jsonResponse]);
|
||||||
|
\Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $jsonResponse]);
|
||||||
|
\Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $jsonResponse]);
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
|
||||||
|
|
||||||
|
echo $jsonResponse;
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send HTTP error response code
|
||||||
|
*
|
||||||
|
* @param int $code HTTP status code (default 404)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function respondInvalid($code = 404)
|
||||||
|
{
|
||||||
|
http_response_code($code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send HTTP error response with JSON body
|
||||||
|
*
|
||||||
|
* @param int $code HTTP status code
|
||||||
|
* @param string|null $message Error message
|
||||||
|
* @param array $data Additional data
|
||||||
|
* @return void (exits)
|
||||||
|
*/
|
||||||
|
public function respondWithError($code, $message = null, $data = [])
|
||||||
|
{
|
||||||
|
http_response_code($code);
|
||||||
|
$this->ajaxError($message, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/ModuleCompatibilityTrait.php
Normal file
31
src/ModuleCompatibilityTrait.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module Compatibility Trait - All-in-one compatibility trait for regular modules
|
||||||
|
*
|
||||||
|
* Combines AjaxResponseTrait and ModuleTemplateTrait for convenient single-use import.
|
||||||
|
* For payment modules, use PaymentModuleCompatibilityTrait instead.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* use MyPrestaRocks\Compatibility\ModuleCompatibilityTrait;
|
||||||
|
*
|
||||||
|
* class YourModule extends Module {
|
||||||
|
* use ModuleCompatibilityTrait;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author mypresta.rocks <info@mypresta.rocks>
|
||||||
|
* @copyright Copyright (c) mypresta.rocks
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MyPrestaRocks\Compatibility;
|
||||||
|
|
||||||
|
if (!defined('_PS_VERSION_')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ModuleCompatibilityTrait
|
||||||
|
{
|
||||||
|
use AjaxResponseTrait;
|
||||||
|
use ModuleTemplateTrait;
|
||||||
|
}
|
||||||
110
src/ModuleTemplateTrait.php
Normal file
110
src/ModuleTemplateTrait.php
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module Template Trait - Simplified Smarty template rendering for PrestaShop modules
|
||||||
|
*
|
||||||
|
* Provides convenient methods for rendering Smarty templates within modules.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* use MyPrestaRocks\Compatibility\ModuleTemplateTrait;
|
||||||
|
*
|
||||||
|
* class YourModule extends Module {
|
||||||
|
* use ModuleTemplateTrait;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author mypresta.rocks <info@mypresta.rocks>
|
||||||
|
* @copyright Copyright (c) mypresta.rocks
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MyPrestaRocks\Compatibility;
|
||||||
|
|
||||||
|
if (!defined('_PS_VERSION_')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ModuleTemplateTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Render a Smarty template from the module's views/templates directory
|
||||||
|
*
|
||||||
|
* @param string $template Template filename without extension
|
||||||
|
* @param string $subfolder Subfolder within views/templates/ (with trailing slash if not empty)
|
||||||
|
* @param array $variables Variables to assign to template
|
||||||
|
* @return string Rendered template HTML
|
||||||
|
*/
|
||||||
|
public function renderTemplate($template, $subfolder = '', $variables = [])
|
||||||
|
{
|
||||||
|
$templatePath = $this->getLocalPath() . 'views/templates/' . $subfolder . $template . '.tpl';
|
||||||
|
|
||||||
|
if (!file_exists($templatePath)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($variables)) {
|
||||||
|
$this->context->smarty->assign([$this->name => $variables]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->context->smarty->fetch($templatePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a front office template
|
||||||
|
*
|
||||||
|
* @param string $template Template filename without extension
|
||||||
|
* @param array $variables Variables to assign to template
|
||||||
|
* @return string Rendered template HTML
|
||||||
|
*/
|
||||||
|
public function renderFrontTemplate($template, $variables = [])
|
||||||
|
{
|
||||||
|
return $this->renderTemplate($template, 'front/', $variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an admin template
|
||||||
|
*
|
||||||
|
* @param string $template Template filename without extension
|
||||||
|
* @param array $variables Variables to assign to template
|
||||||
|
* @return string Rendered template HTML
|
||||||
|
*/
|
||||||
|
public function renderAdminTemplate($template, $variables = [])
|
||||||
|
{
|
||||||
|
return $this->renderTemplate($template, 'admin/', $variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render a hook template (from hooks/ subfolder)
|
||||||
|
*
|
||||||
|
* @param string $template Template filename without extension
|
||||||
|
* @param array $variables Variables to assign to template
|
||||||
|
* @return string Rendered template HTML
|
||||||
|
*/
|
||||||
|
public function renderHookTemplate($template, $variables = [])
|
||||||
|
{
|
||||||
|
return $this->renderTemplate($template, 'hook/', $variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign variables to Smarty and return for chaining
|
||||||
|
*
|
||||||
|
* @param array $variables Variables to assign
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function assignTemplateVars($variables)
|
||||||
|
{
|
||||||
|
$this->context->smarty->assign($variables);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign module-namespaced variables to prevent conflicts
|
||||||
|
*
|
||||||
|
* @param array $variables Variables to assign under module namespace
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function assignModuleVars($variables)
|
||||||
|
{
|
||||||
|
$this->context->smarty->assign([$this->name => $variables]);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/PaymentModuleCompatibilityTrait.php
Normal file
31
src/PaymentModuleCompatibilityTrait.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment Module Compatibility Trait - All-in-one compatibility trait for payment modules
|
||||||
|
*
|
||||||
|
* Combines all compatibility traits including the PaymentModule carrier fix.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* use MyPrestaRocks\Compatibility\PaymentModuleCompatibilityTrait;
|
||||||
|
*
|
||||||
|
* class YourPaymentModule extends PaymentModule {
|
||||||
|
* use PaymentModuleCompatibilityTrait;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author mypresta.rocks <info@mypresta.rocks>
|
||||||
|
* @copyright Copyright (c) mypresta.rocks
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MyPrestaRocks\Compatibility;
|
||||||
|
|
||||||
|
if (!defined('_PS_VERSION_')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait PaymentModuleCompatibilityTrait
|
||||||
|
{
|
||||||
|
use AjaxResponseTrait;
|
||||||
|
use ModuleTemplateTrait;
|
||||||
|
use PaymentModuleTrait;
|
||||||
|
}
|
||||||
75
src/PaymentModuleTrait.php
Normal file
75
src/PaymentModuleTrait.php
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment Module Trait - Fixes for PrestaShop PaymentModule bugs
|
||||||
|
*
|
||||||
|
* Fixes PrestaShop core bugs related to PaymentModule installation.
|
||||||
|
*
|
||||||
|
* Issue: When carriers are edited, PrestaShop creates new carrier records
|
||||||
|
* with the same id_reference. The core addCheckboxCarrierRestrictionsForModule()
|
||||||
|
* method doesn't deduplicate, causing duplicate key errors on payment module install.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* use MyPrestaRocks\Compatibility\PaymentModuleTrait;
|
||||||
|
*
|
||||||
|
* class YourPaymentModule extends PaymentModule {
|
||||||
|
* use PaymentModuleTrait;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author mypresta.rocks <info@mypresta.rocks>
|
||||||
|
* @copyright Copyright (c) mypresta.rocks
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace MyPrestaRocks\Compatibility;
|
||||||
|
|
||||||
|
if (!defined('_PS_VERSION_')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait PaymentModuleTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Override core method to fix duplicate carrier reference bug
|
||||||
|
*
|
||||||
|
* This method overrides the buggy core PaymentModule method that fails
|
||||||
|
* when carriers with duplicate id_reference exist (which happens when
|
||||||
|
* carriers are edited in the back office).
|
||||||
|
*
|
||||||
|
* @param array $shops Shop IDs to process (uses all shops if empty)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function addCheckboxCarrierRestrictionsForModule(array $shops = [])
|
||||||
|
{
|
||||||
|
if (!$shops) {
|
||||||
|
$shops = \Shop::getShops(true, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$carriers = \Carrier::getCarriers(
|
||||||
|
(int) \Context::getContext()->language->id,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
\Carrier::ALL_CARRIERS
|
||||||
|
);
|
||||||
|
|
||||||
|
// Deduplicate by id_reference to avoid duplicate key errors
|
||||||
|
$uniqueReferences = [];
|
||||||
|
foreach ($carriers as $carrier) {
|
||||||
|
$uniqueReferences[$carrier['id_reference']] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($shops as $idShop) {
|
||||||
|
foreach (array_keys($uniqueReferences) as $idReference) {
|
||||||
|
\Db::getInstance()->execute(
|
||||||
|
'INSERT IGNORE INTO `' . _DB_PREFIX_ . 'module_carrier`
|
||||||
|
(`id_module`, `id_shop`, `id_reference`)
|
||||||
|
VALUES (' . (int) $this->id . ', ' . (int) $idShop . ', ' . (int) $idReference . ')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user