<?php
function url_slug($str){
	$search = array("ß",	"ä",	"ö",	"ü",	"Ä",	"Ö",	"Ü");
	$dst 		= array("ss",	"ae",	"oe",	"ue",	"ae",	"oe",	"ue");
	$src = array();
	foreach ($search AS $item){
		$src[] = mb_convert_encoding($item, 'UTF-8', 'ISO-8859-1');
	}
	$str = str_replace($src, $dst, $str);
	
	if($str !== mb_convert_encoding( mb_convert_encoding($str, 'UTF-32', 'UTF-8'), 'UTF-8', 'UTF-32') )
	$str = mb_convert_encoding($str, 'UTF-8', mb_detect_encoding($str));
	$str = str_replace($search, $dst, $str);
	$str = htmlentities($str, ENT_NOQUOTES, 'UTF-8');
	$str = preg_replace('`&([a-z]{1,2})(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig);`i', '\1', $str);
	$str = html_entity_decode($str, ENT_NOQUOTES, 'UTF-8');
	$str = preg_replace(array('`[^a-z0-9_]`i','`[-]+`'), '-', $str);
	$str = strtolower( trim($str, '-') );
	return $str;
}

function title_tag($str){
	$str = strip_tags($str);
	$str = str_replace(array("\r\n", "\n", "\r"), ' ', $str);
	return $str;
}

function isPartUppercase($string) {
    return (bool) preg_match('/[A-Z]/', $string);
}

function str_replace_first($from, $to, $content) {
	$from = '/'.preg_quote($from, '/').'/';
	return preg_replace($from, $to, $content, 1);
}

function is_dir_empty($dir) {
	if (is_dir($dir)){
  	return (count(scandir($dir)) == 2);
  } else return false;
}

function format_dynamic($value, $max_decimals = 5) {
	$rounded = round((float)$value, $max_decimals);
	$formatted = rtrim(rtrim(number_format($rounded, $max_decimals, ',', ''), '0'), ',');
	$parts = explode(',', $formatted);
	if (count($parts) === 2 && strlen($parts[1]) > 2) {
		return $formatted;
	}
	return number_format($rounded, 2, ',', '');
}

function array_multi_diff($array1, $array2) {
	$result = array();
	foreach($array1 AS $key => $a1) {
		if (!array_key_exists($key, $array2)) {
			$result[$key] = $a1;
			continue;
		}
		$a2 = $array2[ $key ];
		if (is_array($a1)) {
			$recc_array = array_multi_diff($a1, $a2);
			if (!empty($recc_array)) {
				$result[$key] = $recc_array;
			}
		} else if ($a1 != $a2) {
			$result[$key] = $a1;
		}
	}
	return $result;
}

function id($label){
	if (defined($label)) return constant($label);
	else return $label;
}

function media_duplicates($array){
	return $result = array_reverse(array_values(array_column(array_reverse($array), null, 'id_media')));
}

function check_url($module, $url, $num = NULL){
	global $conn;
	$sep = NULL;
	if ($num != NULL) $sep = "-".$num;
	$sql_tmp = "SELECT id FROM ".$module." WHERE url = :url LIMIT 1";
	$result_tmp = $conn->prepare($sql_tmp);
	$result_tmp->bindValue(':url', $url.$sep, PDO::PARAM_STR);
	$result_tmp->execute();
	if ($result_tmp->rowCount()){
		if ($num != NULL) $num++;
		else $num = 1;
		return check_url($module, $url, $num);
	}
	return $url.$sep;
}

function check_file($module, $file, $extension, $num = NULL){
	global $conn;
	$sep = NULL;
	if ($num != NULL) $sep = "_".$num;
	$sql_tmp = "SELECT id FROM ".$module." WHERE file = :file LIMIT 1";
	$result_tmp = $conn->prepare($sql_tmp);
	$result_tmp->bindValue(':file', $file.$sep.".".$extension, PDO::PARAM_STR);
	$result_tmp->execute();
	if ($result_tmp->rowCount()){
		if ($num != NULL) $num++;
		else $num = 1;
		return check_file($module, $file, $extension, $num);
	}
	return $file.$sep.".".$extension;
}

