Your IP : 216.73.216.240


Current Path : /home/juvelize/www/plugins/content/easyimagecaption/
Upload File :
Current File : /home/juvelize/www/plugins/content/easyimagecaption/easyimagecaption.php

<?php
/**
 * @package Joomla
 * @subpackage EasyImageCaption
 * @copyright 2009–2019 Thomas Römer
 * @author Thomas Römer <open@roemer-online.net>
 *
 * This plugin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2 (GPLv2) of the License, or (at your option) any later version.
 *
 * This plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 *  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the GNU General Public License for more details <http://www.gnu.org/licenses/>.
 *
 * EasyImageCaption makes use of "PHP Simple HTML DOM Parser" by S.C. Chen <me578022@gmail.com> <http://simplehtmldom.sourceforge.net/>, licensed under The MIT License
 **/

//Joomla security
defined( '_JEXEC' ) or die( 'Restricted access' );

//This will become a Plugin
jimport( 'joomla.event.plugin' );

//Include parser
require_once 'inc/simple_html_dom.php';

//Let's go!
class plgContentEasyImageCaption extends JPlugin {
	//Variables to store the parameter settings
	var $param_hide_captions;
	var $param_apply_to_articles;
	var $param_except_articles;
	var $param_except_categories;
	var $param_apply_to_images;
	var $param_except_classes;
	var $param_except_ids;
	var $param_minimum_size;
	var $param_caption_attr;
	var $param_copy_img_classes;
	var $param_caption_position;
	var $param_use_alt_attr;
	var $param_parse_tags;
	var $param_tags_classes;
	var $param_link_targets;
	var $param_remove_tags;
	var $param_handle_jce_caption;
	var $param_jce_tooltip_fix;
	var $param_internal_style_on;
	var $param_style_background;
	var $param_style_margin_top;
	var $param_style_margin_right;
	var $param_style_margin_bottom;
	var $param_style_margin_left;
	var $param_style_box_padding;
	var $param_style_caption_color;
	var $param_style_caption_size;
	var $param_style_caption_line;
	var $param_style_caption_bold;
	var $param_style_caption_italic;
	var $param_style_caption_align;
	var $param_style_caption_padding_top;
	var $param_style_caption_padding_right;
	var $param_style_caption_padding_bottom;
	var $param_style_caption_padding_left;
	var $param_style_copy_color;
	var $param_style_copy_size;
	var $param_style_copy_line;
	var $param_style_copy_bold;
	var $param_style_copy_italic;
	var $param_style_copy_align;
	var $param_style_copy_padding_top;
	var $param_style_copy_padding_right;
	var $param_style_copy_padding_bottom;
	var $param_style_copy_padding_left;
	var $param_reset_image_margin;

	//Even more variables
	var $replace_jce_caption;
	var $exception_found;
	var $html;
	var $caption_text;
	var $copyright_text;
	var $width = array();
	var $align;
	var $margins;
	var $img_classes_set;
	var $internal_style_box;
	var $internal_style_caption;
	var $internal_style_copyright;
	var $classes = array();
	var $new_wrap_classes;
	var $img_is_block;

