<?php
/**
 * Plugin Helper File
 *
 * @package     Articles Anywhere
 * @version     1.4.4
 *
 * @author      Peter van Westen <peter@nonumber.nl>
 * @link        http://www.nonumber.nl
 * @copyright   Copyright (C) 2010 NoNumber! All Rights Reserved
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 */

// Ensure this file is being included by a parent file
defined( '_JEXEC' ) or die( 'Restricted access' );

// Import library dependencies
jimport( 'joomla.event.plugin' );

/**
* Plugin that places articles
*/
class plgSystemArticlesAnywhereHelper
{
	/**
	* Constructor
	*
	* For php4 compatability we must not use the __constructor as a constructor for
	* plugins because func_get_args ( void ) returns a copy of all passed arguments
	* NOT references.  This causes problems with cross-referencing necessary for the
	* observer design pattern.
	*/
	function plgSystemArticlesAnywhereHelper( &$config )
	{
		global $_MAMBOTS;
		$mainframe =& JFactory::getApplication();

		$this->database	=& JFactory::getDBO();

		// Load plugin parameters
		require_once JPATH_PLUGINS.DS.'system'.DS.'nonumberelements'.DS.'helpers'.DS.'parameters.php';
		$this->parameters =& NNePparameters::getParameters();
		$this->params = $this->parameters->getParams( $config['params'], JPATH_PLUGINS.DS.$config['type'].DS.$config['name'].'.xml' );

		$this->params->comment_start = '<!-- >>> Articles Anywhere >>> -->';
		$this->params->comment_end = '<!-- <<< Articles Anywhere <<< -->';

		$this->params->break_tags_start =	'((?:<p(?: [^>]*)?>\s*)?)';
		$this->params->break_tags_end =		'((?:\s*</p>)?)';
		$this->params->regex =				'#'.$this->params->break_tags_start.'\{'.preg_quote( $this->params->article_tag ).'(?: ([^\}]*))?\}'.$this->params->break_tags_end.'(.*?)'.$this->params->break_tags_start.'\{/'.preg_quote( $this->params->article_tag ).'\}'.$this->params->break_tags_end.'#s';

		$acl =& JFactory::getACL();
		$this->params->acl = $acl->get_group_data( $this->params->articles_security_level );
		$this->params->acl = $this->params->acl['4'];
		$this->params->acls = array();

		$user =& JFactory::getUser();
		$this->params->aid = $user->get( 'aid', 0 );
		$this->params->aid_jaclplus = $user->get( 'jaclplus', 0 );


		$query = 'SHOW COLUMNS FROM #__content';
		$this->database->setQuery( $query );
		$selects = $this->database->loadObjectList( 'Field' );
		if ( is_array( $selects ) ) {
			unset( $selects['introtext'] );
			unset( $selects['fulltext'] );
			$selects = array_keys( $selects );
			$this->params->dbselects_content = $selects;
		}

		$this->params->dbselects_k2 = 0;
		$query = 'SHOW COLUMNS FROM #__k2_items';
		$this->database->setQuery( $query );
		$selects = $this->database->loadObjectList( 'Field' );
		if ( is_array( $selects ) ) {
			unset( $selects['introtext'] );
			unset( $selects['fulltext'] );
			$selects = array_keys( $selects );
			$this->params->dbselects_k2 = $selects;
		}

		$this->params->dispatcher = 0;
	}

////////////////////////////////////////////////////////////////////
// ARTICLES
////////////////////////////////////////////////////////////////////

	function replaceInArticles ( &$article )
	{
		$message = '';

		if ( isset( $article->created_by ) ) {
			// Lookup group level of creator
			if ( !isset( $this->params->acls[$article->created_by] ) ) {
				$acl =& JFactory::getACL();
				$this->params->acls[$article->created_by] = $acl->getAroGroup( $article->created_by );
			}
			$article_group = $this->params->acls[$article->created_by];

			if ( !isset( $article_group->lft ) ) {
				$article_group->lft = 0;
			}

			// Set if security is passed
			// passed = creator is equal or higher than security group level
			if ( $this->params->acl > $article_group->lft ) {
				$message = JText::_( 'ARTICLES ANYWHERE OUTPUT REMOVED - SECURITY' );
			}
		}

		if ( isset( $article->text ) ) {
			$this->processArticles( $article->text, 'articles', $message );
		}
		if ( isset( $article->description ) ) {
			$this->processArticles( $article->description, 'articles', $message );
		}
		if ( isset( $article->title ) ) {
			$this->processArticles( $article->title, 'articles', $message );
		}
		if ( isset( $article->author ) ) {
			if ( isset( $article->author->name ) ) {
				$this->processArticles( $article->author->name, 'articles', $message );
			} else if ( is_string( $article->author ) ) {
				$this->processArticles( $article->author, 'articles', $message );
			}
		}
	}

////////////////////////////////////////////////////////////////////
// COMPONENTS
////////////////////////////////////////////////////////////////////

