Location: PHPKode > scripts > Wapple Architect Mobilization > wapple-architect-mobilization/wapl_builder.php
<?php 
/**
 * Wapple Architect WAPL Builder class
 * 
 * This class allows you to build WAPL ensuring that it's always valid and
 * always is in line with the schema at http://wapl.wapple.net/wapl.xsd
 * 
 * @author Rich Gubby
 * @version 1.0
 * @package WappleArchitect
 */
class waplBuilder
{
	/**
	 * Any universal attributes that apply to all elements
	 * @access public
	 * @var array
	 */
	public $universalAttributes = array('class', 'id');
	
	/**
	 * The current tag we're building
	 * @access public
	 * @var string
	 */
	public $tag;
	
	/**
	 * Tag prefix - used when a "link" becomes an "externalLink"
	 * @access public
	 * @var string
	 */
	public $tagPrefix;
	
	/**
	 * Parent tag
	 * @access public
	 * @var string
	 */
	public $parentTag;
	
	/**
	 * WAPL schema
	 * @access public
	 * @var array
	 * @todo Make sure it's up to date!
	 */
	public $schema = array(
		'head' => array(
			'children' => array('title')
		),
		'title' => array(
			'direct' => true,
			'parent' => 'head'
		),
		'layout' => array(
			
		),
		'meta' => array(
			'attributes' => array('name', 'content'),
			'parent' => 'head',
			'selfClosing' => true
		),
		'css' => array(
			'children' => array('url'),
			'parent' => 'head'
		),
		'link' => array(
			'children' => array('url', 'label', 'prefix', 'linkVars', 'insertion', 'suffix', 'prefix', 'externalImage', 'accessKey')
		),
		'chars' => array(
			'attributes' => array('make_safe'),
			'children' => array('value')
		),
		'linkVars' => array(
			'parent' => 'link',
			'children' => array('var')
		),
		'var' => array(
			'children' => array('name', 'value'),
			'parent' => 'linkVars'
		),
		'externalLink' => array(
			'children' => array('url', 'label', 'prefix', 'suffix', 'externalImage')
		),
		'externalImage' => array(
			'attributes' => array('filetype', 'scale', 'quality', 'alt'),
			'children' => array('url', 'transcol', 'safe_mode')
		),
		'form' => array(
			'children' => array('action', 'formItem', 'url')
		),
		'formItem' => array(
			'parent' => 'form',
			'attributes' => array('item_type', 'default', 'menu_id'),
			'children' => array('name', 'label', 'value', 'possibility', 'input_mask')
		),
		'possibility' => array(
			'parent' => 'formItem',
			'children' => array('label', 'value')
		),
		'rule' => array(
			'attributes' => array('type', 'criteria', 'condition')
		),
		'phonecallChunk' => array(
			'children' => array('phone_number', 'show_label')
		),
		'phonebookChunk' => array(
			'children' => array('phone_number', 'contact_name', 'show_label')
		),
		'rssChunk' => array(
			'children' => array('url', 'max_items', 'items_per_page', 'graphic_scale', 'icon_scale', 'tease_length', 'show_no_tease',
				'do_channel_title', 'do_channel_image', 'do_channel_link', 'do_channel_description', 'do_channel_language',
				'do_channel_copyright', 'do_channel_managing_editor', 'do_channel_webmaster', 'do_channel_publish_date',
				'do_channel_last_build_date', 'do_channel_category', 'do_channel_generator', 'do_channel_documentation', 
				'do_channel_cloud', 'do_channel_ttl', 'do_channel_rating', 'do_channel_text_input', 'do_channel_skip_hours',
				'do_channel_skip_days', 'do_item_title', 'do_item_link', 'do_item_description', 'do_item_author', 
				'do_item_category', 'do_item_comment', 'do_item_comments', 'do_item_enclosure', 'do_item_guid', 
				'do_item_publish_date', 'do_item_source' 
			)
		),
		'rubberduckChunk' => array(
			'children' => array('rubberduck_client_id', 'rubberduck_set_id', 'graphic_scale', 'delivery_performance',
				'display_mode')
		),
		'jumpChunk' => array(
			'children' => array('destination_page', 'url')
		),
		'waplChunk' => array(
			'children' => array('url')
		),
		'wordsChunk' => array(
			'children' => array('display_as', 'quick_text')
		),
		'spacemakerChunk' => array(
			'children' => array('scale')
		),
		'hrChunk' => array(),
		'admobChunk' => array(
			'children' => array('mobile_site_id', 'iphone_site_id', 'iphone_background_color', 'iphone_text_color')
		),
		'admodaChunk' => array(
			'children' => array('admoda_mode', 'admoda_zoneid', 'admoda_showhousebanner', 'admoda_housebannerid')
		),
		'decktradeChunk' => array(
			'children' => array('decktrade_siteid')
		),
		'adsenseChunk' => array(
			'children' => array('channel_id', 'client_id', 'items_per_page', 'col_border', 'col_bg', 'col_link', 'col_text', 'col_url')
		),
		'mbrandChunk' => array(
			'children' => array('mbrand_placement_id', 'mbrand_ad_server')
		),
		'mkhojChunk' => array(
			'children' => array('mkhoj_site_id')
		),
		'mobilecommercemmsChunk' => array(
			'children' => array('client_id', 'items_per_page', 'backfill', 'filter_out_adult', 'use_page_keywords', 
				'ad_keyword', 'do_search', 'test_mode'
			)
		),
		'mpressionChunk' => array(
			'children' => array('adslot_id', 'ad_category', 'ad_keyword')
		),
		'nokiaadsChunk' => array(
			'children' => array('nokiaads_spot_name', 'nokiaads_ad_server')
		),
		'stampChunk' => array(
			'children' => array('stamp_si', 'stamp_al', 'stamp_mode', 'items_per_page', 'graphic_scale')
		),
		'zestadzChunk' => array(
			'children' => array('zestadz_cid', 'zestadz_meta')
		),
		'settings' => array(
			'children' => array('bangoPageTrackingId', 'iphoneTextSizeAdjust', 'iphoneUserScaleable', 'iphoneInitalScale', 'iphoneMinScale', 'iphoneMaxScale', 'iphoneMagicWidth')
		)
	);
	