	//Constructor
	function __construct( &$subject, $params ) {
		parent::__construct( $subject, $params );
		
		//Parameter variable: hide captions (0) never, (1) on frontpage, (2) in blog view, (3) on both
		$this->param_hide_captions = $this->params->def('hide_captions', 0);
		
		//Parameter variable: apply plugin to introtext (0) no, (1) yes
		$this->param_apply_to_intro = $this->params->def('apply_to_intro', 0);
		
		//Parameter variable: apply plugin to all articles (1) or none (0)
		$this->param_apply_to_articles = $this->params->def('apply_to_articles', 1);
		
		//Parameter variable: except articles with certain ids
		$this->param_except_articles = array_map('trim', preg_split("/[\s,;]+/", $this->params->def('except_articles'))); 
		
		//Parameter variable: except categories with certain ids
		$this->param_except_categories = array_map('trim', preg_split("/[\s,;]+/", $this->params->def('except_categories'))); 
		
		//Parameter variable: apply plugin to all images (1) or none (0)
		$this->param_apply_to_images = $this->params->def('apply_to_images', 1);
		
		//Parameter variable: except images with specified classes
		$this->param_except_classes = array_map('trim', preg_split("/[\s,;]+/", $this->params->def('except_classes'))); 

		//Parameter variable: except images with specified ids
		$this->param_except_ids = array_map('trim', preg_split("/[\s,;]+/", $this->params->def('except_ids'))); 

		//Parameter variable: Minimum size of "captionized" images
		$this->param_minimum_size = trim($this->params->def('minimum_size'));
		$this->param_minimum_size = abs(intval($this->param_minimum_size)); //integer, no negatives
		
		//Parameter variable: use ALT attribute (0) or TITLE attribute (1)
		$this->param_caption_attr = $this->params->def('caption_attr', 1);
		
		//Parameter variable: use none (0), data-copyright (1), alt (2) or title attribute (3) as the copyright attribute
		$this->param_copyright_attr = $this->params->def('copyright_attr', 1);
		
		//Parameter variable: show caption and copyright above or below image: img-cap-copy (0), cap-copy-img (1), img-copy-cap (2), copy-cap-img (3), cap-img-copy (4), copy-img-cap (5)
		$this->param_caption_position = $this->params->def('caption_position', 0);
		
		//Parameter variable: copy image's CSS classes to new wrap
		$this->param_copy_img_classes = $this->params->def('copy_img_classes', 0);
		
		//Parameter variable: parse formatting tags never (0), always (1) or only for certain images (3)
		$this->param_parse_tags = $this->params->def('parse_tags', 1);
		
		//Parameter variable: Formatting tags will be parsed, if the image has one of these classes set
		$this->param_tags_classes = array_map('trim', preg_split("/[\s,;]+/", $this->params->def('tags_classes')));
		
		//Parameter variable: Determine which one of the two hyperlink tags ([url], [url2]) opens links in a new browser window
		$this->param_link_targets = $this->params->def('link_targets', 0);
		
		//Parameter variable: Remove the formatting tags from the original attribute
		$this->param_remove_tags = $this->params->def('remove_tags', 1);
		
		//Parameter variable: Handle captions built with JCE caption plugin
		//(another compatibility option: replace DIVs created by the old JCE caption plugin or ignore them)
		$this->param_handle_jce_caption = $this->params->def('handle_jce_caption', 0);
		
		//Parameter variable: Delete JCE's tooltip "control characters" (double colon)
		$this->param_jce_tooltip_fix = $this->params->def('jce_tooltip_fix', 1);
		
		//Parameter variable: Turn on/off internal style
		$this->param_internal_style_on = $this->params->def('use_internal_style', 1);
		
		//Parameter variables: style parameters
		$this->param_style_background = $this->getColorHex($this->params->def('style_background', 'F2F2F2'));
		$this->param_style_margin_top = $this->params->def('style_margin_top', 0);
		$this->param_style_margin_top = abs(intval($this->param_style_margin_top)); //integer, no negatives
		$this->param_style_margin_right = $this->params->def('style_margin_right', 0);
		$this->param_style_margin_right = abs(intval($this->param_style_margin_right)); //integer, no negatives
		$this->param_style_margin_bottom = $this->params->def('style_margin_bottom', 0);
		$this->param_style_margin_bottom = abs(intval($this->param_style_margin_bottom)); //integer, no negatives
		$this->param_style_margin_left = $this->params->def('style_margin_left', 0);
		$this->param_style_margin_left = abs(intval($this->param_style_margin_left)); //integer, no negatives
		$this->param_style_box_padding = trim($this->params->def('style_box_padding', 6));
		$this->param_style_box_padding = abs(intval($this->param_style_box_padding)); //integer, no negatives
		
		$this->param_style_caption_color = $this->getColorHex($this->params->def('style_color', '000000'));
		$this->param_style_caption_size = $this->params->def('style_size', 13);
		$this->param_style_caption_size = abs(intval($this->param_style_caption_size)); //integer, no negatives
		$this->param_style_caption_line = $this->params->def('style_caption_line', 1.3);
		$this->param_style_caption_line = abs(floatval($this->param_style_caption_line)); //float, no negatives
		$this->param_style_caption_bold = 'normal';
		if($this->params->def('style_bold', 0) == 1) {
			$this->param_style_caption_bold = 'bold';
		}
		$this->param_style_caption_italic = 'normal';
		if($this->params->def('style_italic', 0) == 1) {
			$this->param_style_caption_italic = 'italic';
		}
		$this->param_style_caption_align = 'left';
		if($this->params->def('style_align', 0) == 1) {
			$this->param_style_caption_align = 'center';
		}
		elseif($this->params->def('style_align', 0) == 2) {
			$this->param_style_caption_align = 'right';
		}
		$this->param_style_caption_padding_top = $this->params->def('style_caption_padding_top', 4);
		$this->param_style_caption_padding_top = abs(intval($this->param_style_caption_padding_top)); //integer, no negatives
		$this->param_style_caption_padding_right = $this->params->def('style_caption_padding_right', 0);
		$this->param_style_caption_padding_right = abs(intval($this->param_style_caption_padding_right)); //integer, no negatives
		$this->param_style_caption_padding_bottom = $this->params->def('style_caption_padding_bottom', 4);
		$this->param_style_caption_padding_bottom = abs(intval($this->param_style_caption_padding_bottom)); //integer, no negatives
		$this->param_style_caption_padding_left = $this->params->def('style_caption_padding_left', 0);
		$this->param_style_caption_padding_left = abs(intval($this->param_style_caption_padding_left)); //integer, no negatives
		
		$this->param_style_copy_color = $this->getColorHex($this->params->def('style_copy_color', '999999'));
		$this->param_style_copy_size = $this->params->def('style_copy_size', 11);
		$this->param_style_copy_size = abs(intval($this->param_style_copy_size)); //integer, no negatives
		$this->param_style_copy_line = $this->params->def('style_copy_line', 1.3);
		$this->param_style_copy_line = abs(floatval($this->param_style_copy_line)); //float, no negatives
		$this->param_style_copy_bold = 'normal';
		if($this->params->def('style_copy_bold', 0) == 1) {
			$this->param_style_copy_bold = 'bold';
		}
		$this->param_style_copy_italic = 'normal';
		if($this->params->def('style_copy_italic', 0) == 1) {
			$this->param_style_copy_italic = 'italic';
		}
		$this->param_style_copy_align = 'right';
		if($this->params->def('style_copy_align', 2) == 0) {
			$this->param_style_copy_align = 'left';
		}
		elseif($this->params->def('style_copy_align', 2) == 1) {
			$this->param_style_copy_align = 'center';
		}
		$this->param_style_copy_padding_top = $this->params->def('style_copy_padding_top', 0);
		$this->param_style_copy_padding_top = abs(intval($this->param_style_copy_padding_top)); //integer, no negatives
		$this->param_style_copy_padding_right = $this->params->def('style_copy_padding_right', 0);
		$this->param_style_copy_padding_right = abs(intval($this->param_style_copy_padding_right)); //integer, no negatives
		$this->param_style_copy_padding_bottom = $this->params->def('style_copy_padding_bottom', 4);
		$this->param_style_copy_padding_bottom = abs(intval($this->param_style_copy_padding_bottom)); //integer, no negatives
		$this->param_style_copy_padding_left = $this->params->def('style_copy_padding_left', 0);
		$this->param_style_copy_padding_left = abs(intval($this->param_style_copy_padding_left)); //integer, no negatives
		
		$this->param_reset_image_margin = $this->params->def('reset_image_margin', 1);
	}