	function replaceInComponents()
	{
		$document =& JFactory::getDocument();
		$docType = $document->getType();

		if ( $docType == 'feed' && isset( $document->items ) ) {
			for ( $i = 0; $i < count( $document->items ); $i++ ) {
				$this->replaceInArticles( $document->items[$i] );
			}
		}

		if ( isset( $document->_buffer ) ) {
			$this->tagArea( $document->_buffer, 'component' );
		}

		// PDF
		if ( $docType == 'pdf' ) {
			if ( isset( $document->_header ) ) {
				$this->replaceInTheRest( $document->_header );
				$this->cleanLeftoverJunk( $document->_header );
			}
			if ( isset( $document->title ) ) {
				$this->replaceInTheRest( $document->title );
				$this->cleanLeftoverJunk( $document->title );
			}
			if ( isset( $document->_buffer ) ) {
				$this->replaceInTheRest( $document->_buffer );
				$this->cleanLeftoverJunk( $document->_buffer );
			}
		}
	}

////////////////////////////////////////////////////////////////////
// OTHER AREAS
////////////////////////////////////////////////////////////////////
	function replaceInOtherAreas()
	{
		$document =& JFactory::getDocument();
		$orig_document = clone( $document );

		$docType = $document->getType();

		// not in pdf's
		if ( $docType == 'pdf' ) { return; }

		$html = JResponse::getBody();

		if ( $docType != 'html' ) {
			$this->replaceInTheRest( $html );
			$this->cleanLeftoverJunk( $html );
		} else {
			$this->protect( $html );
			$this->replaceInTheRest( $html );

			// only do the handling inside the body
			if ( !( strpos( $html, '<body' ) === false ) && !( strpos( $html, '</body>' ) === false ) ) {
				$html_split = explode( '<body', $html );
				$body_split = explode( '</body>', $html_split['1'] );

				// remove generated articles outside the body
				$this->removeGeneratedArticles( $html_split['0'] );
				$this->removeGeneratedArticles( $body_split['1'] );

				$html_split['1'] = implode( '</body>', $body_split );
				$html = implode( '<body', $html_split );
			}

			$this->cleanLeftoverJunk( $html );
			$this->unprotect( $html );

			// replace head with newly generated head
			// this is necessary because the plugins might have added scripts/styles to the head
			$this->updateHead( $orig_document );
		}

		JResponse::setBody( $html );
		unset( $orig_document );
	}

	function replaceInTheRest( &$str, $docType = 'html' )
	{
		$option = JRequest::getCmd( 'option' );

		if ( $str == '' ) { return; }

		$document	=& JFactory::getDocument();
		$docType = $document->getType();

		// COMPONENT
		if ( $docType == 'feed' ) {
			$search_regex = '#(<item[^>]*>.*</item>)#si';
			$str = preg_replace( $search_regex, '<!-- START: ARTA_COMPONENT -->\1<!-- END: ARTA_COMPONENT -->', $str );
		}
		if ( strpos( $str, '<!-- START: ARTA_COMPONENT -->' ) === false ) {
			$this->tagArea( $str, 'component' );
		}

		$components = $this->params->components;
		if ( !is_array( $components ) ) {
			$components = explode( ',', $components );
		}

		$message = '';
		if ( in_array( $option, $components ) ) {
			// For all components that are selected, set the meassage
			$message = JText::_( 'ARTICLES ANYWHERE OUTPUT REMOVED - NOT ENABLED' );
		}

		$components = $this->getTagArea( $str, 'component' );

		foreach ( $components as $component ) {
			$this->processArticles( $component[1], 'components', $message );
			$str = str_replace( $component[0], $component[1], $str );
		}

		// EVERYWHERE
		$this->processArticles( $str, 'other' );
	}

