BBCode markup; provides automatic integration with lightbox. Part of the standard distribution.
 */
require (plugin_getdir('bbcode') . '/inc/stringparser_bbcode.class.php');
require (plugin_getdir('bbcode') . '/panels/admin.plugin.panel.bbcode.php');
/**
 * Setups the plugin.
 */
function plugin_bbcode_startup() {
	// defintions part
	// load options
	$bbconf = plugin_getoptions('bbcode');
	// get defaults if not configured
	define('BBCODE_ALLOW_HTML', isset($bbconf ['escape-html']) ? $bbconf ['escape-html'] : true);
	define('BBCODE_ENABLE_COMMENTS', isset($bbconf ['comments']) ? $bbconf ['comments'] : false);
	define('BBCODE_USE_EDITOR', isset($bbconf ['editor']) ? $bbconf ['editor'] : true);
	define('BBCODE_URL_MAXLEN', isset($bbconf ['url-maxlen']) ? $bbconf ['url-maxlen'] : 40);
	if (!file_exists('getfile.php')) {
		define('BBCODE_USE_WRAPPER', false);
	} else {
		$funcs = explode(',', ini_get('disable_functions'));
		if (in_array('readfile', $funcs)) {
			define('BBCODE_USE_WRAPPER', false);
		} else {
			define('BBCODE_USE_WRAPPER', true);
		}
	}
	// filter part
	// add_filter('comment_text', 'plugin_bbcode_comment');
	add_filter('title_save_pre', 'wp_specialchars', 1);
	if (!BBCODE_ALLOW_HTML) {
		add_filter('content_save_pre', 'wp_specialchars', 1);
	}
	add_filter('pre_comment_author_name', 'wp_specialchars');
	add_filter('pre_comment_content', 'wp_specialchars');
	add_filter('the_content', 'BBCode', 1);
	add_filter('the_excerpt', 'BBCode', 1);
	add_filter('the_content', 'plugin_bbcode_undoHtml', 30);
	if (BBCODE_USE_EDITOR) {
		add_filter('editor_toolbar', 'plugin_bbcode_toolbar');
	}
	if (BBCODE_ENABLE_COMMENTS) {
		add_filter('comment_text', 'plugin_bbcode_comment', 1);
	}
}
plugin_bbcode_startup();
/**
 * Adds special stlye definitions into the HTML head.
 */
function plugin_bbcode_style() {
	echo "	\n";
	echo '	\n";
	echo "	\n";
}
add_action('wp_head', 'plugin_bbcode_style');
/**
 * Remaps the URL so that there's no hint to your attachs/ directory.
 *
 * @param string $d
 * @return boolean
 */
function bbcode_remap_url(&$d) {
	// NWM: "attachs/" is interpreted as a keyword, and it is translated to the actual path of ATTACHS_DIR
	// CHANGE! we use the getfile.php script to mask the actual path of the attachs dir!
	// DMKE: I got an idea about an integer-id based download/media manager... work-in-progress
	if (strpos($d, ':') === false) {
		// if is relative url
		// absolute path, relative to this server
		if ($d [0] == '/') {
			/*
			 * BLOG_BASEURL contains a trailing slash in the end. If
			 * $d begins with a slash, we first strip it otherwise
			 * the string would look like
			 * http://mysite.com/flatpress//path/you/entered
			 * ^^ ugly double slash :P
			 */
			$d = BLOG_BASEURL . substr($d, 1);
		}
		if (substr($d, 0, 8) == 'attachs/') {
			$d = BBCODE_USE_WRAPPER ? 'getfile.php?f=' . basename($d) . '&dl=true' : substr_replace($d, ATTACHS_DIR, 0, 8);
			return true;
		}
		if (substr($d, 0, 7) == 'images/') {
			$d = substr_replace($d, IMAGES_DIR, 0, 7);
			$d = BBCODE_USE_WRAPPER ? 'getfile.php?f=' . basename($d) : $d;
		}
		return true;
	}
	if (strpos($d, 'www.') === 0) {
		$d = 'http://' . $d;
	}
	return false;
}
/**
 * Function to link documents.
 *
 * @param string $action
 * @param array $attributes
 * @param string $content
 * @param mixed $params
 *        	Not used
 * @param mixed $node_object
 *        	Not used
 * @return string
 */