	//This is where it all happens - manipulating the content before it is displayed
	public function onContentPrepare($context, &$article, &$params, $limitstart = 0) {
		//Don't do anything, if there is no text at all (prevents unexpected error messages to appear)
		if(!isset($article->introtext) AND !isset($article->fulltext) AND !isset($article->text)) return;

		//Don't "captionize" in certain views
		$view = JRequest::getCmd('view');
		$layout = JRequest::getCmd('layout');
		switch($this->param_hide_captions) {
			case 1:
				if($view == 'featured') return;
				break;
			case 2:
				if($layout == 'blog') return;
				break;
			case 3:
				if($view == 'featured' OR $layout == 'blog') return;
				break;
		}

		//Ignore certain articles, depending on parameter settings (except articles, except categories)
		$show_article = false;
		switch($this->param_apply_to_articles) {
			case 0:
				if(!empty($article->catid) AND in_array($article->catid, $this->param_except_categories)) {
					$show_article = true;
				}
				if(!empty($article->id) AND in_array($article->id, $this->param_except_articles)) {
					$show_article = true;
				}
				
				if($show_article == false) return;
				break;
			default:
				if(!empty($article->id) AND in_array($article->id, $this->param_except_articles)) return;
				if(!empty($article->catid) AND in_array($article->catid, $this->param_except_categories)) return;
				break;
		}

		//Article text consists of three different strings:
		//	- introtext	= intro part of article only
		//	- fulltext	= the "rest" of the article (i.e. article without the intro part)
		//	- text		= complete article
		for($t = 0; $t <= 2; $t++) {
			//Parse the content, generate captions, put back the html
			switch($t) {
				case 0:
					if($this->param_apply_to_intro AND !empty($article->introtext)) {
						$this->html = str_get_html($article->introtext);
						$this->generateCaptions();
						$article->introtext = $this->html->save();
					}
					break;
				case 1:
					if(!empty($article->fulltext)) {
						$this->html = str_get_html($article->fulltext);
						$this->generateCaptions();
						$article->fulltext = $this->html->save();
					}
					break;
				case 2:
					if(!empty($article->text)) {
						$this->html = str_get_html($article->text);
						$this->generateCaptions();
						$article->text = $this->html->save();
					}
					break;
			}

			//Delete the parsed HTML
			unset($this->html);
		}

		return '';
	}
	
	
	
	
	
	
	
	
	
