diff --git a/.htaccess b/.htaccess index 0ff8aa4..3c24e90 100644 --- a/.htaccess +++ b/.htaccess @@ -17,7 +17,7 @@ RewriteCond %{REQUEST_URI} !^/admin/.*$ [NC] # Wyklucza ścieżki rozpoczynając RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [R=301,L] -ErrorDocument 404 /404.html +ErrorDocument 404 /index.php RewriteCond %{REQUEST_URI} !^(.*)/libraries/(.*) [NC] RewriteCond %{REQUEST_URI} !^(.*)/layout/(.*) [NC] @@ -237,8 +237,8 @@ RewriteRule ^p-425-a-tabliczki-z-miesiacami-galazka-kopi$ index.php?product=425 RewriteRule ^p-425-a-tabliczki-z-miesiacami-galazka-kopi/([0-9-]+)$ index.php?product=425&permutation_hash=$1 [L] RewriteRule ^p-404-b-tabliczki-z-miesiacami-galazka$ index.php?product=404 [L] RewriteRule ^p-404-b-tabliczki-z-miesiacami-galazka/([0-9-]+)$ index.php?product=404&permutation_hash=$1 [L] -RewriteRule ^drewniana-tabliczka-modlitwa-aniele-bozy-strozu-moj-chmurka$ index.php?product=403 [L] -RewriteRule ^drewniana-tabliczka-modlitwa-aniele-bozy-strozu-moj-chmurka/([0-9-]+)$ index.php?product=403&permutation_hash=$1 [L] +RewriteRule ^p-403-tabliczka-modlitwa-aniele-bozy-strozu-moj-chmurka$ index.php?product=403 [L] +RewriteRule ^p-403-tabliczka-modlitwa-aniele-bozy-strozu-moj-chmurka/([0-9-]+)$ index.php?product=403&permutation_hash=$1 [L] RewriteRule ^en/p-425-kopia$ index.php?product=425 [L] RewriteRule ^en/p-425-kopia/([0-9-]+)$ index.php?product=425&permutation_hash=$1 [L] RewriteCond %{REQUEST_URI} ^/home$ diff --git a/autoload/admin/factory/class.ShopProduct.php b/autoload/admin/factory/class.ShopProduct.php index d915a04..90d5e09 100644 --- a/autoload/admin/factory/class.ShopProduct.php +++ b/autoload/admin/factory/class.ShopProduct.php @@ -701,6 +701,10 @@ class ShopProduct $mdb -> delete( 'pp_shop_products_attributes', ['product_id' => $product_id ] ); $mdb -> delete( 'pp_shop_products', ['id' => $product_id ] ); $mdb -> delete( 'pp_shop_product_sets_products', [ 'product_id' => $product_id ] ); + // pp_routes + $mdb -> delete( 'pp_routes', [ 'product_id' => $product_id ] ); + // pp_redirects + $mdb -> delete( 'pp_redirects', [ 'product_id' => $product_id ] ); \S::delete_dir( '../upload/product_images/product_' . $product_id . '/' ); \S::delete_dir( '../upload/product_files/product_' . $product_id . '/' ); @@ -1055,6 +1059,30 @@ class ShopProduct foreach ( $name as $key => $val ) { if ( $translation_id = $mdb -> get( 'pp_shop_products_langs', 'id', [ 'AND' => [ 'product_id' => $product_id, 'lang_id' => $key ] ] ) ) + { + $current_seo_link = $mdb -> get( 'pp_shop_products_langs', 'seo_link', [ 'id' => $translation_id ] ); + + if ( $seo_link[$key] ) + $new_seo_link = \S::seo( $seo_link[$key] ); + else + $new_seo_link = \S::seo( 'p-' . $product_id . '-' . $name[$key] ); + + if ( $new_seo_link !== $current_seo_link ) + { + if ( !$mdb -> count( 'pp_redirects', [ 'from' => $current_seo_link, 'to' => $new_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] ) ) + { + if ( $mdb -> count( 'pp_redirects', [ 'from' => $new_seo_link, 'to' => $current_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] ) ) + $mdb -> delete( 'pp_redirects', [ 'from' => $new_seo_link, 'to' => $current_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] ); + else + { + if ( \S::canAddRedirect( $current_seo_link, $new_seo_link ) ) + $mdb -> insert( 'pp_redirects', [ 'from' => $current_seo_link, 'to' => $new_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] ); + else + $mdb -> delete( 'pp_redirects', [ 'product_id' => $product_id, 'lang_id' => $key ] ); + } + } + } + $mdb -> update( 'pp_shop_products_langs', [ 'lang_id' => $key, 'name' => '' !== $name[$key] ? $name[$key] : null, @@ -1062,7 +1090,7 @@ class ShopProduct 'description' => '' !== $description[$key] ? $description[$key] : null, 'meta_description' => '' !== $meta_description[$key] ? $meta_description[$key] : null, 'meta_keywords' => '' !== $meta_keywords[$key] ? $meta_keywords[$key] : null, - 'seo_link' => '' !== \S::seo($seo_link[$key]) ? \S::seo($seo_link[$key]) : null, + 'seo_link' => \S::seo( $seo_link[$key] ) != '' ? \S::seo( $seo_link[$key] ) : \S::seo( 'p-' . $product_id . '-' . $name[$key] ), 'copy_from' => '' !== $copy_from[$key] ? $copy_from[$key] : null, 'warehouse_message_zero' => '' !== $warehouse_message_zero[$key] ? $warehouse_message_zero[$key] : null, 'warehouse_message_nonzero' => '' !== $warehouse_message_nonzero[$key] ? $warehouse_message_nonzero[$key] : null, @@ -1076,7 +1104,9 @@ class ShopProduct ], [ 'id' => $translation_id ] ); + } else + { $mdb -> insert( 'pp_shop_products_langs', [ 'product_id' => (int)$product_id, 'lang_id' => $key, @@ -1097,6 +1127,7 @@ class ShopProduct 'meta_title' => '' !== $meta_title[$key] ? $meta_title[$key] : null, 'xml_name' => '' !== $xml_name[$key] ? $xml_name[$key] : null, ] ); + } } $not_in = [0]; diff --git a/autoload/class.S.php b/autoload/class.S.php index 667cb31..71e04c1 100644 --- a/autoload/class.S.php +++ b/autoload/class.S.php @@ -1,6 +1,48 @@ select( 'pp_redirects', '*' ); + + $redirectMap = []; + foreach ( $redirects as $redirect ) + { + $redirectMap[$redirect['from']] = $redirect['to']; + } + + // Dodaj nowe przekierowanie do mapy tymczasowo + $redirectMap[$from] = $to; + + // Funkcja do sprawdzania cyklu za pomocą DFS + $visited = []; + $stack = []; + + function hasCycle($current, $target, &$redirectMap, &$visited) + { + if ($current === $target) { + return true; + } + + if (isset($visited[$current])) { + return false; + } + + $visited[$current] = true; + + if (isset($redirectMap[$current])) { + return hasCycle($redirectMap[$current], $target, $redirectMap, $visited); + } + + return false; + } + + // Sprawdź, czy istnieje ścieżka z $newTo do $newFrom + return !hasCycle($to, $from, $redirectMap, $visited); + } + static public function clear_redis_cache() { $redis = \RedisConnection::getInstance() -> getConnection(); @@ -501,15 +543,19 @@ class S } $results = $mdb -> select( 'pp_langs', [ 'id', 'start' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] ); - if ( is_array( $results ) ) { + if ( is_array( $results ) ) + { foreach ( $results as $row ) { !$row['start'] ? $language_link = $row['id'] . '/' : $language_link = ''; $results2 = $mdb -> select( 'pp_shop_products_langs', [ '[><]pp_shop_products' => [ 'product_id' => 'id' ] ], [ 'seo_link', 'name', 'product_id' ], [ 'lang_id' => $row['id'], 'ORDER' => [ 'name' => 'ASC' ] ] ); - if ( is_array( $results2 ) ) { + if ( is_array( $results2 ) ) + { foreach ( $results2 as $row2 ) { + $mdb -> delete( 'pp_routes', [ 'AND' => [ 'product_id' => $row2['product_id'], 'lang_id' => $row['id'] ] ] ); + if ( $row2['name'] ) { $site_map .= '' . PHP_EOL; @@ -524,13 +570,27 @@ class S if ( $row2['seo_link'] ) { - $htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . \S::seo( $row2['seo_link'] ) . '$ index.php?product=' . $row2['product_id'] . ' [L]'; - $htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . \S::seo( $row2['seo_link'] ) . '/([0-9-]+)$ index.php?product=' . $row2['product_id'] . '&permutation_hash=$1 [L]'; + $pattern = '^' . $language_link . \S::seo( $row2['seo_link'] ) . '$'; + $destination = 'index.php?product=' . $row2['product_id']; + + $mdb -> insert( 'pp_routes', [ 'product_id' => $row2['product_id'], 'lang_id' => $row['id'], 'pattern' => $pattern, 'destination' => $destination ] ); + + $pattern = '^' . $language_link . \S::seo( $row2['seo_link'] ) . '/([0-9-]+)$'; + $destination = 'index.php?product=' . $row2['product_id'] . '&permutation_hash=$1'; + + $mdb -> insert( 'pp_routes', [ 'product_id' => $row2['product_id'], 'lang_id' => $row['id'], 'pattern' => $pattern, 'destination' => $destination ] ); } else { - $htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 'p-' . $row2['product_id'] . '-' . \S::seo( $row2['name'] ) . '$ index.php?product=' . $row2['product_id'] . ' [L]'; - $htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 'p-' . $row2['product_id'] . '-' . \S::seo( $row2['name'] ) . '/([0-9-]+)$ index.php?product=' . $row2['product_id'] . '&permutation_hash=$1 [L]'; + $pattern = '^' . $language_link . 'p-' . $row2['product_id'] . '-' . \S::seo( $row2['name'] ) . '$'; + $destination = 'index.php?product=' . $row2['product_id']; + + $mdb -> insert( 'pp_routes', [ 'product_id' => $row2['product_id'], 'lang_id' => $row['id'], 'pattern' => $pattern, 'destination' => $destination ] ); + + $pattern = '^' . $language_link . 'p-' . $row2['product_id'] . '-' . \S::seo( $row2['name'] ) . '/([0-9-]+)$'; + $destination = 'index.php?product=' . $row2['product_id'] . '&permutation_hash=$1'; + + $mdb -> insert( 'pp_routes', [ 'product_id' => $row2['product_id'], 'lang_id' => $row['id'], 'pattern' => $pattern, 'destination' => $destination ] ); } } } diff --git a/index.php b/index.php index 7a1a785..870a0ba 100644 --- a/index.php +++ b/index.php @@ -79,6 +79,44 @@ if ( \S::get( 'action' ) == 'htaccess' ) exit; } +// check redirects +$request_uri = substr( $_SERVER[ 'REQUEST_URI' ], 1, strlen( $_SERVER[ 'REQUEST_URI' ] ) ); +if ( $request_uri != '' ) +{ + $new_url = $mdb -> get( 'pp_redirects', 'to', [ 'from' => $request_uri ], [ 'ORDER' => [ 'date_add' => 'DESC' ] ] ); + if ( $new_url['to'] ) + { + header( 'Location: ' . $new_url[ 'to' ], true, 301 ); + exit; + } +} + +// check routes +$request_uri = ltrim( $_SERVER['REQUEST_URI'], '/' ); +if ( $request_uri != '' ) +{ + $matched = false; + + $routes = $mdb -> select( 'pp_routes', '*' ); + foreach ( $routes as $route ) + { + $pattern = $route['pattern']; + $destination = $route['destination']; + + if ( preg_match("#^" . $pattern . "#", $request_uri, $matches ) ) + { + // Replace placeholders in the destination with matches from the request URI + $destination = preg_replace( "#^" . $pattern . "#", $destination, $request_uri ); + + // Parse the destination string to extract GET parameters + parse_str(parse_url($destination, PHP_URL_QUERY), $_GET); + + $matched = true; + break; + } + } +} + if ( \S::get( 'a' ) == 'page' and \S::get( 'id' ) ) { $page = \front\factory\Pages::page_details( \S::get( 'id' ) ); diff --git a/libraries/htaccess.conf b/libraries/htaccess.conf index fec03eb..364dd0e 100644 --- a/libraries/htaccess.conf +++ b/libraries/htaccess.conf @@ -17,7 +17,7 @@ RewriteCond %{REQUEST_URI} !^/admin/.*$ [NC] # Wyklucza ścieżki rozpoczynając RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [R=301,L] -ErrorDocument 404 /404.html +ErrorDocument 404 /index.php RewriteCond %{REQUEST_URI} !^(.*)/libraries/(.*) [NC] RewriteCond %{REQUEST_URI} !^(.*)/layout/(.*) [NC] diff --git a/updates/0.20/ver_0.221.zip b/updates/0.20/ver_0.221.zip new file mode 100644 index 0000000..360019e Binary files /dev/null and b/updates/0.20/ver_0.221.zip differ diff --git a/updates/0.20/ver_0.221_sql.txt b/updates/0.20/ver_0.221_sql.txt new file mode 100644 index 0000000..737898f --- /dev/null +++ b/updates/0.20/ver_0.221_sql.txt @@ -0,0 +1,7 @@ +CREATE TABLE `pp_redirects` ( `id` INT NOT NULL AUTO_INCREMENT, `from` TEXT NOT NULL, `to` TEXT NOT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8mb4_unicode_ci'; +ALTER TABLE `pp_redirects` ADD COLUMN `lang_id` VARCHAR(50) NOT NULL DEFAULT '' AFTER `to`; +ALTER TABLE `pp_redirects` ADD COLUMN `date_add` TIMESTAMP NULL DEFAULT CURTIME() AFTER `lang_id`; +ALTER TABLE `pp_redirects` ADD COLUMN `product_id` INT NULL DEFAULT NULL AFTER `to`; +CREATE TABLE pp_routes ( id INT AUTO_INCREMENT PRIMARY KEY, pattern VARCHAR(255) NOT NULL, destination VARCHAR(255) NOT NULL ); +ALTER TABLE `pp_routes` ADD COLUMN `product_id` INT NULL DEFAULT NULL AFTER `destination`; +ALTER TABLE `pp_routes` ADD COLUMN `lang_id` VARCHAR(50) NULL DEFAULT NULL AFTER `product_id`; \ No newline at end of file diff --git a/updates/changelog.php b/updates/changelog.php index 87e3ef2..50ea05b 100644 --- a/updates/changelog.php +++ b/updates/changelog.php @@ -1,3 +1,6 @@ +ver. 0.221
+- NEW - Automatyczne przekierowania adresów URL produktów, zmiany w pliku htaccess +
ver. 0.220
- NEW - Dodanie możliwości wyświetlenia na strone ostatnio dodane produkty [PRODUKTY_NEW] lub [PRODUKTY_NEW:10].
- NEW - Dodanie możliwości wyświetlenia na strone popularnych produktów [PRODUKTY_TOP] lub [PRODUKTY_TOP:10]. diff --git a/updates/versions.php b/updates/versions.php index 8121ca2..147ae0e 100644 --- a/updates/versions.php +++ b/updates/versions.php @@ -1,5 +1,5 @@