<?PHP
/**
 * Urls        : www.der-dirigent.de
 * Last update : rh - 24.11.2005 - Permissions check für security reasons
 * Part of     : Update to Version 01.00.02
 *
 * Check if backenduser have perm to edit contentfield
 *
 * @Args: config - attribute form mod config -> modcontent is editable/ uneditable
 *        tag_attribute - DEDI:tag attribut editable
 *        view - the current userview
 * @Return boolean
 * @Access private
 */
if (!is_object($perm)) die();
function _type_check_editable($config, $tag_attribute, $view, $edit_all=false) {
	global $perm;

	if ($config != true) return false;
	if ($view != 'edit') return false;
	if ($edit_all) return false;
	if ($tag_attribute == 'false') return false;
	if ($tag_attribute == 'true' || empty($tag_attribute)) return true;
	if (_type_check_perm($tag_attribute)) return true;
	return false;
}

function _type_check_editall($dedi_side, $type_config) {
	if (!_type_check_perm($type_config['editable'])) return false;
	if ($dedi_side['view'] == 'edit' && isset($dedi_side['edit']) || ($type_config['editable'] != 'false' || isset($dedi_side['edit_all']))) return true;
	return false;
}

function _type_check_perm($string_to_check) {
	global $perm;

	if (stristr($string_to_check , ',') || is_numeric( trim($string_to_check))) {
		$string_to_check = str_replace(' ', '', $string_to_check);
		$checkme = explode(',', $string_to_check);
		if (in_array($perm->idgroup, $checkme) || $perm->is_admin()) return true;
		return false;
	}
	return true;
}

/**
 * Check DEDI:tag Attributes styleclass, styleid, styledb and returns style with the highest
 * priority
 *
 * @Args: DEDI:tag attributes styleclass, styleid, styledb
 * @Return array ['style'] = 'iamastyle'
 *               ['type'] = 'class|id'
 *               ['fullstyle'] = 'class="iAmAClass"|id="iAmAnId"'
 * @Access private
 */
function _type_get_style($class = '', $id='', $dbstyle='') {
	global $db, $dedi_db, $idlay, $client;

	$css = $class;

	// Style from DB have highest priority
	if (is_numeric($dbstyle)) {
		$sql = "SELECT A.type, A.name FROM ".$dedi_db['css']." A LEFT JOIN ".$dedi_db['css_upl']." B USING(idcss) LEFT JOIN ".$dedi_db['lay_upl']." C USING(idupl) WHERE A.idclient = $client AND C.idlay = $idlay AND B.idcssupl=$dbstyle";
		$db->query($sql);
		if ($db->next_record()) {
			$out['style'] = $db->f('name');
			$out['type'] = ($db->f('type') == '#') ? 'id': ($db->f('type') == '.') ? 'class': 'ERROR-typeIsNotClassAndNotId';
			$out['fullstyle'] = $out['type'] .'="'. $out['style'] . '"';
			return $out;
		}
	}

	// Second priority is styleid
	if (!empty($id)) {
		$out['style'] = $id;
		$out['type'] = 'id';
		$out['fullstyle'] = $out['type'] .'="'. $out['style'] . '"';
		return $out;
	}

	// Last priority is styleclass
	if (!empty($class)) {
		$out['style'] = $class;
		$out['type'] = 'class';
		$out['fullstyle'] = $out['type'] .'="'. $out['style'] . '"';
		return $out;
	}
	return '';
}

function _type_get_stylelist($parameters) {
	global $db, $dedi_db, $client;

	$type_operator = "'.'";
	if (empty($parameters)) return;
	$sql = "SELECT CU.idcssupl, C.type, C.name, C.description, C.styles
         	FROM ".$dedi_db['css']." C
                 LEFT JOIN ".$dedi_db['css_upl']." CU USING(idcss)
                 WHERE C.type = $type_operator
                 AND C.idclient = $client
                 AND CU.idcssupl IN($parameters)
                 ORDER BY C.description, C.name";
	$db->query($sql);
	for ($i=0; $db->next_record(); $i++) {
		$out[$i]['idcssupl'] = $db->f('idcssupl');
		$out[$i]['type'] = $db->f('type');
		$out[$i]['name'] = $db->f('name');
		$out[$i]['desc'] = $db->f('description');
		$out[$i]['autodesc'] = ( empty($out[$i]['desc']) ) ? $out[$i]['name']:$out[$i]['desc'];
		$out[$i]['style'] = $db->f('styles');
	}
	return $out;
}