	//FUNCTION: Find all <img> elements and add captions
	private function generateCaptions() {
		foreach($this->html->find('img') as $e) {
			//Prevent double captioning (happened a lot in K2)
			if($e->parent()->class != 'easy_img_caption' AND $e->parent()->parent()->class != 'easy_img_caption') {
				//Check exception classes and ids;
				//AND Getting image classes
				$this->checkHTML($e);

				if($this->param_apply_to_images != $this->exception_found) {
					//Preserve hyperlink (<a> tag) wrapping the <img> element
					$e_complete = $this->checkHyperlink($e);
					
					//Check if there is already a image caption div, created by (an old version of) the JCE caption plugin;
					//the next steps are obsolete, if there is one; even copyright text is ignored
					if(!$this->checkJCECaption($e_complete)) {
						switch($this->param_caption_attr) {
							case 0:
								$this->caption_text = $e->alt;
								if($this->param_remove_tags AND $this->caption_text) $e->alt = $this->replControlChars($e, $this->caption_text, true);
								break;
							case 1:
								$this->caption_text = $this->JCEToolTipFix($e->title);
								if($this->param_remove_tags AND $this->caption_text) $e->title = $this->replControlChars($e, $this->caption_text, true);
								break;
							default:
								$this->caption_text = '';
								break;
						}
						
						//Define the attribute to take the copyright information from
						switch($this->param_copyright_attr) {
							case 1:
								$this->copyright_text = $e->{'data-copyright'};
								if($this->param_remove_tags AND $this->copyright_text) $e->{'data-copyright'} = $this->replControlChars($e, $this->copyright_text, true);
								break;
							case 2:
								$this->copyright_text = $e->alt;
								if($this->param_remove_tags AND $this->copyright_text) $e->alt = $this->replControlChars($e, $this->copyright_text, true);
								break;
							case 3:
								$this->copyright_text = $this->JCEToolTipFix($e->title);
								if($this->param_remove_tags AND $this->copyright_text) $e->title = $this->replControlChars($e, $this->copyright_text, true);
								break;
							default:
								$this->copyright_text = '';
								break;
						}
					}
					else {
						//Get caption text from the JCE div
						$this->caption_text = $this->JCEToolTipFix($e_complete->parent()->last_child()->innertext);
					}
				}

				//Start generating caption only if there is text at all and the image is not to be ignored
				if(($this->caption_text OR $this->copyright_text) AND ($this->param_apply_to_images != $this->exception_found)) {
					//Building internal style string
					$this->getInternalStyle($e, $this->param_caption_position, !empty($this->caption_text), !empty($this->copyright_text));
						
					//Replace special EasyImageCaption control characters (formatting tags) and wrap texts in <span> and <small>
					if($this->caption_text) $this->caption_text = '<span style="' . $this->internal_style_caption . '">' . $this->replControlChars($e, $this->caption_text) . '</span>';
					if($this->copyright_text) $this->copyright_text = '<small style="' . $this->internal_style_copyright . '">' . $this->replControlChars($e, $this->copyright_text) . '</small>';

					//Extract properties from <img> or <div> elements
					//Exit the function if the image is too small
					$this->getWidth($e);

					if(!empty($this->width)) {
						$this->getAlign($e);
						$this->getMargins($e);
						
						//Delete style attribute from <img> element if all styles have been deleted in the above function calls
						if(trim($e->style) == '') {
							$e->style = null;
						}

						//Build the wrap's CSS class string
						$this->new_wrap_classes = "easy_img_caption";
						if($this->param_copy_img_classes == 1 AND count($this->classes) > 0) {
							$this->new_wrap_classes .= " " . implode(" ", $this->classes);
						}
						
						//Add width property to container
						$tmp_wdth = '';
						if($this->width['w'] > 0 AND !empty($this->width['u']))  {
							$tmp_wdth = 'width:' . $this->width['w'] . $this->width['u'] . ';';
						}
						
						//Wrap the new image box around the <img> element, put the caption and/or copyright info above or below the image
						//and store the whole thing in a string variable
						switch($this->param_caption_position) {
							case 0:
								$image_w_caption = '<span class="' . $this->new_wrap_classes . '" style="' . $this->internal_style_box . $tmp_wdth . $this->align . $this->margins . '">' . $e_complete->outertext . '<span class="easy_img_caption_inner" style="display:block;">' . $this->caption_text . $this->copyright_text . '</span></span>';
								break;
							case 1:
								$image_w_caption = '<span class="' . $this->new_wrap_classes . '" style="' . $this->internal_style_box . $tmp_wdth . $this->align . $this->margins . '"><span class="easy_img_caption_inner" style="display:block;">' . $this->caption_text . $this->copyright_text . '</span>' . $e_complete->outertext . '</span>';
								break;
							case 2:
								$image_w_caption = '<span class="' . $this->new_wrap_classes . '" style="' . $this->internal_style_box . $tmp_wdth . $this->align . $this->margins . '">' . $e_complete->outertext . '<span class="easy_img_caption_inner" style="display:block;">' . $this->copyright_text . $this->caption_text . '</span></span>';
								break;	
							case 3:
								$image_w_caption = '<span class="' . $this->new_wrap_classes . '" style="' . $this->internal_style_box . $tmp_wdth . $this->align . $this->margins . '"><span class="easy_img_caption_inner" style="display:block;">' . $this->copyright_text . $this->caption_text . '</span>' . $e_complete->outertext . '</span>';
								break;
							case 4:
								if($this->caption_text) $this->caption_text = '<span class="easy_img_caption_inner easy_img_caption_inner1" style="display:block;">' . $this->caption_text . '</span>';
								if($this->copyright_text) $this->copyright_text = '<span class="easy_img_caption_inner easy_img_caption_inner2" style="display:block;">' . $this->copyright_text . '</span>';
								$image_w_caption = '<span class="' . $this->new_wrap_classes . '" style="' . $this->internal_style_box . $tmp_wdth . $this->align . $this->margins . '">' . $this->caption_text . $e_complete->outertext . $this->copyright_text . '</span>';
								break;
							case 5:
								if($this->caption_text) $this->caption_text = '<span class="easy_img_caption_inner easy_img_caption_inner2" style="display:block;">' . $this->caption_text . '</span>';
								if($this->copyright_text) $this->copyright_text = '<span class="easy_img_caption_inner easy_img_caption_inner1" style="display:block;">' . $this->copyright_text . '</span>';
								$image_w_caption = '<span class="' . $this->new_wrap_classes . '" style="' . $this->internal_style_box . $tmp_wdth . $this->align . $this->margins . '">' . $this->copyright_text . $e_complete->outertext . $this->caption_text . '</span>';
								break;
						}
						
						//Write caption into HTML
						if(!$this->replace_jce_caption) {
							$e_complete->outertext = $image_w_caption;
						}
						else {
							//Simply replace the JCE caption div with the new one
							$e_complete->parent()->outertext = $image_w_caption;
						}
					}
				}
				//Reset some variables for the next run
				$this->classes = array();
				$this->replace_jce_caption = false;
				$this->img_classes_set = false;
				$this->margins = '';
				$this->align = '';
				$this->img_is_block = false;
				$this->width = array();
			}
		}
	}
	
