Add view classes for articles, banners, languages, menu, newsletter, containers, shop categories, clients, payment methods, products, and search
- Created Articles.php for rendering article views including full articles, miniature lists, and news sections. - Added Banners.php for handling banner displays. - Introduced Languages.php for rendering language options. - Implemented Menu.php for dynamic menu rendering. - Developed Newsletter.php for newsletter view rendering. - Created Scontainers.php for rendering specific containers. - Added ShopCategory.php for category descriptions and product listings. - Introduced ShopClient.php for managing client-related views such as address editing and order history. - Implemented ShopPaymentMethod.php for displaying payment methods in the basket. - Created ShopProduct.php for generating product URLs. - Added ShopSearch.php for rendering a simple search form. - Added .htaccess file to enhance security by restricting access to sensitive files and directories.
This commit is contained in:
60
autoload/Shared/Cache/CacheHandler.php
Normal file
60
autoload/Shared/Cache/CacheHandler.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Shared\Cache;
|
||||
|
||||
class CacheHandler
|
||||
{
|
||||
protected $redis;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
if (class_exists('Redis')) {
|
||||
try {
|
||||
$this->redis = RedisConnection::getInstance()->getConnection();
|
||||
} catch (\Exception $e) {
|
||||
$this->redis = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
if ($this->redis) {
|
||||
return $this->redis->get($key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = 86400)
|
||||
{
|
||||
if ($this->redis) {
|
||||
$this->redis->setex($key, $ttl, serialize($value));
|
||||
}
|
||||
}
|
||||
|
||||
public function exists($key)
|
||||
{
|
||||
if ($this->redis) {
|
||||
return $this->redis->exists($key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
if ($this->redis) {
|
||||
return $this->redis->del($key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function deletePattern($pattern)
|
||||
{
|
||||
if ($this->redis) {
|
||||
$keys = $this->redis->keys($pattern);
|
||||
if (!empty($keys)) {
|
||||
return $this->redis->del($keys);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
45
autoload/Shared/Cache/RedisConnection.php
Normal file
45
autoload/Shared/Cache/RedisConnection.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace Shared\Cache;
|
||||
|
||||
class RedisConnection
|
||||
{
|
||||
private static $instance = null;
|
||||
private $redis;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
global $config;
|
||||
|
||||
$this->redis = new \Redis();
|
||||
|
||||
try {
|
||||
if (!$this->redis->connect($config['redis']['host'], $config['redis']['port'])) {
|
||||
error_log("Nie udalo sie polaczyc z serwerem Redis.");
|
||||
$this->redis = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->redis->auth($config['redis']['password'])) {
|
||||
error_log("Autoryzacja do serwera Redis nie powiodla sie.");
|
||||
$this->redis = null;
|
||||
return;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
error_log("Blad podczas polaczenia z Redis: " . $e->getMessage());
|
||||
$this->redis = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->redis;
|
||||
}
|
||||
}
|
||||
81
autoload/Shared/Email/Email.php
Normal file
81
autoload/Shared/Email/Email.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace Shared\Email;
|
||||
|
||||
class Email
|
||||
{
|
||||
public $table = 'pp_newsletter_templates';
|
||||
|
||||
public function load_by_name( string $name )
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
$result = $mdb -> get( $this -> table, '*', [ 'name' => $name ] );
|
||||
if ( is_array( $result ) ) foreach ( $result as $key => $val )
|
||||
$this -> $key = $val;
|
||||
}
|
||||
|
||||
public function email_check( $email )
|
||||
{
|
||||
return filter_var( $email, FILTER_VALIDATE_EMAIL );
|
||||
}
|
||||
|
||||
public function send( string $email, string $subject, bool $newsletter_headers = false, string $file = null )
|
||||
{
|
||||
global $settings;
|
||||
|
||||
if ( $newsletter_headers )
|
||||
{
|
||||
$text = $settings['newsletter_header'];
|
||||
$text .= $this -> text;
|
||||
$text .= $settings['newsletter_footer'];
|
||||
}
|
||||
else
|
||||
$text = $this -> text;
|
||||
|
||||
$regex = "-(<img[^>]+src\s*=\s*['\"])(((?!'|\"|https?://).)*)(['\"][^>]*>)-i";
|
||||
$text = preg_replace( $regex, "$1https://" . $_SERVER['SERVER_NAME'] . "$2$4", $text );
|
||||
|
||||
$regex = "-(<a[^>]+href\s*=\s*['\"])(((?!'|\"|https?://).)*)(['\"][^>]*>)-i";
|
||||
$text = preg_replace( $regex, "$1https://" . $_SERVER['SERVER_NAME'] . "$2$4", $text );
|
||||
|
||||
if ( $this -> email_check( $email ) and $subject )
|
||||
{
|
||||
$mail = new \PHPMailer();
|
||||
$mail -> IsSMTP();
|
||||
$mail -> SMTPAuth = true;
|
||||
$mail -> Host = $settings['email_host'];
|
||||
$mail -> Port = $settings['email_port'];
|
||||
$mail -> Username = $settings['email_login'];
|
||||
$mail -> Password = $settings['email_password'];
|
||||
$mail -> CharSet = "UTF-8";
|
||||
$mail -> SMTPOptions = array(
|
||||
'ssl' => array(
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'allow_self_signed' => true
|
||||
)
|
||||
);
|
||||
$mail -> AddReplyTo( $settings['contact_email'], $settings['firm_name'] );
|
||||
$mail -> SetFrom( $settings['contact_email'], $settings['firm_name'] );
|
||||
$mail -> AddAddress( $email, '' );
|
||||
$mail -> Subject = $subject;
|
||||
$mail -> Body = $text;
|
||||
if ( is_array( $file ) )
|
||||
{
|
||||
foreach ( $file as $file_tmp )
|
||||
{
|
||||
if ( file_exists( $file_tmp ) )
|
||||
$mail -> AddAttachment( $file_tmp );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( file_exists( $file ) )
|
||||
$mail -> AddAttachment( $file );
|
||||
}
|
||||
$mail -> IsHTML( true );
|
||||
return $mail -> Send();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
975
autoload/Shared/Helpers/Helpers.php
Normal file
975
autoload/Shared/Helpers/Helpers.php
Normal file
@@ -0,0 +1,975 @@
|
||||
<?php
|
||||
namespace Shared\Helpers;
|
||||
class Helpers
|
||||
{
|
||||
static function canAddRedirect( $from, $to, $lang_id = null )
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
if ( !$from or !$to or $from === $to )
|
||||
return false;
|
||||
|
||||
$where = [];
|
||||
if ( null !== $lang_id )
|
||||
$where['lang_id'] = $lang_id;
|
||||
|
||||
$redirects = $mdb -> select( 'pp_redirects', [ 'from', 'to' ], $where );
|
||||
|
||||
$redirectMap = [];
|
||||
foreach ( $redirects as $redirect )
|
||||
{
|
||||
if ( !isset( $redirectMap[$redirect['from']] ) )
|
||||
$redirectMap[$redirect['from']] = [];
|
||||
|
||||
if ( !in_array( $redirect['to'], $redirectMap[$redirect['from']], true ) )
|
||||
$redirectMap[$redirect['from']][] = $redirect['to'];
|
||||
}
|
||||
|
||||
if ( !isset( $redirectMap[$from] ) )
|
||||
$redirectMap[$from] = [];
|
||||
|
||||
if ( !in_array( $to, $redirectMap[$from], true ) )
|
||||
$redirectMap[$from][] = $to;
|
||||
|
||||
$visited = [];
|
||||
$stack = [ $to ];
|
||||
while ( !empty( $stack ) )
|
||||
{
|
||||
$current = array_pop( $stack );
|
||||
|
||||
if ( $current === $from )
|
||||
return false;
|
||||
|
||||
if ( isset( $visited[$current] ) )
|
||||
continue;
|
||||
|
||||
$visited[$current] = true;
|
||||
|
||||
if ( isset( $redirectMap[$current] ) )
|
||||
{
|
||||
foreach ( $redirectMap[$current] as $next )
|
||||
if ( !isset( $visited[$next] ) )
|
||||
$stack[] = $next;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function clear_product_cache( int $product_id )
|
||||
{
|
||||
if ( class_exists('Redis') )
|
||||
{
|
||||
try
|
||||
{
|
||||
$cacheHandler = new \Shared\Cache\CacheHandler();
|
||||
// Wyczyść cache produktu dla wszystkich języków i permutacji
|
||||
$cacheHandler -> deletePattern( "shop\\product:$product_id:*" );
|
||||
// Wyczyść cache związane z opcjami ilościowymi
|
||||
$cacheHandler -> deletePattern( "ProductRepository::getProductPermutationQuantityOptions:v2:$product_id:*" );
|
||||
// Wyczyść cache zestawów produktów
|
||||
$cacheHandler -> deletePattern( "ProductRepository::productSetsWhenAddToBasket:$product_id" );
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
error_log("Błąd podczas czyszczenia cache produktu: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public function remove_special_chars( $string ) {
|
||||
return str_ireplace( array( '\'', '"', ',' , ';', '<', '>' ), ' ', $string );
|
||||
}
|
||||
|
||||
static public function removeDuplicates( $array, $param ) {
|
||||
$result = [];
|
||||
foreach ($array as $key => $subArray) {
|
||||
$idsSeen = [];
|
||||
foreach ($subArray as $subKey => $item) {
|
||||
if (!in_array($item[ $param ], $idsSeen)) {
|
||||
$idsSeen[] = $item[ $param ];
|
||||
$result[$key][] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
static public function generate_webp_image($file, $compression_quality = 85)
|
||||
{
|
||||
if ( strpos( $file, 'thumb/' ) !== false )
|
||||
{
|
||||
$file_tmp = explode( '/', $file );
|
||||
|
||||
$width = $file_tmp[1];
|
||||
if ( empty( $width ) and $width !== '0' )
|
||||
$width = 500;
|
||||
|
||||
$height = $file_tmp[2];
|
||||
if ( empty( $height ) and $height !== '0' )
|
||||
$height = 500;
|
||||
|
||||
for ( $i = 0; $i <= 2; $i++ )
|
||||
unset( $file_tmp[$i] );
|
||||
|
||||
$img_src = implode( '/', $file_tmp );
|
||||
|
||||
$crop_w = $_GET['c_w'] ?? null;
|
||||
$crop_h = $_GET['c_h'] ?? null;
|
||||
|
||||
$img_md5 = md5( $img_src . $height . $width . $crop_h . $crop_w );
|
||||
$file = 'thumbs/' . $img_md5[0] . '/' . $img_md5[1] . '/' . $img_md5[2] . '/' . $img_md5;
|
||||
}
|
||||
|
||||
if ( !file_exists( $file ) )
|
||||
return false;
|
||||
|
||||
$output_file = 'cache/' . $file . '.webp';
|
||||
if ( file_exists( $output_file ) )
|
||||
return $output_file;
|
||||
|
||||
$file_type = mime_content_type( $file );
|
||||
|
||||
if ( function_exists( 'imagewebp' ) )
|
||||
{
|
||||
switch ( $file_type )
|
||||
{
|
||||
case 'image/jpeg':
|
||||
$image = imagecreatefromjpeg($file);
|
||||
break;
|
||||
|
||||
case 'image/png':
|
||||
$image = imagecreatefrompng($file);
|
||||
imagepalettetotruecolor($image);
|
||||
imagealphablending($image, true);
|
||||
imagesavealpha($image, true);
|
||||
break;
|
||||
|
||||
case 'image/gif':
|
||||
$image = imagecreatefromgif($file);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$dir = dirname($output_file);
|
||||
if (!is_dir($dir))
|
||||
mkdir($dir, 0755, true);
|
||||
|
||||
$result = imagewebp($image, $output_file, $compression_quality);
|
||||
if (false === $result)
|
||||
return false;
|
||||
|
||||
imagedestroy($image);
|
||||
|
||||
return $output_file;
|
||||
}
|
||||
elseif (class_exists('Imagick'))
|
||||
{
|
||||
$dir = dirname($output_file);
|
||||
if (!is_dir($dir))
|
||||
mkdir($dir, 0755, true);
|
||||
|
||||
$image = new \Imagick();
|
||||
$image->readImage($file);
|
||||
|
||||
if ($file_type === 'image/png')
|
||||
{
|
||||
$image->setImageFormat('webp');
|
||||
$image->setImageCompressionQuality($compression_quality);
|
||||
$image->setOption('webp:lossless', 'true');
|
||||
}
|
||||
|
||||
$image->writeImage($output_file);
|
||||
return $output_file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function is_array_fix( $value )
|
||||
{
|
||||
if ( is_array( $value ) and count( $value ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function delete_cache()
|
||||
{
|
||||
self::delete_dir( '../cache/' );
|
||||
self::delete_dir( '../temp/' );
|
||||
self::delete_dir( '../cron/temp/' );
|
||||
self::delete_dir( 'temp/' );
|
||||
}
|
||||
|
||||
public static function pretty_date( $format, $timestamp = null )
|
||||
{
|
||||
$to_convert = array(
|
||||
'l' => array( 'dat' => 'N', 'str' => array( 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela' ) ),
|
||||
'F' => array( 'dat' => 'n', 'str' => array( 'styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień' ) ),
|
||||
'f' => array( 'dat' => 'n', 'str' => array( 'stycznia', 'lutego', 'marca', 'kwietnia', 'maja', 'czerwca', 'lipca', 'sierpnia', 'września', 'października', 'listopada', 'grudnia' ) )
|
||||
);
|
||||
if ( $pieces = preg_split( '#[:/.\-, ]#', $format ) )
|
||||
{
|
||||
if ( $timestamp === null )
|
||||
$timestamp = time();
|
||||
|
||||
foreach ( $pieces as $datepart )
|
||||
{
|
||||
if ( array_key_exists( $datepart, $to_convert ) )
|
||||
$replace[] = $to_convert[$datepart]['str'][( date( $to_convert[$datepart]['dat'], $timestamp ) - 1)];
|
||||
else
|
||||
$replace[] = date( $datepart, $timestamp );
|
||||
}
|
||||
$result = strtr( $format, array_combine( $pieces, $replace ) );
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
public static function lang( $text )
|
||||
{
|
||||
global $lang;
|
||||
return $lang[$text] ? $lang[$text] : 'LANG-' . $text;
|
||||
}
|
||||
|
||||
public static function array_cartesian_product( $input )
|
||||
{
|
||||
$result = array();
|
||||
|
||||
foreach ($input as $key => $values)
|
||||
{
|
||||
if ( empty( $values ) )
|
||||
continue;
|
||||
|
||||
if ( empty( $result ) )
|
||||
{
|
||||
foreach ( $values as $value )
|
||||
{
|
||||
$result[] = array( $key => $value );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$append = array();
|
||||
|
||||
foreach ( $result as &$product )
|
||||
{
|
||||
$product[$key] = array_shift( $values );
|
||||
$copy = $product;
|
||||
|
||||
foreach ( $values as $item )
|
||||
{
|
||||
$copy[$key] = $item;
|
||||
$append[] = $copy;
|
||||
}
|
||||
|
||||
array_unshift( $values, $product[$key] );
|
||||
}
|
||||
|
||||
$result = array_merge( $result, $append );
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
static public function normalize_decimal($val, int $precision = 2)
|
||||
{
|
||||
if ($val === null || $val === '') {
|
||||
return number_format(0, $precision, '.', '');
|
||||
}
|
||||
|
||||
// 1) wstępne czyszczenie
|
||||
$s = (string)$val;
|
||||
$s = str_replace(["\xC2\xA0", ' ', '’', "'"], '', $s); // spacje (w tym NBSP) i apostrofy
|
||||
$s = preg_replace('/[^0-9.,\-]/', '', $s); // zostaw tylko cyfry, . , i -
|
||||
|
||||
// 2) ustalenie separatora dziesiętnego
|
||||
$lastDot = strrpos($s, '.');
|
||||
$lastComma = strrpos($s, ',');
|
||||
|
||||
if ($lastDot !== false && $lastComma !== false) {
|
||||
// oba występują – prawy znak traktujemy jako dziesiętny
|
||||
if ($lastDot > $lastComma) {
|
||||
$s = str_replace(',', '', $s); // , = tysiące
|
||||
} else {
|
||||
$s = str_replace('.', '', $s); // . = tysiące
|
||||
$s = str_replace(',', '.', $s); // , = dziesiętny
|
||||
}
|
||||
} elseif ($lastComma !== false) {
|
||||
// tylko przecinek – traktuj jako dziesiętny
|
||||
$s = str_replace(',', '.', $s);
|
||||
} elseif (substr_count($s, '.') > 1) {
|
||||
// wiele kropek – ostatnia dziesiętna, pozostałe tysiące
|
||||
$pos = strrpos($s, '.');
|
||||
$s = str_replace('.', '', substr($s, 0, $pos)) . '.' . substr($s, $pos + 1);
|
||||
}
|
||||
// na tym etapie mamy opcjonalny '-' i co najwyżej jedną kropkę dziesiętną
|
||||
|
||||
// 3) zaokrąglenie i normalizacja
|
||||
$rounded = round((float)$s, $precision);
|
||||
return number_format($rounded, $precision, '.', '');
|
||||
}
|
||||
|
||||
public static function decimal( $val, $precision = 2, $dec_point = ',', $thousands_sep = ' ' )
|
||||
{
|
||||
return number_format( $val, $precision, $dec_point, $thousands_sep );
|
||||
}
|
||||
|
||||
public static function get_new_version()
|
||||
{
|
||||
global $settings;
|
||||
|
||||
if ( $version = self::get_session( 'new-version' ) )
|
||||
return $version;
|
||||
|
||||
$version = 0;
|
||||
$versions = file_get_contents( 'https://shoppro.project-dc.pl/updates/versions.php?key=' . $settings['update_key'] );
|
||||
$versions = explode( PHP_EOL, $versions );
|
||||
foreach ( $versions as $key => $version_tmp )
|
||||
{
|
||||
$version_tmp = floatval( $version_tmp );
|
||||
if ( $version_tmp > $version and $version_tmp )
|
||||
$version = $version_tmp;
|
||||
}
|
||||
|
||||
self::set_session( 'new-version', $version );
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
public static function get_version()
|
||||
{
|
||||
return (float) @file_get_contents( '../libraries/version.ini' );
|
||||
}
|
||||
|
||||
public static function set_session( $var, $val )
|
||||
{
|
||||
$_SESSION[$var] = $val;
|
||||
}
|
||||
|
||||
public static function get_session( $var )
|
||||
{
|
||||
return $_SESSION[$var];
|
||||
}
|
||||
|
||||
public static function delete_session( $var )
|
||||
{
|
||||
unset( $_SESSION[$var] );
|
||||
}
|
||||
|
||||
public static function get( $var, $clear = false )
|
||||
{
|
||||
if ( isset( $_POST[$var] ) )
|
||||
{
|
||||
if ( is_string( $_POST[$var] ) )
|
||||
{
|
||||
$value = $_POST[$var];
|
||||
|
||||
if ( $clear )
|
||||
{
|
||||
$value = strip_tags( $value );
|
||||
$value = preg_replace( '/[\'\"\\\\]/i', '', $value );
|
||||
}
|
||||
|
||||
return trim( $value );
|
||||
}
|
||||
else
|
||||
return $_POST[$var];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $_GET[$var] ) )
|
||||
{
|
||||
if ( is_string( $_GET[$var] ) )
|
||||
return trim( $_GET[$var] );
|
||||
else
|
||||
return $_GET[$var];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function set_message( $text )
|
||||
{
|
||||
self::set_session( 'message', $text );
|
||||
}
|
||||
|
||||
public static function alert( $text )
|
||||
{
|
||||
self::set_session( 'alert', $text );
|
||||
}
|
||||
|
||||
public static function error( $text )
|
||||
{
|
||||
self::set_session( 'error', $text );
|
||||
}
|
||||
|
||||
public static function htacces( $dir = '../' )
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
$settings = ( new \Domain\Settings\SettingsRepository( $mdb ) )->allSettings( true );
|
||||
|
||||
$url = preg_replace( '#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME'] );
|
||||
|
||||
$robots = 'User-agent: *' . PHP_EOL;
|
||||
$robots .= 'Allow: /' . PHP_EOL;
|
||||
|
||||
$site_map = '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
|
||||
$site_map .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . PHP_EOL;
|
||||
$site_map .= '<url>' . PHP_EOL;
|
||||
$site_map .= '<loc>https://' . $url . '</loc>' . PHP_EOL;
|
||||
$site_map .= '<lastmod>' . date( 'Y-m-d' ) . '</lastmod>' . PHP_EOL;
|
||||
$site_map .= '<changefreq>daily</changefreq>' . PHP_EOL;
|
||||
$site_map .= '<priority>1</priority>' . PHP_EOL;
|
||||
$site_map .= '</url>' . PHP_EOL;
|
||||
|
||||
$htaccess_data = file_get_contents( $dir . 'libraries/htaccess.conf' );
|
||||
$htaccess_data = str_replace( '{PAGE}', $url, $htaccess_data );
|
||||
|
||||
$results = $mdb -> select( 'pp_langs', [ 'id' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
|
||||
if ( is_array( $results ) ) foreach ( $results as $row )
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $row['id'] . '/$ index.php?a=change_language&id=' . $row['id'] . ' [L]';
|
||||
}
|
||||
|
||||
//
|
||||
// INNE
|
||||
//
|
||||
$htaccess_data .= PHP_EOL;
|
||||
$htaccess_data .= 'RewriteRule ^newsletter/signin/$ index.php?module=newsletter&action=signin [L]' . PHP_EOL;
|
||||
$htaccess_data .= 'RewriteRule ^newsletter/confirm/hash=(.*)$ index.php?module=newsletter&action=confirm&hash=$1 [L]' . PHP_EOL;
|
||||
$htaccess_data .= 'RewriteRule ^newsletter/unsubscribe/hash=(.*)$ index.php?module=newsletter&action=unsubscribe&hash=$1 [L]' . PHP_EOL;
|
||||
|
||||
//
|
||||
// PRODUCENCI
|
||||
//
|
||||
$categoryDefaultLayoutId = ( new \Domain\Layouts\LayoutsRepository( $mdb ) )->categoryDefaultLayoutId();
|
||||
$htaccess_data .= 'RewriteRule ^producenci$ index.php?module=shop_producer&action=list&layout_id=' . $categoryDefaultLayoutId . '&%{QUERY_STRING} [L]' . PHP_EOL;
|
||||
|
||||
$rows = $mdb -> select( 'pp_shop_producer', '*', [ 'status' => 1 ] );
|
||||
if ( self::is_array_fix( $rows ) ) foreach ( $rows as $row )
|
||||
{
|
||||
$htaccess_data .= 'RewriteRule ^producent/' . self::seo( $row['name'] ) . '$ index.php?module=shop_producer&action=products&producer_id=' . $row['id'] . '&layout_id=' . $categoryDefaultLayoutId . '&%{QUERY_STRING} [L]' . PHP_EOL;
|
||||
$htaccess_data .= 'RewriteRule ^producent/' . self::seo( $row['name'] ) . '/([0-9]+)$ index.php?module=shop_producer&action=products&producer_id=' . $row['id'] . '&layout_id=' . $categoryDefaultLayoutId . '&bs=$1&%{QUERY_STRING} [L]' . PHP_EOL;
|
||||
}
|
||||
|
||||
$results = $mdb -> select( 'pp_langs', [ 'id', 'start' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
|
||||
if ( is_array( $results ) ) foreach ( $results as $row )
|
||||
{
|
||||
!$row['start'] ? $language_link = $row['id'] . '/' : $language_link = '';
|
||||
|
||||
$results2 = $mdb -> select( 'pp_shop_categories_langs', [ '[><]pp_shop_categories' => [ 'category_id' => 'id' ] ], [ 'seo_link', 'title', 'category_id' ], [ 'lang_id' => $row['id'], 'ORDER' => [ 'o' => 'ASC' ] ] );
|
||||
if ( is_array( $results2 ) ) foreach ( $results2 as $row2 )
|
||||
{
|
||||
if ( $row2['title'] )
|
||||
{
|
||||
$site_map .= '<url>' . PHP_EOL;
|
||||
if ( $row2['seo_link'] )
|
||||
$site_map .= '<loc>https://' . $url . '/' . $language_link . self::seo( $row2['seo_link'] ) . '</loc>' . PHP_EOL;
|
||||
else
|
||||
$site_map .= '<loc>https://' . $url . '/' . $language_link . 'k-' . $row2['category_id'] . '-' . self::seo( $row2['title'] ) . '</loc>' . PHP_EOL;
|
||||
$site_map .= '<lastmod>' . date( 'Y-m-d' ) . '</lastmod>' . PHP_EOL;
|
||||
$site_map .= '<changefreq>daily</changefreq>' . PHP_EOL;
|
||||
$site_map .= '<priority>1</priority>' . PHP_EOL;
|
||||
$site_map .= '</url>' . PHP_EOL;
|
||||
|
||||
if ( $row2['seo_link'] )
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '$ index.php?category=' . $row2['category_id'] . '&lang=' . $row['id'] . '&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '/([0-9]+)$ index.php?category=' . $row2['category_id'] . '&lang=' . $row['id'] . '&bs=$1&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '/1$ ' . $language_link . self::seo( $row2['seo_link'] ) . ' [R=301,L]';
|
||||
}
|
||||
else
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 'k-' . $row2['category_id'] . '-' . self::seo( $row2['title'] ) . '$ index.php?category=' . $row2['category_id'] . '&lang=' . $row['id'] . '&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 'k-' . $row2['category_id'] . '-' . self::seo( $row2['title'] ) . '/([0-9]+)$ index.php?category=' . $row2['category_id'] . '&lang=' . $row['id'] . '&bs=$1&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 'k-' . $row2['category_id'] . '-' . self::seo( $row2['title'] ) . '/1$ ' . $language_link . 'k-' . $row2['category_id'] . '-' . self::seo( $row2['title'] ) . ' [R=301,L]';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results = $mdb -> select( 'pp_langs', [ 'id', 'start' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
|
||||
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 ) )
|
||||
{
|
||||
foreach ( $results2 as $row2 )
|
||||
{
|
||||
$mdb -> delete( 'pp_routes', [ 'AND' => [ 'product_id' => $row2['product_id'], 'lang_id' => $row['id'] ] ] );
|
||||
|
||||
if ( $row2['name'] )
|
||||
{
|
||||
$site_map .= '<url>' . PHP_EOL;
|
||||
if ( $row2['seo_link'] )
|
||||
$site_map .= '<loc>https://' . $url . '/' . $language_link . self::seo( $row2['seo_link'] ) . '</loc>' . PHP_EOL;
|
||||
else
|
||||
$site_map .= '<loc>https://' . $url . '/' . $language_link . 'p-' . $row2['product_id'] . '-' . self::seo( $row2['name'] ) . '</loc>' . PHP_EOL;
|
||||
$site_map .= '<lastmod>' . date( 'Y-m-d' ) . '</lastmod>' . PHP_EOL;
|
||||
$site_map .= '<changefreq>daily</changefreq>' . PHP_EOL;
|
||||
$site_map .= '<priority>1</priority>' . PHP_EOL;
|
||||
$site_map .= '</url>' . PHP_EOL;
|
||||
|
||||
if ( $row2['seo_link'] )
|
||||
{
|
||||
$pattern = '^' . $language_link . self::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 . self::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
|
||||
{
|
||||
$pattern = '^' . $language_link . 'p-' . $row2['product_id'] . '-' . self::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'] . '-' . self::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 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results = $mdb -> select( 'pp_langs', [ 'id', 'start' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
|
||||
if ( is_array( $results ) )
|
||||
foreach ( $results as $row )
|
||||
{
|
||||
( !$row['start'] and count( $results ) > 1 ) ? $language_link = $row['id'] . '/' : $language_link = '';
|
||||
|
||||
$results2 = $mdb -> select( 'pp_pages_langs', [ '[><]pp_pages' => [ 'page_id' => 'id' ] ], [ 'seo_link', 'title', 'page_id', 'noindex', 'start', 'link', 'page_type' ], [ 'lang_id' => $row['id'], 'ORDER' => [ 'start' => 'DESC', 'o' => 'ASC' ] ] );
|
||||
if ( is_array( $results2 ) )
|
||||
foreach ( $results2 as $row2 )
|
||||
{
|
||||
if ( $row2['title'] and $row2['page_type'] != 3 and $row2['page_type'] != 5 )
|
||||
{
|
||||
if ( !$row2['noindex'] )
|
||||
{
|
||||
$site_map .= '<url>' . PHP_EOL;
|
||||
if ( $row2['seo_link'] )
|
||||
$site_map .= '<loc>https://' . $url . '/' . self::seo( $row2['seo_link'] ) . '</loc>' . PHP_EOL;
|
||||
else
|
||||
$site_map .= '<loc>https://' . $url . '/s-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . '</loc>' . PHP_EOL;
|
||||
$site_map .= '<lastmod>' . date( 'Y-m-d' ) . '</lastmod>' . PHP_EOL;
|
||||
$site_map .= '<changefreq>daily</changefreq>' . PHP_EOL;
|
||||
$site_map .= '<priority>1</priority>' . PHP_EOL;
|
||||
$site_map .= '</url>' . PHP_EOL;
|
||||
}
|
||||
else if ( $row2['noindex'] and $row2['seo_link'] )
|
||||
{
|
||||
$robots .= 'User-agent: GoogleBot' . PHP_EOL;
|
||||
$robots .= 'Disallow: /' . $row2['seo_link'] . PHP_EOL;
|
||||
}
|
||||
|
||||
if ( $row2['start'] )
|
||||
{
|
||||
if ( $row2['seo_link'] )
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteCond %{REQUEST_URI} ^/' . self::seo( $row2['seo_link'] ) . '$';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^(.*)$ http://www.' . $url . '/' . $language_link . ' [R=permanent,L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteCond %{REQUEST_URI} ^/' . self::seo( $row2['seo_link'] ) . '-1$';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^(.*)$ http://www.' . $url . '/' . $language_link . ' [R=permanent,L]';
|
||||
}
|
||||
else
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteCond %{REQUEST_URI} ^/s-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . '$';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^(.*)$ http://www.' . $url . '/' . $language_link . ' [R=permanent,L]';
|
||||
|
||||
$htaccess_data .= PHP_EOL . 'RewriteCond %{REQUEST_URI} ^/s-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . '-1$';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^(.*)$ http://www.' . $url . '/' . $language_link . ' [R=permanent,L]';
|
||||
}
|
||||
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^$ index.php?a=page&id=' . $row2['page_id'] . '&lang=' . $row['id'] . ' [L]';
|
||||
}
|
||||
|
||||
if ( $row2['seo_link'] )
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '$ index.php?a=page&id=' . $row2['page_id'] . '&lang=' . $row['id'] . '&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '/([0-9]+)$ index.php?a=page&id=' . $row2['page_id'] . '&lang=' . $row['id'] . '&bs=$1&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '/1$ ' . $language_link . self::seo( $row2['seo_link'] ) . ' [R=301,L]';
|
||||
}
|
||||
else
|
||||
{
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 's-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . '$ index.php?a=page&id=' . $row2['page_id'] . '&lang=' . $row['id'] . '&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 's-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . '/([0-9]+)$ index.php?a=page&id=' . $row2['page_id'] . '&lang=' . $row['id'] . '&bs=$1&%{QUERY_STRING} [L]';
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 's-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . '/1$ ' . $language_link . 's-' . $row2['page_id'] . '-' . self::seo( $row2['title'] ) . ' [R=301,L]';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results2 = $mdb -> select( 'pp_articles_langs', [ '[><]pp_articles' => [ 'article_id' => 'id' ] ], [ 'seo_link', 'title', 'article_id', 'noindex', 'copy_from' ], [ 'AND' => [ 'status' => 1, 'lang_id' => $row['id'], 'block_direct_access' => 0 ] ] );
|
||||
if ( is_array( $results2 ) )
|
||||
foreach ( $results2 as $row2 )
|
||||
{
|
||||
if ( $row2['copy_from'] != null )
|
||||
{
|
||||
$results_tmp = $mdb -> get( 'pp_articles_langs', [
|
||||
'seo_link',
|
||||
'title'
|
||||
], [
|
||||
'AND' => [
|
||||
'article_id' => $row2['article_id'],
|
||||
'lang_id' => $row2['copy_from']
|
||||
]
|
||||
] );
|
||||
$row2['seo_link'] = $results_tmp['seo_link'];
|
||||
$row2['title'] = $results_tmp['title'];
|
||||
}
|
||||
|
||||
if ( !$row2['noindex'] )
|
||||
{
|
||||
$site_map .= '<url>' . PHP_EOL;
|
||||
if ( $row2['seo_link'] )
|
||||
$site_map .= '<loc>https://' . $url . '/' . self::seo( $row2['seo_link'] ) . '</loc>' . PHP_EOL;
|
||||
else
|
||||
$site_map .= '<loc>https://' . $url . '/a-' . $row2['article_id'] . '-' . self::seo( $row2['title'] ) . '</loc>' . PHP_EOL;
|
||||
$site_map .= '<lastmod>' . date( 'Y-m-d' ) . '</lastmod>' . PHP_EOL;
|
||||
$site_map .= '<changefreq>daily</changefreq>' . PHP_EOL;
|
||||
$site_map .= '<priority>1</priority>' . PHP_EOL;
|
||||
$site_map .= '</url>' . PHP_EOL;
|
||||
}
|
||||
else if ( $row2['noindex'] and $row2['seo_link'] )
|
||||
{
|
||||
$robots .= 'User-agent: GoogleBot' . PHP_EOL;
|
||||
$robots .= 'Disallow: /' . $row2['seo_link'] . PHP_EOL;
|
||||
}
|
||||
|
||||
if ( $row2['seo_link'] )
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . self::seo( $row2['seo_link'] ) . '$ index.php?article=' . $row2['article_id'] . '&lang=' . $row['id'] . '&%{QUERY_STRING} [L]';
|
||||
else if ( $row2['title'] != null )
|
||||
$htaccess_data .= PHP_EOL . 'RewriteRule ^' . $language_link . 'a-' . $row2['article_id'] . '-' . self::seo( $row2['title'] ) . '$ index.php?article=' . $row2['article_id'] . '&lang=' . $row['id'] . '&%{QUERY_STRING} [L]';
|
||||
}
|
||||
}
|
||||
|
||||
$results = $mdb -> get( 'pp_settings', 'value', [ 'param' => 'htaccess' ] );
|
||||
if ( $results )
|
||||
$htaccess_data .= PHP_EOL . $results;
|
||||
|
||||
$results = $mdb -> get( 'pp_settings', 'value', [ 'param' => 'robots' ] );
|
||||
if ( $results )
|
||||
$robots .= PHP_EOL . $results;
|
||||
|
||||
$site_map .= '</urlset>';
|
||||
|
||||
/* cache */
|
||||
if ( $settings['htaccess_cache'] )
|
||||
{
|
||||
$htaccess_data = str_replace( '{HTACCESS_CACHE}',
|
||||
'<IfModule mod_deflate.c>' . PHP_EOL
|
||||
. 'AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript' . PHP_EOL
|
||||
. '</IfModule>' . PHP_EOL
|
||||
. '<IfModule mod_headers.c>' . PHP_EOL
|
||||
. 'Header set Access-Control-Allow-Origin "*"' . PHP_EOL
|
||||
. '</IfModule>' . PHP_EOL
|
||||
. '<IfModule mod_expires.c>' . PHP_EOL
|
||||
. 'ExpiresActive on' . PHP_EOL
|
||||
. 'ExpiresDefault "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType text/css "access plus 1 year"' . PHP_EOL
|
||||
. 'ExpiresByType application/json "access plus 0 seconds"' . PHP_EOL
|
||||
. 'ExpiresByType application/xml "access plus 0 seconds"' . PHP_EOL
|
||||
. 'ExpiresByType text/xml "access plus 0 seconds"' . PHP_EOL
|
||||
. 'ExpiresByType image/x-icon "access plus 1 week"' . PHP_EOL
|
||||
. 'ExpiresByType text/x-component "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType text/html "access plus 0 seconds"' . PHP_EOL
|
||||
. 'ExpiresByType application/javascript "access plus 1 year"' . PHP_EOL
|
||||
. 'ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"' . PHP_EOL
|
||||
. 'ExpiresByType text/cache-manifest "access plus 0 seconds"' . PHP_EOL
|
||||
. 'ExpiresByType audio/ogg "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType image/gif "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType image/jpeg "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType image/png "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType video/mp4 "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType video/ogg "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType video/webm "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType application/atom+xml "access plus 1 hour"' . PHP_EOL
|
||||
. 'ExpiresByType application/rss+xml "access plus 1 hour"' . PHP_EOL
|
||||
. 'ExpiresByType application/font-woff "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType application/vnd.ms-fontobject "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType application/x-font-ttf "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType font/opentype "access plus 1 month"' . PHP_EOL
|
||||
. 'ExpiresByType image/svg+xml "access plus 1 month"' . PHP_EOL
|
||||
. '</IfModule>'
|
||||
, $htaccess_data );
|
||||
}
|
||||
else
|
||||
{
|
||||
$htaccess_data = str_replace( '{HTACCESS_CACHE}',
|
||||
'<IfModule mod_headers.c>' . PHP_EOL
|
||||
. 'Header set Cache-Control "no-cache, no-store, must-revalidate"' . PHP_EOL
|
||||
. 'Header set Pragma "no-cache"' . PHP_EOL
|
||||
. 'Header set Expires 0' . PHP_EOL
|
||||
. '</IfModule>',
|
||||
$htaccess_data );
|
||||
}
|
||||
|
||||
$htaccess_data .= PHP_EOL;
|
||||
$htaccess_data .= 'RewriteCond %{REQUEST_FILENAME} !-f' . PHP_EOL;
|
||||
$htaccess_data .= 'RewriteCond %{REQUEST_FILENAME} !-d' . PHP_EOL;
|
||||
$htaccess_data .= 'RewriteRule ^ index.php [L]';
|
||||
|
||||
// Niektore hostingi blokuja zmiane wersji PHP przez .htaccess.
|
||||
// Automatycznie komentujemy niedozwolone dyrektywy, aby generowany plik byl kompatybilny.
|
||||
$htaccess_data = preg_replace( '/^(\\s*)(AddHandler|SetHandler|ForceType)\\b/im', '$1# $2', $htaccess_data );
|
||||
|
||||
$fp = fopen( $dir . '.htaccess', 'w' );
|
||||
fwrite( $fp, $htaccess_data );
|
||||
fclose( $fp );
|
||||
|
||||
$fp = fopen( $dir . 'sitemap.xml', 'w' );
|
||||
fwrite( $fp, $site_map );
|
||||
fclose( $fp );
|
||||
|
||||
$fp = fopen( $dir . 'robots.txt', 'w' );
|
||||
fwrite( $fp, $robots );
|
||||
fclose( $fp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function seo( $val, $delete_rhombs = false )
|
||||
{
|
||||
$array_rep1 = array('*', '_', ' ', '+', '"', "'", '?', '-', ',', '!', '~', '<', '>', '@', '#', '$', '%', '^', '&', '*' . '(', ')' . '-', '=', '\\', '|', '[', ']', ':', '(', ')');
|
||||
$array_rep2 = array('-', '-', '-', '-', '', '', '', '-', '-', '', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '', '-', '-', '-', '-', '-', '-', '-', '-');
|
||||
$val = self::noPl($val);
|
||||
$val = str_replace($array_rep1, $array_rep2, $val);
|
||||
if ($delete_rhombs)
|
||||
$val = str_replace('/', '', $val);
|
||||
|
||||
$val = strtolower($val);
|
||||
$val = preg_replace('/(-){2,}/', '-', $val);
|
||||
$val = ltrim($val, '-');
|
||||
$val = rtrim($val, '-');
|
||||
return $val;
|
||||
}
|
||||
|
||||
public static function noPL($string)
|
||||
{
|
||||
$chars = array( // Decompositions for Latin-1 Supplement chr(195).chr(128)=> 'A', chr(195).chr(129) => 'A',
|
||||
chr(195) . chr(130) => 'A', chr(195) . chr(131) => 'A',
|
||||
chr(195) . chr(132) => 'A', chr(195) . chr(133) => 'A',
|
||||
chr(195) . chr(135) => 'C', chr(195) . chr(136) => 'E',
|
||||
chr(195) . chr(137) => 'E', chr(195) . chr(138) => 'E',
|
||||
chr(195) . chr(139) => 'E', chr(195) . chr(140) => 'I',
|
||||
chr(195) . chr(141) => 'I', chr(195) . chr(142) => 'I',
|
||||
chr(195) . chr(143) => 'I', chr(195) . chr(145) => 'N',
|
||||
chr(195) . chr(146) => 'O', chr(195) . chr(147) => 'O',
|
||||
chr(195) . chr(148) => 'O', chr(195) . chr(149) => 'O',
|
||||
chr(195) . chr(150) => 'O', chr(195) . chr(153) => 'U',
|
||||
chr(195) . chr(154) => 'U', chr(195) . chr(155) => 'U',
|
||||
chr(195) . chr(156) => 'U', chr(195) . chr(157) => 'Y',
|
||||
chr(195) . chr(159) => 's', chr(195) . chr(160) => 'a',
|
||||
chr(195) . chr(161) => 'a', chr(195) . chr(162) => 'a',
|
||||
chr(195) . chr(163) => 'a', chr(195) . chr(164) => 'a',
|
||||
chr(195) . chr(165) => 'a', chr(195) . chr(167) => 'c',
|
||||
chr(195) . chr(168) => 'e', chr(195) . chr(169) => 'e',
|
||||
chr(195) . chr(170) => 'e', chr(195) . chr(171) => 'e',
|
||||
chr(195) . chr(172) => 'i', chr(195) . chr(173) => 'i',
|
||||
chr(195) . chr(174) => 'i', chr(195) . chr(175) => 'i',
|
||||
chr(195) . chr(177) => 'n', chr(195) . chr(178) => 'o',
|
||||
chr(195) . chr(179) => 'o', chr(195) . chr(180) => 'o',
|
||||
chr(195) . chr(181) => 'o', chr(195) . chr(182) => 'o',
|
||||
chr(195) . chr(182) => 'o', chr(195) . chr(185) => 'u',
|
||||
chr(195) . chr(186) => 'u', chr(195) . chr(187) => 'u',
|
||||
chr(195) . chr(188) => 'u', chr(195) . chr(189) => 'y',
|
||||
chr(195) . chr(191) => 'y',
|
||||
// Decompositions for Latin Extended-A
|
||||
chr(196) . chr(128) => 'A', chr(196) . chr(129) => 'a',
|
||||
chr(196) . chr(130) => 'A', chr(196) . chr(131) => 'a',
|
||||
chr(196) . chr(132) => 'A', chr(196) . chr(133) => 'a',
|
||||
chr(196) . chr(134) => 'C', chr(196) . chr(135) => 'c',
|
||||
chr(196) . chr(136) => 'C', chr(196) . chr(137) => 'c',
|
||||
chr(196) . chr(138) => 'C', chr(196) . chr(139) => 'c',
|
||||
chr(196) . chr(140) => 'C', chr(196) . chr(141) => 'c',
|
||||
chr(196) . chr(142) => 'D', chr(196) . chr(143) => 'd',
|
||||
chr(196) . chr(144) => 'D', chr(196) . chr(145) => 'd',
|
||||
chr(196) . chr(146) => 'E', chr(196) . chr(147) => 'e',
|
||||
chr(196) . chr(148) => 'E', chr(196) . chr(149) => 'e',
|
||||
chr(196) . chr(150) => 'E', chr(196) . chr(151) => 'e',
|
||||
chr(196) . chr(152) => 'E', chr(196) . chr(153) => 'e',
|
||||
chr(196) . chr(154) => 'E', chr(196) . chr(155) => 'e',
|
||||
chr(196) . chr(156) => 'G', chr(196) . chr(157) => 'g',
|
||||
chr(196) . chr(158) => 'G', chr(196) . chr(159) => 'g',
|
||||
chr(196) . chr(160) => 'G', chr(196) . chr(161) => 'g',
|
||||
chr(196) . chr(162) => 'G', chr(196) . chr(163) => 'g',
|
||||
chr(196) . chr(164) => 'H', chr(196) . chr(165) => 'h',
|
||||
chr(196) . chr(166) => 'H', chr(196) . chr(167) => 'h',
|
||||
chr(196) . chr(168) => 'I', chr(196) . chr(169) => 'i',
|
||||
chr(196) . chr(170) => 'I', chr(196) . chr(171) => 'i',
|
||||
chr(196) . chr(172) => 'I', chr(196) . chr(173) => 'i',
|
||||
chr(196) . chr(174) => 'I', chr(196) . chr(175) => 'i',
|
||||
chr(196) . chr(176) => 'I', chr(196) . chr(177) => 'i',
|
||||
chr(196) . chr(178) => 'IJ', chr(196) . chr(179) => 'ij',
|
||||
chr(196) . chr(180) => 'J', chr(196) . chr(181) => 'j',
|
||||
chr(196) . chr(182) => 'K', chr(196) . chr(183) => 'k',
|
||||
chr(196) . chr(184) => 'k', chr(196) . chr(185) => 'L',
|
||||
chr(196) . chr(186) => 'l', chr(196) . chr(187) => 'L',
|
||||
chr(196) . chr(188) => 'l', chr(196) . chr(189) => 'L',
|
||||
chr(196) . chr(190) => 'l', chr(196) . chr(191) => 'L',
|
||||
chr(197) . chr(128) => 'l', chr(197) . chr(129) => 'L',
|
||||
chr(197) . chr(130) => 'l', chr(197) . chr(131) => 'N',
|
||||
chr(197) . chr(132) => 'n', chr(197) . chr(133) => 'N',
|
||||
chr(197) . chr(134) => 'n', chr(197) . chr(135) => 'N',
|
||||
chr(197) . chr(136) => 'n', chr(197) . chr(137) => 'N',
|
||||
chr(197) . chr(138) => 'n', chr(197) . chr(139) => 'N',
|
||||
chr(197) . chr(140) => 'O', chr(197) . chr(141) => 'o',
|
||||
chr(197) . chr(142) => 'O', chr(197) . chr(143) => 'o',
|
||||
chr(197) . chr(144) => 'O', chr(197) . chr(145) => 'o',
|
||||
chr(197) . chr(146) => 'OE', chr(197) . chr(147) => 'oe',
|
||||
chr(197) . chr(148) => 'R', chr(197) . chr(149) => 'r',
|
||||
chr(197) . chr(150) => 'R', chr(197) . chr(151) => 'r',
|
||||
chr(197) . chr(152) => 'R', chr(197) . chr(153) => 'r',
|
||||
chr(197) . chr(154) => 'S', chr(197) . chr(155) => 's',
|
||||
chr(197) . chr(156) => 'S', chr(197) . chr(157) => 's',
|
||||
chr(197) . chr(158) => 'S', chr(197) . chr(159) => 's',
|
||||
chr(197) . chr(160) => 'S', chr(197) . chr(161) => 's',
|
||||
chr(197) . chr(162) => 'T', chr(197) . chr(163) => 't',
|
||||
chr(197) . chr(164) => 'T', chr(197) . chr(165) => 't',
|
||||
chr(197) . chr(166) => 'T', chr(197) . chr(167) => 't',
|
||||
chr(197) . chr(168) => 'U', chr(197) . chr(169) => 'u',
|
||||
chr(197) . chr(170) => 'U', chr(197) . chr(171) => 'u',
|
||||
chr(197) . chr(172) => 'U', chr(197) . chr(173) => 'u',
|
||||
chr(197) . chr(174) => 'U', chr(197) . chr(175) => 'u',
|
||||
chr(197) . chr(176) => 'U', chr(197) . chr(177) => 'u',
|
||||
chr(197) . chr(178) => 'U', chr(197) . chr(179) => 'u',
|
||||
chr(197) . chr(180) => 'W', chr(197) . chr(181) => 'w',
|
||||
chr(197) . chr(182) => 'Y', chr(197) . chr(183) => 'y',
|
||||
chr(197) . chr(184) => 'Y', chr(197) . chr(185) => 'Z',
|
||||
chr(197) . chr(186) => 'z', chr(197) . chr(187) => 'Z',
|
||||
chr(197) . chr(188) => 'z', chr(197) . chr(189) => 'Z',
|
||||
chr(197) . chr(190) => 'z', chr(197) . chr(191) => 's'
|
||||
);
|
||||
|
||||
$string = strtr($string, $chars);
|
||||
|
||||
$table = array(
|
||||
"А" => "a", "Б" => "b", "В" => "v", "Г" => "g", "Д" => "d",
|
||||
"Е" => "e", "Ё" => "yo", "Ж" => "zh", "З" => "z", "И" => "i",
|
||||
"Й" => "j", "К" => "k", "Л" => "l", "М" => "m", "Н" => "n",
|
||||
"О" => "o", "П" => "p", "Р" => "r", "С" => "s", "Т" => "t",
|
||||
"У" => "u", "Ф" => "f", "Х" => "kh", "Ц" => "ts", "Ч" => "ch",
|
||||
"Ш" => "sh", "Щ" => "sch", "Ъ" => "", "Ы" => "y", "Ь" => "",
|
||||
"Э" => "e", "Ю" => "yu", "Я" => "ya", "а" => "a", "б" => "b",
|
||||
"в" => "v", "г" => "g", "д" => "d", "е" => "e", "ё" => "yo",
|
||||
"ж" => "zh", "з" => "z", "и" => "i", "й" => "j", "к" => "k",
|
||||
"л" => "l", "м" => "m", "н" => "n", "о" => "o", "п" => "p",
|
||||
"р" => "r", "с" => "s", "т" => "t", "у" => "u", "ф" => "f",
|
||||
"х" => "kh", "ц" => "ts", "ч" => "ch", "ш" => "sh", "щ" => "sch",
|
||||
"ъ" => "", "ы" => "y", "ь" => "", "э" => "e", "ю" => "yu",
|
||||
"я" => "ya", " " => "-", "." => "", "," => "",
|
||||
":" => "", ";" => "", "—" => "", "–" => "-"
|
||||
);
|
||||
|
||||
$string = strtr($string, $table);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
public static function delete_dir( $dir )
|
||||
{
|
||||
if ( is_file( $dir ) )
|
||||
return @unlink( $dir );
|
||||
|
||||
else if ( is_dir( $dir ) )
|
||||
{
|
||||
$scan = glob( rtrim( $dir, '/' ) . '/*' );
|
||||
|
||||
if ( is_array( $scan ) )
|
||||
foreach ( $scan as $index => $path )
|
||||
self::delete_dir( $path );
|
||||
|
||||
if ( is_dir( $dir ) && ( ( $files = @scandir( $dir ) ) && count( $files ) <= 2 ) )
|
||||
return @rmdir( $dir );
|
||||
}
|
||||
}
|
||||
|
||||
public static function email_check( $email )
|
||||
{
|
||||
return filter_var( $email, FILTER_VALIDATE_EMAIL );
|
||||
}
|
||||
|
||||
public static function send_email( $email, $subject, $text, $replay = '', $file = '' )
|
||||
{
|
||||
global $settings;
|
||||
|
||||
if ( self::email_check( $email ) and $subject )
|
||||
{
|
||||
$mail = new \PHPMailer();
|
||||
$mail -> IsSMTP();
|
||||
$mail -> SMTPAuth = true;
|
||||
$mail -> Host = $settings['email_host'];
|
||||
$mail -> Port = $settings['email_port'];
|
||||
$mail -> Username = $settings['email_login'];
|
||||
$mail -> Password = $settings['email_password'];
|
||||
$mail -> CharSet = "UTF-8";
|
||||
$mail -> SMTPOptions = array(
|
||||
'ssl' => array(
|
||||
'verify_peer' => false,
|
||||
'verify_peer_name' => false,
|
||||
'allow_self_signed' => true
|
||||
)
|
||||
);
|
||||
|
||||
if ( self::email_check( $replay ) )
|
||||
{
|
||||
$mail -> AddReplyTo( $replay, $replay );
|
||||
$mail -> SetFrom( $replay, $replay );
|
||||
}
|
||||
else
|
||||
{
|
||||
$mail -> AddReplyTo( $settings['contact_email'], $settings['firm_name'] );
|
||||
$mail -> SetFrom( $settings['contact_email'], $settings['firm_name'] );
|
||||
}
|
||||
$mail -> AddAddress( $email, '' );
|
||||
$mail -> Subject = $subject;
|
||||
$mail -> Body = $text;
|
||||
if ( is_array( $file ) )
|
||||
{
|
||||
foreach ( $file as $file_tmp )
|
||||
{
|
||||
if ( file_exists( $file_tmp ) )
|
||||
$mail -> AddAttachment( $file_tmp );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( file_exists( $file ) )
|
||||
$mail -> AddAttachment( $file );
|
||||
}
|
||||
$mail -> IsHTML( true );
|
||||
return $mail -> Send();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function shortPrice( $price )
|
||||
{
|
||||
if ( self::isWholeNumber( $price ) )
|
||||
$price = round( $price, 0 );
|
||||
else
|
||||
$price = self::decimal( $price );
|
||||
|
||||
return $price;
|
||||
}
|
||||
|
||||
public static function isWholeNumber( $value )
|
||||
{
|
||||
return ( is_numeric( $value ) && ( round( $value, 3 ) == round( $value ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
93
autoload/Shared/Html/Html.php
Normal file
93
autoload/Shared/Html/Html.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace Shared\Html;
|
||||
|
||||
class Html
|
||||
{
|
||||
public static function form_text( array $params = array() )
|
||||
{
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/form-text' );
|
||||
}
|
||||
|
||||
public static function input_switch( array $params = array() )
|
||||
{
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/input-switch' );
|
||||
}
|
||||
|
||||
public static function select( array $params = array() )
|
||||
{
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/select' );
|
||||
}
|
||||
|
||||
public static function textarea( array $params = array() )
|
||||
{
|
||||
$defaults = array(
|
||||
'rows' => 4,
|
||||
);
|
||||
|
||||
$params = array_merge( $defaults, $params );
|
||||
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/textarea' );
|
||||
}
|
||||
|
||||
public static function input_icon( array $params = array() )
|
||||
{
|
||||
$defaults = array(
|
||||
'type' => 'text',
|
||||
);
|
||||
|
||||
$params = array_merge( $defaults, $params );
|
||||
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/input-icon' );
|
||||
}
|
||||
|
||||
public static function input( array $params = array() )
|
||||
{
|
||||
$defaults = array(
|
||||
'type' => 'text',
|
||||
);
|
||||
|
||||
$params = array_merge( $defaults, $params );
|
||||
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/input' );
|
||||
}
|
||||
|
||||
public static function button( array $params = array() )
|
||||
{
|
||||
$defaults = array(
|
||||
'class' => 'btn-sm btn-info',
|
||||
);
|
||||
|
||||
$params = array_merge( $defaults, $params );
|
||||
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/button' );
|
||||
}
|
||||
|
||||
public static function panel( array $params = array() )
|
||||
{
|
||||
$defaults = array(
|
||||
'title' => 'panel-title',
|
||||
'class' => 'panel-primary',
|
||||
'content' => 'panel-content'
|
||||
);
|
||||
|
||||
$params = array_merge( $defaults, $params );
|
||||
|
||||
$tpl = new \Shared\Tpl\Tpl;
|
||||
$tpl -> params = $params;
|
||||
return $tpl -> render( 'html/panel' );
|
||||
}
|
||||
}
|
||||
442
autoload/Shared/Image/ImageManipulator.php
Normal file
442
autoload/Shared/Image/ImageManipulator.php
Normal file
@@ -0,0 +1,442 @@
|
||||
<?php
|
||||
namespace Shared\Image;
|
||||
|
||||
class ImageManipulator
|
||||
{
|
||||
protected int $width;
|
||||
protected int $height;
|
||||
/** @var resource|\GdImage */
|
||||
protected $image;
|
||||
protected ?string $file = null;
|
||||
|
||||
/**
|
||||
* Image manipulator constructor
|
||||
*
|
||||
* @param string|null $file Path to image file or image data as string
|
||||
*/
|
||||
public function __construct(?string $file = null)
|
||||
{
|
||||
if ($file !== null) {
|
||||
$this->file = $file;
|
||||
|
||||
if (is_file($file)) {
|
||||
$this->setImageFile($file);
|
||||
} else {
|
||||
$this->setImageString($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set image resource from file
|
||||
*
|
||||
* @param string $file Path to image file
|
||||
* @return self
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setImageFile(string $file): self
|
||||
{
|
||||
if (!(is_readable($file) && is_file($file))) {
|
||||
throw new \InvalidArgumentException("Image file $file is not readable");
|
||||
}
|
||||
|
||||
if (isset($this->image) && $this->isValidImageResource($this->image)) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
|
||||
[$width, $height, $type] = getimagesize($file);
|
||||
|
||||
if ($width === false || $height === false) {
|
||||
throw new \InvalidArgumentException("Unable to get image size for $file");
|
||||
}
|
||||
|
||||
error_log("Loaded image size from file: width: $width, height: $height, type: $type");
|
||||
|
||||
switch ($type) {
|
||||
case IMAGETYPE_GIF:
|
||||
$this->image = imagecreatefromgif($file);
|
||||
break;
|
||||
case IMAGETYPE_JPEG:
|
||||
$this->image = imagecreatefromjpeg($file);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$this->image = imagecreatefrompng($file);
|
||||
break;
|
||||
case IMAGETYPE_WEBP:
|
||||
$this->image = imagecreatefromwebp($file);
|
||||
break;
|
||||
default:
|
||||
throw new \InvalidArgumentException("Image type $type not supported");
|
||||
}
|
||||
|
||||
if (!$this->isValidImageResource($this->image)) {
|
||||
throw new \InvalidArgumentException("Failed to create image from $file");
|
||||
}
|
||||
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
|
||||
error_log("Set image dimensions: width: {$this->width}, height: {$this->height}");
|
||||
|
||||
if ($this->width === 0 || $this->height === 0) {
|
||||
throw new \InvalidArgumentException("Image dimensions are invalid (width: $this->width, height: $this->height)");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set image resource from string data
|
||||
*
|
||||
* @param string $data Image data as string
|
||||
* @return self
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function setImageString(string $data): self
|
||||
{
|
||||
if (isset($this->image) && $this->isValidImageResource($this->image)) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
|
||||
$image = imagecreatefromstring($data);
|
||||
if (!$this->isValidImageResource($image)) {
|
||||
throw new \RuntimeException('Cannot create image from data string');
|
||||
}
|
||||
|
||||
$this->image = $image;
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
|
||||
error_log("Set image dimensions from string: width: {$this->width}, height: {$this->height}");
|
||||
|
||||
if ($this->width === 0 || $this->height === 0) {
|
||||
throw new \RuntimeException("Image dimensions are invalid (width: $this->width, height: $this->height)");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resamples the current image
|
||||
*
|
||||
* @param int $width New width
|
||||
* @param int $height New height
|
||||
* @param bool $constrainProportions Constrain current image proportions when resizing
|
||||
* @return self
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function resample(int $width, int $height, bool $constrainProportions = true): self
|
||||
{
|
||||
if (!isset($this->image) || !$this->isValidImageResource($this->image)) {
|
||||
throw new \RuntimeException('No image set');
|
||||
}
|
||||
|
||||
if ($constrainProportions) {
|
||||
if ($this->height === 0) {
|
||||
throw new \RuntimeException('Image height is zero, cannot calculate aspect ratio');
|
||||
}
|
||||
|
||||
$aspectRatio = $this->width / $this->height;
|
||||
|
||||
// Ustaw domyślną wysokość, jeśli podana jest równa zero
|
||||
if ($height === 0) {
|
||||
$height = (int) round($width / $aspectRatio);
|
||||
}
|
||||
|
||||
if ($width / $height > $aspectRatio) {
|
||||
$width = (int) round($height * $aspectRatio);
|
||||
} else {
|
||||
$height = (int) round($width / $aspectRatio);
|
||||
}
|
||||
|
||||
if ($width <= 0 || $height <= 0) {
|
||||
throw new \RuntimeException('Calculated dimensions are invalid (width: ' . $width . ', height: ' . $height . ')');
|
||||
}
|
||||
}
|
||||
|
||||
// reszta kodu metody
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enlarge canvas
|
||||
*
|
||||
* @param int $width Canvas width
|
||||
* @param int $height Canvas height
|
||||
* @param array $rgb RGB colour values [R, G, B]
|
||||
* @param int|null $xpos X-Position of image in new canvas, null for centre
|
||||
* @param int|null $ypos Y-Position of image in new canvas, null for centre
|
||||
* @return self
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function enlargeCanvas(int $width, int $height, array $rgb = [], ?int $xpos = null, ?int $ypos = null): self
|
||||
{
|
||||
if (!isset($this->image) || !$this->isValidImageResource($this->image)) {
|
||||
throw new \RuntimeException('No image set');
|
||||
}
|
||||
|
||||
$width = max($width, $this->width);
|
||||
$height = max($height, $this->height);
|
||||
|
||||
$temp = imagecreatetruecolor($width, $height);
|
||||
if (!$this->isValidImageResource($temp)) {
|
||||
throw new \RuntimeException('Failed to create a new image for enlarging canvas');
|
||||
}
|
||||
|
||||
// Fill background if RGB provided
|
||||
if (count($rgb) === 3) {
|
||||
[$r, $g, $b] = $rgb;
|
||||
$bg = imagecolorallocate($temp, $r, $g, $b);
|
||||
imagefill($temp, 0, 0, $bg);
|
||||
} else {
|
||||
// Preserve transparency
|
||||
imagealphablending($temp, false);
|
||||
imagesavealpha($temp, true);
|
||||
$transparent = imagecolorallocatealpha($temp, 255, 255, 255, 127);
|
||||
imagefilledrectangle($temp, 0, 0, $width, $height, $transparent);
|
||||
}
|
||||
|
||||
// Calculate positions
|
||||
if ($xpos === null) {
|
||||
$xpos = (int) round(($width - $this->width) / 2);
|
||||
}
|
||||
if ($ypos === null) {
|
||||
$ypos = (int) round(($height - $this->height) / 2);
|
||||
}
|
||||
|
||||
// Logowanie przed kopiowaniem obrazu na nowe płótno
|
||||
error_log("Enlarging canvas: xpos: $xpos, ypos: $ypos");
|
||||
|
||||
if (!imagecopy(
|
||||
$temp,
|
||||
$this->image,
|
||||
$xpos,
|
||||
$ypos,
|
||||
0,
|
||||
0,
|
||||
$this->width,
|
||||
$this->height
|
||||
)) {
|
||||
throw new \RuntimeException('Failed to copy image onto enlarged canvas');
|
||||
}
|
||||
|
||||
return $this->_replace($temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crop image
|
||||
*
|
||||
* @param int|array $x1 Top left x-coordinate of crop box or array of coordinates [x1, y1, x2, y2]
|
||||
* @param int $y1 Top left y-coordinate of crop box
|
||||
* @param int $x2 Bottom right x-coordinate of crop box
|
||||
* @param int $y2 Bottom right y-coordinate of crop box
|
||||
* @return self
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function crop($x1, int $y1 = 0, int $x2 = 0, int $y2 = 0): self
|
||||
{
|
||||
if (!isset($this->image) || !$this->isValidImageResource($this->image)) {
|
||||
throw new \RuntimeException('No image set');
|
||||
}
|
||||
|
||||
if (is_array($x1) && count($x1) === 4) {
|
||||
[$x1, $y1, $x2, $y2] = $x1;
|
||||
}
|
||||
|
||||
$x1 = max((int)$x1, 0);
|
||||
$y1 = max($y1, 0);
|
||||
$x2 = min($x2, $this->width);
|
||||
$y2 = min($y2, $this->height);
|
||||
|
||||
$cropWidth = $x2 - $x1;
|
||||
$cropHeight = $y2 - $y1;
|
||||
|
||||
// Logowanie wymiarów do przycięcia
|
||||
error_log("Cropping image: x1: $x1, y1: $y1, x2: $x2, y2: $y2, cropWidth: $cropWidth, cropHeight: $cropHeight");
|
||||
|
||||
if ($cropWidth <= 0 || $cropHeight <= 0) {
|
||||
throw new \RuntimeException('Invalid crop dimensions');
|
||||
}
|
||||
|
||||
$temp = imagecreatetruecolor($cropWidth, $cropHeight);
|
||||
if (!$this->isValidImageResource($temp)) {
|
||||
throw new \RuntimeException('Failed to create a new image for cropping');
|
||||
}
|
||||
|
||||
// Preserve transparency
|
||||
imagealphablending($temp, false);
|
||||
imagesavealpha($temp, true);
|
||||
$transparent = imagecolorallocatealpha($temp, 255, 255, 255, 127);
|
||||
imagefilledrectangle($temp, 0, 0, $cropWidth, $cropHeight, $transparent);
|
||||
|
||||
if (!imagecopy(
|
||||
$temp,
|
||||
$this->image,
|
||||
0,
|
||||
0,
|
||||
$x1,
|
||||
$y1,
|
||||
$cropWidth,
|
||||
$cropHeight
|
||||
)) {
|
||||
throw new \RuntimeException('Failed to crop image');
|
||||
}
|
||||
|
||||
return $this->_replace($temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace current image resource with a new one
|
||||
*
|
||||
* @param resource|\GdImage $res New image resource
|
||||
* @return self
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
protected function _replace($res): self
|
||||
{
|
||||
if (!$this->isValidImageResource($res)) {
|
||||
throw new \UnexpectedValueException('Invalid image resource');
|
||||
}
|
||||
|
||||
if (isset($this->image) && $this->isValidImageResource($this->image)) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
|
||||
$this->image = $res;
|
||||
$this->width = imagesx($res);
|
||||
$this->height = imagesy($res);
|
||||
|
||||
error_log("Replaced image dimensions: width: {$this->width}, height: {$this->height}");
|
||||
|
||||
if ($this->width === 0 || $this->height === 0) {
|
||||
throw new \UnexpectedValueException("Replaced image has invalid dimensions (width: $this->width, height: $this->height)");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save current image to file
|
||||
*
|
||||
* @param string $fileName Path to save the image
|
||||
* @param int|null $type Image type (IMAGETYPE_*) or null to auto-detect from file extension
|
||||
* @return void
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function save(string $fileName, ?int $type = null): void
|
||||
{
|
||||
$dir = dirname($fileName);
|
||||
if (!is_dir($dir)) {
|
||||
if (!mkdir($dir, 0755, true) && !is_dir($dir)) {
|
||||
throw new \RuntimeException('Error creating directory ' . $dir);
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-detect type from file extension if not provided
|
||||
if ($type === null) {
|
||||
$extension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
switch ($extension) {
|
||||
case 'gif':
|
||||
$type = IMAGETYPE_GIF;
|
||||
break;
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
$type = IMAGETYPE_JPEG;
|
||||
break;
|
||||
case 'png':
|
||||
$type = IMAGETYPE_PNG;
|
||||
break;
|
||||
case 'webp':
|
||||
$type = IMAGETYPE_WEBP;
|
||||
break;
|
||||
default:
|
||||
$type = IMAGETYPE_JPEG;
|
||||
}
|
||||
}
|
||||
|
||||
error_log("Saving image to $fileName with type $type");
|
||||
|
||||
try {
|
||||
switch ($type) {
|
||||
case IMAGETYPE_WEBP:
|
||||
if (!imagewebp($this->image, $fileName)) {
|
||||
throw new \RuntimeException('Failed to save image as WEBP');
|
||||
}
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
if (!imagegif($this->image, $fileName)) {
|
||||
throw new \RuntimeException('Failed to save image as GIF');
|
||||
}
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
if (!imagepng($this->image, $fileName)) {
|
||||
throw new \RuntimeException('Failed to save image as PNG');
|
||||
}
|
||||
break;
|
||||
case IMAGETYPE_JPEG:
|
||||
default:
|
||||
if (!imagejpeg($this->image, $fileName, 95)) {
|
||||
throw new \RuntimeException('Failed to save image as JPEG');
|
||||
}
|
||||
}
|
||||
error_log("Image saved successfully to $fileName");
|
||||
} catch (\Exception $ex) {
|
||||
throw new \RuntimeException('Error saving image file to ' . $fileName . ': ' . $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the GD image resource
|
||||
*
|
||||
* @return resource|\GdImage
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current image width
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getWidth(): int
|
||||
{
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current image height
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getHeight(): int
|
||||
{
|
||||
return $this->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor to clean up the image resource
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if (isset($this->image) && $this->isValidImageResource($this->image)) {
|
||||
imagedestroy($this->image);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compatibility helper for PHP 7.4 (resource) and PHP 8+ (GdImage).
|
||||
*
|
||||
* @param mixed $image
|
||||
*/
|
||||
private function isValidImageResource($image): bool
|
||||
{
|
||||
if (is_resource($image)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return class_exists('GdImage', false) && $image instanceof \GdImage;
|
||||
}
|
||||
}
|
||||
63
autoload/Shared/Tpl/Tpl.php
Normal file
63
autoload/Shared/Tpl/Tpl.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace Shared\Tpl;
|
||||
|
||||
class Tpl
|
||||
{
|
||||
protected $vars = array();
|
||||
|
||||
public static function view($file, $values = '')
|
||||
{
|
||||
$tpl = new self;
|
||||
if (is_array($values)) foreach ($values as $key => $val)
|
||||
$tpl->$key = $val;
|
||||
return $tpl->render($file);
|
||||
}
|
||||
|
||||
public function secureHTML($val)
|
||||
{
|
||||
$out = stripslashes($val);
|
||||
$out = str_replace("'", "'", $out);
|
||||
$out = str_replace('"', """, $out);
|
||||
$out = str_replace("<", "<", $out);
|
||||
$out = str_replace(">", ">", $out);
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function render($file)
|
||||
{
|
||||
$paths = [
|
||||
'templates_user/' . $file . '.php',
|
||||
'templates/' . $file . '.php',
|
||||
'../templates_user/' . $file . '.php',
|
||||
'../templates/' . $file . '.php',
|
||||
$file . '.php',
|
||||
];
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path)) {
|
||||
return $this->renderFile($path);
|
||||
}
|
||||
}
|
||||
|
||||
return '<div class="alert alert-danger" role="alert">Nie znaleziono pliku widoku: <b>' . $file . '.php</b>';
|
||||
}
|
||||
|
||||
private function renderFile($path)
|
||||
{
|
||||
ob_start();
|
||||
include $path;
|
||||
$out = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->vars[$name] = $value;
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->vars[$name];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user