	function tagArea( &$str, $area = '' )
	{
		if ( $area ) {
			if ( is_array( $str ) ) {
				foreach ( $str as $key => $val ) {
					$this->tagArea( $val, $area );
					$str[ $key ] = $val;
				}
			} else if ( $str ) {
				$str = '<!-- START: ARTA_'.strtoupper( $area ).' -->'.$str.'<!-- END: ARTA_'.strtoupper( $area ).' -->';
			}
		}
	}
	function getTagArea( $str, $area = '' )
	{
		$matches = array( '', '' );

		if ( $str && $area ) {
			preg_match_all( '#<\!-- START: ARTA_'.strtoupper( $area ).' -->(.*?)<\!-- END: ARTA_'.strtoupper( $area ).' -->#s', $str, $matches, PREG_SET_ORDER );
		}

		return $matches;
	}

	function processArticles( &$string, $area = 'articles', $message = '' )
	{
		while ( preg_match_all( $this->params->regex, $string, $matches, PREG_SET_ORDER ) > 0 ) {
			if (
				$area == 'articles' && !$this->params->articles_enable ||
				$area == 'components' && !$this->params->components_enable ||
				$area == 'other' && !$this->params->other_enable
			) {
				$message = JText::_( 'ARTICLES ANYWHERE OUTPUT REMOVED - NOT ENABLED' );
			}

			foreach ( $matches as $match ) {
				if ( $message != '' ) {
					$article_html = '';
					if ( $this->params->place_comments ) {
						$article_html = '<!-- '.$message.' -->';
					}
				} else {
					$article = trim( $match['2'] );
					$text = trim( $match['4'] );
					
					if ( stripos( $article, 'k2:' ) === 0 ) {
						$article = substr( $article, 3 );
						$article_html = $this->processArticle( $article, $text, $area, 'k2' );
					} else {
						$article_html = $this->processArticle( $article, $text, $area );
					}
					
					// optional paragraph tags
					$this->addParagraphTags( $article_html, trim( $match['1' ] ), trim( $match['6'] ) );
				}
				
				$article_html = $this->params->comment_start.$article_html.$this->params->comment_end;

				$string = str_replace( $match['0'], $article_html, $string );
			}
		}
	}

