code:
<?php
/*
	#######################################################
	#  Viddler API / PHP Wrapper
	#  By: Colin Devroe | cdevroe@viddler.com
	#
	#  Docs: http://wiki.developers.viddler.com/index.php/Phpviddler
	#
	#  License(s): Licensed under:
	#  MIT (MIT-LICENSE.txt)
    #
    #  Third-party code:
    #  XML Library by Keith Devens
	#  xmlparser.php
	#
	#  Version 0.3
	########################################################
*/

class Phpviddler {

	var $apiKey = '01172c643b9743485249534a4441564953151';
	var $viddlerREST = 'http://api.viddler.com/rest/v1/'; // REST URL Version 1.0
	var $xml; // Raw XML returned by API
	var $response; // Array of results
	var $parser = false; // Use the included XML parser? Default: true.

	// Optional
	var $uploaddir = false; // Used for temporary upload directory.
/*##########  User functions ########### */
	/* viddler.users.auth
	/ accepts: $userInfo = array
	/ returns: array - sessionid (if not asking for record_token)
	/ returns: array - sessionid and recordtoken (if asking for record token)
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.users.auth
	*/
	function user_authenticate($userInfo) {
		$args = '';
		$args = $this->buildArguments($userInfo); // Arguments as string
		//var_dump( $args ); exit;
		$xml = $this->sendRequest('viddler.users.auth',$args); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				// Return record token too? Or just session id?
				if (!$args['record_token']) {
					return $response['auth']['sessionid'];
				} else {
					return $response['auth'];
				}
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* viddler.users.getProfile
	/ accepts: $username = string
	/ returns: array - user's profile
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.users.getProfile
	*/
	function user_profile($username) {

		$xml = $this->sendRequest('viddler.users.getProfile','user='.$username); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['user'];
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* viddler.users.setOptions
	/ accepts: $options = array
	/ returns: string - number of options updated
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.users.setOptions
	*/
	function user_setoptions($options) {
		$args = '';
		$args = $this->buildArguments($options); // Arguments as string

		$xml = $this->sendRequest('viddler.users.setOptions',$args); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['user'];
			}
		} else {
			return $xml;
		}
	return false;
	}

/*##########  Video functions ########### */

	/* viddler.videos.upload
	/ requires: POST HTTP Method
	/ accepts: $videoInfo = array
	/ returns: array - info about video uploaded
	doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.upload
	*/
	function video_upload($videoInfo) {
		$args = '';
		$args = $this->buildArguments($videoInfo,'array'); // Arguments as array

		$xml = $this->sendRequest('viddler.videos.upload',$args); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			// Deletes the uploaded file from the server
			//if ($this->uploaddir) {
			//	unlink($this->uploaddir.$_FILES['file']['name']);
			//}

			if ($response['error']) {
				return $response;
			} else {
				return $response['video'];
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* viddler.videos.getRecordToken
	/ accepts: $sessionid = string
	/ returns: string - token needed for recording with webcam
	}
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.getRecordToken
	/ Instructions for use: http://wiki.developers.viddler.com/index.php/Record_With_Webcam_API
	*/
	function video_getrecordtoken($sessionid) {

		$xml = $this->sendRequest('viddler.videos.getRecordToken','sessionid='.$sessionid); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['record_token'];
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* Not a method...
	/ accepts: $token = string
	/ returns: string - html for recorder embed with token included.
	}
	/ doc: None.
	*/
	function video_getrecordembed($token) {

		if (!$token) return false;

		$html = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="449" height="400" id="viddler_recorder" align="middle">
			<param name="allowScriptAccess" value="always" />
			<param name="allowNetworking" value="all" />
			<param name="movie" value="http://www.viddler.com/flash/recorder.swf" />
			<param name="quality" value="high" />
			<param name="scale" value="noScale">
			<param name="bgcolor" value="#000000" />
			<param name="flashvars" value="fake=1&recordToken='.$token.'" />
			<embed src="http://www.viddler.com/flash/recorder.swf" quality="high" scale="noScale" bgcolor="#000000" allowScriptAccess="always" allowNetworking="all" width="449" height="400" name="viddler_recorder" flashvars="fake=1&recordToken='.$token.'" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
		</object>';

		return $html;
	}

	/* viddler.videos.getStatus
	/ accepts: $videoID = string
	/ returns: array - info about video's upload status
	/ Method specific responses {
	    1: Waiting in encode queue (failed=0)
		2: Encoding (failed=0)
		3: Encoding process failed (failed=1)
		4: Ready (failed=0)
		5: Deleted (failed=0)
		6: Wrong priviledges (failed=0)
	}
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.getStatus
	*/
	function video_status($videoID) {

		$xml = $this->sendRequest('video.status','video_id='.$videoID); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['video_status'];
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* viddler.videos.getDetails
	/ accepts: $sessionid and $videoID = string
	/ returns: array - info about video's upload status
	/ Method specific responses {
	    1: Waiting in encode queue (failed=0)
		2: Encoding (failed=0)
		3: Encoding process failed (failed=1)
		4: Ready (failed=0)
		5: Deleted (failed=0)
		6: Wrong priviledges (failed=0)
	}
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.getDetails
	*/
	function video_details($sessionid,$videoID) {

		$xml = $this->sendRequest('viddler.videos.getDetails','sessionid='.$sessionid.'&video_id='.$videoID); // Get XML response

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['video'];
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* viddler.videos.getByUser
	/ accepts: $user = string, $page = string, $per_page = string
	/ returns: array - information about the videos matching this user
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.getByUser
	*/
	function videos_listbyuser($user,$page =1,$per_page =5) {

		 // Get XML response
		$xml = $this->sendRequest('viddler.videos.getByUser','user='.$user.'&page='.$page.'&per_page='.$per_page);

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['video_list'];
			}
		} else {
			return $xml;
		}
	}

	/* viddler.videos.getByTag
	/ accepts: $tag = string, $page = string, $per_page = string
	/ returns: array - information about videos matching this tag
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.getByTag
	*/
	function videos_listbytag($tag,$page =1,$per_page =5) {

		 // Get XML response
		$xml = $this->sendRequest('viddler.videos.getByTag','tag='.$tag.'&page='.$page.'&per_page='.$per_page);

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['video_list'];
			}
		} else {
			return $xml;
		}
	return false;
	}

	/* viddler.videos.getFeatured
	/ accepts: nothing.
	/ returns: array - information about videos that are featured
	/ doc: http://wiki.developers.viddler.com/index.php/Viddler.videos.getFeatured
	*/
	function videos_listfeatured() {

		 // Get XML response
		$xml = $this->sendRequest('viddler.videos.getFeatured','');

		// Use included parser?
		if ($this->parser) {
			// Several steps
			// 1. Convert XML into an array
			// 2. Check for errors
			//    i. Return array of error number, short, and long description
			// 3. Return multidimensional array of response.
			$response = $this->checkErrors(XML_unserialize($xml));

			if ($response['error']) {
				return $response;
			} else {
				return $response['video_list'];
			}
		} else {
			return $xml;
		}
	return false;
	}

/*##########  Misc. Functions ########### */

	// Error checking
	function checkErrors($response) {

		if ($response['error']) {

			switch($response['error']) {

				case '1':
					$errorshort = 'An internal error has occurred.';
					break;
				case '2':
					$errorshort = 'Bad argument format.';
					break;
				case '3':
					$errorshort = 'Unknown argument specified.';
					break;
				case '4':
					$errorshort = 'Missing required argument for this method.';
					break;
				case '5':
					$errorshort = 'No method specified.';
					break;
				case '6':
					$errorshort = 'Unknown method specified.';
					break;
				case '7':
					$errorshort = 'API key missing.';
					break;
				case '8':
					$errorshort = 'Invalid or unknown API key specified.';
					break;
				case '9':
					$errorshort = 'Invalid or expired sessionid.';
					break;
				case '10':
					$errorshort = 'HTTP method used not allowed on this method.';
					break;
				case '100':
					$errorshort = 'Video could not be found.';
					break;
				case '101':
					$errorshort = 'Username not found.';
					break;
				case '102':
					$errorshort = 'This account has been suspended.';
					break;
				case '103':
					$errorshort = 'Password incorrect for this username.';
					break;
				case '104':
					$errorshort = 'Terms of Service not accepted by user.';
					break;
				case '105':
					$errorshort = 'Username already in use.';
					break;
				case '106':
					$errorshort = 'Email address already in use.';
					break;
				case '200':
					$errorshort = 'The file is too large. Please limit to 500Mb.';
					break;
				default:
					$errorshort = 'An unknown error has occured.';
					break;
			} // End switch

			$error = array('error' => array('number'=>$response['error'],'shortdesc'=>$errorshort));

			return $error;
		}

		return $response;

	}

	/**
	 * Build arguments to use for a request to the API
	 *
	 * @param array $p An associative array of parameters
	 * @param string $return_type Optional return type of parameters ['array'|'string']
	 * @return mixed The filtered arguments in the format requested
	 */
	public function buildArguments( $p, $return_type = 'string') {
		$args = array();
		foreach ($p as $key => $value) {

			// Skip method request name and submit button
			switch($key) {
				case 'method':
				case 'submit':
				case 'MAX_FILE_SIZE':
					continue;
			}

			$args[$key] = $value;

		} // end foreach

		switch($return_type) {
			// If array assume uploading
			case 'array':
				$uploadfile = $this->uploaddir . basename($_FILES['file']['name']);

				if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)) {
					$args['file'] = "@{$uploadfile}";
				}
				break;

			// If String, chop off last ampersand
			case 'string':
			default:
				$args = http_build_query($args, null, '&');
				break;
		}

		return $args;
	}

	// Send REST request
	function sendRequest($method,$args) {

		// Build Request URL
		$reqURL = $this->viddlerREST.'?api_key='.$this->apiKey.'&method='.$method;
		if ($method != 'viddler.videos.upload') $reqURL .= '&'.$args;

		// Send request via CURL
		$curl_handle = curl_init();
		curl_setopt ($curl_handle, CURLOPT_URL, $reqURL); // Request URL
		curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1); // Return as string
		curl_setopt ($curl_handle, CURLOPT_CONNECTTIMEOUT, 1); // Fail if timeout

		// If sending a file, change to POST instead of GET
		if ($method == 'viddler.videos.upload') {
			curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);
		}

		$response = curl_exec($curl_handle); // Call!

		if (!$response)	$response = curl_error($curl_handle);

		curl_close($curl_handle); // Close connection

		// When CURL doesn't work, use this.
		//$response = file_get_contents($reqURL);

		// Return XML response as string
		if (!$response) {
			return false; // 'There is no response. CURL might not by allowed?
'.$reqURL.'

';
		}

		return $response;

	} // End sentReq();

}