function _type_get_stylesheet() {
	global $db, $dedi_db, $idcatside, $lang, $cfg_client, $cache;

	if (!$cache['stylesheet']) {
		$sql = "SELECT G.dirname, F.filename
                 	FROM ".$dedi_db['cat_side']." A
                         LEFT JOIN ".$dedi_db['side_lang']." B USING(idside)
                         LEFT JOIN ".$dedi_db['tpl_conf']." C USING(idtplconf)
                         LEFT JOIN ".$dedi_db['tpl']." D USING(idtpl)
                         LEFT JOIN ".$dedi_db['lay_upl']." E USING(idlay)
                         LEFT JOIN ".$dedi_db['upl']." F USING(idupl)
                         LEFT JOIN ".$dedi_db['directory']." G USING(iddirectory)
                         WHERE A.idcatside='$idcatside'
                         AND B.idlang='$lang'
                         AND B.idtplconf!='0'
                         AND F.idfiletype='1'";
		$db->query($sql);
		if (!$db->affected_rows()) {
			$sql = "SELECT G.dirname, F.filename
                         	FROM ".$dedi_db['cat_side']." A
                                 LEFT JOIN ".$dedi_db['cat_lang']." B USING(idcat)
                                 LEFT JOIN ".$dedi_db['tpl_conf']." C USING(idtplconf)
                                 LEFT JOIN ".$dedi_db['tpl']." D USING(idtpl)
                                 LEFT JOIN ".$dedi_db['lay_upl']." E USING(idlay)
                                 LEFT JOIN ".$dedi_db['upl']." F USING(idupl)
                                 LEFT JOIN ".$dedi_db['directory']." G USING(iddirectory)
                                 WHERE A.idcatside='$idcatside'
                                 AND B.idlang='$lang'
                                 AND B.idtplconf!='0'
                                 AND F.idfiletype='1'";
			$db->query($sql);
		}
		$cache['stylesheet_files'] = '';
		while ($db->next_record()) $cache['stylesheet_files'] .= "<link rel=\"StyleSheet\" href=\"".$cfg_client['htmlpath'].$db->f('dirname').$db->f('filename')."\" type=\"text/css\">";
		$cache['stylesheet'] = 'true';
	}
	return $cache['stylesheet_files'];
}


/**
 * Extract fileinfos in the light of maded  DEDI:tag attributes settings filetypes, folders and subfolders
 * This settings are in use in the DEDI:tag image, file, wysiwyg...
 *
 * @Args:  string filetypes - idfiletypes (comma seperated or empty)
 *         string folders - iddirectories (comma seperated or empty)
 *         string subfolders - if true subdirectorys of folders will extracted too
 * @Return array [$i]['id'] - idupload from table dedi_upload
 *               [$i]['dirname'] - full directory relative from $dedi_client['upl_path']
 *               [$i]['filename'] - filename
 *               [$i]['pic_width'] - if picture, width of the picture
 *               [$i]['pic_height'] - if picture, height of the picture
 *               [$i]['pic_thumb_width'] - if picture, thumbwidth, if no thumbnail available, width is 0
 *               [$i]['pic_thumb_height'] - if pictur, thumbheight, if no thumbnail available, height is 0
 *               [$i]['titel'] - title from filebrowser titelfield
 *               [$i]['name'] = contract of dirname, filename and (optionally if not empty) titel
 * @Access private
 */
