This commit is contained in:
2026-03-12 19:58:37 +01:00
parent 51ea37d2ec
commit 0182d60971
15 changed files with 163 additions and 50 deletions

View File

@@ -318,9 +318,7 @@ class ArticleRepository
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
@@ -337,9 +335,7 @@ class ArticleRepository
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
@@ -819,9 +815,7 @@ class ArticleRepository
$results = $this->db->select('pp_articles_files', '*', ['article_id' => null]);
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
@@ -836,15 +830,31 @@ class ArticleRepository
$results = $this->db->select('pp_articles_images', '*', ['article_id' => null]);
if (is_array($results)) {
foreach ($results as $row) {
if (file_exists('../' . $row['src'])) {
unlink('../' . $row['src']);
}
$this->safeUnlink($row['src']);
}
}
$this->db->delete('pp_articles_images', ['article_id' => null]);
}
/**
* Usuwa plik z dysku tylko jeśli ścieżka pozostaje wewnątrz katalogu upload/.
* Zapobiega path traversal przy danych z bazy.
*/
private function safeUnlink(string $src): void
{
$base = realpath('../upload');
if (!$base) {
return;
}
$full = realpath('../' . ltrim($src, '/'));
if ($full && strpos($full, $base . DIRECTORY_SEPARATOR) === 0 && is_file($full)) {
unlink($full);
} elseif ($full) {
error_log( '[shopPRO] safeUnlink: ścieżka poza upload/: ' . $src );
}
}
/**
* Pobiera artykuly opublikowane w podanym zakresie dat.
*/

View File

@@ -28,10 +28,9 @@ class IntegrationsRepository
public function getSettings( string $provider ): array
{
$table = $this->settingsTable( $provider );
$stmt = $this->db->query( "SELECT * FROM $table" );
$results = $stmt ? $stmt->fetchAll( \PDO::FETCH_ASSOC ) : [];
$rows = $this->db->select( $table, [ 'name', 'value' ] );
$settings = [];
foreach ( $results as $row )
foreach ( $rows ?: [] as $row )
$settings[$row['name']] = $row['value'];
return $settings;
@@ -160,10 +159,15 @@ class IntegrationsRepository
if ( empty( $response['accessToken'] ) )
return false;
$this->saveSetting( 'apilo', 'access-token', $response['accessToken'] );
$this->saveSetting( 'apilo', 'refresh-token', $response['refreshToken'] );
$this->saveSetting( 'apilo', 'access-token-expire-at', $response['accessTokenExpireAt'] );
$this->saveSetting( 'apilo', 'refresh-token-expire-at', $response['refreshTokenExpireAt'] );
try {
$this->saveSetting( 'apilo', 'access-token', $response['accessToken'] );
$this->saveSetting( 'apilo', 'refresh-token', $response['refreshToken'] );
$this->saveSetting( 'apilo', 'access-token-expire-at', $response['accessTokenExpireAt'] );
$this->saveSetting( 'apilo', 'refresh-token-expire-at', $response['refreshTokenExpireAt'] );
} catch ( \Exception $e ) {
error_log( '[shopPRO] Apilo: błąd zapisu tokenów: ' . $e->getMessage() );
return false;
}
return true;
}

View File

@@ -814,7 +814,7 @@ class OrderRepository
\Shared\Helpers\Helpers::send_email($settings['contact_email'], 'Nowe zamówienie / ' . $settings['firm_name'] . ' / ' . $order['number'] . ' - ' . $order['client_surname'] . ' ' . $order['client_name'], $mail_order);
// zmiana statusu w realizacji jeżeli płatność przy odbiorze
if ($payment_id == 3) {
if (!empty($payment_method['is_cod'])) {
$this->updateOrderStatus($order_id, 4);
$this->insertStatusHistory($order_id, 4, 1);
}

View File

@@ -122,6 +122,7 @@ class PaymentMethodRepository
'apilo_payment_type_id' => $this->normalizeApiloPaymentTypeId($data['apilo_payment_type_id'] ?? null),
'min_order_amount' => $this->normalizeDecimalOrNull($data['min_order_amount'] ?? null),
'max_order_amount' => $this->normalizeDecimalOrNull($data['max_order_amount'] ?? null),
'is_cod' => (int)(!empty($data['is_cod']) ? 1 : 0),
];
$this->db->update('pp_shop_payment_methods', $row, ['id' => $paymentMethodId]);
@@ -240,7 +241,8 @@ class PaymentMethodRepository
spm.status,
spm.apilo_payment_type_id,
spm.min_order_amount,
spm.max_order_amount
spm.max_order_amount,
spm.is_cod
FROM pp_shop_payment_methods AS spm
INNER JOIN pp_shop_transport_payment_methods AS stpm
ON stpm.id_payment_method = spm.id
@@ -335,6 +337,7 @@ class PaymentMethodRepository
$row['apilo_payment_type_id'] = $this->normalizeApiloPaymentTypeId($row['apilo_payment_type_id'] ?? null);
$row['min_order_amount'] = $this->normalizeDecimalOrNull($row['min_order_amount'] ?? null);
$row['max_order_amount'] = $this->normalizeDecimalOrNull($row['max_order_amount'] ?? null);
$row['is_cod'] = (int)($row['is_cod'] ?? 0);
return $row;
}

View File

@@ -1601,9 +1601,7 @@ class ProductRepository
$results = $this->db->select( 'pp_shop_products_files', '*', [ 'AND' => [ 'product_id' => $productId, 'to_delete' => 1 ] ] );
if ( is_array( $results ) ) {
foreach ( $results as $row ) {
if ( file_exists( '../' . $row['src'] ) ) {
unlink( '../' . $row['src'] );
}
$this->safeUnlink( $row['src'] );
}
}
$this->db->delete( 'pp_shop_products_files', [ 'AND' => [ 'product_id' => $productId, 'to_delete' => 1 ] ] );
@@ -1614,9 +1612,7 @@ class ProductRepository
$results = $this->db->select( 'pp_shop_products_images', '*', [ 'AND' => [ 'product_id' => $productId, 'to_delete' => 1 ] ] );
if ( is_array( $results ) ) {
foreach ( $results as $row ) {
if ( file_exists( '../' . $row['src'] ) ) {
unlink( '../' . $row['src'] );
}
$this->safeUnlink( $row['src'] );
}
}
$this->db->delete( 'pp_shop_products_images', [ 'AND' => [ 'product_id' => $productId, 'to_delete' => 1 ] ] );
@@ -2125,14 +2121,30 @@ class ProductRepository
$results = $this->db->select( 'pp_shop_products_images', '*', [ 'product_id' => null ] );
if ( is_array( $results ) ) {
foreach ( $results as $row ) {
if ( file_exists( '../' . $row['src'] ) ) {
unlink( '../' . $row['src'] );
}
$this->safeUnlink( $row['src'] );
}
}
$this->db->delete( 'pp_shop_products_images', [ 'product_id' => null ] );
}
/**
* Usuwa plik z dysku tylko jeśli ścieżka pozostaje wewnątrz katalogu upload/.
* Zapobiega path traversal przy danych z bazy.
*/
private function safeUnlink(string $src): void
{
$base = realpath('../upload');
if (!$base) {
return;
}
$full = realpath('../' . ltrim($src, '/'));
if ($full && strpos($full, $base . DIRECTORY_SEPARATOR) === 0 && is_file($full)) {
unlink($full);
} elseif ($full) {
error_log( '[shopPRO] safeUnlink: ścieżka poza upload/: ' . $src );
}
}
/**
* Oznacza plik do usunięcia.
*/