/**
* Viddler Silo
*/

class ViddlerSilo extends Plugin implements MediaSilo
{
	const SILO_NAME = 'Viddler';

	protected $cache = array();

	/*
	// add a rewrite rule for our auto-generated video page.
	public function filter_rewrite_rules( $rules )	{
		$rules[] = new RewriteRule(array(
			'name' => 'viddlerlist',
			'parse_regex' => '/^sillytv[\/]{0,1}$/i',
			'build_str' => 'viddlerlist',
			'handler' => 'ViddlerAdminHandler',
			'action' => 'display_viddlerlist',
			'priority' => 7,
			'is_active' => 1,
		));

		return $rules;
	}
	*/

	/**
	* Initialize some internal values when plugin initializes
	*/
	public function action_init()
	{
		// add some js to the admin header
		Stack::add( 'admin_header_javascript',  $this->get_url(true) . 'vidfuncs.js', 'viddlerjs', array('media','jquery') );
		$this->viddler = new Phpviddler();
	}

	/**
	* Return basic information about this silo
	*     name- The name of the silo, used as the root directory for media in this silo
	*/
	public function silo_info()
	{
		if($this->is_auth()) {
			return array('name' => self::SILO_NAME, 'icon' => URL::get_from_filesystem(__FILE__) . '/icon.png');
		}
		else {
			return array();
		}
	}

	/**
	* Return directory contents for the silo path
	*
	* @param string $path The path to retrieve the contents of
	* @return array An array of MediaAssets describing the contents of the directory
	*/
	public function silo_dir($path)
	{
		$user = User::identify()->info->viddler__username;

		if(Cache::has('viddler:videos:' . $user)) {
			$pre = Cache::get('viddler:videos:' . $user);
		}
		else {
			$pre = $this->viddler->videos_listbyuser( $user, '', 20 );
			Cache::set('viddler:videos:' . $user, $pre);
		}
		$xml = new SimpleXMLElement( $pre );
		$results = array();
		foreach( $xml->video as $video ) {

			$props = array();
			foreach($video->children() as $name => $value) {
				$props[$name] = (string)$value;
			}
			$props['filetype'] = 'viddler';

			$asset = new MediaAsset(
				self::SILO_NAME . '/' . $path . ($path == '' ? '' : '/') . $video->id,
				false,
				$props
			);
			$results[] = $asset;

			//echo '
thumbnail_url . '" width="150px">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="370" id="viddler_chrisjdavis_' . $video->id . '"><param name="movie" value="http://www.viddler.com/player/' . $video->id . '/" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><embed src="http://www.viddler.com/player/' . $video->id . '/" width="437" height="370" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_chrisjdavis" ></embed></object>

';
		}
		return $results;
	}

	/**
	* Get the file from the specified path
	*
	* @param string $path The path of the file to retrieve
	* @param array $qualities Qualities that specify the version of the file to retrieve.
	* @return MediaAsset The requested asset
	*/
	public function silo_get($path, $qualities = null)
	{
	}

	/**
	* Get the direct URL of the file of the specified path
	*
	* @param string $path The path of the file to retrieve
	* @param array $qualities Qualities that specify the version of the file to retrieve.
	* @return string The requested url
	*/
	public function silo_url( $path, $qualities = null )
	{
		$id = basename($path);
		$video = $this->cache[$id];
		if(isset($qualities['size']) && $qualities['size']=='thumbnail') {
			$url = $video->thumbnail_url;
		}
		else {
			$url = $video->url;
		}
		return $url;
	}

	/**
	* Create a new asset instance for the specified path
	*
	* @param string $path The path of the new file to create
	* @return MediaAsset The requested asset
	*/
	public function silo_new($path)
	{
	}

	/**
	* Store the specified media at the specified path
	*
	* @param string $path The path of the file to retrieve
	* @param MediaAsset $ The asset to store
	*/
	public function silo_put($path, $filedata)
	{
	}

	/**
	* Delete the file at the specified path
	*
	* @param string $path The path of the file to retrieve
	*/
	public function silo_delete($path)
	{
	}

	/**
	* Retrieve a set of highlights from this silo
	* This would include things like recently uploaded assets, or top downloads
	*
	* @return array An array of MediaAssets to highlihgt from this silo
	*/
	public function silo_highlights()
	{
	}

	public function controls()
	{
		echo '

Upload</li
Record

Viddler Stream

';
	}

	public function silo_upload_form()
	{
		echo '<form name="viddler_upload"></form>';
	}

	public function upload_form()
	{
	?>

Upload a Video

		<form name="viddler_upload">

Video

<input type="file" name="viddler_file">

Video Title

<input type="text" name="viddler_title">

Video Tags

<input type="text" name="viddler_tags">

Video Description

<textarea name="viddler_desc"></textarea>

<input type="submit" value="Upload Video" id="execute_viddler">

		</form>

Record a Video

<?php
			$user = User::identify()->info->viddler__username;
			$pass = User::identify()->info->viddler__password;
			$auth = $this->viddler->user_authenticate( array( 'user' => $user, 'password' => $pass, 'get_record_token' => 1 ) );
			$sid = new SimpleXMLElement( $auth );
			$mt = $test->video_getrecordtoken( $sid->sessionid );
			$token = new SimpleXMLElement( $mt );
			$embed = $test->video_getrecordembed( $token );
			echo $embed;
			?>

	<?php
	}

	/**
	* Retrieve the permissions for the current user to access the specified path
	*
	* @param string $path The path to retrieve permissions for
	* @return array An array of permissions constants (MediaSilo::PERM_READ, MediaSilo::PERM_WRITE)
	*/
	public function silo_permissions($path)
	{
	}

	/**
	* Add actions to the plugin page for this plugin
	* The authorization should probably be done per-user.
	*
	* @param array $actions An array of actions that apply to this plugin
	* @param string $plugin_id The string id of a plugin, generated by the system
	* @return array The array of actions to attach to the specified $plugin_id
	*/
	public function filter_plugin_config( $actions, $plugin_id ) {
		if ( $plugin_id == $this->plugin_id() ) {
			$viddler_ok = $this->is_auth();
			if( $viddler_ok ) {
				$actions[]= 'Log Out';
			} else {
				$actions[]= 'Log In';
			}
		}
		return $actions;
	}

	/**
	* Respond to the user selecting an action on the plugin page
	*
	* @param string $plugin_id The string id of the acted-upon plugin
	* @param string $action The action string supplied via the filter_plugin_config hook
	*/
	public function action_plugin_ui( $plugin_id, $action ) {
		switch ( $action ) {
			case 'Log In':
				$ui = new FormUI( strtolower( get_class( $this ) ) );
				$ui->append('text', 'username', 'user:viddler__username', 'Viddler Username:');
				$ui->append('password', 'password', 'user:viddler__password', 'Viddler Password:');
				$ui->append('submit', 'submit', 'Log In');
				$ui->on_success( array( $this, 'updated_config' ) );
				$ui->out();

/*
				if( $this->is_auth() ) {
					$deauth_url= URL::get('admin', array('page' => 'plugins', 'configure' => $this->plugin_id(), 'action' => 'Log Out')) . '#plugin_options';
					echo "
You have successfully logged into Vidder via Habari.
";
					echo "
Do you want to log out?
";
				}
				else {
					$username = $ui->username->value;
					$password = $ui->password->value;
					if($username != '' && $password != '') {
						$auth= $this->viddler->user_authenticate( array( 'user' => $username, 'password' => $password ) );

						$xml= new SimpleXMLElement( $auth );
						User::identify()->info->viddler__token = (string) $xml->session_id;
					}
				}
*/
				break;
			case 'Log Out':
				unset(User::identify()->info->viddler__token);
				$reauth_url = URL::get('admin', array('page' => 'plugins', 'configure' => $this->plugin_id(), 'action' => 'Log In')) . '#plugin_options';
				echo '
The Viddler Silo Plugin session has been logged out.
';
				echo "
Do you want to log in again?
";
				break;
		}
	}

	/**
   * Returns true if plugin config form values defined in action_plugin_ui should be stored in options by Habari
   * @return boolean True if options should be stored
   **/
  public function updated_config($ui)
  {
		$username = $ui->username->value;
		$password = $ui->password->value;
		if($username != '' && $password != '') {
			$auth = $this->viddler->user_authenticate( array( 'user' => $username, 'password' => $password ) );

			$xml = new SimpleXMLElement( $auth );
			$token = (string) $xml->sessionid;
			if($token == '') {
		  	$ui->set_option('success_message', _t('The username and password you supplied failed to log in to Viddler.'));
			}
			else {
		  	$ui->save();
				User::identify()->info->viddler__token = $token;
				User::identify()->info->commit();
		  	return  '
' . _t('You have logged in to Viddler.') . '
';
			}
		}

    return false;
  }

	private function is_auth()
	{
		$token = User::identify()->info->viddler__token;
		if( $token != '' ) {
			return true;
		} else {
			return false;
		}
	}

	public function action_admin_header( $theme )
	{
		if(Controller::get_var('page') == 'publish') {
			$header = <<< HEADER
habari.media.output.viddler = {display: function(index, fileobj) {
	habari.editor.insertSelection( ''+
		'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="370" id="viddler_' + fileobj.basename + '">' +
		'<param name="movie" value="http://www.viddler.com/player/' + fileobj.basename + '/" />' +
		'<param name="allowScriptAccess" value="always" />' +
		'<param name="allowFullScreen" value="true" />' +
		'<embed src="http://www.viddler.com/player/' + fileobj.basename + '/" width="437" height="370" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" ></embed>' +
		'</object>'
	);
}}
HEADER;
		Stack::add( 'admin_header_javascript',  $header, 'viddlerinline', array('viddlerjs', 'media','jquery') );

		}
	}

	/**
	 * Produce a link for the media control bar that causes a specific panel to be displayed
	 *
	 * @param string $path The path to pass
	 * @param string $path The panel to display
	 * @param string $title The text to use for the link in the control bar
	 * @return string The link to create
	 */
	public function link_panel( $path, $panel, $title )
	{
		return '' . $title . '';
	}

	/**
	 * Provide controls for the media control bar
	 *
	 * @param array $controls Incoming controls from other plugins
	 * @param MediaSilo $silo An instance of a MediaSilo
	 * @param string $path The path to get controls for
	 * @param string $panelname The name of the requested panel, if none then emptystring
	 * @return array The altered $controls array with new (or removed) controls
	 *
	 * @todo This should really use FormUI, but FormUI needs a way to submit forms via ajax
	 */
	public function filter_media_controls( $controls, $silo, $path, $panelname )
	{
		$class = __CLASS__;
		if($silo instanceof $class) {
			if(User::identify()->can('upload_viddler')) {
				$controls[] = $this->link_panel(self::SILO_NAME . '/' . $path, 'upload', 'Upload');
				$controls[] = $this->link_panel(self::SILO_NAME . '/' . $path, 'record', 'Record');
			}
		}
		return $controls;
	}