function _type_get_files($filetypes , $folders, $subfolders) {
	global $db, $dedi_db, $dedi_lang, $client, $perm;

	//Eventuell vorangehende Kommas aus mip-forms strippen
	if (substr($filetypes,0,1) == ',') $filetypes = substr($filetypes,1);
	if (substr($folders,0,1) == ',') $folders = substr($folders,1);
	if (!empty($filetypes)) {
		$sql_filetypes = '';
		$exploded = explode(',', $filetypes);
		while (list ($key, $value) = each($exploded)) $sql_filetypes .= "'" . trim($value) . "',";
		$sql_filetypes = substr ($sql_filetypes, 0, strlen($sql_filetypes)-1);
	}
	$sql_filetypes = (empty($filetypes) || $filetypes == 'true' ) ? '': ' AND B.filetype IN ('. $sql_filetypes .') ';
	$sql_folders = (empty($folders) || $folders == 'true' ) ? '': ' AND C.iddirectory IN ('. $folders .') ';

	// user have rights to show subdirectorys, figure they out
	if (trim($subfolders) == 'true' && ! empty($sql_folders)) {
		$sql = "SELECT DISTINCT iddirectory, dirname
			FROM ".$dedi_db['directory']." C
			WHERE idclient= '$client' $sql_folders";
		$db -> query($sql);
		for ($i=0; $db->next_record(); $i++) {
			if (!$perm->have_perm( 1, 'folder', $db->f('iddirectory'))) {
				$i--;
				continue;
			}
			$subfolder_list[$i] = "C.dirname like '". $db->f('dirname') ."%'";
		}
		$sql_folders = 'AND '.implode(' AND ', $subfolder_list);
	}
	$sql = "SELECT A.*, B.filetype, C.dirname, C.iddirectory
		FROM ".$dedi_db['upl']." A
		LEFT JOIN ".$dedi_db['filetype']." B USING(idfiletype)
		LEFT JOIN ".$dedi_db['directory']." C ON A.iddirectory=C.iddirectory $access_sql
		WHERE A.idclient= '$client'
		AND C.dirname NOT LIKE('cms/%')
		$sql_filetypes
		$sql_folders
		ORDER BY C.dirname, A.filename, A.titel";
	$db -> query($sql);
	for($i=0; $db -> next_record(); $i++) {
		if (!$perm->have_perm( 17, 'file', $db->f('idupl'), $db->f('iddirectory'))) {
			$i--;
			continue;
		}
		$file_list[$i]['id'] = $db->f('idupl');
		$file_list[$i]['dirname'] = $db->f('dirname');
		$file_list[$i]['filename'] = $db->f('filename');
		$file_list[$i]['pic_width'] = $db->f('pictwidth');
		$file_list[$i]['pic_height'] = $db->f('pictheight');
		$file_list[$i]['pic_thumb_height'] = $db->f('pictthumbheight');
		$file_list[$i]['pic_thumb_width'] = $db->f('pictthumbwidth');
		$titel_temp = $db->f('titel');
		$file_list[$i]['titel'] = ($titel_temp == '') ? '': '[ ' . $db->f('titel') .' ]';
		$file_list[$i]['name'] = $file_list[$i]['dirname'] . $file_list[$i]['filename'] . $file_list[$i]['titel'];
		$subfolder_list[$i] = "C.dirname like '". $file_list[$i]['dirname'] ."%'";
	}
	return $file_list;
}

/**
 * Extract folderinfos in the light of maded  DEDI:tag attributes settings folders and subfolders
 * This settings are in use in the DEDI:tag image, file, wysiwyg...
 *
 * @Args:  string folders - iddirectories (comma seperated for some or empty for all folders)
 *         string subfolders - if true subdirectorys of folders will extracted too
 * @Return array [$i]['id'] - iddirectory from table dedi_directory
 *               [$i]['dirname'] - full directory relative from $dedi_client['upl_path']
 */
function _type_get_folders($folders = '', $subfolders = 'true') {
	global $db, $dedi_db, $dedi_lang, $client, $perm;

	// Eventuell vorangehende Kommas aus mip-forms strippen
	if (substr($folders,0,1) == ',') $folders = substr($folders,1);
	$sql_folders = (empty($folders) || trim($folders) == 'true' ) ? '': ' AND C.iddirectory IN ('. $folders .') ';

	// user have rights to show subdirectorys, figure they out
	if (trim($subfolders) == 'true' && ! empty($sql_folders)) {
		$sql = "SELECT DISTINCT iddirectory, dirname
			FROM ".$dedi_db['directory']." C
			WHERE idclient= '$client' $sql_folders";
		$db->query($sql);
		for($i=0; $db -> next_record(); $i++) {
			if (!$perm->have_perm( 1, 'folder', $db->f('iddirectory'))) {
				$i--;
				continue;
			}
			$subfolder_list[$i] = "C.dirname like '". $db->f('dirname') ."%'";
		}
		$sql_folders = 'AND '.implode(' OR ', $subfolder_list);
	}
	$sql = "SELECT C.iddirectory, C.dirname
		FROM ".$dedi_db['directory']." C
		WHERE C.idclient= '$client'
		AND C.dirname NOT LIKE('cms/%')
		$sql_folders
		ORDER BY C.dirname";
	$db->query($sql);
	for ($i=0; $db->next_record(); $i++) {
	    	if (!$perm->have_perm( 1, 'folder', $db->f('iddirectory'))) {
			$i--;
			continue;
		}
		$folder_list[$i]['id'] = $db->f('iddirectory');
		$folder_list[$i]['dirname'] = $db->f('dirname');
	}
	return $folder_list;
}