function get_children_levels(array &$data, $module, $guidv4 = NULL){
	global $conn;
	if ($guidv4 !== NULL) $sql = "SELECT guidv4 FROM ".$module." WHERE parent_guidv4 = :guidv4 GROUP BY guidv4";
	else $sql = "SELECT guidv4 FROM ".$module." WHERE parent_guidv4 IS NULL GROUP BY guidv4";
	$result = $conn->prepare($sql);
	if ($guidv4 !== NULL) $result->bindValue(':guidv4', $guidv4, PDO::PARAM_STR);
	$result->execute();
	if ($result->rowCount()){
		while ($arr = $result->fetch()){
			$data[] = $arr['guidv4'];
			get_children_levels($data, $module, $arr['guidv4']);
		}
	}
	return $data;
}

function get_parent_levels($module, $guidv4){
	$data = array();
	$has = true;
	$data[] = $guidv4;
	while($has){
		$guidv4 = get_parent_level($module, $guidv4);
		if ($guidv4) $data[] = $guidv4;
		else $has = false;
	}
	$data = array_reverse($data);
	return $data;
}

function get_parent_level($module, $guidv4){
	global $conn;
	$sql = "SELECT parent_guidv4 FROM ".$module." WHERE c_active = '1' AND guidv4 = :guidv4 LIMIT 1";
	$result = $conn->prepare($sql);
	$result->bindValue(':guidv4', $guidv4, PDO::PARAM_STR);
	$result->execute();
	if ($result->rowCount()){
		$arr = $result->fetch();
		if (isset($arr['parent_guidv4']) && $arr['parent_guidv4']) return $arr['parent_guidv4'];
		else return false;
	} else return false;
}

function build_tree(array &$elements, $label = false, $parent_guidv4 = NULL, $path = NULL) {
	$data = array();
	foreach ($elements AS &$element) {
		if ($element['parent_guidv4'] == $parent_guidv4){
			if ($path) $children = build_tree($elements, $label, $element['guidv4'], $path."/".$element['title']);
			else $children = build_tree($elements, $label, $element['guidv4'], $element['title']);
			if ($children) $element['children'] = $children;
			$new['name'] = $element['title'];
			$new['value'] = $element['guidv4'];
			if ($label === true) $new['label'] = $element['title'];
			
			if (isset($element['children']) && $element['children']) {
				if ($label === true) {
					foreach ($element['children'] AS $key => $value){
						if ($path) $element['children'][$key]['label'] = $path."/".$element['title']."/".$value['label'];
						else $element['children'][$key]['label'] = $element['title']."/".$value['label'];
					}
				}
				$new['children'] = $element['children'];
			}
			
			$data[] = $new;
			unset($new, $element, $children);
		}
	}
	return $data;
}

function getNextNumber($module, $column, $prefix, $default, $length = 4){
	global $conn;
	$sql = "SELECT ".$column." FROM ".$module." WHERE ".$column." LIKE :pattern ORDER BY ".$column." DESC LIMIT 1";
	$result = $conn->prepare($sql);
	$result->bindValue(':pattern', $prefix.'%');
	$result->execute();
	if ($result->rowCount()){
		$arr = $result->fetch();
		return (int) substr($arr[$column], - $length) + 1;
	}
	return $default;
}