	/**
	 * Provide requested media panels for this plugin
	 *
	 * @param string $panel The HTML content of the panel to be output in the media bar
	 * @param MediaSilo $silo The silo for which the panel was requested
	 * @param string $path The path within the silo (silo root omitted) for which the panel was requested
	 * @param string $panelname The name of the requested panel
	 * @return string The modified $panel to contain the HTML output for the requested panel
	 *
	 * @todo Move the uploaded file from the temporary location to the location indicated by the path field.
	 */
	public function filter_media_panels( $panel, $silo, $path, $panelname)
	{
		$class = __CLASS__;
		if($silo instanceof $class) {
			switch($panelname) {
				case 'record':
					$user = User::identify()->info->viddler__username;
					$pass = User::identify()->info->viddler__password;
					$auth = $this->viddler->user_authenticate( array( 'user' => $user, 'password' => $pass, 'get_record_token' => 1, 'record_token' => 1 ) );
					$sid = new SimpleXMLElement( $auth );
					$rt = $sid->record_token;
					$panel .= "
";
					$panel .= $this->viddler->video_getrecordembed( $rt );
					$panel .= '
';
					break;
				case 'upload':
					if(isset($_FILES['file'])) {
						$size = Utils::human_size($_FILES['file']['size']);
						$panel .= "

File Uploaded: {$_FILES['file']['name']} ($size)
";

						$path = self::SILO_NAME . '/' . preg_replace('%\.{2,}%', '.', $path). '/' . $_FILES['file']['name'];
						$asset = new MediaAsset($path, false);
						$asset->upload($_FILES['file']);

						if($asset->put()) {
							$panel .= '
File added successfully.
';
						}
						else {
							$panel .= '
File could not be added to the silo.
';
						}

						$panel .= '
Browse the current silo path.

';
					}
					else {

						$fullpath = self::SILO_NAME . '/' . $path;
						$form_action = URL::get('admin_ajax', array('context' => 'media_panel'));
						$panel .= <<< UPLOAD_FORM
<form enctype="multipart/form-data" method="post" id="simple_upload" target="simple_upload_frame" action="{$form_action}" class="span-10" style="margin:0px auto;text-align: center">

Upload to: /{$path}

<input type="file" name="file"><input type="submit" name="upload" value="Upload">
	<input type="hidden" name="path" value="{$fullpath}">
	<input type="hidden" name="panel" value="{$panelname}">

</form>

UPLOAD_FORM;

				}
			}
		}
		return $panel;
	}

}

/*
// This is an auto-generated video page.  There is a rewrite rules array in the plugin
// above that needs to be uncommented as well.  Not sure if we actually want this in
// the plugin, which is why it is commented out.

class ViddlerAdminHandler extends ActionHandler
{
	private $vids;
	private $theme= null;

	public function __construct() {
		$this->theme= Themes::create();
	}

	public function act_display_viddlerlist() {
		$this->load_vids();
		$this->theme->assign( 'vids', $this->vid );
		$this->theme->display( 'vids' );
	}

	public function load_vids() {
		$user= Options::get( 'viddlersilo:username_' . User::identify()->id );
		$viddler= new Phpviddler();
		$pre= $viddler->videos_listbyuser( $user, '', 20, 'view_count' );
		$xml= new SimpleXMLElement( $pre );
			foreach( $xml->video as $video ) {
				$this->vid[]= $video;
			}
		}
}
*/
?>


code:
<?xml version="1.0" encoding="utf-8" ?>
<pluggable type="plugin">
	<name>Viddler Media Silo</name>
	<license url="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software License 2.0</license>

	<author url="http://habariproject.org/">The Habari Community</author>

	<version>1.0</version>
	<url>http://habariproject.org/</url>
	<description><![CDATA[Implements basic Viddler integration.]]></description>

	<copyright>2009</copyright>
</pluggable>

repo_name: DaSourcerer/habari


code:
$(document).ready(function() {
	$('#vupload').click(function() {
		$('.media').hide();
		$('#viddlerrecord').hide();
		$('#viddlerform').animate({ "opacity": "toggle" }, "slow");
		return false;
	});

	$('#vrecord').click(function() {
		$('.media').hide();
		$('#viddlerform').hide();
		$('#viddlerrecord').animate({ "opacity": "toggle" }, "slow");
		return false;
	});

	$('#vstream').click(function() {
		$('#viddlerform').hide();
		$('#viddlerrecord').hide();
		$('.media').show();
		return false;
	});
});


code:
<?php

define( 'IMPORT_BATCH', 100 );

/**
 * WordPress Importer - Imports data from WordPress into Habari
 *
 * @package Habari
 */
class WPImport extends Plugin implements Importer
{
	private $supported_importers = array();

	/**
	 * Initialize plugin.
	 * Set the supported importers.
	 **/
	public function action_init()
	{
		$this->supported_importers = array( _t( 'WordPress Database' ) );
	}

	/**
	 * Return a list of names of things that this importer imports
	 *
	 * @return array List of importables.
	 */
	public function filter_import_names( $import_names )
	{
		return array_merge( $import_names, $this->supported_importers );
	}

	/**
	 * Plugin filter that supplies the UI for the WP importer
	 *
	 * @param string $stageoutput The output stage UI
	 * @param string $import_name The name of the selected importer
	 * @param string $stage The stage of the import in progress
	 * @param string $step The step of the stage in progress
	 * @return output for this stage of the import
	 */
	public function filter_import_stage( $stageoutput, $import_name, $stage, $step )
	{
		// Only act on this filter if the import_name is one we handle...
		if( !in_array( $import_name, $this->supported_importers ) ) {
			// Must return $stageoutput as it may contain the stage HTML of another importer
			return $stageoutput;
		}

		$inputs = array();

		// Validate input from various stages...
		switch( $stage ) {
		case 1:
			if( count( $_POST ) ) {
				$valid_fields = array( 'db_name','db_host','db_user','db_pass','db_prefix', 'category_import', 'utw_import' );
				$inputs = array_intersect_key( $_POST->getArrayCopy(), array_flip( $valid_fields ) );
				if( $this->wp_connect( $inputs['db_host'], $inputs['db_name'], $inputs['db_user'], $inputs['db_pass'], $inputs['db_prefix'] ) ) {
					$stage = 2;
				}
				else {
					$inputs['warning']= _t( 'Could not connect to the WordPress database using the values supplied. Please correct them and try again.' );
				}
			}
			break;
		}

		// Based on the stage of the import we're on, do different things...
		switch( $stage ) {
		case 1:
		default:
			$output = $this->stage1( $inputs );
			break;
		case 2:
			$output = $this->stage2( $inputs );
		}

		return $output;
	}

	/**
	 * Create the UI for stage one of the WP import process
	 *
	 * @param array $inputs Inputs received via $_POST to the importer
	 * @return string The UI for the first stage of the import process
	 */
	private function stage1( $inputs )
	{
		$default_values = array(
			'db_name' => '',
			'db_host' => 'localhost',
			'db_user' => '',
			'db_pass' => '',
			'db_prefix' => 'wp_',
			'warning' => '',
			'category_import' => 1,
			'utw_import' => 0,
		 );
		$inputs = array_merge( $default_values, $inputs );
		extract( $inputs );
		if( $warning != '' ) {
			$warning = "
{$warning}
";
		}

		$output = '
' . _t('Habari will attempt to import from a WordPress Database.') . '
';
		$output .=	$warning;
		$output .= '
' . _t('Please provide the connection details for an existing WordPress database:') . '
';
		$output .= '
';
		$output .= '' . _t('Database Name') . '<input type="text" name="db_name" value="' . $db_name . '" tab index="1">';
		$output .= '
';
		$output .= '
';
		$output .= '' . _t('Database Host') . '<input type="text" name="db_host" value="' . $db_host . '" tab index="2">';
		$output .= '
';
		$output .= '
';
		$output .= '' . _t('Database User') . '<input type="text" name="db_user" value="' . $db_user . '" tab index="3">';
		$output .= '
';
		$output .= '
';
		$output .= '' . _t('Database Password') . '<input type="password" name="db_pass" value="' . $db_pass . '" tab index="4">';
		$output .= '
';
		$output .= '
';
		$output .= '' . _t('Table Prefix') . '<input type="text" name="db_prefix" value="' . $db_prefix . '" tab index="5">';
		$output .= '
';
		$output .= '
';
		$output .= '' . _t('Import Category as Tag') . '<input type="checkbox" name="category_import" value="1" checked>';
		$output .= '
';
		$output .= '

';
		$output .= '<input type="hidden" name="stage" value="1">';
		$output .= '
' . _t('Extras - additional data from WordPress plugins') . '
';
		$output .= '
';
		$output .= '' . _t('Import tags from Ultimate Tag Warrior') . '';
		$output .= '<input type="checkbox" name="utw_import" value="1" tab index="6">';
		$output .= '
';
		$output .= '
';
		$output .= '<input type="submit" class="button" name="import" value="' . _t('Import') . '" />';
		$output .= '
';

		return $output;
	}