/**
 * Get values for new width and new height of an existing image.
 * One of the inputvalues $new_width and $new_height must be set or an
 * erreor occur. If you would like to set booth values, it's fine but
 * not necessary.
 *
 * @Args:  int original_width - width of the given image
 *         int original_height - height of the given image
 *         int new_width - new width
 *         int new_height - new height
 *         boolean aspectratio - calculate new imagesize by aspectratio
 * @Return array ['width'] - new width of an image
 *               ['height'] - new height of an image
 *         OR
 *         boolean false - if an error occur
 * @Access private
 */
function _type_calculate_new_image_size($original_width, $original_height, $new_width = '', $new_height = '', $aspectratio = false) {
	if( empty($new_width) && empty($new_height)) return false;
	if( empty($original_width) ||  empty($original_height) ) return false;

	// calculate without aspectratio
	if ($aspectratio != 'true') {
		$out['width'] = (empty($new_width)) ? $original_width: $new_width;
		$out['height'] = (empty($new_height)) ? $original_height: $new_height;
	// calculate with aspectratio
	} else {
		$calculate_height_by_width = round( ($new_width / $original_width) * $original_height, 0);
		$calculate_width_by_height = round( ($new_height / $original_height) * $original_width, 0);
		if (!empty($new_width) && ! empty($new_height)) {
			// resize by height
			if ($calculate_height_by_width > $new_height) {
				$out['width'] = $calculate_width_by_height;
				$out['height'] = $new_height;
			// resize by width
			} else {
				$out['width'] = $new_width;
				$out['height'] = $calculate_height_by_width;
			}
		// by width
		} else if (empty($new_height)) {
			$out['width'] = $new_width;
			$out['height'] = $calculate_height_by_width;
		// by height
		} else if (empty($new_width)) {
			$out['width'] = $calculate_width_by_height;
			$out['height'] = $new_height;
		// how did you create this nonsens?
		} else return false;
	}
	return $out;
}



/**
* Generate the menus for the dedi:tag- elements
*
* @vars   array ids - the ids of the element taken from the idtype from the
*                     table dedi_types
*                  array infos['container_number']
*                    ['deditag_id']
*                    ['pre_compiled'] - full editstring, used by typegroup and edit_container
*                    ['mod_repeat_id']
*                    ['title']
*                    ['base_url']
*                    ['mode']
*         bool delete
*         bool new
*         bool up
*         bool down
*         bool inline
*/
function _type_get_layer_menu($ids, $infos, $delete, $new, $up, $down, $inline=false) {
	global $p_menu, $cfg_dedi, $mod_lang;

	if (!is_object($p_menu)) {
		include_once($cfg_dedi['dedi_path'].'inc/class.popupmenubuilder_js.php');
		$p_menu = new popupmenubuilder_js();
		$p_menu->set_image('cms/img/but_edit.gif', 18, 14);
	}

	// generate sublink {typeid}-{mod_repeat_id},{typeid}-{mod_repeat_id}...
	// generate edit-sublink for normal contentelements, like, text, wysiwyg, image...
	if (empty($infos['pre_compiled'])) {
		$subs = array();
		foreach ($ids AS $v) array_push($subs, $v.'-'.$infos['deditag_id']);
		$subs_to_string = implode(',', $subs);
	// special content generation for typegroup and edit_container
	} else {
		$subs_to_string = $infos['pre_compiled'];
		//container und repeat id, sind bei precompielt schon vorhanden und sind daher
		//später doppelt, müssen daher ersetzt werden
		if ($infos['tag_type'] == 'edit_container') {
			$to_replace = $infos['container_number'].'.'.$infos['mod_repeat_id'];
			$subs_to_string = substr ($subs_to_string,  strlen ($to_replace)+1);
		}
	}

	// generate menu
	$p_menu->add_title($infos['title']);
	if ($inline) $p_menu->add_entry($mod_lang['type_save'], $infos['base_url'], '_self', $mod_lang['type_save'],
		'con_setcontent('.$infos['container_number'].','.$infos['mod_repeat_id'].','.$ids['0'].','.$infos['deditag_id'].');return;');
	$p_menu->add_entry($mod_lang['type_edit'],
		$infos['base_url'] .'&action=edit&content='.$infos['container_number'].'.'
		.$infos['mod_repeat_id'].'.'.$subs_to_string,'_self', $mod_lang['type_edit']);
	if ($infos['mode'] == 'advanced') {
		if($new || $delete || $up || $down) $p_menu->add_seperator();
		if ($new) $p_menu->add_entry(
			$mod_lang['type_new'], $infos['base_url'].'&action=new&entry='.$infos['mod_repeat_id'].'&content='
			.$infos['container_number'].'.new.'.$subs_to_string, '_self', $mod_lang['type_new']);
		if ($delete) $p_menu->add_entry(
			$mod_lang['type_delete'], $infos['base_url'].'&action=delete&content='
			.$infos['container_number'].'.'.$infos['mod_repeat_id'], '_self', $mod_lang['type_delete'], 'if(delete_confirm())');
		if ($up) $p_menu->add_entry(
			$mod_lang['type_up'], $infos['base_url'].'&action=move_up&content='
			.$infos['container_number'].'.'.$infos['mod_repeat_id'], '_self', $mod_lang['type_up']);
		if ($down) $p_menu->add_entry(
			$mod_lang['type_down'], $infos['base_url'].'&action=move_down&content='
			.$infos['container_number'].'.'.$infos['mod_repeat_id'], '_self', $mod_lang['type_down']);
	}
	return $p_menu->get_menu_and_flush();
}