	//FUNCTION: Checks the parent elements recursively to find HTML elements with classes or ids that are excepted
	//AND gets the image classes
	private function checkHTML($image) {
		$this->exception_found = 0;
	
		//Exit if exception is found
		if(isset($image->class) AND trim($image->class) != '') {
			if(!$this->img_classes_set) {
				$this->classes = explode(' ', $image->class);
				$this->img_classes_set = true;
			}
			
			if(count(array_intersect(explode(' ', $image->class), $this->param_except_classes)) > 0) {
				$this->exception_found = 1;
				return;
			}
		}
		
		if(isset($image->id) AND trim($image->id) != '') {
			if(in_array($image->id, $this->param_except_ids)) {
				$this->exception_found = 1;
				return;
			}
		}
		
		if($image->parent()->tag != 'root') {
			$image = $this->checkHTML($image->parent());
		}
		else {
			return;
		}
	}
	
	//FUNCTION: Determines whether there already is a JCE caption div wrapped around the image; returns true if so;
	//checks only for older JCE code; they changed their caption markup meanwhile
	private function checkJCECaption($image) {
		if ($image->parent()->tag == 'div') {
			$wrap = $image->parent();
			if(isset($wrap->class) AND trim($wrap->class) != '') {
				$wrap_classes = explode(' ', $wrap->class);
				if(in_array('jce_caption', $wrap_classes)) {
					if($this->param_handle_jce_caption == 0) {
						$this->replace_jce_caption = true;
					}
					else {
						$this->exception_found = true;
					}
					
					return true;
				}
			}
		}
	}
	