	/**
	 * Create the UI for stage two of the WP import process
	 * This stage kicks off the ajax import.
	 *
	 * @param array $inputs Inputs received via $_POST to the importer
	 * @return string The UI for the second stage of the import process
	 */
	private function stage2( $inputs )
	{
		extract( $inputs );

		if ( ! isset( $category_import ) ) {
			$category_import = 0;
		}
		if ( ! isset( $utw_import ) ) {
			$utw_import = 0;
		}
		$ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_users' ) );
		EventLog::log(sprintf(_t('Starting import from "%s"'), $db_name));
		Options::set('import_errors', array());

		$vars = Utils::addslashes( array( 'host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass, 'prefix' => $db_prefix ) );

		$prompt = '
' . _t('Import In Progress') . '
';
		$prompt .= '
' . _t('Starting Import...') . '</div';
		$output = <<< WP_IMPORT_STAGE2
		{$prompt}

WP_IMPORT_STAGE2;
		return $output;
	}

	/**
	 * Attempt to connect to the WordPress database
	 *
	 * @param string $db_host The hostname of the WP database
	 * @param string $db_name The name of the WP database
	 * @param string $db_user The user of the WP database
	 * @param string $db_pass The user's password for the WP database
	 * @param string $db_prefix The table prefix for the WP instance in the database
	 * @return mixed false on failure, DatabseConnection on success
	 */
	private function wp_connect( $db_host, $db_name, $db_user, $db_pass, $db_prefix )
	{
		// Connect to the database or return false
		try {
			$wpdb = DatabaseConnection::ConnectionFactory( "mysql:host={$db_host};dbname={$db_name}" );;
			$wpdb->connect( "mysql:host={$db_host};dbname={$db_name}", $db_user, $db_pass );
			return $wpdb;
		}
		catch( Exception $e ) {
			return false;
		}
	}

	/**
	 * The plugin sink for the auth_ajax_wp_import_posts hook.
	 * Responds via authenticated ajax to requests for post importing.
	 *
	 * @param AjaxHandler $handler The handler that handled the request, contains $_POST info
	 */
	public function action_auth_ajax_wp_import_posts( $handler )
	{
		$valid_fields = array( 'db_name','db_host','db_user','db_pass','db_prefix','postindex', 'category_import', 'utw_import' );
		$inputs = array_intersect_key( $_POST->getArrayCopy(), array_flip( $valid_fields ) );
		extract( $inputs );
		if ( ! isset( $inputs['category_import'] ) ) {
			$inputs['category_import']= 0;
		}
		if ( ! isset( $inputs['utw_import'] ) ) {
			$inputs['utw_import']= 0;
		}

		$wpdb = $this->wp_connect( $db_host, $db_name, $db_user, $db_pass, $db_prefix );
		if( $wpdb ) {
			if( !DB::in_transaction() ) DB::begin_transaction();

			$has_taxonomy = count($wpdb->get_column( "SHOW TABLES LIKE '{$db_prefix}term_taxonomy';" ));

			$postcount = $wpdb->get_value( "SELECT count( id ) FROM {$db_prefix}posts;" );
			$min = $postindex * IMPORT_BATCH + ( $postindex == 0 ? 0 : 1 );
			$max = min( ( $postindex + 1 ) * IMPORT_BATCH, $postcount );

			$user_map = array();
			$user_info = DB::get_results( "SELECT user_id, value FROM {userinfo} WHERE name= 'wp_id';" );
			foreach( $user_info as $info ) {
				$user_map[$info->value]= $info->user_id;
			}
			echo '
' . _t( 'Importing posts %1$d - %2$d of %3$d.', array( $min, $max, $postcount ) ) . '
';
			$posts = $wpdb->get_results( "
				SELECT
					post_content as content,
					ID as id,
					post_title as title,
					post_name as slug,
					post_author as user_id,
					guid as guid,
					post_date as pubdate,
					post_modified as updated,
					post_status,
					post_type
				FROM {$db_prefix}posts
				WHERE post_type != 'revision' AND post_type != 'attachment'
				ORDER BY ID DESC
				LIMIT {$min}, " . IMPORT_BATCH
				, array(), 'Post' );

			$post_map = DB::get_column( "SELECT value FROM {postinfo} WHERE name='wp_id';");
			foreach( $posts as $post ) {
				if(in_array($post->id, $post_map)) {
					continue;
				}

				if ( $has_taxonomy ) {
					// Importing from >= WP2.3
					if ( $category_import == 1 ) {
						// Import WP category and tags as tags
						$taxonomies = "({$db_prefix}term_taxonomy.taxonomy= 'category' OR {$db_prefix}term_taxonomy.taxonomy= 'post_tag')";
					}
					else {
						// Import WP tags as tags
						$taxonomies = "{$db_prefix}term_taxonomy.taxonomy= 'post_tag'";
					}
					$tags = $wpdb->get_column(
						"SELECT DISTINCT name
						FROM {$db_prefix}terms
						INNER JOIN {$db_prefix}term_taxonomy
						ON ( {$db_prefix}terms.term_id= {$db_prefix}term_taxonomy.term_id AND {$taxonomies} )
						INNER JOIN {$db_prefix}term_relationships
						ON ({$db_prefix}term_taxonomy.term_taxonomy_id= {$db_prefix}term_relationships.term_taxonomy_id)
						WHERE {$db_prefix}term_relationships.object_id= {$post->id}"
						);
				}
				else {
					// Importing from < WP2.3
					if ( $category_import == 1 ) {
						// Import WP category as tags
						$tags = $wpdb->get_column(
							"SELECT category_nicename
							FROM {$db_prefix}post2cat
							INNER JOIN {$db_prefix}categories
							ON ( {$db_prefix}categories.cat_ID= {$db_prefix}post2cat.category_id )
							WHERE post_id= {$post->id}"
						 );
					} else {
						$tags = array();
					}
				}

				// we want to include the Ultimate Tag Warrior in that list of tags
				if ( $utw_import == 1 && count( DB::get_results( "show tables like 'post2tag'" ) ) ) {
					$utw_tags = $wpdb->get_column(
					"SELECT tag
					FROM {$db_prefix}post2tag
					INNER JOIN {$db_prefix}tags
					ON ( {$db_prefix}tags.tag_ID= {$db_prefix}post2tag.tag_id )
					WHERE post_id= {$post->id}"
					 );
					// UTW substitutes underscores and hyphens for spaces, so let's do the same
					$utw_tag_formatter = create_function( '$a', 'return preg_replace( "/_|-/", " ", $a );' );

					// can this be done in just two calls instead of three? I think so.
					$tags = array_unique( array_merge( $tags, array_map( $utw_tag_formatter, $utw_tags ) ) );
				}

				$post->content = MultiByte::convert_encoding( $post->content );
				$post->title = MultiByte::convert_encoding( $post->title );
				$tags = implode( ',', $tags );
				$tags = MultiByte::convert_encoding( $tags );

				$post_array = $post->to_array();
				switch( $post_array['post_status'] ) {
				case 'publish':
					$post_array['status']= Post::status( 'published' );
					break;
				default:
					$post_array['status']= Post::status( $post_array['post_status'] );
					break;
				}
				unset( $post_array['post_status'] );

				switch( $post_array['post_type'] ) {
				case 'post':
					$post_array['content_type']= Post::type( 'entry' );
					break;
				case 'page':
					$post_array['content_type']= Post::type( 'page' );
					break;
				default:
					// We're not inserting WP's media records.  That would be silly.
					continue;
				}
				unset( $post_array['post_type'] );

				$p = new Post( $post_array );
				$p->slug = $post->slug;
				if(isset($user_map[$p->user_id])) {
					$p->user_id = $user_map[$p->user_id];
				}
				else {
					$errors = Options::get('import_errors');
					$errors[] = _t('Post author id %1$s was not found in WP database, assigning post "%2$s" (WP post id #%3$d) to current user.', array($p->user_id, $p->title,$post_array['id']) );
					Options::set('import_errors', $errors);
					$p->user_id = User::identify()->id;
				}

				$p->guid = $p->guid; // Looks fishy, but actually causes the guid to be set.
				$p->tags = $tags;

				$p->info->wp_id = $post_array['id'];  // Store the WP post id in the post_info table for later

				try {
					$p->insert();
					$p->updated = $post_array['updated'];
					$p->update();
				}
				catch( Exception $e ) {
					EventLog::log($e->getMessage(), 'err', null, null, print_r(array($p, $e), 1));
					Session::error( $e->getMessage() );
					$errors = Options::get('import_errors');
					$errors[] = $p->title . ' : ' . $e->getMessage();
					Options::set('import_errors', $errors);
				}
			}

			if( DB::in_transaction() ) DB::commit();

			if( $max < $postcount ) {
				$ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_posts' ) );
				$postindex++;

				$vars = Utils::addslashes( array( 'host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass, 'prefix' => $db_prefix ) );

				echo <<< WP_IMPORT_AJAX1

WP_IMPORT_AJAX1;
			}
			else {
				$ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_comments' ) );

				$vars = Utils::addslashes( array( 'host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass, 'prefix' => $db_prefix ) );

				echo <<< WP_IMPORT_AJAX2

WP_IMPORT_AJAX2;

			}
		}
		else {
			EventLog::log(sprintf(_t('Failed to import from "%s"'), $db_name), 'crit');
			Session::error( $e->getMessage() );
			echo '
'._t( 'The database connection details have failed to connect.' ).'
';
		}
	}

	/**
	 * The plugin sink for the auth_ajax_wp_import_posts hook.
	 * Responds via authenticated ajax to requests for post importing.
	 *
	 * @param mixed $handler
	 * @return
	 */
	public function action_auth_ajax_wp_import_users( $handler )
	{
		$valid_fields = array( 'db_name','db_host','db_user','db_pass','db_prefix','userindex', 'category_import', 'utw_import' );
		$inputs = array_intersect_key( $_POST->getArrayCopy(), array_flip( $valid_fields ) );
		extract( $inputs );
		$wpdb = $this->wp_connect( $db_host, $db_name, $db_user, $db_pass, $db_prefix );
		if( $wpdb ) {
			if( !DB::in_transaction() ) DB::begin_transaction();
			$wp_users = $wpdb->get_results(
				"
					SELECT
						user_login as username,
						user_pass as password,
						user_email as email,
						user_url as wp_url,
						{$db_prefix}users.id as wp_id
					FROM {$db_prefix}users
					INNER JOIN {$db_prefix}posts ON {$db_prefix}posts.post_author = {$db_prefix}users.id
					GROUP BY {$db_prefix}users.id
				",
				array(),
				'User'
			);
			$usercount = 0;
			echo '
' . _t( 'Importing users...' ) . '
';

			foreach($wp_users as $user) {
				$habari_user = User::get_by_name($user->username);
				// If username exists
				if($habari_user instanceof User) {
					$habari_user->info->wp_id = $user->wp_id;
					$habari_user->info->url = $user->wp_url;
					$habari_user->update();
				}
				else {
					try {
						$user->info->wp_id = $user->wp_id;
						if($user->wp_url != '') {
							$user->info->url = $user->wp_url;
						}
						// This should probably remain commented until we implement ACL more,
						// or any imported user will be able to log in and edit stuff
						//$user->password = '{MD5}' . $user->password;
						$user->exclude_fields(array('wp_id', 'wp_url'));
						$user->insert();
						$usercount++;
					}
					catch( Exception $e ) {
						EventLog::log($e->getMessage(), 'err', null, null, print_r(array($user, $e), 1));
						Session::error( $e->getMessage() );
						$errors = Options::get('import_errors');
						$errors[] = $user->username . ' : ' . $e->getMessage();
						Options::set('import_errors', $errors);
					}
				}
			}
			if( DB::in_transaction()) DB::commit();

			$ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_posts' ) );

			$vars = Utils::addslashes( array( 'host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass, 'prefix' => $db_prefix ) );

			echo <<< WP_IMPORT_USERS1

WP_IMPORT_USERS1;
		}
		else {
			EventLog::log(sprintf(_t('Failed to import from "%s"'), $db_name), 'crit');
			Session::error( $e->getMessage() );
			echo '
'._t( 'Failed to connect using the given database connection details.' ).'
';
		}
	}

	/**
	 * The plugin sink for the auth_ajax_wp_import_comments hook.
	 * Responds via authenticated ajax to requests for comment importing.
	 *
	 * @param AjaxHandler $handler The handler that handled the request, contains $_POST info
	 */
	public function action_auth_ajax_wp_import_comments( $handler )
	{
		$valid_fields = array( 'db_name','db_host','db_user','db_pass','db_prefix','commentindex', 'category_import', 'utw_import' );
		$inputs = array_intersect_key( $_POST->getArrayCopy(), array_flip( $valid_fields ) );
		extract( $inputs );

		$wpdb = $this->wp_connect( $db_host, $db_name, $db_user, $db_pass, $db_prefix );
		if( $wpdb ) {
			if( !DB::in_transaction() ) DB::begin_transaction();

			$commentcount = $wpdb->get_value( "SELECT count( comment_ID ) FROM {$db_prefix}comments;" );
			$min = $commentindex * IMPORT_BATCH + 1;
			$max = min( ( $commentindex + 1 ) * IMPORT_BATCH, $commentcount );

			echo '
' . _t( 'Importing comments %1$d - %2$d of %3$d', array( $min, $max, $commentcount ) ) . '
';

			$post_info = DB::get_results( "SELECT post_id, value FROM {postinfo} WHERE name= 'wp_id';" );
			foreach( $post_info as $info ) {
				$post_map[$info->value]= $info->post_id;
			}

			$comments = $wpdb->get_results( "
				SELECT
				comment_content as content,
				comment_author as name,
				comment_author_email as email,
				comment_author_url as url,
				INET_ATON( comment_author_IP ) as ip,
			 	comment_approved as status,
				comment_date as date,
				comment_type as type,
				ID as wp_post_id
				FROM {$db_prefix}comments
				INNER JOIN
				{$db_prefix}posts on ( {$db_prefix}posts.ID= {$db_prefix}comments.comment_post_ID )
				LIMIT {$min}, " . IMPORT_BATCH
				, array(), 'Comment' );

			foreach( $comments as $comment ) {
				switch( $comment->type ) {
					case 'pingback': $comment->type = Comment::PINGBACK; break;
					case 'trackback': $comment->type = Comment::TRACKBACK; break;
					default: $comment->type = Comment::COMMENT;
				}

				$comment->content = MultiByte::convert_encoding( $comment->content );
				$comment->name = MultiByte::convert_encoding( $comment->name );

				$carray = $comment->to_array();
				if ( $carray['ip'] == '' ) {
					$carray['ip']= 0;
				}
				switch( $carray['status'] ) {
				case '0':
					$carray['status']= Comment::STATUS_UNAPPROVED;
					break;
				case '1':
					$carray['status']= Comment::STATUS_APPROVED;
					break;
				case 'spam':
					$carray['status']= Comment::STATUS_SPAM;
					break;
				}

				if( isset( $post_map[$carray['wp_post_id']] ) ) {
					$carray['post_id']= $post_map[$carray['wp_post_id']];
					unset( $carray['wp_post_id'] );

					$c = new Comment( $carray );
					//Utils::debug( $c );
					try{
						$c->insert();
					}
					catch( Exception $e ) {
						EventLog::log($e->getMessage(), 'err', null, null, print_r(array($c, $e), 1));
						Session::error( $e->getMessage() );
						$errors = Options::get('import_errors');
						$errors[] = $e->getMessage();
						Options::set('import_errors', $errors);
					}
				}
			}
			if( DB::in_transaction() ) DB::commit();

			if( $max < $commentcount ) {
				$ajax_url = URL::get( 'auth_ajax', array( 'context' => 'wp_import_comments' ) );
				$commentindex++;

				$vars = Utils::addslashes( array( 'host' => $db_host, 'name' => $db_name, 'user' => $db_user, 'pass' => $db_pass, 'prefix' => $db_prefix ) );

				echo <<< WP_IMPORT_AJAX1

WP_IMPORT_AJAX1;
			}
			else {
				EventLog::log( _t( 'Import complete from "%s"', array( $db_name ) ) );
				echo '
' . _t( 'Import is complete.' ) . '
';

				$errors = Options::get('import_errors');
				if(count($errors) > 0 ) {
					echo '
' . _t( 'There were errors during import:' ) . '
';

					echo '
';
					foreach($errors as $error) {
						echo '
' . $error . '
';
					}
					echo '
';
				}

			}
		}
		else {
			EventLog::log(sprintf(_t('Failed to import from "%s"'), $db_name), 'crit');
			Session::error( $e->getMessage() );
			echo '
'._t( 'Failed to connect using the given database connection details.' ).'
';
		}
	}

}

?>


code:
<?xml version="1.0" encoding="utf-8" ?>
<pluggable type="plugin">
	<name>WordPress Importer</name>
	<license url="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software License 2.0</license>

	<author url="http://habariproject.org/">The Habari Community</author>

	<version>1.0</version>
	<url>http://habariproject.org/</url>
	<description><![CDATA[Import Wordpress 2.3.1 - 2.6 database.]]></description>

	<copyright>2009</copyright>
</pluggable>


code:
<?php
Config::set( 'db_connection', array(
	'connection_string'=>'mysql:host={$db_host};dbname={$db_schema}',
	'username'=>'{$db_user}',
	'password'=>'{$db_pass}',
	'prefix'=>'{$table_prefix}'
));

// $locale = '{$locale}';
?>


code:
<?php
/**
 * Habari database specific connection class
 *
 * @package Habari
 */

class MySQLConnection extends DatabaseConnection
{
	/**
	 * Extends default connection method. It will be useful in order to
	 * allow accents and other DB-centric global commands.
	 *
	 * @param string $connect_string a PDO connection string
	 * @param string $db_user the database user name
	 * @param string $db_pass the database user password
	 * @return boolean TRUE on success, FALSE on error
	 */
	public function connect ( $connect_string, $db_user, $db_pass )
	{
		// If something went wrong, we don't need to exec the specific commands.
		if ( !parent::connect( $connect_string, $db_user, $db_pass ) ) {
			return false;
		}
		$this->pdo->setAttribute( PDO::ATTR_EMULATE_PREPARES, true );

		// Everything is OK. Let's update the charset!
		if ( !defined('MYSQL_CHAR_SET') ) {
			define('MYSQL_CHAR_SET', 'UTF8');
		}
		$this->exec('SET NAMES ' . MYSQL_CHAR_SET);
		$this->exec('SET CHARACTER SET ' . MYSQL_CHAR_SET);

		return true;
	}

	/**
	 * Database specific SQL translation function, loosely modelled on the
	 * internationalization _t() function.
	 * Call with a database independent SQL string and it will be translated
	 * to a MySQL specific SQL string.
	 *
	 * @param $sql database independent SQL
	 * @return string translated SQL string
	 * @todo Actually implement this.
	 */
	function sql_t( $sql )
	{
		return $sql;
	}

	/**
	 * automatic diffing function - used for determining required database upgrades
	 * based on Owen Winkler's microwiki upgrade function
	 *
	 * @param queries array of create table and insert statements which constitute a fresh install
	 * @param (optional)  execute should the queries be executed against the database or just simulated. default = true
	 * @param (optional) silent silent running with no messages printed? default = true
	 * @param boolean $doinserts (optional) Execute all insert queries found, default=false
	 * @return  array list of updates made
	 */
	function dbdelta( $queries, $execute = true, $silent = true, $doinserts = false )
	{
		$queries = preg_replace("/({\$prefix})/",$this->prefix,$queries);	//Converts {$prefix}table_name to prefix__table_name
		$queries = $this->filter_tables( $queries );	//Converts {table_name} to prefix__table_name

		if ( !is_array($queries) ) {
			$queries = explode( ';', $queries );
			if ( '' == $queries[count($queries) - 1] ) {
				array_pop($queries);
			}
		}

		$cqueries = array();
		$iqueries = array();
		$for_update = array();
		$indices = array();

		foreach ( $queries as $qry ) {
			if ( preg_match("|CREATE TABLE\s+(\w*)|", $qry, $matches) ) {
				$cqueries[strtolower($matches[1])] = $qry;
				$for_update[$matches[1]] = 'Created table '.$matches[1];
			}
			else if ( preg_match("|CREATE DATABASE ([^ ]*)|", $qry, $matches) ) {
				array_unshift($cqueries, $qry);
			}
			else if ( preg_match("|INSERT INTO ([^ ]*)|", $qry, $matches) ) {
				$iqueries[] = $qry;
			}
			else if ( preg_match("|UPDATE ([^ ]*)|", $qry, $matches) ) {
				$iqueries[] = $qry;
			}
			else {
				// Unrecognized query type
			}
		}

		if ( $tables = $this->get_column('SHOW TABLES;') ) {
			foreach ( $tables as $table ) {
				if ( array_key_exists(strtolower($table), $cqueries) ) {
					unset($cfields);
					$cfields = array();
					unset($indices);
					$indices = array();
					preg_match("|\((.*)\)|ms", $cqueries[strtolower($table)], $match2);
					$qryline = trim($match2[1]);

					$flds = explode("\n", $qryline);
					foreach ( $flds as $fld ) {
						preg_match("|^([^ ]*)|", trim($fld), $fvals);
						$fieldname = $fvals[1];
						$validfield = true;
						switch ( strtolower($fieldname) ) {
							case '':
							case 'primary':
							case 'index':
							case 'fulltext':
							case 'unique':
							case 'key':
								$validfield = false;
								$indices[] = trim(trim($fld), ", \n");
								break;
						}
						$fld = trim($fld);
						if ( $validfield ) {
							$cfields[strtolower($fieldname)] = trim($fld, ", \n");
						}
					}
					$tablefields = $this->get_results("DESCRIBE {$table};");
					foreach ( (array)$tablefields as $tablefield ) {
						if ( array_key_exists(strtolower($tablefield->Field), $cfields) ) {
							preg_match("|".$tablefield->Field." ([^ ]*( unsigned)?)|i", $cfields[strtolower($tablefield->Field)], $matches);
							$fieldtype = $matches[1];
							// Use default field sizes
							$field_default_names = array('/(?'.'>\bint\s*)(?!\(.*$)/i','/(?'.'>smallint\s*)(?!\(.*$)/i','/(?'.'>tinyint\s*)(?!\(.*$)/i','/(?'.'>bigint\s*)(?!\(.*$)/i');
							$field_sized_names = array('int(10) ','smallint(5) ','tinyint(3) ','bigint(20) ');
							$fieldtype = preg_replace($field_default_names, $field_sized_names, $fieldtype);
							if ( strtolower($tablefield->Type) != strtolower($fieldtype) ) {
								$cqueries[] = "ALTER TABLE {$table} CHANGE COLUMN {$tablefield->Field} " . $cfields[strtolower($tablefield->Field)];
								$for_update[$table.'.'.$tablefield->Field] = "Changed type of {$table}.{$tablefield->Field} from {$tablefield->Type} to {$fieldtype}";
							}
							if ( preg_match("| DEFAULT ([^ ]*)|i", $cfields[strtolower($tablefield->Field)], $matches) ) {
								$default_value = $matches[1];
								if ( $tablefield->Default != $default_value ) {
									$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} SET DEFAULT {$default_value}";
									$for_update[$table.'.'.$tablefield->Field] = "Changed default value of {$table}.{$tablefield->Field} from {$tablefield->Default} to {$default_value}";
								}
							}
							elseif ( strlen( $tablefield->Default) > 0 ) {
								$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->Field} DROP DEFAULT";
								$for_update[$table.'.'.$tablefield->Field] = "Dropped default value of {$table}.{$tablefield->Field}";
							}
							unset($cfields[strtolower($tablefield->Field)]);
						}
						else {
							// This field exists in the table, but not in the creation queries?
						}
					}
					foreach ( $cfields as $fieldname => $fielddef ) {
						$cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
						$for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
					}
					$tableindices = $this->get_results("SHOW INDEX FROM {$table};");

					if ( $tableindices ) {
						unset($index_ary);
						$index_ary = array();
						foreach ( $tableindices as $tableindex ) {
							$keyname = $tableindex->Key_name;
							$index_ary[$keyname]['columns'][] = array('fieldname' => $tableindex->Column_name, 'subpart' => $tableindex->Sub_part);
							$index_ary[$keyname]['unique'] = ($tableindex->Non_unique == 0)?true:false;
						}
						foreach ( $index_ary as $index_name => $index_data ) {
							$index_string = '';
							if ( $index_name == 'PRIMARY' ) {
								$index_string .= 'PRIMARY ';
							}
							else if ( $index_data['unique'] ) {
								$index_string .= 'UNIQUE ';
							}
							$index_string .= 'KEY ';
							if ( $index_name != 'PRIMARY' ) {
								$index_string .= $index_name;
							}
							$index_columns = '';
							foreach ( $index_data['columns'] as $column_data ) {
								if ( $index_columns != '' ) {
								 	$index_columns .= ',';
								}
								$index_columns .= $column_data['fieldname'];
								if ( $column_data['subpart'] != '' ) {
									$index_columns .= '('.$column_data['subpart'].')';
								}
							}
							$index_string = rtrim($index_string, ' ');
							$index_string .= ' ('.$index_columns.')';
							if ( !(($aindex = array_search($index_string, $indices)) === false) ) {
								unset($indices[$aindex]);
							}
							else {
								preg_match( '|(^.*)\((.*)\)|', $index_string, $matches );
								$tindextype = $matches[1];
								if ( preg_match( '/^KEY|UNIQUE KEY/i', $tindextype ) > 0 ) {
									$cqueries[] = "ALTER TABLE {$table} DROP INDEX {$index_name}";
								}
								else {
									$cqueries[] = "ALTER TABLE {$table} DROP PRIMARY KEY";
								}
							}
						}
					}
					foreach ( $indices as $index ) {
						$cqueries[] = "ALTER TABLE {$table} ADD $index";
						$for_update[$table.'.'.$fieldname] = 'Added index '.$table.' '.$index;
					}
					unset($cqueries[strtolower($table)]);
					unset($for_update[strtolower($table)]);
				}
				else {
				}
			}
		}

		$allqueries = $cqueries;
		if ( $doinserts ) {
			$allqueries = array_merge($allqueries, $iqueries);
		}
		if ( $execute ) {
			foreach ( $allqueries as $query ) {
				if ( !$this->exec($query) ) {
					$this->get_errors();
					return false;
				}
			}
		}

		if ( !$silent ) {
			if ( count($for_update) > 0) {
				echo "
\n";
				foreach ( $for_update as $upgrade ) {
					echo "
{$upgrade}
\n";
				}
				echo "
\n";
			}
			else {
				echo "

" . _t('No Upgrades') . "

";
			}
		}
		return $for_update;
	}

	/**
	 * Run all of the upgrades slated for pre-dbdelta since the last database revision.
	 *
	 * @param integer $old_version The current version of the database that is being upgraded
	 * @return boolean True on success
	 */
	public function upgrade_pre( $old_version, $upgrade_path = '' )
	{
		return parent::upgrade( $old_version, dirname(__FILE__) . '/upgrades/pre');
	}

	/**
	 * Run all of the upgrades slated for post-dbdelta since the last database revision.
	 *
	 * @param integer $old_version The current version of the database that is being upgraded
	 * @return boolean True on success
	 */
	public function upgrade_post( $old_version, $upgrade_path = '' )
	{
		return parent::upgrade( $old_version, dirname(__FILE__) . '/upgrades/post');
	}
}
?>


code:
CREATE TABLE {$prefix}posts (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  slug VARCHAR(255) NOT NULL,
  content_type SMALLINT UNSIGNED NOT NULL,
  title VARCHAR(255) NOT NULL,
  guid VARCHAR(255) NOT NULL,
  content LONGTEXT NOT NULL,
  cached_content LONGTEXT NOT NULL,
  user_id SMALLINT UNSIGNED NOT NULL,
  status SMALLINT UNSIGNED NOT NULL,
  pubdate INT UNSIGNED NOT NULL,
  updated INT UNSIGNED NOT NULL,
  modified INT UNSIGNED NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY slug (slug(80))
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}postinfo  (
  post_id INT UNSIGNED NOT NULL,
  name VARCHAR(255) NOT NULL,
  type SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  value TEXT,
  PRIMARY KEY (post_id,name)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}posttype (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  active TINYINT(1) DEFAULT 1,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}poststatus (
  id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  internal TINYINT(1),
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}options (
  name VARCHAR(255) NOT NULL,
  type SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  value TEXT,
  PRIMARY KEY (name)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}users (
  id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  username VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  password VARCHAR(255) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY username (username)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}userinfo (
  user_id SMALLINT UNSIGNED NOT NULL,
  name VARCHAR(255) NOT NULL,
  type SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  value TEXT,
  PRIMARY KEY (user_id,name)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}tags (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  tag_text VARCHAR(255) NOT NULL,
  tag_slug VARCHAR(255) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY tag_slug (tag_slug)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}tag2post (
  tag_id INT UNSIGNED NOT NULL,
  post_id INT UNSIGNED NOT NULL,
  PRIMARY KEY (tag_id,post_id),
  KEY post_id (post_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}comments (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  post_id INT UNSIGNED NOT NULL,
  name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  url VARCHAR(255) NULL,
  ip INT UNSIGNED NOT NULL,
  content TEXT,
  status SMALLINT UNSIGNED NOT NULL,
  date INT UNSIGNED NOT NULL,
  type SMALLINT UNSIGNED NOT NULL,
  PRIMARY KEY (id),
  KEY post_id (post_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}commenttype (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  active TINYINT(1) DEFAULT 1,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}commentstatus (
  id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  internal TINYINT(1),
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE  {$prefix}commentinfo (
  comment_id INT UNSIGNED NOT NULL,
  name VARCHAR(255) NOT NULL,
  type SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  value TEXT NULL,
  PRIMARY KEY (comment_id,name)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}rewrite_rules (
  rule_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  parse_regex VARCHAR(255) NOT NULL,
  build_str VARCHAR(255) NOT NULL,
  handler VARCHAR(255) NOT NULL,
  action VARCHAR(255) NOT NULL,
  priority SMALLINT UNSIGNED NOT NULL,
  is_active SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  rule_class SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  description TEXT NULL,
  parameters TEXT NULL,
  PRIMARY KEY (rule_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}crontab (
  cron_id INT unsigned NOT NULL auto_increment,
  name VARCHAR(255) NOT NULL,
  callback VARCHAR(255) NOT NULL,
  last_run INT UNSIGNED,
  next_run INT UNSIGNED NOT NULL,
  increment INT UNSIGNED NOT NULL,
  start_time INT UNSIGNED NOT NULL,
  end_time INT UNSIGNED,
  result VARCHAR(255) NOT NULL,
  notify VARCHAR(255) NOT NULL,
  cron_class TINYINT unsigned NOT NULL DEFAULT 0,
  description TEXT NULL,
  PRIMARY KEY (cron_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}log (
  id INT NOT NULL AUTO_INCREMENT,
  user_id INT NULL DEFAULT NULL,
  type_id INT NOT NULL,
  severity_id TINYINT NOT NULL,
  message VARCHAR(255) NOT NULL,
  data BLOB NULL,
  timestamp INT UNSIGNED NOT NULL,
  ip INT UNSIGNED NOT NULL,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}log_types (
  id INT NOT NULL AUTO_INCREMENT,
  module VARCHAR(100) NOT NULL,
  type VARCHAR(100) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY module_type (module,type)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}groups (
  id INT unsigned not null auto_increment,
  name VARCHAR(255) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY name (name)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}users_groups (
  id INT unsigned not null auto_increment,
  user_id INT unsigned not null,
  group_id INT unsigned not null,
  PRIMARY KEY (id),
  UNIQUE KEY user_group (user_id,group_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}sessions  (
  token varchar(255) NOT NULL,
  subnet INT NOT NULL DEFAULT 0,
  expires INT UNSIGNED NOT NULL DEFAULT 0,
  ua VARCHAR(255) NOT NULL,
  data MEDIUMTEXT,
  user_id SMALLINT UNSIGNED,
  PRIMARY KEY (token)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}terms (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  term VARCHAR(255) NOT NULL,
  term_display VARCHAR(255) NOT NULL,
  vocabulary_id INT UNSIGNED NOT NULL,
  mptt_left INT UNSIGNED NOT NULL,
  mptt_right INT UNSIGNED NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY ix_mptt (vocabulary_id, mptt_right, mptt_left),
  UNIQUE KEY ix_term (vocabulary_id, term)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}vocabularies (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  description TEXT,
  features TEXT,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}object_terms (
  object_id INT UNSIGNED NOT NULL,
  term_id INT UNSIGNED NOT NULL,
  object_type_id INT NOT NULL,
  PRIMARY KEY (object_id,term_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}object_types (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(50),
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

INSERT INTO {$prefix}object_types (name) VALUES
  ('post');

CREATE TABLE {$prefix}tokens (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  description VARCHAR(255) NULL,
  token_type INT UNSIGNED NOT NULL DEFAULT 0,
  token_group VARCHAR(255) NULL,
  PRIMARY KEY (id),
  UNIQUE INDEX name (name)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}post_tokens (
  post_id INT UNSIGNED NOT NULL,
  token_id INT UNSIGNED NOT NULL,
  PRIMARY KEY (post_id, token_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}group_token_permissions (
  group_id INT UNSIGNED NOT NULL,
  token_id INT UNSIGNED NOT NULL,
  access_mask TINYINT UNSIGNED NOT NULL,
  PRIMARY KEY (group_id, token_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}user_token_permissions (
  user_id INT UNSIGNED NOT NULL,
  token_id INT UNSIGNED NOT NULL,
  access_mask TINYINT UNSIGNED NOT NULL,
  PRIMARY KEY (user_id, token_id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}scopes (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  criteria TEXT NOT NULL,
	description TEXT NULL,
	priority TINYINT UNSIGNED NOT NULL,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}blocks (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  title VARCHAR(255) NOT NULL,
  type VARCHAR(255) NOT NULL,
  data TEXT NULL,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE TABLE {$prefix}blocks_areas (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  block_id INT UNSIGNED NOT NULL,
  area VARCHAR(255) NOT NULL,
  scope_id INT UNSIGNED NOT NULL,
	display_order INT UNSIGNED NOT NULL DEFAULT 0,
  PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;


code:
ALTER TABLE {$prefix}posts CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}postinfo CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}posttype CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}poststatus CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}options CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}users CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}userinfo CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}tags CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}tag2post CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}comments CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}commentinfo CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}rewrite_rules CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}crontab CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}log CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}log_types CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}groups CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}users_groups CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}groups_permissions CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}sessions CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}posts CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}postinfo CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}posttype CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}poststatus CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}options CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}users CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}userinfo CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}tags CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}tag2post CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}comments CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}commentinfo CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}rewrite_rules CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}crontab CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}log CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}log_types CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}groups CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}users_groups CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}groups_permissions CONVERT TO CHARACTER SET binary;
ALTER TABLE {$prefix}sessions CONVERT TO CHARACTER SET binary;