function do_bbcode_url($action, $attributes, $content, $params, $node_object) {
	if ($action == 'validate') {
		return true;
	}
	// the code was specified as follows: [url]http://.../[/url]
	if (!isset($attributes ['default'])) {
		// cut url if longer than > BBCODE_URL_MAXLEN
		$url = $content;
		if (($l = strlen($url)) > BBCODE_URL_MAXLEN) {
			$t = (int) (BBCODE_URL_MAXLEN / 2);
			$content = substr($url, 0, $t) . ' … ' . substr($url, $l - $t);
		}
	} else {
		// else the code was specified as follows: [url=http://.../]Text[/url]
		$url = $attributes ['default'];
	}
	$local = bbcode_remap_url($url);
	$the_url = $local ? (BLOG_BASEURL . $url) : $url;
	// DMKE: uh?
	$content = $content;
	$rel = isset($attributes ['rel']) ? ' rel="' . $attributes ['rel'] . '"' : '';
	$extern = !$local ? ' class="externlink" title="Go to ' . $the_url . '"' : '';
	return '' . $content . '';
}
/**
 * Function to include images.
 *
 * @param string $action
 * @param array $attributes
 * @param string $content
 * @param mixed $params
 *        	Not used
 * @param mixed $node_object
 *        	Not used
 * @return string
 */