	//FUNCTION: Build the internal style strings
	private function getInternalStyle($image, $position, $has_caption, $has_copyright) {
		//1. Required internal styling
		
		//Check weather the image is a block or inline element
		if(preg_match('/\b(display\s*:\s*block)/i', $image->style)) $this->img_is_block = true;
	
		if($this->img_is_block) {
			$this->internal_style_box = 'display:table;max-width:100%;box-sizing:border-box;vertical-align:top;';
		}
		else {
			$this->internal_style_box = 'display:inline-table;max-width:100%;box-sizing:border-box;vertical-align:top;';
		}
		$this->internal_style_caption = 'display:block;';
		$this->internal_style_copyright = 'display:block;';
	
		//2. Optional internal styling
		if($this->param_internal_style_on) {
			if($position == 0 OR $position == 2) {
				//Caption/copyright below image only
				$this->internal_style_box .= 'background-color:' . $this->param_style_background .
					';padding:' . $this->param_style_box_padding . 'px ' . $this->param_style_box_padding . 'px 0px ' . $this->param_style_box_padding . 'px;';
			}
			elseif($position == 1 OR $position == 3) {
				//Caption/copyright above image only
				$this->internal_style_box .= 'background-color:' . $this->param_style_background .
					';padding: 0px ' . $this->param_style_box_padding . 'px ' . $this->param_style_box_padding . 'px ' . $this->param_style_box_padding . 'px;';
			}
			elseif($position == 4) {
				//Caption above image, copyright below
				$this->internal_style_box .= 'background-color:' . $this->param_style_background .
					';padding: ' . ($has_caption?'0':$this->param_style_box_padding) . 'px ' . $this->param_style_box_padding . 'px ' . ($has_copyright?'0':$this->param_style_box_padding) . 'px ' . $this->param_style_box_padding . 'px;';
			}
			elseif($position == 5) {
				//Copyright above image, caption below
				$this->internal_style_box .= 'background-color:' . $this->param_style_background .
					';padding: ' . ($has_copyright?'0':$this->param_style_box_padding) . 'px ' . $this->param_style_box_padding . 'px ' . ($has_caption?'0':$this->param_style_box_padding) . 'px ' . $this->param_style_box_padding . 'px;';
			}
					

			$this->internal_style_caption .= 'color:' . $this->param_style_caption_color .
				';font-size:' . $this->param_style_caption_size . 'px' .
				';line-height:' . $this->param_style_caption_line .
				';font-weight:' . $this->param_style_caption_bold .
				';font-style:' . $this->param_style_caption_italic .
				';text-align:' . $this->param_style_caption_align .
				';padding:' . $this->param_style_caption_padding_top . 'px ' . $this->param_style_caption_padding_right . 'px ' . $this->param_style_caption_padding_bottom . 'px ' . $this->param_style_caption_padding_left . 'px' .
				';margin:0px;';
				
			$this->internal_style_copyright .= 'color:' . $this->param_style_copy_color .
				';font-size:' . $this->param_style_copy_size . 'px' .
				';line-height:' . $this->param_style_copy_line .
				';font-weight:' . $this->param_style_copy_bold .
				';font-style:' . $this->param_style_copy_italic .
				';text-align:' . $this->param_style_copy_align .
				';padding:' . $this->param_style_copy_padding_top . 'px ' . $this->param_style_copy_padding_right . 'px ' . $this->param_style_copy_padding_bottom . 'px ' . $this->param_style_copy_padding_left . 'px' .
				';margin:0px;';
			
		}
	}
	
	//Replaces special EasyImageCaption control characters (formatting tags) in the caption text
	//and returns either the full HTML or the text with all tags stripped
	private function replControlChars($image, $string, $return_stripped = false) {
		if($this->param_parse_tags == 1 OR ($this->param_parse_tags == 2 AND count(array_intersect($this->param_tags_classes, $this->classes)) > 0)) {
			if(substr($image->outertext, -2, 1) == "/") {
				$lb = "<br />";
			}
			else {
				$lb = "<br>";
			}

			$search = array('#\[url]([a-z]+?://){1}(.*?)\[/url]#',
							'#\[url](.*?)\[/url\]#',
							'#\[url=([a-z]+?://){1}(.*?)\](.*?)\[/url]#',
							'#\[url=(.*?)\](.*?)\[/url]#',
							'#\[url2]([a-z]+?://){1}(.*?)\[/url2]#',
							'#\[url2](.*?)\[/url2\]#',
							'#\[url2=([a-z]+?://){1}(.*?)\](.*?)\[/url2]#',
							'#\[url2=(.*?)\](.*?)\[/url2]#',
							'#\[b](.*?)\[/b\]#',
							'#\[i](.*?)\[/i\]#',
							'#\[u](.*?)\[/u\]#',
							'#\[br]#'
							) ;
			
			if($this->param_link_targets == 1) {
				$replace = array('<a href="\1\2" target="_blank">\1\2</a>',
								'<a href="http://\1" target="_blank">\1</a>',
								'<a href="\1\2" target="_blank">\3</a>',
								'<a href="http://\1" target="_blank">\2</a>',
								'<a href="\1\2">\1\2</a>',
								'<a href="http://\1">\1</a>',
								'<a href="\1\2">\3</a>',
								'<a href="http://\1">\2</a>',
								'<b>\1</b>',
								'<i>\1</i>',
								'<u>\1</u>',
								$lb
								) ;
			}
			else {
				$replace = array('<a href="\1\2">\1\2</a>',
								'<a href="http://\1">\1</a>',
								'<a href="\1\2">\3</a>',
								'<a href="http://\1">\2</a>',
								'<a href="\1\2" target="_blank">\1\2</a>',
								'<a href="http://\1" target="_blank">\1</a>',
								'<a href="\1\2" target="_blank">\3</a>',
								'<a href="http://\1" target="_blank">\2</a>',
								'<b>\1</b>',
								'<i>\1</i>',
								'<u>\1</u>',
								$lb
								) ;
			}

			if($return_stripped) {
				return strip_tags(preg_replace($search, $replace, $string));
			}else {
				return preg_replace($search, $replace, $string);
			}
		}
		else {
			return $string;
		}
	}
	
