- Add category_id, page_id, article_id, type columns to pp_routes (migration 0.329) - Move routing block in index.php before checkUrlParams() with Redis cache - Routes for categories, pages, articles now stored in pp_routes instead of .htaccess - Delete category/page/article routes on entity delete in respective repositories - Eliminate libraries/htaccess.conf: generate .htaccess content entirely from PHP - Move 32 static system routes (koszyk, logowanie, newsletter, AJAX modules, etc.) plus dynamic language/producer routes to pp_routes with type='system' - Invalidate pp_routes Redis cache on every htacces() regeneration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
380 lines
13 KiB
PHP
380 lines
13 KiB
PHP
<?php
|
|
error_reporting( E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED );
|
|
|
|
function __autoload_my_classes( $classname )
|
|
{
|
|
$q = explode( '\\', $classname );
|
|
$c = array_pop( $q );
|
|
$f = 'autoload/' . implode( '/', $q ) . '/class.' . $c . '.php';
|
|
|
|
if ( file_exists( $f ) )
|
|
require_once( $f );
|
|
else
|
|
{
|
|
$f = 'autoload/' . implode( '/', $q ) . '/' . $c . '.php';
|
|
if ( file_exists( $f ) )
|
|
require_once( $f );
|
|
}
|
|
}
|
|
|
|
spl_autoload_register( '__autoload_my_classes' );
|
|
date_default_timezone_set( 'Europe/Warsaw' );
|
|
|
|
require_once 'config.php';
|
|
require_once 'libraries/medoo/medoo.php';
|
|
require_once 'libraries/rb.php';
|
|
require_once 'libraries/phpmailer/class.phpmailer.php';
|
|
require_once 'libraries/phpmailer/class.smtp.php';
|
|
|
|
\R::setup( 'mysql:host=' . $database[ 'host' ] . ';dbname=' . $database[ 'name' ], $database[ 'user' ], $database[ 'password' ] );
|
|
\R::ext( 'xdispense', function ( $type )
|
|
{
|
|
return R::getRedBean() -> dispense( $type );
|
|
} );
|
|
$pdo = \R::getPDO();
|
|
|
|
session_start();
|
|
|
|
if ( !isset( $_SESSION[ 'check' ] ) )
|
|
{
|
|
session_regenerate_id();
|
|
$_SESSION[ 'check' ] = true;
|
|
$_SESSION[ 'ip' ] = $_SERVER[ 'REMOTE_ADDR' ];
|
|
}
|
|
|
|
if ( $_SESSION[ 'ip' ] !== $_SERVER[ 'REMOTE_ADDR' ] )
|
|
{
|
|
session_destroy();
|
|
header( 'Location: /' );
|
|
exit;
|
|
}
|
|
|
|
$mdb = new medoo( [
|
|
'database_type' => 'mysql',
|
|
'database_name' => $database[ 'name' ],
|
|
'server' => $database[ 'host' ],
|
|
'username' => $database[ 'user' ],
|
|
'password' => $database[ 'password' ],
|
|
'charset' => 'utf8',
|
|
'time_debug' => $database['time_debug']
|
|
] );
|
|
|
|
// check routes
|
|
$parsed_url = parse_url($_SERVER['REQUEST_URI']);
|
|
$request_uri = ltrim($parsed_url['path'], '/');
|
|
$query_string = isset($parsed_url['query']) ? $parsed_url['query'] : '';
|
|
parse_str($query_string, $query_params);
|
|
|
|
if ($request_uri != '')
|
|
{
|
|
$cache = new \Shared\Cache\CacheHandler();
|
|
$cacheKey = 'pp_routes:all';
|
|
$routesCached = $cache->get($cacheKey);
|
|
|
|
if ($routesCached === false || $routesCached === null)
|
|
{
|
|
$routes = $mdb->select('pp_routes', '*');
|
|
$cache->set($cacheKey, $routes, 86400);
|
|
}
|
|
else
|
|
{
|
|
$routes = unserialize($routesCached);
|
|
}
|
|
|
|
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), $destination_params);
|
|
|
|
// Merge the destination params with query params from the URL
|
|
$_GET = array_merge($destination_params, $query_params);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
\front\App::checkUrlParams();
|
|
|
|
$langRepo = new \Domain\Languages\LanguagesRepository( $mdb );
|
|
|
|
if ( !$lang_id = \Shared\Helpers\Helpers::get_session( 'current-lang' ) )
|
|
{
|
|
$lang_id = $langRepo->defaultLanguage();
|
|
\Shared\Helpers\Helpers::set_session( 'current-lang', $lang_id );
|
|
}
|
|
|
|
if ( !$lang = \Shared\Helpers\Helpers::get_session( 'lang-' . $lang_id ) )
|
|
{
|
|
$lang = $langRepo->translations( $lang_id );
|
|
\Shared\Helpers\Helpers::set_session( 'lang-' . $lang_id, $lang );
|
|
}
|
|
|
|
$settings = ( new \Domain\Settings\SettingsRepository( $mdb ) )->allSettings();
|
|
$client = \Shared\Helpers\Helpers::get_session( 'client' );
|
|
|
|
if ( \Shared\Helpers\Helpers::get( 'action' ) == 'htaccess' )
|
|
{
|
|
\Shared\Helpers\Helpers::htacces( '' );
|
|
unlink( 'install.php' );
|
|
unlink( 'update.zip' );
|
|
header( 'Location: /' );
|
|
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;
|
|
}
|
|
}
|
|
|
|
$pagesRepo = new \Domain\Pages\PagesRepository( $mdb );
|
|
|
|
if ( \Shared\Helpers\Helpers::get( 'a' ) == 'page' and \Shared\Helpers\Helpers::get( 'id' ) )
|
|
{
|
|
$page = $pagesRepo->frontPageDetails( \Shared\Helpers\Helpers::get( 'id' ), $lang_id );
|
|
\Shared\Helpers\Helpers::set_session( 'page', $page );
|
|
}
|
|
|
|
if ( !is_array( $page ) or !(int)$page['id'] )
|
|
{
|
|
$page = \Shared\Helpers\Helpers::get_session( 'page' );
|
|
}
|
|
|
|
if ( !is_array( $page ) or !(int)$page['id'] )
|
|
{
|
|
$page = $pagesRepo->frontPageDetails( '', $lang_id );
|
|
\Shared\Helpers\Helpers::set_session( 'page', $page );
|
|
}
|
|
|
|
if ( \Shared\Helpers\Helpers::get( 'devel' ) )
|
|
$settings[ 'devel' ] = true;
|
|
|
|
$out = \front\LayoutEngine::show();
|
|
|
|
if ( !isset( $_COOKIE[ "cookie_information" ] ) )
|
|
$out = strrev( implode( strrev( \front\LayoutEngine::cookieInformation() . '</body>' ), explode( strrev( '</body>' ), strrev( $out ), 2 ) ) );
|
|
|
|
if ( $settings[ 'statistic_code' ] )
|
|
$out = strrev( implode( strrev( $settings[ 'statistic_code' ] . '</body>' ), explode( strrev( '</body>' ), strrev( $out ), 2 ) ) );
|
|
|
|
/* wysyłka newslettera w tle */
|
|
$newsletterRepo = new \Domain\Newsletter\NewsletterRepository( $mdb );
|
|
$newsletterRepo->sendQueued( 1, $_SERVER['SERVER_NAME'], !empty( $settings['ssl'] ), $lang['wypisz-sie'] ?? 'Wypisz się' );
|
|
|
|
$dom = new DOMDocument( '1.0', 'UTF-8' );
|
|
$dom -> loadHTML( $out );
|
|
$stylesheet = $dom -> getElementsByTagName( 'link' );
|
|
$remove = [];
|
|
foreach ( $stylesheet as $item )
|
|
{
|
|
if ( $item -> getAttribute( 'rel' ) == 'stylesheet' and strpos( $item -> getAttribute( 'class' ), 'footer' ) !== false )
|
|
$remove[] = $item;
|
|
}
|
|
|
|
if ( $settings['google_tag_manager_id'] or ( $settings['own_gtm_js'] and $settings['own_gtm_html'] ) )
|
|
{
|
|
$element = $dom -> createElement( 'script' );
|
|
if ( $settings['own_gtm_js'] )
|
|
$element -> nodeValue = $settings['own_gtm_js'];
|
|
else
|
|
$element -> nodeValue = '(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({\'gtm.start\': new Date().getTime(),event:\'gtm.js\'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!=\'dataLayer\'?\'&l=\'+l:\'\';j.async=true;j.src=\'https://www.googletagmanager.com/gtm.js?id=\'+i+dl;f.parentNode.insertBefore(j,f);})(window,document,\'script\',\'dataLayer\',\'' . $settings['google_tag_manager_id'] . '\');';
|
|
|
|
$dom -> getElementsByTagName( 'head' ) -> item( 0 ) -> appendChild( $element );
|
|
|
|
if ( $settings['own_gtm_html'] )
|
|
$newElementHTML = $settings['own_gtm_html'];
|
|
else
|
|
$newElementHTML = '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=' . $settings['google_tag_manager_id'] . '" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>';
|
|
|
|
$newElement = $dom->createDocumentFragment();
|
|
$newElement -> appendXML( $newElementHTML );
|
|
|
|
$body = $dom -> getElementsByTagName( 'body' ) -> item( 0 );
|
|
$body -> insertBefore( $newElement, $body -> firstChild );
|
|
}
|
|
|
|
/* piksel */
|
|
if ( $settings[ 'piksel' ] )
|
|
{
|
|
$element = $dom -> createElement( 'script' );
|
|
$piskel_code = '!function(f,b,e,v,n,t,s)
|
|
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
|
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
|
|
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version=\'2.0\';
|
|
n.queue=[];t=b.createElement(e);t.async=!0;
|
|
t.src=v;s=b.getElementsByTagName(e)[0];
|
|
s.parentNode.insertBefore(t,s)}(window, document,\'script\',
|
|
\'https://connect.facebook.net/en_US/fbevents.js\');
|
|
fbq(\'init\', \'' . $settings[ 'piksel' ] . '\');
|
|
fbq(\'track\', \'PageView\');';
|
|
|
|
if ( $_SERVER['REQUEST_URI'] == '/' )
|
|
$piskel_code .= PHP_EOL . 'fbq( "track", "ViewContent", { content_category: "strona", content_name: "Strona główna" });';
|
|
|
|
if ( $category[ 'id' ] )
|
|
$piskel_code .= PHP_EOL . 'fbq(
|
|
"track",
|
|
"ViewCategory", {
|
|
content_category: "kategoria",
|
|
content_name: "' . htmlspecialchars( str_replace( '"', '', ( new \Domain\Category\CategoryRepository( $GLOBALS['mdb'] ) )->categoryName( (int)$category['id'], $lang_id ) ) ) . '",
|
|
content_ids: ["' . implode( ',', ( new \Domain\Category\CategoryRepository( $GLOBALS['mdb'] ) )->getCategoryProductIds( (int)$category['id'] ) ) . '"],
|
|
content_type: "product"
|
|
});';
|
|
|
|
if ( \Shared\Helpers\Helpers::get( 'product' ) )
|
|
$piskel_code .= PHP_EOL . 'fbq( "track", "ViewContent", { content_category: "produkt", content_name: "' . htmlspecialchars( str_replace( '"', '', ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->getProductNameCached( (int)\Shared\Helpers\Helpers::get( 'product' ), $lang_id ) ) ) . '", content_ids: ["' . \Shared\Helpers\Helpers::get( 'product' ) . '"], content_type: "product" });';
|
|
|
|
$element -> nodeValue = $piskel_code;
|
|
|
|
$head = $dom -> getElementsByTagName( 'head' ) -> item( 0 );
|
|
$head -> appendChild( $element );
|
|
}
|
|
/* end piksel */
|
|
|
|
/* meta tagi Facebook */
|
|
if ( \Shared\Helpers\Helpers::get( 'product' ) )
|
|
{
|
|
$url = preg_replace( '#^(http(s)?://)?w{3}\.#', '$1', $_SERVER[ 'SERVER_NAME' ] );
|
|
|
|
$head = $dom -> getElementsByTagName( 'head' ) -> item( 0 );
|
|
|
|
$product = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )->productDetailsFrontCached( (int)\Shared\Helpers\Helpers::get( 'product' ), $lang_id );
|
|
$product_image = $product[ 'images' ][ 0 ][ 'src' ];
|
|
if ( $product_image and file_exists( substr( $product_image, 1, strlen( $product_image ) ) ) )
|
|
{
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'og:image' );
|
|
$node -> setAttribute( 'content', 'https://' . $url . $product_image );
|
|
}
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'og:title' );
|
|
$node -> setAttribute( 'content', $product[ 'language' ][ 'name' ] );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'og:description' );
|
|
$node -> setAttribute( 'content', trim( preg_replace( '~[\r\n]+~', ' ', strip_tags( $product[ 'language' ][ 'short_description' ] ) ) ) );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'og:url' );
|
|
$node -> setAttribute( 'content', 'https://' . $url . $_SERVER[ 'REQUEST_URI' ] );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'product:availability' );
|
|
$node -> setAttribute( 'content', 'in stock' );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'product:condition' );
|
|
$node -> setAttribute( 'content', 'new' );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'product:price:amount' );
|
|
$node -> setAttribute( 'content', $product[ 'price_brutto_promo' ] ? \Shared\Helpers\Helpers::normalize_decimal( $product[ 'price_brutto_promo' ] ) : \Shared\Helpers\Helpers::normalize_decimal( $product[ 'price_brutto' ] ) );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'product:price:currency' );
|
|
$node -> setAttribute( 'content', 'PLN' );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'product:retailer_item_id' );
|
|
$node -> setAttribute( 'content', 'produkt-' . $product[ 'id' ] );
|
|
|
|
$node = $head -> appendChild( $dom -> createElement( 'meta' ) );
|
|
$node -> setAttribute( 'property', 'product:gtin' );
|
|
$node -> setAttribute( 'content', $product[ 'id' ] );
|
|
}
|
|
/* end meta tagi Facebook */
|
|
|
|
foreach ( $remove as $item )
|
|
{
|
|
$item -> parentNode -> removeChild( $item );
|
|
if ( strpos( $item -> getAttribute( 'class' ), 'footer' ) !== false )
|
|
{
|
|
$body = $dom -> getElementsByTagName( 'body' ) -> item( 0 );
|
|
$body -> appendChild( $item );
|
|
}
|
|
}
|
|
|
|
$script = $dom -> getElementsByTagName( 'script' );
|
|
$remove = [];
|
|
foreach ( $script as $item )
|
|
{
|
|
if ( $item -> getAttribute( 'class' ) == 'footer' )
|
|
$remove[] = $item;
|
|
}
|
|
|
|
foreach ( $remove as $item )
|
|
{
|
|
$item -> parentNode -> removeChild( $item );
|
|
$body = $dom -> getElementsByTagName( 'body' ) -> item( 0 );
|
|
$body -> appendChild( $item );
|
|
}
|
|
|
|
// dodanie specyficznej klasy do body
|
|
if ( !empty( $page['class'] ) )
|
|
{
|
|
$body = $dom -> getElementsByTagName( 'body' ) -> item( 0 );
|
|
$body -> setAttribute( 'class', $body -> getAttribute( 'class' ) . ' ' . $page['class'] );
|
|
}
|
|
|
|
// konwersja obrazków na webp
|
|
if ( $settings['generate_webp'] )
|
|
{
|
|
$images = $dom -> getElementsByTagName( 'img' );
|
|
foreach ( $images as $img )
|
|
{
|
|
$img_src = $img -> getAttribute( 'src' );
|
|
|
|
if ( $img_src != '' and strpos( $img -> getAttribute( 'class' ), 'nowebp' ) === false )
|
|
{
|
|
if ( strpos( $img_src, '/' ) === 0 )
|
|
$img_src = substr( $img_src, 1, strlen( $img_src ) );
|
|
|
|
$img_webp = \Shared\Helpers\Helpers::generate_webp_image( $img_src, 85 );
|
|
if ( $img_webp !== false )
|
|
{
|
|
$img -> setAttribute( 'src', '/' . $img_webp );
|
|
$img -> setAttribute( 'src-nowebp', '/' . $img_src );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// lazy loading obrazków
|
|
if ( $settings['lazy_loading'] )
|
|
{
|
|
$images = $dom -> getElementsByTagName( 'img' );
|
|
foreach ( $images as $img )
|
|
{
|
|
if ( strpos( $img -> getAttribute( 'class' ), 'nolazy' ) === false )
|
|
{
|
|
$img -> setAttribute( 'data-src', $img -> getAttribute( 'src' ) );
|
|
$img -> setAttribute( 'class', $img -> getAttribute( 'class' ) . ' lozad' );
|
|
$img -> removeAttribute( 'src' );
|
|
}
|
|
}
|
|
}
|
|
|
|
$html = $dom -> saveHTML();
|
|
|
|
if ( file_exists( 'plugins/special-actions-end.php' ) )
|
|
include 'plugins/special-actions-end.php';
|
|
|
|
echo $html;
|
|
?>
|