/**
* Catch vars and arrays from the deditag attributes. Returns a string wich must
* execute with eval() in the type-function, to get the dynamic values
*
*
* @vars   array type_config - dedi:tag attributes
* @return string
*/
function _type_get_dynamic_val_string($type_config) {
        $to_eval = '';
        foreach($type_config AS $k=>$v){
                if(preg_match("/^\\$/", $v)) {
                        //globa delaration for array or single_var?
                        preg_match("/^\\$([^\\[]*)/", $v, $my_global);
                        $to_eval .= "global $".$my_global['1'].";\n";
                        $to_eval .= '$type_config["'.$k.'"] = '.$v.';'."\n";
                        //eval($to_eval);
                        //$type_config[$k] = $extracted_var;
                }
        }
        return $to_eval;
}

function type_validate_color($s) {
        $regex = '#[0-9a-fA-F]{6}';
        return preg_match("/^$regex$/", $s);
}

// Quelle: http://aktuell.de.selfhtml.org/tippstricks/programmiertechnik/email/index.htm
function type_validate_email($s) {
	$nonascii = "\x80-\xff"; // Non-ASCII-Chars are not allowed
	$nqtext = "[^\\\\$nonascii\015\012\"]";
	$qchar = "\\\\[^$nonascii]";
	$protocol = '(?:mailto:)';
	$normuser = '[a-zA-Z0-9][a-zA-Z0-9_.-]*';
	$quotedstring = "\"(?:$nqtext|$qchar)+\"";
	$user_part = "(?:$normuser|$quotedstring)";
	$dom_mainpart = '[a-zA-Z0-9][a-zA-Z0-9._-]*\\.';
	$dom_subpart = '(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\\.)*';
	$dom_tldpart = '[a-zA-Z]{2,5}';
	$domain_part = "$dom_subpart$dom_mainpart$dom_tldpart";
	$regex = "$protocol?$user_part\@$domain_part";
	return preg_match("/^$regex$/", $s);
}

function type_validate_anchorid($s) {
	$regex = '#?[a-zA-Z][a-zA-Z0-9.:,-]*';
	return preg_match("/^$regex$/", $s);
}

function type_validate_linkdest($s, $allowurl) {
	global $con_side;

	if (is_numeric($s)) return isset($con_side[(int)$s]);
	elseif ($allowurl) return type_validate_url($s);
}

function type_validate_url($s) {
	$regex = "^(http|https|ftp):\/\/(?:[a-zA-Z0-9][a-zA-Z0-9._-]*\.)*[a-zA-Z0-9][a-zA-Z0-9._-]*\.[a-zA-Z]{2,5}\/?[\x21\x23-\x3B\x3D\x3F-\x7E]*$";
	return preg_match("/$regex/", $s);
}

function type_convertlinebreaks($text) {
	return preg_replace("/\015\012|\015|\012/", "\n", $text);
}