function generateFormattedNumber($pattern, $id = NULL, $module = NULL, $column = NULL, $timestamp = NULL){
	global $conn;
	
	$timestamp = $timestamp ?? time();
	$year = date('Y', $timestamp);
	$year_short = date('y', $timestamp);
  $month = date('m', $timestamp);
  $day = date('d', $timestamp);
	$week = date('W', $timestamp);
  
	$replacements = [
    '[YEAR]'  => $year,
    '[YEAR2]' => $year_short,
    '[MONTH]' => $month,
    '[DAY]'   => $day,
		'[WEEK]'  => $week,
		'[RAND]'  => rand(0, 9),
  ];
  
  if ($id !== null) {
    $replacements['[ID]'] = $id;
	}
  
  $return = strtr($pattern, $replacements);
  
  $return = preg_replace_callback('/\[ID(\d+)\]/', function($m) use ($id) {
  	if ($id === null) return $m[0];
		$padLength = (int) $m[1];
		return str_pad($id, $padLength, '0', STR_PAD_LEFT);
	}, $return);

	$return = preg_replace_callback('/\[RAND(\d+)\]/', function($m) {
		$length = (int) $m[1];
		$max = pow(10, $length) - 1;
		$rand = rand(0, $max);
		return str_pad($rand, $length, '0', STR_PAD_LEFT);
	}, $return);
  
  $return = preg_replace_callback('/\[NR(\d+)(?::(\d+))?\]/', function($matches) use ($module, $column, $pattern, $replacements) {
  	$length = (int)$matches[1];
  	$default = isset($matches[2]) ? (int) $matches[2] : 1;
  	
  	$placeholder = $matches[0];
		$matchStart = strpos($pattern, $placeholder);
		$prefixRaw = substr($pattern, 0, $matchStart);
		
  	$prefix = strtr($prefixRaw, $replacements);

		$number = getNextNumber($module, $column, $prefix, $default, $length);
    return str_pad($number, $length, '0', STR_PAD_LEFT);
  
  }, $return);
  
  return $return;
}


function pw_security($passw, $length = 6){
	$security = 0;
	if (!$passw) return false;
	if (strlen($passw) < $length){        // Passwort zu kurz
		return false;
	}
	if (preg_match('/[[:alpha:]]/', $passw)) $security+=2;
	if (preg_match('/[[:digit:]]/', $passw)) $security+=1;
	if (preg_match('/[[:upper:]]/', $passw) && preg_match('/[[:lower:]]/', $passw)) $security+=3;
	if (preg_match('/[[:punct:]]/', $passw)) $security+=4;
	$security += round((strlen($passw) - $length) / 2);
	if ($security > 3){ 
		return true;
	} else { 
		return false;
	}
}

function replace_placeholders($title, $data, $delimitter = '-') {
	
	if (!is_string($title)) {
		$title = '';
	}
	
	foreach ($data as $key => $value) {
		if (!empty($value)) {
			$title = str_replace("[$key]", (string) $value, $title);
		}
	}
	
	if (empty($title)) {
		return '';
  }
	
	$title = preg_replace('/\s*\[.*?\]\s*/', '', $title);
	
	if (!isset($delimitter) || !is_string($delimitter)) {
		$delimitter = '-';
	}
	
	$title = str_replace(' ', $delimitter, $title);
	$title = trim(preg_replace('/\s*[-,]\s*/', $delimitter, $title) ?? '', $delimitter);
	
	return $title;
}

function guidv4($data = null) {
  $data = $data ?? random_bytes(16);
  assert(strlen($data) == 16);
  $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
  $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
  return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}

function fix_serialized_string(string $serialized): string {
  return preg_replace_callback('/s:(\d+):"(.*?)";/s', function ($m) {
      return 's:' . strlen($m[2]) . ':"' . $m[2] . '";';
  }, $serialized);
}

function excluded_date($dateObj, $excluded) {
  $d1 = $dateObj->format('d.m');
  $d2 = $dateObj->format('d.m.Y');
  return in_array($d1, $excluded) || in_array($d2, $excluded);
}