	function processArticle( $article, $text = '', $area = '', $type = 'article' )
	{
		if ( $type == 'k2' && !$this->params->dbselects_k2 ) {
			$type = '';
		}
		$regex = '#\{(/?[^\}]+)\}#si';
		if ( preg_match_all( $regex, $text, $matches, PREG_SET_ORDER ) > 0 ) {
			if ( $type == 'k2' ) {
				$selects = $this->params->dbselects_k2;
			} else {
				$selects = $this->params->dbselects_content;
			}

			foreach ( $matches as $match ) {
				$data = trim( $match['1'] );
				if ( !( strpos( $data, 'intro' ) === false ) ) {
					$selects[] = 'introtext';
				} else if ( !( strpos( $data, 'full' ) === false ) ) {
					$selects[] = 'fulltext';
				} else if ( !( strpos( $data, 'text' ) === false ) ) {
					$selects[] = 'introtext';
					$selects[] = 'fulltext';
				}
			}

			$selects = array_unique($selects);
			$selects = 'c.`'.implode( '`, c.`', $selects ).'`';

			$joins = '';
			if ( $type == 'article' ) {
				$selects .= ', CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(":", c.id, c.alias) ELSE c.id END as slug';
				$selects .= ', CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug';
				$joins = ' LEFT JOIN #__categories as cc ON cc.id = c.catid';
			}

			$where = ' AND ( c.title = '.$this->database->Quote( html_entity_decoder( $article ) );
			$where .= ' OR c.alias = '.$this->database->Quote( html_entity_decoder( $article ) );
			if ( is_numeric( $article ) ) {
				$where .= ' OR c.id = '.$article;
			}
			$where .= ' ) ';
			if ( !$this->params->ignore_state ) {
				$jnow =& JFactory::getDate();
				$now = $jnow->toMySQL();
				$nullDate = $this->database->getNullDate();
				if ( $type == 'k2' ) {
					$where .= ' AND c.published = 1';
				} else {
					$where .= ' AND c.state = 1';
				}
				$where .= ' AND ( c.publish_up = '.$this->database->Quote( $nullDate ).' OR c.publish_up <= '.$this->database->Quote( $now ).' )'
					.' AND ( c.publish_down = '.$this->database->Quote( $nullDate ).' OR c.publish_down >= '.$this->database->Quote( $now ).' )'
					;
			}

			$query = 'SELECT '.$selects
				.' FROM '.( $type == 'k2' ? '#__k2_items as c' : '#__content as c' )
				.$joins
				.' WHERE c.access '.( defined( '_JACL' ) ? 'IN ('.$this->params->aid_jaclplus.')' : '<= '. (int) $this->params->aid )
				.$where
				.' ORDER BY c.ordering'
				.' LIMIT 1';

			$this->database->setQuery( $query );
			$article = $this->database->loadObject();

			if ( !$article ) {
				return '<!-- '.JText::_( 'Access to article denied' ).' -->';
			}
			
			foreach ( $matches as $match ) {
				$data = trim( $match['1'] );
				$ok = 0;
				$str = '';
				$data = explode( ':', $data, 2 );
				$tag = trim( $data['0'] );
				$extra = isset( $data['1'] ) ? trim( $data['1'] ) : '';
				
				if ( $tag == '/link' ) {
					$str = '</a>';
					$ok = 1;
				} else if (
						( $tag == 'link' || $tag == 'url' )
					||	!( strpos( $tag, 'readmore' ) === false )
				) {
					if ( isset( $article->id ) ) {
						if ( $type == 'k2' ) {
							$link = 'index.php?option=com_k2&view=item&id='.$article->id;
							$component	=& JComponentHelper::getComponent( 'com_k2' );
							$menus		=& JApplication::getMenu( 'site', array() );
							$menuitems	= $menus->getItems( 'componentid', $component->id );
							$id = 0;
							if( is_array( $menuitems ) ) {
								foreach( $menuitems as $item ) {
									if ( @$item->query['view'] == 'item' && @$item->query['layout'] == 'item' && @$item->query['id'] == $article->id ) {
										$id = $item->id;
										break;
									}
								}
								if ( !$id ) {
									foreach( $menuitems as $item ) {
										if ( @$item->query['view'] == 'itemlist' && @$item->query['layout'] == 'category' && @$item->query['id'] == $article->catid ) {
											$id = $item->id;
											break;
										}
									}
								}
							}
						} else {
							$slug = 'id='.$article->slug;
							if ( $article->catid ) {
								$slug .= '&catid='.$article->catslug;
							}
							$link = 'index.php?option=com_content&view=article&'.$slug;
							$component	=& JComponentHelper::getComponent( 'com_content' );
							$menus		=& JApplication::getMenu( 'site', array() );
							$menuitems	= $menus->getItems( 'componentid', $component->id );
							$id = 0;
							if( is_array( $menuitems ) ) {
								foreach( $menuitems as $item ) {
									if ( @$item->query['view'] == 'article' && @$item->query['id'] == $article->id ) {
										$id = $item->id;
										break;
									}
								}
								if ( !$id ) {
									foreach( $menuitems as $item ) {
										if ( @$item->query['view'] == 'category' && @$item->query['id'] == $article->catid ) {
											$id = $item->id;
											break;
										}
									}
								}

								if ( !$id ) {
									foreach( $menuitems as $item ) {
										if ( @$item->query['view'] == 'section' && @$item->query['id'] == $article->sectionid ) {
											$id = $item->id;
											break;
										}
									}
								}
							}
						}
						if ( $id ) {
							$link .= '&Itemid='.$id;
						}
						$link = JRoute::_( $link );

						if ( $tag == 'link' ) {
							$str = '<a href="'.$link.'">';
						} else if ( $tag == 'url' ) {
							$str = $link;
						} else {
							$readmore = JText::_( 'Read more...' );

							if ( $extra ) {
								$readmore = JText::_( $tag );
							}

							$str = '<a href="'.$link.'" class="readmore">'.$readmore.'</a>';
						}
						$ok = 1;
					}
				} else if (
						!( strpos( $tag, 'text' ) === false )
					||	!( strpos( $tag, 'intro' ) === false )
					||	!( strpos( $tag, 'full' ) === false )
				) {
					// TEXT data
					$article->text = '';

					if ( !( strpos( $tag, 'intro' ) === false ) ) {
						if ( isset( $article->introtext ) ) {
							$article->text = $article->introtext;
							$ok = 1;
						}
					} else if ( !( strpos( $tag, 'full' ) === false ) ) {
						if ( isset( $article->fulltext ) ) {
							$article->text = $article->fulltext;
							$ok = 1;
						}
					} else if ( !( strpos( $tag, 'text' ) === false ) ) {
						if ( isset( $article->introtext ) && isset( $article->fulltext ) ) {
							$article->text = $article->introtext.$article->fulltext;
							$ok = 1;
						}
					}


					if ( $type == 'k2' ) {
						$article->parameters = new JParameter( $article->params );
					} else {
						$article->parameters = new JParameter( $article->attribs );
					}

					if ( !$this->params->dispatcher ) {
						$plugins = JPluginHelper::_load();
						foreach ( $plugins as $plugin )	{
							if ( $plugin->type == 'content' || $plugin->type == 'system' ) {
								JPluginHelper::_import( $plugin );
							}
						}
						$this->params->dispatcher = clone( JDispatcher::getInstance() );
						$unset = 0;
						foreach( $this->params->dispatcher->_observers as $i => $observer ) {
							if (	!is_array( $observer )
								&&	(
										$observer->_name == 'articlesanywhere'
									||	$observer->_name == 'betterpreview'
								)
							) {
								unset( $this->params->dispatcher->_observers[$i] );
							}
						}
					}
					$this->params->dispatcher->trigger( 'onPrepareContent', array( &$article, &$article->parameters, 0 ) );

					
					$str = $article->text;

					if ( $extra ) {
						$attribs = explode( ':', $extra );

						$max = 0;
						$strip = 0;
						foreach ( $attribs as $attrib ) {
							if ( trim( $attrib ) == 'strip' ) {
								$strip = 1;
							} else {
								$max = (int) $attrib;
							}
						}

						if ( $strip ) {
							$str = preg_replace( '#(<script[^a-z0-9].*?</script>)#si', '', $str );
							$str = preg_replace( '#(<noscript[^a-z0-9].*?</noscript>)#si', '', $str );
							$str = preg_replace( '#(</?[a-z][a-z0-9]?.*?>)#si', '', $str );
							if ( $max && $max < strlen( $str ) ) {
								$str = rtrim( substr( $str, 0, ( $max-3 ) ) ).'...';
							}
						} else if ( $max && $max < strlen( $str ) ) {
							// add explode helper strings around tags
							$explode_str = '<!-- ARTA_TAG -->';
							$str = preg_replace( '#(<\/?[a-z][a-z0-9]?.*?>|<!--.*?-->)#si', $explode_str.'\1'.$explode_str, $str );

							$str_array = explode( $explode_str, $str );

							$str = array();
							$tags = array();
							$lasttag = '';
							$count = 0;
							$is_script = 0;
							foreach ( $str_array as $i => $str_part ) {
								if ( fmod( $i, 2 ) ) {
									// is tag
									$str[] = $str_part;
									preg_match( '#^<(\/?([a-z][a-z0-9]*))#si', $str_part, $tag );
									if ( !empty( $tag ) ) {
										if ( $tag['1'] == 'script' ) {
											$is_script = 1;
										}

										if (	!$is_script
												// only if tag is not a single html tag
											&&	( strpos( $str_part, '/>' ) === false )
												// just in case single html tag has no closing character
											&& 	!in_array( $tag['2'], array( 'area', 'br', 'hr', 'img', 'input', 'param' ) )
										) {
											$tags[] = $tag['1'];
										}

										if ( $tag['1'] == '/script' ) {
											$is_script = 0;
										}
									}
								} else if ( $is_script ) {
									$str[] = $str_part;
								} else {
									if ( $max < ( $count + strlen( $str_part ) ) ) {
										// strpart has to be cut off
										$maxlen = $max-$count;
										if ( $maxlen < 3 ) {
											$str[] = '...';
										} else {
											$str[] = rtrim( substr( $str_part, 0, ( $maxlen-3 ) ) ).'...';
										}
										break;
									} else {
										$count += strlen( $str_part );
										$str[] = $str_part;
									}
								}
							}
							// revers sort open tags
							krsort( $tags );
							$tags = array_values( $tags );
							$count = count( $tags );

							for( $i = 0; $i < 3; $i++ ) {
								foreach( $tags as $ti => $tag ) {
									if( $tag['0'] == '/' ) {
										for( $oi = $ti+1; $oi < $count; $oi++ ) {
											$opentag = $tags[$oi];
											if ( $opentag == $tag ) {
												break;
											}
											if ( '/'.$opentag == $tag ) {
												unset( $tags[$ti] );
												unset( $tags[$oi] );
												break;
											}
										}
									}
								}
							}

							foreach ( $tags as $tag ) {
								// add closing tag to end of string
								if( $tag['0'] != '/' ) {
									$str[] = '</'.$tag.'>';
								}
							}

							$str = implode( '', $str );
						}
					}
				} else {
					// Get data from db columns
					if ( isset( $article->$tag ) ) {
						$str = $article->$tag;
						$ok = 1;
					}
					// otherwise get data from parameter data
					if ( !$ok ) {
						$params = '';
						if ( isset( $article->attribs ) ) {
							$params = $this->parameters->getParams( $article->attribs );
						} else if ( isset( $article->params ) ) {
							$params = $this->parameters->getParams( $article->params );
						}
						if ( $params && isset( $params->$tag ) ) {
							$str = $params->$tag;
							$ok = 1;
						}
					}
					// otherwise get data from extra fields (for k2 items)
					if ( !$ok && $type == 'k2' ) {
						$extravalue = $this->getExtraFieldValue( $article->extra_fields, $tag, $article->catid );
						if ( $extravalue !== null ) {
							$str = $extravalue;
							$ok = 1;
						}
					}

					if ( $ok ) {
						if ( $extra && strtotime( $str ) ) {
							$str = date( $extra, strtotime( $str ) );
						}
					}
				}

				if ( $ok ) {
					$text = str_replace( $match['0'], $str, $text );
				}
			}
		}

		return $text;
	}