function do_bbcode_img($action, $attributes, $content, $params, $node_object) {
	if ($action == 'validate') {
		return true;
	}
	if (!isset($attributes ['default'])) {
		return '[No valid img specified]';
	}
	$absolutepath = $actualpath = $attributes ['default'];
	// NWM: "images/" is interpreted as a keyword, and it is translated to the actual path of IMAGES_DIR
	$image_is_local = bbcode_remap_url($actualpath);
	$float = ' class="center" ';
	$popup_start = '';
	$popup_end = '';
	$alt = $title = basename($actualpath);
	$useimageinfo = true; // use IPTC info
	if (isset($attributes ['alt'])) {
		$alt = wp_specialchars($attributes ['alt']);
		$useimageinfo = false;
	}
	if (isset($attributes ['title'])) {
		$title = wp_specialchars($attributes ['title']);
		$useimageinfo = false;
	}
	$img_size = array();
	// let's disable socket functions for remote files
	// slow remote servers may otherwise lockup the system
	if ($image_is_local) {
		$img_info = array();
		$img_size = @getimagesize($actualpath, $img_info);
		$absolutepath = BLOG_BASEURL . $actualpath;
		if ($useimageinfo && function_exists('iptcparse')) {
			if ($img_size ['mime'] == 'image/jpeg') {
				// tiffs won't be supported
				if (is_array($img_info)) {
					if (isset($img_info ["APP13"])) {
						$iptc = iptcparse($img_info ["APP13"]);
						$title = @$iptc ["2#005"] [0] ? wp_specialchars($iptc ["2#005"] [0]) : $title;
						$alt = isset($iptc ["2#120"] [0]) ? wp_specialchars($iptc ["2#120"] [0], 1) : $title;
					}
				}
			}
		}
	}
	$orig_w = $width = isset($img_size [0]) ? $img_size [0] : 0;
	$orig_h = $height = isset($img_size [1]) ? $img_size [1] : 0;
	$thumbpath = null;
	// default: resize to 0, which means leaving it as it is, as width and hight will be ignored ;)
	$scalefact = 0;
	/*
	 * scale attribute has priority over width and height if scale is
	 * set popup is set to true automatically, unless it is explicitly
	 * set to false
	 */
	if (isset($attributes ['scale'])) {
		if (substr($attributes ['scale'], -1, 1) == '%') {
			// Format: NN%. We ignore %
			$val = substr($attributes ['scale'], 0, -1);
		} else {
			$val = $attributes ['scale'];
		}
		$scalefact = $val / 100.0;
		$width = (int) ($scalefact * $width);
		$height = (int) ($scalefact * $height);
	} elseif (isset($attributes ['width']) && isset($attributes ['height'])) {
		// if both width and height are set, we assume proportions are ok
		$width = (int) $attributes ['width'];
		$height = (int) $attributes ['height'];
	} elseif (isset($attributes ['width'])) {
		// if only width is set we calc proportions
		$scalefact = $orig_w ? ($attributes ['width'] / $orig_w) : 0;
		$width = (int) $attributes ['width'];
		$height = (int) ($scalefact * $orig_h);
	} elseif (isset($attributes ['height'])) {
		// if only height is set we calc proportions
		$scalefact = $orig_w ? ($attributes ['height'] / $orig_h) : 0;
		$height = (int) $attributes ['height'];
		$width = (int) ($scalefact * $orig_w);
	}
	if ($height < $orig_h) {
		$attributes ['popup'] = true;
	}
	if ($height != $orig_h) {
		// bbcode_img_scale_filter($actualpath, $img_props, $newsize)
		$thumbpath = apply_filters('bbcode_img_scale', $actualpath, $img_size, array(
			$width,
			$height
		));
	}
	// Calculating the "loading" attribute of the image.
	// For details, see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading
	// -> "lazy" is default (see https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading)
	$loadingValue = 'lazy';
	// Use img attribute value if explicitly set
	if (isset($attributes ['loading'])) {
		$loadingValue = $attributes ['loading'];
	}
	$loading = ' loading="' . $loadingValue . '"';
	// JS for popup
	if (isset($attributes ['popup']) && ($attributes ['popup'])) {
		$pop_width = $orig_w ? $orig_w : 800;
		$pop_height = $orig_h ? $orig_h : 600;
		$popup = ' onclick="Popup=window.open("' . $absolutepath . '","Popup","toolbar=no,location=no,status=no,"' . '"menubar=no,scrollbars=yes,resizable=yes,width=' . $pop_width . ',height=' . $pop_height . '"); return false;"';
		// Plugin hook, here lightbox attachs
		$popup = apply_filters('bbcode_img_popup', $popup, $absolutepath);
		$popup_start = $attributes ['popup'] == 'true' ? '' : '';
		$popup_end = $attributes ['popup'] == 'true' ? '' : '';
	}
	$img_width = $width ? ' width="' . $width . '"' : '';
	$img_height = $height ? ' height="' . $height . '"' : '';
	if (isset($attributes ['float'])) {
		$float = ($attributes ['float'] == 'left' || $attributes ['float'] == 'right') ? ' class="float' . $attributes ['float'] . '"' : ' class="center"';
	}
	$src = $thumbpath ? (BLOG_BASEURL . $thumbpath) : $absolutepath;
	$pop = $popup_start ? '' : ' title="' . $title . '" ';
	// Finally: Put together the whole img tag with all its attributes and return it
	return $popup_start . ' ' . $popup_end;
}
/**
 * Function for email links
 *
 * @param string $action
 * @param array $attr
 * @param string $content
 * @param mixed $params
 *        	Not used
 * @param mixed $node_object
 *        	Not used
 * @return string
 */
function do_bbcode_mail($action, $attributes, $content, $params, $node_object) {
	if ($action == 'validate') {
		// not used for now
		return true;
	}
	// obfuscation mode: decimal/hexadecimal ASCII randomly mixed
	$mode = 3;
	// the code was specified as follows: [mail]user@example.org[/mail]
	if (!isset($attributes ['default'])) {
		return "" . obfuscateEmailAddress($content, $mode) . "";
	} else {
		// else the code was specified as follows: [mail=user@example.org]link text[/url]
		return "" . $content . "";
	}
}
/**
 * Function for embedding videos
 *
 * @param string $action
 * @param array $attr
 * @param string $content
 * @param mixed $params
 *        	Not used
 * @param mixed $node_object
 *        	Not used
 * @return string
 */