ALTER TABLE {$prefix}posts CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}postinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posttype CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}poststatus CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}options CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}userinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tags CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tag2post CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}comments CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}commentinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}rewrite_rules CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}crontab CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log_types CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users_groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups_permissions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}sessions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posts CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}postinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posttype CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}poststatus CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}options CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}userinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tags CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tag2post CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}comments CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}commentinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}rewrite_rules CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}crontab CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log_types CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users_groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups_permissions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}sessions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

ALTER TABLE {$prefix}posts DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}postinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posttype DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}poststatus DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}options DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}userinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tags DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tag2post DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}comments DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}commentinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}rewrite_rules DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}crontab DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log_types DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users_groups DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups_permissions DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}sessions DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posts DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}postinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posttype DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}poststatus DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}options DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}userinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tags DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tag2post DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}comments DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}commentinfo DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}rewrite_rules DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}crontab DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log_types DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users_groups DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups_permissions DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}sessions DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

ALTER TABLE {$prefix}posts modify column content longtext;
ALTER TABLE {$prefix}posts modify column cached_content longtext;
ALTER TABLE {$prefix}postinfo modify column value text;
ALTER TABLE {$prefix}postinfo modify column value text;
ALTER TABLE {$prefix}options modify column value text;
ALTER TABLE {$prefix}userinfo modify column value text;
ALTER TABLE {$prefix}comments modify column content text;
ALTER TABLE {$prefix}commentinfo modify column value text;
ALTER TABLE {$prefix}rewrite_rules modify column description text;
ALTER TABLE {$prefix}crontab modify column description text;
ALTER TABLE {$prefix}sessions modify column data mediumtext;