	/*
	 * Retrieve data from k2 extra fields
	 */
	function getExtraFieldValue( &$extra, $data, $catid )
	{
		$value = null;
		
		$db =& JFactory::getDBO();
		$query = "SELECT extraFieldsGroup FROM #__k2_categories WHERE id = ".(int) $catid." LIMIT 1";
		$db->setQuery($query);
		$extragroup = $db->loadResult();
		if ( !$extragroup ) {
			return $value;
		}

		require_once JPATH_ADMINISTRATOR.DS.'components'.DS.'com_k2'.DS.'lib'.DS.'JSON.php';
		$json = new Services_JSON;

		$query = "SELECT * FROM #__k2_extra_fields
			WHERE `group` = ".(int) $extragroup."
			AND name = ".$db->quote( $data )."
			AND published = 1
			LIMIT 1";
		$db->setQuery($query);
		$extrafield = $db->loadObject();
		if ( !$extrafield ) {
			return $value;
		}

		$fielddata = $json->decode( $extra );
		foreach ( $fielddata as $field ) {
			if ( $field->id == $extrafield->id ) {
				if ( $field->value != '' ) {
					$value = $field->value;
					if ( $extrafield->type == 'textfield' || $extrafield->type == 'textarea' || $extrafield->type == 'csv' ) {
						return $value;
					} else if ( $extrafield->type == 'link' && is_array( $field->value ) ) {
						$link = '';
						$link->name = isset( $field->value['0'] ) ? $field->value['0'] : '';
						$link->value = isset( $field->value['1'] ) ? $field->value['1'] : '';
						$link->target = isset( $field->value['2'] ) ? $field->value['2'] : '';
						return $this->getFieldLink( $link );
					}
				}
				break;
			}
		}

		$defaultdata = $json->decode( $extrafield->value );
		if ( $value !== null ) {
			$v = '';
			foreach( $defaultdata as $defaultvalue ) {
				if ( $value == $defaultvalue->value ) {
					$v = $defaultvalue->name;
				}
			}
			$value = $v;
		} else {
			if ( isset( $defaultdata['0'] ) ) {
				$value = '';
				if ( $extrafield->type == 'textfield' || $extrafield->type == 'textarea' || $extrafield->type == 'csv' ) {
					$value = $defaultdata['0']->value;
				} else if ( $extrafield->type == 'link' ) {
					$value = $this->getFieldLink( $defaultdata['0'] );
				} else if ( $extrafield->type != 'multipleSelect' ) {
					$value = $defaultdata['0']->name;
				}
			}
		}
		return $value;
	}