function mime2ext($mime, $extension = NULL) {
	$mime_map = [
		'video/3gpp2'                                                               => '3g2',
		'video/3gp'                                                                 => '3gp',
		'video/3gpp'                                                                => '3gp',
		'application/x-compressed'                                                  => '7zip',
		'audio/x-acc'                                                               => 'aac',
		'audio/ac3'                                                                 => 'ac3',
		'application/postscript'                                                    => 'ai',
		'audio/x-aiff'                                                              => 'aif',
		'audio/aiff'                                                                => 'aif',
		'audio/x-au'                                                                => 'au',
		'video/x-msvideo'                                                           => 'avi',
		'video/msvideo'                                                             => 'avi',
		'video/avi'                                                                 => 'avi',
		'application/x-troff-msvideo'                                               => 'avi',
		'application/macbinary'                                                     => 'bin',
		'application/mac-binary'                                                    => 'bin',
		'application/x-binary'                                                      => 'bin',
		'application/x-macbinary'                                                   => 'bin',
		'image/bmp'                                                                 => 'bmp',
		'image/x-bmp'                                                               => 'bmp',
		'image/x-bitmap'                                                            => 'bmp',
		'image/x-xbitmap'                                                           => 'bmp',
		'image/x-win-bitmap'                                                        => 'bmp',
		'image/x-windows-bmp'                                                       => 'bmp',
		'image/ms-bmp'                                                              => 'bmp',
		'image/x-ms-bmp'                                                            => 'bmp',
		'application/bmp'                                                           => 'bmp',
		'application/x-bmp'                                                         => 'bmp',
		'application/x-win-bitmap'                                                  => 'bmp',
		'application/cdr'                                                           => 'cdr',
		'application/coreldraw'                                                     => 'cdr',
		'application/x-cdr'                                                         => 'cdr',
		'application/x-coreldraw'                                                   => 'cdr',
		'image/cdr'                                                                 => 'cdr',
		'image/x-cdr'                                                               => 'cdr',
		'zz-application/zz-winassoc-cdr'                                            => 'cdr',
		'application/mac-compactpro'                                                => 'cpt',
		'application/pkix-crl'                                                      => 'crl',
		'application/pkcs-crl'                                                      => 'crl',
		'application/x-x509-ca-cert'                                                => 'crt',
		'application/pkix-cert'                                                     => 'crt',
		'text/css'                                                                  => 'css',
		'text/x-comma-separated-values'                                             => 'csv',
		'text/comma-separated-values'                                               => 'csv',
		'application/vnd.msexcel'                                                   => 'csv',
		'application/x-director'                                                    => 'dcr',
		'application/vnd.openxmlformats-officedocument.wordprocessingml.document'   => 'docx',
		'application/x-dvi'                                                         => 'dvi',
		'message/rfc822'                                                            => 'eml',
		'application/x-msdownload'                                                  => 'exe',
		'video/x-f4v'                                                               => 'f4v',
		'audio/x-flac'                                                              => 'flac',
		'video/x-flv'                                                               => 'flv',
		'image/gif'                                                                 => 'gif',
		'application/gpg-keys'                                                      => 'gpg',
		'application/x-gtar'                                                        => 'gtar',
		'application/x-gzip'                                                        => 'gzip',
		'application/mac-binhex40'                                                  => 'hqx',
		'application/mac-binhex'                                                    => 'hqx',
		'application/x-binhex40'                                                    => 'hqx',
		'application/x-mac-binhex40'                                                => 'hqx',
		'text/html'                                                                 => 'html',
		'image/x-icon'                                                              => 'ico',
		'image/x-ico'                                                               => 'ico',
		'image/vnd.microsoft.icon'                                                  => 'ico',
		'text/calendar'                                                             => 'ics',
		'application/java-archive'                                                  => 'jar',
		'application/x-java-application'                                            => 'jar',
		'application/x-jar'                                                         => 'jar',
		'image/jp2'                                                                 => 'jp2',
		'video/mj2'                                                                 => 'jp2',
		'image/jpx'                                                                 => 'jp2',
		'image/jpm'                                                                 => 'jp2',
		'image/jpeg'                                                                => 'jpeg',
		'image/pjpeg'                                                               => 'jpeg',
		'application/x-javascript'                                                  => 'js',
		'application/json'                                                          => 'json',
		'text/json'                                                                 => 'json',
		'application/vnd.google-earth.kml+xml'                                      => 'kml',
		'application/vnd.google-earth.kmz'                                          => 'kmz',
		'text/x-log'                                                                => 'log',
		'audio/x-m4a'                                                               => 'm4a',
		'application/vnd.mpegurl'                                                   => 'm4u',
		'audio/midi'                                                                => 'mid',
		'application/vnd.mif'                                                       => 'mif',
		'video/quicktime'                                                           => 'mov',
		'video/x-sgi-movie'                                                         => 'movie',
		'audio/mpeg'                                                                => 'mp3',
		'audio/mpg'                                                                 => 'mp3',
		'audio/mpeg3'                                                               => 'mp3',
		'audio/mp3'                                                                 => 'mp3',
		'video/mp4'                                                                 => 'mp4',
		'video/mpeg'                                                                => 'mpeg',
		'application/oda'                                                           => 'oda',
		'audio/ogg'                                                                 => 'ogg',
		'video/ogg'                                                                 => 'ogg',
		'application/ogg'                                                           => 'ogg',
		'application/x-pkcs10'                                                      => 'p10',
		'application/pkcs10'                                                        => 'p10',
		'application/x-pkcs12'                                                      => 'p12',
		'application/x-pkcs7-signature'                                             => 'p7a',
		'application/pkcs7-mime'                                                    => 'p7c',
		'application/x-pkcs7-mime'                                                  => 'p7c',
		'application/x-pkcs7-certreqresp'                                           => 'p7r',
		'application/pkcs7-signature'                                               => 'p7s',
		'application/pdf'                                                           => 'pdf',
		'application/octet-stream'                                                  => $extension,
		'application/x-x509-user-cert'                                              => 'pem',
		'application/x-pem-file'                                                    => 'pem',
		'application/pgp'                                                           => 'pgp',
		'application/x-httpd-php'                                                   => 'php',
		'application/php'                                                           => 'php',
		'application/x-php'                                                         => 'php',
		'text/php'                                                                  => 'php',
		'text/x-php'                                                                => 'php',
		'application/x-httpd-php-source'                                            => 'php',
		'image/png'                                                                 => 'png',
		'image/x-png'                                                               => 'png',
		'application/powerpoint'                                                    => 'ppt',
		'application/vnd.ms-powerpoint'                                             => 'ppt',
		'application/vnd.ms-office'                                                 => 'ppt',
		'application/msword'                                                        => 'doc',
		'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
		'application/x-photoshop'                                                   => 'psd',
		'image/vnd.adobe.photoshop'                                                 => 'psd',
		'audio/x-realaudio'                                                         => 'ra',
		'audio/x-pn-realaudio'                                                      => 'ram',
		'application/x-rar'                                                         => 'rar',
		'application/rar'                                                           => 'rar',
		'application/x-rar-compressed'                                              => 'rar',
		'audio/x-pn-realaudio-plugin'                                               => 'rpm',
		'application/x-pkcs7'                                                       => 'rsa',
		'text/rtf'                                                                  => 'rtf',
		'text/richtext'                                                             => 'rtx',
		'video/vnd.rn-realvideo'                                                    => 'rv',
		'application/x-stuffit'                                                     => 'sit',
		'application/smil'                                                          => 'smil',
		'text/srt'                                                                  => 'srt',
		'image/svg+xml'                                                             => 'svg',
		'application/x-shockwave-flash'                                             => 'swf',
		'application/x-tar'                                                         => 'tar',
		'application/x-gzip-compressed'                                             => 'tgz',
		'image/tiff'                                                                => 'tiff',
		'text/plain'                                                                => 'txt',
		'text/x-vcard'                                                              => 'vcf',
		'application/videolan'                                                      => 'vlc',
		'text/vtt'                                                                  => 'vtt',
		'audio/x-wav'                                                               => 'wav',
		'audio/wave'                                                                => 'wav',
		'audio/wav'                                                                 => 'wav',
		'application/wbxml'                                                         => 'wbxml',
		'video/webm'                                                                => 'webm',
		'image/webp'																																=> 'webp',
		'audio/x-ms-wma'                                                            => 'wma',
		'application/wmlc'                                                          => 'wmlc',
		'video/x-ms-wmv'                                                            => 'wmv',
		'video/x-ms-asf'                                                            => 'wmv',
		'application/xhtml+xml'                                                     => 'xhtml',
		'application/excel'                                                         => 'xl',
		'application/msexcel'                                                       => 'xls',
		'application/x-msexcel'                                                     => 'xls',
		'application/x-ms-excel'                                                    => 'xls',
		'application/x-excel'                                                       => 'xls',
		'application/x-dos_ms_excel'                                                => 'xls',
		'application/xls'                                                           => 'xls',
		'application/x-xls'                                                         => 'xls',
		'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'         => 'xlsx',
		'application/vnd.ms-excel'                                                  => 'xlsx',
		'application/xml'                                                           => 'xml',
		'text/xml'                                                                  => 'xml',
		'text/xsl'                                                                  => 'xsl',
		'application/xspf+xml'                                                      => 'xspf',
		'application/x-compress'                                                    => 'z',
		'application/x-zip'                                                         => 'zip',
		'application/zip'                                                           => 'zip',
		'application/x-zip-compressed'                                              => 'zip',
		'application/s-compressed'                                                  => 'zip',
		'multipart/x-zip'                                                           => 'zip',
		'text/x-scriptzsh'                                                          => 'zsh',
	];
		
	return isset($mime_map[$mime]) === true ? $mime_map[$mime] : false;
}