code:
ALTER TABLE {$prefix}commentinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}comments CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}crontab CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}group_token_permissions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log_types CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}object_terms CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}object_types CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}options CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}post_tokens CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}postinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posts CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}poststatus CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}posttype CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}rewrite_rules CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}sessions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tag2post CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tags CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}terms CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tokens CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}user_token_permissions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}userinfo CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users_groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}vocabularies CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;


code:
ALTER TABLE {$prefix}crontab CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}group_token_permissions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}log_types CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}object_terms CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}object_types CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}post_tokens CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}rewrite_rules CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}sessions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tags CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}terms CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}tokens CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}users_groups CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}user_token_permissions CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE {$prefix}vocabularies CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;


code:
ALTER TABLE {$prefix}posts MODIFY pubdate VARCHAR(25) NOT NULL;
ALTER TABLE {$prefix}posts MODIFY updated VARCHAR(25) NOT NULL;
ALTER TABLE {$prefix}posts ADD COLUMN modified INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}comments MODIFY date VARCHAR(25) NOT NULL;
ALTER TABLE {$prefix}log MODIFY timestamp VARCHAR(25) NOT NULL;

UPDATE {$prefix}posts SET pubdate = UNIX_TIMESTAMP(pubdate);
UPDATE {$prefix}posts SET updated = UNIX_TIMESTAMP(updated);
UPDATE {$prefix}posts SET modified = updated;
UPDATE {$prefix}comments SET date = UNIX_TIMESTAMP(date);
UPDATE {$prefix}log SET timestamp = UNIX_TIMESTAMP(timestamp);