	/**
	 * List of tags that don't have rows or cells
	 * @access public
	 * @var array
	 */
	public $noRowTags = array(
		'head', 'title', 'meta', 'css', 'linkVars', 'var', 'formItem', 'possibility', 
		'rule', 'phonecallChunk', 'phonebookChunk', 'rssChunk', 'rubberduckChunk', 
		'jumpChunk', 'waplChunk', 'wordsChunk', 'spacemakerChunk', 'hrChunk', 'admobChunk',
		'decktradeChunk', 'adsenseChunk', 'mbrandChunk', 'mkhojChunk', 'mobilecommercemmsChunk',
		'mpressionChunk', 'nokiaadsChunk', 'stampChunk', 'zestadzChunk', 'settings', 'row', 'cell', 'layout'
	);
	
	/**
	 * Number of pages in an article
	 * @access public
	 * @var array
	 */
	public $pages = array();
	
	/**
	 * The current page we're on
	 * @access public
	 * @var integer
	 */
	public $currentPage;
	
	/**
	 * Build the page header
	 * 
	 * @access public
	 * @return string
	 */
	public function start()
	{
		return '<' . '?xml version="1.0" encoding="utf-8" ?'.'><wapl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://wapl.wapple.net/wapl.xsd">';
	}
	
	/**
	 * Build the page layout
	 * 
	 * @access public
	 * @param array $options
	 * @return unknown_type
	 */
	public function layout($options = array())
	{
		$this->tag = 'layout';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build the page footer
	 * 
	 * @access public
	 * @return string
	 */
	public function end()
	{
		return '</wapl>';
	}
	
	/**
	 * Build a WAPL head element
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function head($options = array())
	{
		$this->tag = 'head';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a META element
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function meta($options = array())
	{
		$this->tag = 'meta';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a CSS element
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function css($options = array())
	{
		$this->tag = 'css';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL link element
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function link($options = array())
	{
		$this->tag = 'link';
		$this->__doExternal($options);
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL image element
	 * 
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function image($options = array())
	{
		$this->tag = 'image';
		$this->__doExternal($options);
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL chars element
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function chars($options = array())
	{
		$this->tag = 'chars';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL chunk element
	 * @param string $type
	 * @param array $options
	 * @return string
	 */
	public function chunk($type, $options)
	{
		$this->tag = $type.'Chunk';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL form element (includes all form item elements)
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function form($options = array())
	{
		$this->tag = 'form';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL formItem element
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function formItem($options = array())
	{
		$this->tag = 'formItem';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a WAPL rule
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function rule($options)
	{
		$this->tag = 'rule';
		return $this->__do_tag($options);
	}
	
	/**
	 * Build any page settings
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function settings($options)
	{
		$this->tag = 'settings';
		$this->tagPrefix = null;
		return $this->__do_tag($options);
	}
	
	/**
	 * Build a row start tag
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function rowStart($options = array())
	{
		$this->tag = 'row';		
		$this->tagPrefix = null;
		$options['end'] = false;
		$options['row'] = false;
		$options['cell'] = false;
		return $this->__do_tag_start($options);
	}
	
	/**
	 * Build a row end tag
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function rowEnd($options = array())
	{
		$this->tag = 'row';
		$this->tagPrefix = null;
		$options['start'] = false;
		$options['row'] = false;
		$options['cell'] = false;
		return $this->__do_tag_end($options);
	}
	
	/**
	 * Build a cell start tag
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function cellStart($options = array())
	{
		$this->tag = 'cell';
		$options['end'] = false;
		$options['row'] = false;
		$options['cell'] = false;
		return $this->__do_tag_start($options);
	}
	
	/**
	 * Build a cell end tag
	 * @param array $options
	 * @access public
	 * @return string
	 */
	public function cellEnd($options = array())
	{
		$this->tag = 'cell';
		$options['start'] = false;
		$options['row'] = false;
		$options['cell'] = false;
		return $this->__do_tag_end($options);
	}

	
	/**
	 * Format content into WAPL readable format
	 * @param string $content
	 * @param integer $imagescale
	 * @param integer $imagequality
	 * @param string $class
	 * @param integer $length
	 * @access public
	 * @return string
	 */
	public function format_text($content, $imagescale = 95, $imagequality = 90, $class = '', $length = null)
	{
		// Remove newlines and tabs
		$content = str_replace(array("\r", "\n", "\t", "\r\n"), ' ', $content);
		
		$this->pages = array();

		// Replace p tags with a new wordsChunk element
		$content = preg_replace('/<p class="(.*?)">(.*?)<\/p>/is', '</quick_text></wordsChunk><wordsChunk class="${1}"><quick_text>${2}</quick_text></wordsChunk><wordsChunk class="'.$class.'"><quick_text>', $content);
		$content = preg_replace('/<p>(.*?)<\/p>/is', '</quick_text></wordsChunk><wordsChunk class="'.$class.'"><quick_text>${1}</quick_text></wordsChunk><wordsChunk class="'.$class.'"><quick_text>', $content);
		
		// Remove images with WAPL versions
		//$content = preg_replace('/<img(.*?)src=\"(.*?)(\.)(jpeg|png|jpg|bmp|gif)\".*?\/>/i', '</quick_text></wordsChunk><row><cell><externalImage filetype="${4}" scale="'.$imagescale.'" quality="'.$imagequality.'"><url>${2}.${4}</url></externalImage></cell></row><wordsChunk class="'.$class.'"><quick_text>', $content);
		preg_match_all('/<img(.*?)src=\"(.*?)(\.)*(jpeg|png|jpg|bmp|gif)*\"(.*?)(\/>|><\/img>)/i', $content, $imageMatches);
		
		foreach($imageMatches[2] as $key => $val)
		{
			if(isset($imageMatches[3][$key]) AND $imageMatches[3][$key] == '.')
			{
				$content = str_replace($imageMatches[0][$key], '</quick_text></wordsChunk><row><cell><externalImage filetype="'.$imageMatches[4][$key].'" scale="'.$imagescale.'" quality="'.$imagequality.'"><url>'.$val.'.'.$imageMatches[4][$key].'</url></externalImage></cell></row><wordsChunk class="'.$class.'"><quick_text>', $content);
			}
		}

		// Replace any strong tags with WTF [b] tags
		$content = preg_replace('/<strong>(.*?)<\/strong>/i', '[b]${1}[/b]', $content);
		
		// Replace any h* tags
		$content = preg_replace('/<h(.*?)>(.*?)<\/h(.*?)>/i', '</quick_text></wordsChunk><wordsChunk class="'.$class.'"><display_as>h${1}</display_as><quick_text>${2}</quick_text></wordsChunk><wordsChunk class="'.$class.'"><quick_text>', $content);
		
		// Lists
		$content = preg_replace('/<ul(.*?)>/', '[list]', $content);
		$content = preg_replace('/<\/ul>/', '[/list]', $content);
		// List items
		$content = preg_replace('/<li(.*?)>(.*?)<\/li>/i', '[*]${2}[/*]', $content);

		// Replace any links
		$content = preg_replace('/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/i', '[url=${2}]${4}[/url]', $content);
		
		// Replace any form tags - upgrade this later!
		$content = preg_replace('/<form(.*?)>/i', '', $content);
		$content = preg_replace('/<\/form>/i', '', $content);
		$content = preg_replace('/<script(.*?)>.*<\/script>/', '', $content);
		
		// Replace any rogue wordsChunk chars
		$content = preg_replace('/<\/wordsChunk><quick_text>(.*?)<\/quick_text><\/wordsChunk>/i', '', $content);
		$content = preg_replace('/<\/wordsChunk><quick_text>(.*?)<\/quick_text><\/wordsChunk>/i', '', $content);
		$content = preg_replace('/<wordsChunk><quick_text>([\s\t])+<\/quick_text><\/wordsChunk>/i', '', $content);
		$content = str_replace('</wordsChunk><quick_text>', '', $content);
		$content = str_replace('</externalLink></quick_text></wordsChunk>', '', $content);
		
		// Lastly strip any other tags
		$stripTagExclude = array();
		foreach($this->schema as $key => $val)
		{
			$stripTagExclude[$key] = $key;
			if(isset($val['children']))
			{
				foreach($val['children'] as $child)
				{
					$stripTagExclude[$child] = $child;
				}
			}
		}
		$stripTagExcludeString = '';
		foreach($stripTagExclude as $tag)
		{
			$stripTagExcludeString .= '<'.$tag.'>';
		}
		$stripTagExcludeString.= '<row><cell>';

		// Strip any remaining html
		$content = strip_tags($content, $stripTagExcludeString);
		
		// Remove multiple BR and make a new wordschunk
		$content = preg_replace('/(<br \/>\s){2,}/', '</quick_text></wordsChunk><wordsChunk class="'.$class.'"><quick_text>', $content);
		
		// Clean up any empty wordsChunk elements
		$content = preg_replace('/<wordsChunk class="'.$class.'"><quick_text><\/quick_text><\/wordsChunk>/i', '', $content);
		
		if($length)
		{
			$this->getPages($content, $length);
			
			$tidyContent = $this->pages[($this->currentPage - 1)];
			
			if((strpos($tidyContent, '<row>') === 0) OR (strpos($tidyContent, '<wordsChunk') === 0))
			{
				$tidyContent = '</quick_text></wordsChunk>'.$tidyContent;
			}
			
			if(strrpos($tidyContent, '</quick_text></wordsChunk>') === (strlen($tidyContent) - strlen('</quick_text></wordsChunk>')))
			{
				$tidyContent = substr($tidyContent, 0, strrpos($tidyContent, '</quick_text></wordsChunk'));
			}
			
			return $tidyContent;
		} else
		{
			$this->pages = array('page');
			$this->currentPage = 1;
			
			return $content;
		}
	}
	
	/**
	 * Get the number of pages
	 * @param string $content
	 * @access public
	 * @return unknown_type
	 */
	public function getPages($content, $length)
	{
		$chunks = preg_split('/<\/quick_text><\/wordsChunk>/', $content, -1);

		$r = 0;
		$tmpPages = array();
		for($i = 0; $i < count($chunks); $i++)
		{
			if (strlen($this->pages[$r] . $chunks[$i].' ') < $length)
			{
				$tmpPages[$r] .= $chunks[$i] . '</quick_text></wordsChunk>';
			} else
			{
				$r++;
				$tmpPages[$r] .= $chunks[$i] . '</quick_text></wordsChunk>';
			}
		}
		
		// Order pages correctly
		foreach($tmpPages as $val)
		{
			$this->pages[] = $val;
		}

		// which page are we on?
		if(isset($_GET['page']))
		{
			$this->currentPage = $_GET['page'];
		} else
		{
			$this->currentPage = 1;
		}
	}
	
	/**
	 * Main function to build a tag
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag($options)
	{
		if(in_array($this->__getTag(), $this->noRowTags))
		{
			$options['row'] = false;
			$options['cell'] = false;
		}
		
		$string = '';
		$string .= $this->__do_tag_start($options);
		$string .= $this->__do_tag_contents($options);
		$string .= $this->__do_tag_end($options);
		return $string;
	}
	
	/**
	 * Start an element off by building a row and cell if needed and setting up a tag prefix
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag_start($options)
	{
		if(isset($options['start']) AND $options['start'] == false) 
		{
			return;
		}
		
		$string = null;
		
		if(!isset($options['row']) OR $options['row'] !== false)
		{
			$string .= $this->__do_tag_row_start($options);
		}
		if(!isset($options['cell']) OR $options['cell'] !== false)
		{
			$string .= $this->__do_tag_cell_start($options);
		}
		
		$string .= '<'.$this->tagPrefix;
		
		if($this->tagPrefix)
		{
			$tag = $this->tagPrefix.ucwords($this->tag);
			$string .= ucwords($this->tag);
		} else
		{
			$tag = $this->tag;
			$string .= $this->tag;
		}
		foreach($this->universalAttributes as $val)
		{
			if(isset($options[$val]))
			{
				$string .= ' '.$val.'="'.$options[$val].'"';
			}
		}
		
		if(isset($this->schema[$tag]['attributes']))
		{
			foreach($this->schema[$tag]['attributes'] as $val)
			{
				if(isset($options[trim($val)]))
				{
					$string .= ' '.trim($val).'="'.$options[trim($val)].'"';
				}
			}
		}
		
		if(!isset($this->schema[$tag]['selfClosing']) OR $this->schema[$tag]['selfClosing'] == false)
		{ 
			$string .= '>';
		}
		
		return $string;
	}
	
	/**
	 * Build the internal contents of an element
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag_contents($options)
	{
		if(isset($options['contents']) AND $options['contents'] == false) 
		{
			return;
		}
		
		$string = null;
	
		$tag = $this->__getTag();
		
		if(isset($this->schema[$tag]['children']) AND !empty($this->schema[$tag]['children']))
		{
			foreach($this->schema[$tag]['children'] as $val)
			{
				if((isset($this->schema[$val]['parent']) AND ($this->schema[$val]['parent'] == $this->__getTag())) OR !isset($this->schema[$val]['parent']))
				{
					if(isset($options[$val]))
					{
						$string .= '<'.$val.'>'.$options[$val].'</'.$val.'>';
					}
				}
			}
		}
		if(isset($options['children']))
		{
			$childString = null;
			$this->parentTag = $this->tag;
			$tmpTagPrefix = $this->tagPrefix;
			
			foreach($options['children'] as $child)
			{
				if(isset($child['tag']))
				{
					$this->tag = $child['tag'];
					
					$options = array();
					
					// Build up any attributes
					if(isset($this->schema[$this->tag]['attributes']))
					{
						foreach($this->schema[$this->tag]['attributes'] as $attVal)
						{
							if(isset($child[$attVal]))
							{
								$options[$attVal] = $child[$attVal];
							}
						}
					}
					
					if(isset($child['options']))
					{
						$options = array_merge($options, $child['options']);
					}
					
					if(method_exists($this, $this->tag))
					{
						$childString .= $this->{$this->tag}($options);
					} else
					{
						$childString .= $this->__do_tag($options);
					}
				}
			}
			
			$this->tagPrefix = $tmpTagPrefix;
			$this->tag = $this->parentTag;
			$string .= $childString;
		}

		// Set a direct value into a tag
		if(isset($this->schema[$tag]['direct']) AND $this->schema[$tag]['direct'] == true)
		{
			$string .= $options['value'];
		}
		return $string;
	}
	
	/**
	 * Close elements properly
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag_end($options)
	{
		if(isset($options['end']) AND $options['end'] == false) 
		{
			return;
		}
		
		$string = '';
		
		if(isset($this->schema[$this->tag]['selfClosing']) AND $this->schema[$this->tag]['selfClosing'] == true)
		{ 
			$string .= ' />';
		} else
		{
			$string .= '</'.$this->tagPrefix;
			if($this->tagPrefix)
			{
				$string .= ucwords($this->tag);
			} else
			{
				$string .= $this->tag;
			}
			$string .= '>';
	
			if(!isset($options['cell']) OR $options['cell'] !== false)
			{
				$string .= $this->__do_tag_cell_end($options);
			}
			if(!isset($options['row']) OR $options['row'] !== false)
			{
				$string .= $this->__do_tag_row_end($options);
			}
		}
		
		return $string;
	}
	
	/**
	 * Open an elements row
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag_row_start($options)
	{
		$string = '<row';
		
		if(isset($options['rowClass']))
		{
			$string .= ' class="'.$options['rowClass'].'"';
		}
		if(isset($options['rowId']))
		{
			$string .= ' id="'.$options['rowId'].'"';
		}
		$string .= '>';
		return $string;
	}
	
	/**
	 * Close a row
	 * @access private
	 * @return string
	 */
	private function __do_tag_row_end()
	{
		return '</row>';
	}
	
	/**
	 * Open an elements cell
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag_cell_start($options)
	{
		$string = '<cell';
		
		if(isset($options['cellClass']))
		{
			$string .= ' class="'.$options['cellClass'].'"';
		}
		if(isset($options['cellId']))
		{
			$string .= ' id="'.$options['cellId'].'"';
		}
		$string .= '>';
		return $string;
	}
	
	/**
	 * Close a cell
	 * @param array $options
	 * @access private
	 * @return string
	 */
	private function __do_tag_cell_end($options)
	{
		return '</cell>';
	}
	
	/**
	 * Get proper tag
	 * @access private
	 * @return string
	 */
	private function __getTag()
	{
		if($this->tagPrefix)
		{
			return $this->tagPrefix.ucwords($this->tag);
		} else
		{
			return $this->tag;
		}
	}
	
	/**
	 * Work out external link
	 * @param array $options
	 * @access private
	 * @return void
	 */
	private function __doExternal($options)
	{
		$this->tagPrefix = null;
		
		if(!isset($options['external']) || $options['external'] == true)
		{
			$this->tagPrefix = 'external';
		}
	}
}
?>
Return current item: Wapple Architect Mobilization