	//FUNCTION: Get width (and unit) of the image, if it is defined (1) in the width attribute of the <img> element,
	//  or (2) through a width property within a style attribute;
	function getWidth($image) {
		$temp_width = 0;
		$temp_unit = '';

		//width attribute
		preg_match('/\b(\d+)(px|%)?/i', $image->width, $matches);
		if(@$matches[1] AND intval($matches[1]) > 0) {
			$temp_width = $matches[1];

			if(@$matches[2]) {
				$temp_unit = $matches[2];
			}
			else {
				$temp_unit = 'px';
			}
		}
		else {
			//no width attribute found; let's check the height, no percentages allowed here
			preg_match('/\b(\d+)(px)?/i', $image->height, $matches);
			if(@$matches[1]) {
				$temp_width = $matches[1]; //let's call it 'width' for now, even if it's the height
				$temp_unit = 'px';
				$temp_width = $this->getRealDims($image, 'ratio') * $temp_width;
			}
		}

		//style attribute: CSS width property
		if(isset($image->style)) {
			preg_match('/(^|\"|\'|;| )(width\s*:\s*(\d+)(px|em|ex|in|cm|mm|pt|pc|%);?)/i', $image->style, $matches1);
			if(@$matches1[3] AND intval($matches1[3]) > 0 AND @$matches1[4] AND in_array($matches1[4], array('px','em','ex','in','cm','mm','pt','pc','%'))) {
				$temp_width = $matches1[3];
				$temp_unit = $matches1[4];
			}
			else {
				//check for height property, no percentages allowed here
				preg_match('/(^|\"|\'|;| )(height\s*:\s*(\d+)(px|em|ex|in|cm|mm|pt|pc);?)/i', $image->style, $matches2);
				if(@$matches2[3] AND intval($matches2[3]) > 0 AND @$matches2[4] AND in_array($matches2[4], array('px','em','ex','in','cm','mm','pt','pc'))) {
					$temp_width = $matches2[3]; //let's call it 'width' for now, even if it's the height
					$temp_unit = $matches2[4];
					
					$temp_width = $this->getRealDims($image, 'ratio') * $temp_width;
				}
			}
		}
		
		$temp_width = abs(intval($temp_width)); //integer, no negatives
		if($temp_width == 0) $temp_unit = '';

		//if the image is larger than the minimum size for captioning (as defined in the parameters), delete any width/height settings
		//from the image and set image width to 100%, so that the image fills the surrounding caption box completely;
		if(($temp_unit == 'px' AND $temp_width >= $this->param_minimum_size) OR ($temp_unit != 'px' AND $this->getRealDims($image) >= $this->param_minimum_size)) {
			$image->width = $image->height = null;
			if(!empty($matches1)) $image->style = str_replace($matches1[2], '', $image->style);
			if(!empty($matches2)) $image->style = str_replace($matches2[2], '', $image->style);
			$image->style .= 'width:100%;';
			
			$this->width = array('w' => $temp_width, 'u' => $temp_unit);
		}
	}
	
	//FUNCTION: Define the alignment of the new image caption container, checking (1) the align attribute of the img element and
	//  (2) a 'float' property within a style attribute; the image's align attribute resp. 'float' property is deleted
	//If there is a JCE caption to be replaced, the alignment will be extracted from the style attribute of the surrounding div
	private function getAlign($image) {
		$clear = '';

		if(empty($this->align)) {
			if(!$this->replace_jce_caption) {
				//(1) take from <align>
				$this->align = $image->align;
				$image->align = null;
			}
			//(2) take from <style="float...; clear...;">
			//even if the extracted align property is overwritten in case of JCE caption replacement

			if(isset($image->style)) {
				preg_match('/\b(float\s*:\s*(left|right);*)/i', $image->style, $matches);
				if(@$matches[2]) {
					$this->align = $matches[2];
					$image->style = str_replace($matches[1], '', $image->style);
				}
				preg_match('/\b(clear\s*:\s*(left|right|both);*)/i', $image->style, $matches);
				if(@$matches[1]) {
					$clear = $matches[1];
					$image->style = str_replace($matches[1], '', $image->style);
				}
			}
			
			if($this->replace_jce_caption) {
				$this->align = $clear = '';
			
				$jceimg = $this->checkHyperlink($image)->parent();
				
				if(isset($jceimg->style)) {
					preg_match('/\b(float\s*:\s*(left|right);*)/i', $jceimg->style, $matches);
					if(@$matches[2]) {
						$this->align = $matches[2];
					}
					preg_match('/\b(clear\s*:\s*(left|right|both);*)/i', $jceimg->style, $matches);
					if(@$matches[1]) {
						$clear = $matches[1];
					}
				}
			}
			
			if($this->align == 'right' OR $this->align == 'left') {
				$this->align = 'float:' . $this->align . ';';
			}
			else {
				$this->align = '';
			}

			if(!empty($clear)) {
				if(substr($clear, -1, 1) != ';') {
					$clear .= ';';
				}
				
				$this->align .= $clear;
			}
		}
	}
	