	function getExtraFieldInfo( $id ){
		$db =& JFactory::getDBO();
		$query= "SELECT * FROM #__k2_extra_fields WHERE published = 1 AND id = ".(int) $id." LIMIT 1";
		$db->setQuery( $query );
		return $db->loadObject();
	}

	function getFieldLink( &$field ){
		if ( !$field->value || $field->value == 'http://' ) {
			return $field->name;
		}
		$params =& JComponentHelper::getParams('com_k2');
		
		switch ( $field->target ){
			case 'same':
			default:
				$attributes='';
				break;

			case 'new':
				$attributes='target="_blank"';
				break;

			case 'popup':
				$attributes='class="classicPopup" rel="{x:'.$params->get('linkPopupWidth').',y:'.$params->get('linkPopupHeight').'}"';
				break;

			case 'lightbox':
				$filename = @basename( $field->value );
				$extension = JFile::getExt( $filename );
				if ( !empty( $extension ) && in_array( $extension, $imgExtensions )) {
					$attributes='class="modal"';
				}
				else {
					$attributes='class="modal" rel="{handler:\'iframe\',size:{x:'.$params->get('linkPopupWidth').',y:'.$params->get('linkPopupHeight').'}}"';
				}
				break;

		}
		return '<a href="'.$field->value.'" '.$attributes.'>'.$field->name.'</a>';
	}