$type_fileinfo = array();
function type_get_fileinfo($idupl) {
	global $db, $dedi_db, $cfg_client;

	$sql = "SELECT A.filename filename, A.titel titel, A.description description, A.filesize, B.dirname dirname, C.filetype type, C.description typedesc
         	FROM ".$dedi_db['upl']." AS A,
                 ".$dedi_db['directory']." AS B,
                 ".$dedi_db['filetype']." AS C
                 WHERE A.idupl = $idupl
                 AND B.iddirectory = A.iddirectory
                 AND C.idfiletype = A.idfiletype";
	$db -> query($sql);
	if ($db -> next_record()) {
		return array(
			'FILENAME' => $db -> f('filename'),
			'TITLE' => $db -> f('titel'),
			'DESC' => $db -> f('description'),
			'SIZE' => $db -> f('filesize'),
			'TYPE' => $db -> f('type'),
			'TYPEDESC' => $db -> f('typedesc'),
			'LINK' => $cfg_client['upl_htmlpath'].$db -> f('dirname').$db -> f('filename'));
	}
}

function type_get_fileurl($idupl) {
	global $type_fileinfo;

	if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	return $type_fileinfo[$idupl]['LINK'];
}

function type_get_filename($idupl) {
	global $type_fileinfo;

	if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	return $type_fileinfo[$idupl]['FILENAME'];
}

function type_get_filesize($idupl) {
	global $type_fileinfo;

         if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	$bytes = $type_fileinfo[$idupl]['SIZE'];
	$formats = array("%d Bytes", "%.1f KB", "%.1f MB", "%.1f GB", "%.1f TB");
	$logsize = min((int)(log($bytes)/log(1024)), count($formats)-1);
	return sprintf( $formats[$logsize], $bytes/pow(1024, $logsize));
}

function type_get_filetype($idupl) {
	global $type_fileinfo;

         if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	return $type_fileinfo[$idupl]['TYPE'];
}

function type_get_filetypedesc($idupl) {
	global $type_fileinfo;

	if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	return $type_fileinfo[$idupl]['TYPEDESC'];
}

function type_get_filedesc($idupl) {
	global $type_fileinfo;

	if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	return $type_fileinfo[$idupl]['DESC'];
}

function type_get_filetitle($idupl) {
	global $type_fileinfo;

	if(!isset($type_fileinfo[$idupl])) $type_fileinfo[$idupl] = type_get_fileinfo($idupl);
	return $type_fileinfo[$idupl]['TITLE'];
}

function type_validate_imgsrc($s) {
	return true;
}

function type_get_sideurl($idcatside) {
	global $con_side;

	return $con_side[$idcatside]['link'];
}

function type_get_sidename($idcatside) {
	global $con_side;

	return $con_side[$idcatside]['name'];
}

function type_convert_php($str) {
	return str_replace(array('<?', '?>'), array('&lt;?', '?&gt;'), $str);
}

function type_xhtml_highlight($str) {
	if(substr(trim($str), 0, 2) != '<?') $str = '<?PHP ' . $str . '?>';
	$str = highlight_string($str, true);
	$str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
	$str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
	return $str;
}

function type_replace_nls_xhtml($s) {
	return str_replace("\n", "<br />\n", $s);
}

function type_replace_nls($s) {
	return str_replace("\n", "<br>\n", $s);
}

$__bbcode_named_entities = '';
function initNamedEntities() {
	global $__bbcode_named_entities, $cfg_dedi, $lang_charset;
	require_once($cfg_dedi['dedi_path'].'tpl/'.$cfg_dedi['skin'].'/lang/'.$cfg_dedi['backend_lang'].'_'.$lang_charset.'/'.'lang_entities.php');
	$__bbcode_named_entities = '|' . implode('|', array_keys(get_named_entites()));
}

// Diese Funktion wandelt <, > und & in Entitäten um, lässt jedoch ein
// & passieren, wenn es Teil einer Numerischen oder Hexadezimalen
// Entität ist. Damit lassen sich weiterhin alle Unicode-Sonderzeichen
// einfügen.
function specialchars($str) {
	global $__bbcode_named_entities;

	$str = preg_replace('/&(?!#\d{1,5};|#x[0-9A-F]{1,4}'.$__bbcode_named_entities.';)/is', '&amp;', $str);
	$str = str_replace(array('<', '>'), array('&lt;', '&gt;'), $str);
	return $str;
}
?>