function mime2category($mime) {
	if (substr($mime, 0, 6) == 'video/') return 'video';
	else if (substr($mime, 0, 6) == 'audio/') return 'audio';
	else if (substr($mime, 0, 6) == 'image/' && $mime != 'image/cdr' && $mime != 'image/x-cdr' && $mime != 'image/vnd.adobe.photoshop'
	&& $mime != 'image/x-icon' && $mime != 'image/x-ico' && $mime != 'image/vnd.microsoft.icon'
	&& $mime != 'image/jp2'	&& $mime != 'image/mj2'	&& $mime != 'image/jpx'	&& $mime != 'image/jpm'
	&& $mime != 'image/svg+xml'	&& $mime != 'image/tiff') return 'image';
	else if ($mime == 'text/css' OR $mime == 'text/html' OR $mime == 'application/x-javascript' OR $mime == 'application/json' OR $mime == 'text/json' OR $mime == 'application/xhtml+xml') return 'code';
	else if ($mime == 'application/x-httpd-php' OR $mime == 'application/php' OR $mime == 'application/x-php' OR $mime == 'text/php' OR $mime == 'text/x-php') return 'code';
	else if ($mime == 'text/plain') return 'text';
	else if ($mime == 'application/pdf') return 'pdf';
	else return 'file';
}