	/*
	 * Protect input and text area's
	 */
	function addParagraphTags( &$string, $p_start = '', $p_end = '' )
	{
		$str = trim( preg_replace( '#<\!--.*?-->#si', '', $string ) );

		if ( $str == '' ) {
			return;
		}
		
		// if there is a starting p tag
		if ( $p_start ) {
			$p_match = '#<p( |\s|>)#si';
			// add starting p tag if content has no starting p tag
			// or if ending p tag appears before starting p tag
			if (
					!( preg_match( $p_match, $str ) )
				||	(
						!( stripos( $str, '</p>' ) === false )
						&& stripos( $str, '</p>' ) < stripos( $str, '<p' )
					)
			) {
				$string = $p_start.$string;
			}
		}
		// if there is a ending p tag
		if ( $p_end ) {
			// add ending p tag if content has no ending p tag
			// or if starting p tag appears later than ending p tag
			if (
					stripos( $str, '</p>' ) === false
				||	strripos( $str, '</p>' ) < strripos( $str, '<p' )
			) {
				$string .= $p_end;
			}
		}
	}

	/*
	 * Protect input and text area's
	 */
	function protect( &$string )
	{
		$option = JRequest::getCmd( 'option' );
		$task = JRequest::getCmd( 'task' );

		// Protect complete adminForm (to prevent articles from being created when editing articles and such)
		$regex = '#<form [^>]*name="adminForm".*?>.*?<div id="editor-xtd-buttons".*?</form>#si';
		if ( preg_match_all( $regex, $string, $matches, PREG_SET_ORDER ) > 0 ) {
			$protected_syntax = $this->protectStr( '{'.$this->params->article_tag );
			foreach ( $matches as $match ) {
				if ( !( strpos( $match[0], '{'.$this->params->article_tag ) === false ) ) {
					$form_string = str_replace( '{'.$this->params->article_tag, $protected_syntax, $match[0] );
					$string = str_replace( $match[0], $form_string, $string );
				}
			}
		}
	}

	function unprotect( &$string )
	{
		$protected_start = $this->protectStr( '{'.$this->params->article_tag );
		$string = str_replace( $protected_start, '{'.$this->params->article_tag, $string );
	}

	function protectStr( $string )
	{
		$string = base64_encode( $string );
		return $string;
	}

	function cleanLeftoverJunk( &$str )
	{
		$str = preg_replace( $this->params->regex, '', $str );
		$str = preg_replace( '#<\!-- (START|END): ARTA_[^>]* -->#', '', $str );
		if ( !$this->params->place_comments ) {
			$str = str_replace( array( $this->params->comment_start, $this->params->comment_end ), '', $str );
		}
	}

	function removeGeneratedArticles( &$str )
	{
		$str = preg_replace( '#'.preg_quote( $this->params->comment_start, '#' ).'.*?'.preg_quote( $this->params->comment_end, '#' ).'\s*#s', '', $str );
		$str = preg_replace( '#'.preg_quote( htmlentities( $this->params->comment_start ), '#' ).'.*?'.preg_quote( htmlentities( $this->params->comment_end ), '#' ).'\s*#s', '', $str );
	}