function do_bbcode_video($action, $attr, $content, $params, $node_object) {
	if ($action == 'validate') {
		return true;
	}
	$vurl = parse_url($attr ['default']);
	if (isset($attr ['type'])) {
		$type = $attr ['type'];
	} else {
		// is it http://www.MYSITE.com or http://MYSITE.com ?
		$web = explode('.', $vurl ['host']);
		array_pop($web);
		$type = isset($web [1]) ? $web [1] : $web [0];
	}
	// Check the [video] element's attributes width, height and float
	$width = isset($attr ['width']) ? $attr ['width'] : '560';
	$height = isset($attr ['height']) ? $attr ['height'] : '315';
	$float = isset($attr ['float']) ? 'align="' . $attr ['float'] . '" ' : 'style="margin: 0 auto; display:block;" ';
	$query = utils_kexplode($vurl ['query'], '=&');
	$output = null;
	// We recognize different video providers by the given video URL.
	switch ($type) {
		// YouTube
		case 'youtube':
			$output = '';
			break;
		// Vimeo
		case 'vimeo':
			$vid = isset($query ['sec']) ? $query ['sec'] : str_replace('/', '', $vurl ['path']);
			$output = '';
			break;
		// Facebook
		case 'facebook':
			$vid = isset($query ['sec']) ? $query ['sec'] : str_replace('/video/', '', $vurl ['path']);
			$output = '
' . $popup_end;
}
/**
 * Function for email links
 *
 * @param string $action
 * @param array $attr
 * @param string $content
 * @param mixed $params
 *        	Not used
 * @param mixed $node_object
 *        	Not used
 * @return string
 */
function do_bbcode_mail($action, $attributes, $content, $params, $node_object) {
	if ($action == 'validate') {
		// not used for now
		return true;
	}
	// obfuscation mode: decimal/hexadecimal ASCII randomly mixed
	$mode = 3;
	// the code was specified as follows: [mail]user@example.org[/mail]
	if (!isset($attributes ['default'])) {
		return "" . obfuscateEmailAddress($content, $mode) . "";
	} else {
		// else the code was specified as follows: [mail=user@example.org]link text[/url]
		return "" . $content . "";
	}
}
/**
 * Function for embedding videos
 *
 * @param string $action
 * @param array $attr
 * @param string $content
 * @param mixed $params
 *        	Not used
 * @param mixed $node_object
 *        	Not used
 * @return string
 */
function do_bbcode_video($action, $attr, $content, $params, $node_object) {
	if ($action == 'validate') {
		return true;
	}
	$vurl = parse_url($attr ['default']);
	if (isset($attr ['type'])) {
		$type = $attr ['type'];
	} else {
		// is it http://www.MYSITE.com or http://MYSITE.com ?
		$web = explode('.', $vurl ['host']);
		array_pop($web);
		$type = isset($web [1]) ? $web [1] : $web [0];
	}
	// Check the [video] element's attributes width, height and float
	$width = isset($attr ['width']) ? $attr ['width'] : '560';
	$height = isset($attr ['height']) ? $attr ['height'] : '315';
	$float = isset($attr ['float']) ? 'align="' . $attr ['float'] . '" ' : 'style="margin: 0 auto; display:block;" ';
	$query = utils_kexplode($vurl ['query'], '=&');
	$output = null;
	// We recognize different video providers by the given video URL.
	switch ($type) {
		// YouTube
		case 'youtube':
			$output = '';
			break;
		// Vimeo
		case 'vimeo':
			$vid = isset($query ['sec']) ? $query ['sec'] : str_replace('/', '', $vurl ['path']);
			$output = '';
			break;
		// Facebook
		case 'facebook':
			$vid = isset($query ['sec']) ? $query ['sec'] : str_replace('/video/', '', $vurl ['path']);
			$output = '
			
			';
			break;
		// Any video file that can be played with HTML5