function deleteFolder($folder_path) {
	if (!is_dir($folder_path)) {
		return false;
  }
  
  $items = scandir($folder_path);
  foreach ($items as $item) {
  	if ($item === '.' || $item === '..') continue;
  	$full_path = $folder_path.DIRECTORY_SEPARATOR.$item;
  	if (is_dir($full_path)) {
  		deleteFolder($full_path);
    } else {
    	chmod($full_path, 0644);
    	unlink($full_path);
    }
  }
  return rmdir($folder_path);
}

function formatSizeUnits($bytes) {
  if ($bytes >= 1073741824) {
  	$bytes = number_format($bytes / 1073741824, 2).' GB';
  } elseif ($bytes >= 1048576) {
		$bytes = number_format($bytes / 1048576, 2).' MB';
	} elseif ($bytes >= 1024) {
		$bytes = number_format($bytes / 1024, 2).' KB';
	} elseif ($bytes > 1) {
		$bytes = $bytes.' bytes';
	} elseif ($bytes == 1) {
		$bytes = $bytes.' byte';
	} else {
		$bytes = '0 bytes';
	}
  return $bytes;
}

function remote_call($url = NULL){
	if ($url != NULL){
		$headers = array('Content-Type:application/json');
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 0);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_POST, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
		$result = curl_exec($ch);
		curl_close($ch);
		if ($result !== FALSE) return json_decode($result);
		else return NULL;
	} else return NULL;
}