	function updateHead( $orig_document )
	{
		$document =& JFactory::getDocument();
		$hashead = 0;
		if ( !isset( $document->_buffer ) || !isset( $document->_buffer['component'] )  ) {
			return;
		}
		foreach( $document->_buffer['component'] as $buffer ) {
			if ( !( strpos( $buffer, '</head>' ) === false ) ) {
				$hashead = 1;
				break;
			}
		}
		if ( !$hashead ) {
			return;
		}
		
		$head = JDocumentRendererHead::fetchHead( $document );

		// get line endings
		$lnEnd = $document->_getLineEnd();
		$tab = $document->_getTab();
		$tagEnd	= ' />';
		$strHtml = '';
		
		// Generate link declarations
		foreach ($document->_links as $link) {
			if ( !in_array( $link, $orig_document->_links ) ) {
				$strHtml .= $tab.$link.$tagEnd.$lnEnd;
			}
		}

		// Generate stylesheet links
		foreach ($document->_styleSheets as $strSrc => $strAttr ) {
			if ( !array_key_exists( $strSrc, $orig_document->_styleSheets ) ) {
				$strHtml .= $tab . '<link rel="stylesheet" href="'.$strSrc.'" type="'.$strAttr['mime'].'"';
				if (!is_null($strAttr['media'])){
					$strHtml .= ' media="'.$strAttr['media'].'" ';
				}
				$temp = JArrayHelper::toString($strAttr['attribs']);
				if ( $temp ) {
					$strHtml .= ' '.$temp;;
				}
				$strHtml .= $tagEnd.$lnEnd;
			}
		}

		// Generate stylesheet declarations
		foreach ($document->_style as $type => $content) {
			if ( !in_array( $content, $orig_document->_style ) ) {
				$strHtml .= $tab.'<style type="'.$type.'">'.$lnEnd;

				// This is for full XHTML support.
				if ($document->_mime == 'text/html' ) {
					$strHtml .= $tab.$tab.'<!--'.$lnEnd;
				} else {
					$strHtml .= $tab.$tab.'<![CDATA['.$lnEnd;
				}

				$strHtml .= $content . $lnEnd;

				// See above note
				if ($document->_mime == 'text/html' ) {
					$strHtml .= $tab.$tab.'-->'.$lnEnd;
				} else {
					$strHtml .= $tab.$tab.']]>'.$lnEnd;
				}
				$strHtml .= $tab.'</style>'.$lnEnd;
			}
		}

		// Generate script file links
		foreach ($document->_scripts as $strSrc => $strType) {
			if ( !array_key_exists( $strSrc, $orig_document->_scripts ) ) {
				$strHtml .= $tab.'<script type="'.$strType.'" src="'.$strSrc.'"></script>'.$lnEnd;
			}
		}

		// Generate script declarations
		foreach ($document->_script as $type => $content) {
			if ( !in_array( $content, $orig_document->_script ) ) {
				$strHtml .= $tab.'<script type="'.$type.'">'.$lnEnd;

				// This is for full XHTML support.
				if ($document->_mime != 'text/html' ) {
					$strHtml .= $tab.$tab.'<![CDATA['.$lnEnd;
				}

				$strHtml .= $content.$lnEnd;

				// See above note
				if ($document->_mime != 'text/html' ) {
					$strHtml .= $tab.$tab.'// ]]>'.$lnEnd;
				}
				$strHtml .= $tab.'</script>'.$lnEnd;
			}
		}

		foreach($document->_custom as $custom) {
			if ( !in_array( $custom, $orig_document->_custom ) ) {
				$strHtml .= $tab.$custom.$lnEnd;
			}
		}

		JResponse::setBody( str_replace( '</head>', $strHtml."\n".'</head>', JResponse::getBody() ) );
	}
}

if ( !function_exists( 'html_entity_decoder' ) ) {
	function html_entity_decoder( $given_html, $quote_style = ENT_QUOTES, $charset = 'UTF-8' )
	{
		if ( phpversion() < '5.0.0' ) {
			$trans_table = array_flip( get_html_translation_table( HTML_SPECIALCHARS, $quote_style ) );
			$trans_table['&#39;'] = "'";
			return ( strtr( $given_html, $trans_table ) );
		}else {
			return html_entity_decode( $given_html, $quote_style, $charset );
		}
	}
}

// PHP4 compatiblility for cloning objects
if ( phpversion() < '5.0.0' && function_exists( 'clone' ) == false ) {
	eval('
		function clone( $object )
		{
			return $object;
		}
	');
}
// PHP4 compatiblility for strripos
if ( phpversion() < '5.0.0' &&  function_exists('strripos') == false ) {
    eval('
		function strripos( $haystack, $needle )
		{
			$pos = strlen( $haystack ) - strpos( strrev( $haystack ), strrev( $needle ) );
			if ( $pos == strlen( $haystack ) ) { $pos = 0; }
			return $pos;
		}
	');
}