ALTER TABLE {$prefix}posts MODIFY pubdate INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}posts MODIFY updated INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}comments MODIFY date INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}log MODIFY timestamp INT UNSIGNED NOT NULL;

ALTER TABLE {$prefix}crontab MODIFY COLUMN last_run INT UNSIGNED;
ALTER TABLE {$prefix}crontab MODIFY COLUMN next_run INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}crontab MODIFY COLUMN increment INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}crontab MODIFY COLUMN start_time INT UNSIGNED NOT NULL;
ALTER TABLE {$prefix}crontab MODIFY COLUMN end_time INT UNSIGNED;

UPDATE {$prefix}crontab SET last_run=NULL WHERE last_run=0;
UPDATE {$prefix}crontab SET end_time=NULL WHERE end_time=0;

DROP TABLE {$prefix}groups_permissions;


code:
<?php
Config::set( 'db_connection', array(
	'connection_string'=>'pgsql:host={$db_host} dbname={$db_schema}',
	'username'=>'{$db_user}',
	'password'=>'{$db_pass}',
	'prefix'=>'{$table_prefix}'
));

// $locale = '{$locale}';
?>


code:
<?php
/**
 * Habari database specific connection class
 *
 * @package Habari
 */

class PGSQLConnection extends DatabaseConnection
{
	/**
	 * Extends default connection method. It will be useful in order to
	 * allow accents and other DB-centric global commands.
	 *
	 * @param string $connect_string a PDO connection string
	 * @param string $db_user the database user name
	 * @param string $db_pass the database user password
	 * @return boolean TRUE on success, FALSE on error
	 */
	public function connect( $connect_string, $db_user, $db_pass )
	{
		// If something went wrong, we don't need to exec the specific commands.
		if ( !parent::connect( $connect_string, $db_user, $db_pass ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Database specific SQL translation function, loosely modelled on the
	 * internationalization _t() function.
	 * Call with a database independent SQL string and it will be translated
	 * to a PostgreSQL specific SQL string.
	 *
	 * @param $sql database independent SQL
	 * @return string translated SQL string
	 */
	function sql_t( $sql )
	{
		$sql = preg_replace_callback( '%concat\(([^)]+?)\)%i', array( &$this, 'replace_concat' ), $sql );
		$sql = preg_replace( '%DATE_SUB\s*\(\s*NOW\(\s*\)\s*,\s*INTERVAL\s+([0-9]+)\s+DAY\s*\)%ims', 'NOW() - INTERVAL \'${1} DAYS\'', $sql );
		$sql = preg_replace( '%OPTIMIZE TABLE ([^ ]*)%i', 'VACUUM ${1};', $sql );
		//$sql= preg_replace( '%YEAR\s*\(\s*([^ ]*)\s*\)%ims', 'date_part(\'year\', ${1})', $sql );
		//$sql= preg_replace( '%MONTH\s*\(\s*([^ ]*)\s*\)%ims', 'date_part(\'month\', ${1})', $sql );
		//$sql= preg_replace( '%DAY\s*\(\s*([^ ]*)\s*\)%ims', 'date_part(\'day\', ${1})', $sql );
		$sql = preg_replace( '%YEAR\s*\(\s*FROM_UNIXTIME\s*\(\s*([^ ]*)\s*\)\s*\)%ims', 'date_part(\'year\', \'epoch\'::timestamptz + ${1} * \'1 second\'::interval)', $sql );
		$sql = preg_replace( '%MONTH\s*\(\s*FROM_UNIXTIME\s*\(\s*([^ ]*)\s*\)\s*\)%ims', 'date_part(\'month\',  \'epoch\'::timestamptz + ${1} * \'1 second\'::interval)', $sql );
		$sql = preg_replace( '%DAY\s*\(\s*FROM_UNIXTIME\s*\(\s*([^ ]*)\s*\)\s*\)%ims', 'date_part(\'day\',  \'epoch\'::timestamptz + ${1} * \'1 second\'::interval)', $sql );
		$sql = preg_replace('%LIKE\s+((\'|").*\2)%iUms', 'ILIKE \1', $sql);
		$sql = preg_replace( '%RAND\s*\(\s*\)%i', 'RANDOM()', $sql );
		return $sql;
	}

	/**
	 * Replaces the MySQL CONCAT function with PostgreSQL-compatible statements
	 * @todo needs work, kind of sucky conversion
	 * @param array $matches Matches from the regex in sql_t()
	 * @return string The replacement for the MySQL SQL
	 * @see PGSQLConnection::sql_t()
	 */
	function replace_concat( $matches )
	{
		$innards = explode( ',', $matches[1] );
		return implode( ' || ', $innards );
	}

	/**
	 * automatic diffing function - used for determining required database upgrades
	 * based on Owen Winkler's microwiki upgrade function
	 *
	 * @param queries array of create table and insert statements which constitute a fresh install
	 * @param (optional)  execute should the queries be executed against the database or just simulated. default = true
	 * @param (optional) silent silent running with no messages printed? default = true
	 * @param boolean $doinserts (optional) Execute all insert queries found, default=false
	 * @return  array list of updates made
	 */
	function dbdelta( $queries, $execute = true, $silent = true, $doinserts = false )
	{
		if ( !is_array( $queries ) ) {
			$queries = explode( ';', $queries );
			if ( '' == $queries[count( $queries ) - 1] ) {
				array_pop( $queries );
			}
		}

		$cseqqueries = array();
		$cqueries = array();
		$alterseqqueries = array();
		$indexqueries = array();
		$iqueries = array();
		$for_update = array();
		$indices = array();

		foreach ( $queries as $qry ) {
			if ( preg_match( "|CREATE TABLE\s+(\w*)|", $qry, $matches ) ) {
				$cqueries[strtolower( $matches[1] )] = $qry;
				$for_update[$matches[1]] = 'Created table ' . $matches[1];
			}
			else if ( preg_match( "|CREATE (UNIQUE )?INDEX ([^ ]*) ON ([^ ]*)|", $qry, $matches ) ) {
				$indexqueries[strtolower( $matches[3] )] = $qry;
			}
			else if ( preg_match( "|CREATE DATABASE ([^ ]*)|", $qry, $matches ) ) {
				array_unshift( $cqueries, $qry );
			}
			else if ( preg_match( "|CREATE SEQUENCE ([^ ]*)|", $qry, $matches ) ) {
				$cseqqueries[strtolower( $matches[1] )] = $qry;
			}
			else if ( preg_match( "|ALTER SEQUENCE ([^ ]*)|", $qry, $matches ) ) {
				$alterseqqueries[] = $qry;
			}
			else if ( preg_match( "|INSERT INTO ([^ ]*)|", $qry, $matches ) ) {
				$iqueries[] = $qry;
			}
			else if ( preg_match( "|UPDATE ([^ ]*)|", $qry, $matches ) ) {
				$iqueries[] = $qry;
			}
			else {
				// Unrecognized query type
			}
		}

		// Checking sequence
		if ( $seqnames = $this->get_results(
			"SELECT c.relname as name,
				CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END AS type
			   FROM pg_catalog.pg_class c
			   JOIN pg_catalog.pg_roles r ON r.oid = c.relowner
				LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
				WHERE c.relkind IN ('S','')
				AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
				AND pg_catalog.pg_table_is_visible(c.oid)
				ORDER BY 1,2;" ) ) {
			foreach ( ( array ) $seqnames as $seqname ) {
				if ( array_key_exists( strtolower( $seqname->name ), $cseqqueries ) ) {
					unset( $cseqqueries[$seqname->name] );
				}
			}
		}

		if ( $tables = $this->get_column(
			"SELECT table_name
				 FROM information_schema.tables
				 WHERE table_type = 'BASE TABLE'
				 AND table_schema NOT IN ('pg_catalog', 'information_schema');" ) ) {
			foreach ( $tables as $table ) {
				if ( array_key_exists( strtolower( $table ), $cqueries ) ) {
					unset( $cfields );
					$cfields = array();
					unset( $indices );
					$indices = array();
					preg_match( "|\((.*)\)|ms", $cqueries[strtolower( $table )], $match2 );
					$qryline = trim( $match2[1] );

					$flds = explode( "\n", $qryline );
					foreach ( $flds as $fld ) {
						preg_match( "|^([^ ]*)|", trim( $fld ), $fvals );
						$fieldname = $fvals[1];
						$validfield = true;
						switch ( strtolower( $fieldname ) ) {
							case '':
							case 'primary':
							case 'index':
							case 'fulltext':
							case 'unique':
							case 'key':
								$validfield = false;
								$indices[] = trim( trim( $fld ), ", \n" );
								break;
						}
						$fld = trim( $fld );
						if ( $validfield ) {
							$cfields[strtolower( $fieldname )] = trim( $fld, ", \n" );
						}
					}
					if ( isset( $indexqueries[$table] ) ) {
						preg_match( "|CREATE (UNIQUE )?INDEX ([^ ]*) ON ([^ ]*) \((.*)\)|ms", $indexqueries[$table], $matches );
						if ( $matches ) {
							$indices[] = ' (' . preg_replace( '/\s/ms', '', $matches[4] ) . ')';
						}
					}
					$tablefields = $this->get_results(
						"SELECT column_name AS field,
								  data_type AS type,
								  column_default AS default,
								  is_nullable AS null,
								  character_maximum_length AS length,
								  numeric_precision
						   FROM information_schema.columns
						   WHERE table_name = '{$table}'
						   ORDER BY ordinal_position;" );

					foreach ( ( array ) $tablefields as $tablefield ) {
						if ( array_key_exists( strtolower( $tablefield->field ), $cfields ) ) {
							preg_match( '/^(.*) (.*)( |$)/U', $cfields[strtolower( $tablefield->field )], $matches );
							$cfieldname = $matches[1];
							$cfieldtype = $matches[2];
							$fieldtype = $tablefield->type;

							if ( stripos( $fieldtype, 'character' ) === false ) {
								// do nothing
							}
							else {
								if ( stripos( $fieldtype, 'varying' ) > 0 ) {
									$fieldtype = 'varchar(' . $tablefield->length . ')';
								}
								else {
									$fieldtype = 'char(' . $tablefield->length . ')';
								}
							}
							if ( stripos( $fieldtype, 'timestamp' ) === false ) {
								// do nothing
							}
							else {
								$fieldtype = 'timestamp';
							}
							if ( strtolower( $fieldtype ) != strtolower( $cfieldtype ) ) {
								$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN " . $cfieldname . " TYPE " . $cfieldtype;
								$for_update[$table.'.'.$tablefield->field] = "Changed type of {$table}.{$tablefield->field} from {$tablefield->type} to {$fieldtype}";
							}
							if ( preg_match( "| DEFAULT ([^ ]*)|i", $cfields[strtolower( $tablefield->field )], $matches ) ) {
								$default_value = $matches[1];
								if ( strpos( '::', $tablefield->default) === false ) {
									$tablefield_default = $tablefield->default;
								}
								else {
									preg_match( '|(.*)::|', $tablefield->default, $matches );
									$tablefield_default = $matches[1] . ( preg_match( '|^nextval|i', $matches[1] ) > 0 ? ')' : '' );
								}
								if ( $tablefield_default != $default_value ) {
									$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->field} SET DEFAULT {$default_value}";
									$for_update[$table.'.'.$tablefield->field] = "Changed default value of {$table}.{$tablefield->field} from {$tablefield->default} to {$default_value}";
								}
							}
							elseif ( strlen( $tablefield->default) > 0 ) {
								$cqueries[] = "ALTER TABLE {$table} ALTER COLUMN {$tablefield->field} DROP DEFAULT";
								$for_update[$table.'.'.$tablefield->field] = "Dropped default value of {$table}.{$tablefield->field}";
							}
							unset( $cfields[strtolower( $tablefield->field )] );
						}
						else {
							// This field exists in the table, but not in the creation queries?
						}
					}
					foreach ( $cfields as $fieldname => $fielddef ) {
						$cqueries[] = "ALTER TABLE {$table} ADD COLUMN $fielddef";
						$for_update[$table.'.'.$fieldname] = 'Added column '.$table.'.'.$fieldname;
					}
					$tableindices = $this->get_results(
						"SELECT c2.relname AS key_name,
									i.indisprimary AS is_primary,
									i.indisunique AS is_unique,
									i.indisclustered AS is_clustered,
									i.indisvalid AS is_valid,
									pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS index_def,
									c2.reltablespace
							 FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
									pg_catalog.pg_index i
							 WHERE c.oid = (
								SELECT c.oid
									FROM pg_catalog.pg_class c
									LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
									WHERE c.relname = '{$table}'
									AND pg_catalog.pg_table_is_visible(c.oid)
								)
								AND c.oid = i.indrelid AND i.indexrelid = c2.oid
								ORDER BY i.indisprimary DESC, i.indisunique DESC,
									c2.relname;" );

					if ( $tableindices ) {
						unset( $index_ary );
						$index_ary = array();
						foreach ( ( array ) $tableindices as $tableindex ) {
							$keyname = $tableindex->key_name;
							preg_match( '/\((.*)\)/', $tableindex->index_def, $matches );
							$fieldnames = str_replace( '"', '', str_replace( ' ', '', $matches[1] ) );
							$index_ary[$keyname]['fieldnames'] = $fieldnames;
							$index_ary[$keyname]['unique'] = ( $tableindex->is_unique == true ) ? true : false;
							$index_ary[$keyname]['primary'] = ( $tableindex->is_primary == true ) ? true : false;
						}

						foreach ( $index_ary as $index_name => $index_data ) {
							$index_string = '';
							if ( $index_data['primary'] ) {
								$index_string .= 'PRIMARY KEY ';
							}
							else if ( $index_data['unique'] ) {
								$index_string .= 'UNIQUE ';
							}
							$index_columns = $index_data['fieldnames'];

							$index_string = rtrim( $index_string, ' ' );
							$index_string .= ' (' . $index_columns . ')';
							if ( !( ( $aindex = array_search( $index_string, $indices ) ) === false ) ) {
								unset( $indices[$aindex] );
								unset( $indexqueries[$table] );
							}
							else {
								if ( $index_data['unique'] ) {
									$cqueries[] = "ALTER TABLE {$table} DROP CONSTRAINT {$index_name}";
								}
								else {
									$cqueries[] = "DROP INDEX {$index_name}";
								}
							}
						}
					}
					foreach ( $indices as $index ) {
						$cqueries[] = "ALTER TABLE {$table} ADD $index";
						$for_update[$table . '.' . $fieldname] = 'Added index ' . $table . ' ' . $index;
					}
					unset( $cqueries[strtolower( $table )] );
					unset( $for_update[strtolower( $table )] );
				}
				else {
				}
			}
		}

		$allqueries = array_merge( $cseqqueries, $cqueries, $alterseqqueries );
		if ( $doinserts ) {
			$allqueries = array_merge( $allqueries, $iqueries );
		}
		foreach ( $indexqueries as $tablename => $indexquery ) {
			$allqueries = array_merge( $allqueries, ( array ) $indexquery );
		}

		if ( $execute ) {
			foreach ( $allqueries as $query ) {
				if ( !$this->exec( $query ) ) {
					$this->get_errors();
					return false;
				}
			}
		}

		if ( !$silent ) {
			if ( count( $for_update ) > 0 ) {
				echo "
\n";
				foreach ( $for_update as $upgrade ) {
					echo "
{$upgrade}
\n";
				}
				echo "
\n";
			}
			else {
				echo "

" . _t('No Upgrades') . "

";
			}
		}
		return $for_update;
	}

	/**
	 * Run all of the upgrades slated for pre-dbdelta since the last database revision.
	 *
	 * @param integer $old_version The current version of the database that is being upgraded
	 * @return boolean True on success
	 */
	public function upgrade_pre( $old_version, $upgrade_path = '' )
	{
		return parent::upgrade( $old_version, dirname(__FILE__) . '/upgrades/pre');
	}

	/**
	 * Run all of the upgrades slated for post-dbdelta since the last database revision.
	 *
	 * @param integer $old_version The current version of the database that is being upgraded
	 * @return boolean True on success
	 */
	public function upgrade_post( $old_version, $upgrade_path = '' )
	{
		return parent::upgrade( $old_version, dirname(__FILE__) . '/upgrades/post');
	}
}
?>