	//FUNCTION: Define the margins of the new image caption container, checking (1) the hspace, vspace attributes of the <img> element and
	//  (2) 'margin' properties within a style attribute; the image's margins are deleted
	//If there is a JCE caption to be replaced, the margins will be extracted from the style attribute of the surrounding div
	//If the internal styling is turned on, the margins will be taken from the parameters as long as there are no margins declared in the <img> element
	private function getMargins($pimage) {
		$image = $pimage;
		$margin_is_set = false;
	
		if(!$this->replace_jce_caption) {
			if(isset($image->vspace)) {
				$v = $image->vspace;
			}
			else {
				$v = 0;
			}
			if(isset($image->hspace)) {
				$h = $image->hspace;
			}
			else {
				$h = 0;
			}
			
			if(!($v == 0 AND $h == 0)) {
				$this->margins = 'margin:' . $v . 'px ' . $h . 'px;';
				$margin_is_set = true;
			}
			
			$image->vspace = null;
			$image->hspace = null;
		}
		else {
			$image = $this->checkHyperlink($image)->parent();
		}
		
		if(isset($image->style)) {
			preg_match_all('/\b(margin(\-top|\-right|\-bottom|\-left|)\s*:\s*(\d+[a-zA-Z]*\s*|auto\s*|calc\(.+\))+;*)/i', $image->style, $matches);
			if(@$matches[1]) {
				$this->margins = '';
				foreach($matches[1] as $match) {
					$image->style = str_replace($match, '', $image->style);
					if(substr($match, -1, 1) == ';') {
						$match = substr($match, 0, -1);
					}
					$this->margins .= $match . ';';
				}
				$margin_is_set = true;
			}
		}
		
		if($this->param_internal_style_on) {
			if($margin_is_set == false) {
				$this->margins = 'margin:' . $this->param_style_margin_top . 'px ' . $this->param_style_margin_right . 'px ' . $this->param_style_margin_bottom . 'px ' . $this->param_style_margin_left . 'px;';
			}
			
			if($this->param_reset_image_margin) {
				if(trim($image->style) != "" AND substr($image->style, -1, 1) != ';') {
					$image->style .= ";";
				}
				
				$image->style .= "margin:0;";
			}			
		}
	}
	
	//FUNCTION: Checks whether the image element is surrounded by a hyperlink <a> element; returns the image element
	//  (together with the <a> element if present)
	private function checkHyperlink($image) {
		if ($image->parent()->tag == 'a') {
			return $image->parent();
		}
		else {
			return $image;
		}
	}
	
	//FUNCTION: Build the hexadecimal notation of a color
	private function getColorHex($hex) {
		if(substr($hex, 0, 1) != '#') {
			$hex = '#' . $hex;
		}
		$hex = substr($hex, 0, 7);
		
		return $hex;
	}
	
	//FUNCTION: Get real image dimensions from file; the $ret parameter defines the return value: 'width' or 'ratio'
	private function getRealDims($image, $ret = 'width') {
		if(in_array('juimage', $this->classes)) {
			//Compatibility: JUMultithumb generates thumbnails "on the fly" -> path to image may not be altered
			$image_url = $image->src;
		}
		else {
			$image_url = $this->urlToFile($image->src);
		}
		
		$image_params = @getimagesize($image_url);
		
		switch($ret) {
			case 'ratio':
				if($image_params[1] > 0) {
					return $image_params[0] / $image_params[1];
				}
				else {
					return 0;
				}
				break;
			default:
				return $image_params[0];
				break;
		}
		
	}
	
	//FUNCTION: Build the image path
	private function urlToFile($url) {
		$siteUri = JFactory::getURI();
		$imgUri = JURI::getInstance($url);
		
		$siteHost = $siteUri->getHost();
		$imgHost = $imgUri->getHost();
		
		$siteHost = preg_replace('/^www\./', '', $siteHost);
		$imgHost = preg_replace('/^www\./', '', $imgHost);
		if (empty($imgHost) || $imgHost == $siteHost) {
			$imgPath = $imgUri->getPath(); 
			
			if ($imgPath[0] == '/')	{
				$siteBase = $siteUri->base();
				$dirSite = substr($siteBase, strpos($siteBase, $siteHost) + strlen($siteHost));
				$url = substr($imgPath, strlen($dirSite));
			}
			$url = urldecode($url);
		}
		return $url;
	}

	//JCE tooltip compatibility: Deletes a double colon :: at the end of the caption string (only TITLE) and returns the string;
	//Expl: JCE adds these colons as control characters when using its tooltip function
	private function JCEToolTipFix($caption) {
		if(strlen($caption) >= 2 AND $this->param_jce_tooltip_fix) {
			if(substr($caption, -2) == '::') {
				$caption = substr($caption, 0, -2);
			}
		}
		return $caption;
	}
}
?>