1. rhizomatik
  2. lorea_production

Source

lorea_production / elgg / mod / etherpad / lib.php

<?php
        /**
         * EtherPad Class
         * 
         * @package etherpad
         * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
         * @author Lorea <devel@lorea.org>
         * @copyright Lorea 2010-2020
         * @link http://lorea.org/
         */

class EtherPad {
	function __construct($ether_ns, $pad=NULL) {
		$this->ns = $ether_ns;
		$this->host = $ether_ns . ':'.get_plugin_setting("port", "etherpad").'/';
		$this->initUser();
		if (!empty($pad)) {
			$this->selectPage($pad);
		}
	}
	/* Connect to db */
	function connect($host, $user, $pass, $db) {
		$dbe = mysql_connect($host, $user, $pass, true);
		mysql_select_db($db, $dbe);
		$this->dbe = $dbe;
	}
	/* Close db connection */
	function close() {
		/*
		breaks other mysql stuff...
		mysql_close($this->dbe);
		*/
	}
	/* Initialize username and track code */
	function initUser() {
	/*	if (!isloggedin()) {
			return;
		}*/
		if (isloggedin()) {
			if (!empty(get_loggedin_user()->ethertrack)) {
				$usertrack = get_loggedin_user()->ethertrack;
			}
			else {
				$usertrack = ''.rand(0,100000000);
				get_loggedin_user()->ethertrack = $usertrack;
			}
			$this->usercode = 'g.'.substr(md5(get_loggedin_user()->username), 0, 8);
		} else {
			if (!empty($_SESSION['ethertrack'])) {
				$usertrack = $_SESSION['ethertrack'];
			}
			else {
				$usertrack = ''.rand(0,100000000);
				$_SESSION['ethertrack'] = $usertrack;
			}
			$this->usercode = 'g.'.substr(md5($usertrack), 8);
		}
		$this->usertrack = $usertrack;
	}
	/* ProxyPass some ep/pad adress */
	function proxyPass($path, $method, $data=null) {
		$ch = curl_init($this->host.'ep/pad/'.$path);
		curl_setopt($ch, CURLOPT_COOKIEFILE, '/dev/null');
		curl_setopt($ch, CURLOPT_HEADER, 0);
		if ($method == 'POST') {
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
		}
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		$output = curl_exec($ch);      
		curl_close($ch);
		return $output;

	}
	/* load the content for a url from etherpad */
	function loadUrl($url) {
		global $CONFIG;
		$ch = curl_init();

		# parse cookies and follow all redirects
		curl_setopt($ch, CURLOPT_COOKIEFILE, '/dev/null');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

		# first, post to get a cookie
		curl_setopt($ch, CURLOPT_URL, $this->host.$url);
		$res = curl_exec($ch);
		curl_close($ch);
		return $res;
	}

	/* Load the content for a pad from etherpad */
	function loadPage($pad) {
		return $this->loadUrl('ep/pad/export/' . urlencode($pad).'/latest?format=html');
	}
	/* Shorten the pad name */
	function shortenName($entity_guid) {
		global $CONFIG;
		if ($this->pad)
			$padId = $this->pad;
		else
			$padId = 'elgg-entitypad-'.md5($CONFIG->wwwroot).'-'.$entity_guid;
		$content = $this->loadPage($padId);
		$body_start = strpos($content, "<body>")+6;
		$body_end = strpos($content, "</body>");
		$content = substr($content, $body_start, $body_end-$body_start);

		$newPadId = md5($CONFIG->wwwroot).'-'.$entity_guid;
		if ($this->pad == $newPadId) {
			return;
		}
		$this->selectPage($newPadId);
		$this->syncPage($content);

	}
	/* Save the content from a pad into an entity of type page */
	function saveToPage($entity_guid, $padId=false) {
		global $CONFIG;
		if (!$padId) {
			if ($this->pad)
				$padId = $this->pad;
			else
				$padId = 'elgg-entitypad-'.md5($CONFIG->wwwroot).'-'.$entity_guid;
		}
		$content = $this->loadPage($padId);
		$body_start = strpos($content, "<body>")+6;
		$body_end = strpos($content, "</body>");
		$content = substr($content, $body_start, $body_end-$body_start);

		// save on elgg entity
		$ent = get_entity($entity_guid);
                $ent->description = $content;
                $ent->save();
		return $ent->annotate('page', $content, $ent->access_id);
	}
	/* put content for some page into etherpad */
	function syncPage($content) {
		global $CONFIG;
		$pad = $this->pad;
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_HTTPHEADER,array('Expect:', 'Connection: keep-alive'));

		curl_setopt($ch, CURLOPT_COOKIEFILE, '/dev/null');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

		# parse cookies and follow all redirects
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

		# first, post to get a cookie
		curl_setopt($ch, CURLOPT_URL, $this->host . urlencode($pad));
		curl_exec($ch);

		// not so nice... but there is no other way to
		// send as file or can't find it.
		chdir('/tmp');
		$file_path = '/tmp/entity-'.$pad.'.html';
		$f = fopen($file_path, 'w');
		fwrite($f, $content);
		fclose($f);
		$size = filesize($file_path);
		// now prepare and send the import request to etherpad
		$options = array(CURLOPT_URL => $this->host.'ep/pad/impexp/import',
				 CURLOPT_POST => true,
				 CURLOPT_HEADER => 1,
				 CURLOPT_USERAGENT => "PubSubHubbub-Publisher-PHP/1.0");
		curl_setopt_array($ch, $options);
		curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, array('padId'=>urlencode($pad),"file"=>"@$file_path",'submit'=>'Import Now'));

		$response = curl_exec($ch);
		$info = curl_getinfo($ch);

		if (($start_success_pos = strpos($response, 'importSuccessful')) > 0) {
			// this means the content is uploaded, now we need to
			// confirm.
			$end_success_pos = strrpos($response, ')');
			$success = substr($response, $start_success_pos+17, $end_success_pos-$start_success_pos-17);
			$token_start = strpos($success, "'");
			$token = substr($success, $token_start+1, strrpos($success, "'")-$token_start-1);
			// ok, so post confirmation
			$options = array(CURLOPT_URL => $this->host.'ep/pad/impexp/import2',
				 CURLOPT_POST => true,
				CURLOPT_HEADER => 1,
				 CURLOPT_USERAGENT => "PubSubHubbub-Publisher-PHP/1.0");
			curl_setopt_array($ch, $options);
			curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, 'padId='.urlencode($pad)."&token=".$token);
			$response = curl_exec($ch);
		}

		if ($response) {
			// its ok
		}
		else {
			error_log('!!!!syncPageError:'.curl_error($ch));
		}
		curl_close($ch);

	}
	/* set some page as current */
	function selectPage($pad) {
		global $CONFIG;
		$this->pad = $pad;
		// -- ensure page
		$ch = curl_init();
		curl_setopt($ch, CURL_HTTP_VERSION_1_0, 1);

		# parse cookies and follow all redirects
		curl_setopt($ch, CURLOPT_COOKIEFILE, '/dev/null');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

		# first, post to get a cookie
		curl_setopt($ch, CURLOPT_URL, $this->host . urlencode($pad));

		$response = curl_exec($ch);
		$js_stance = '<script type="text/javascript" src="';
		$script_start = strpos($response, $js_stance)+strlen($js_stance);
		$script_end = strpos($response, '">', $script_start);
		$js_file = substr($response, $script_start, $script_end-$script_start);
		$this->jsfile = $js_file;

		$cvars_pos = strpos($response, 'collab_client_vars');
		// get the client_vars from response
		if ($cvars_pos !== FALSE) {
			// page exists and we got client_vars
			$cvars_start = strpos($response, '{', $cvars_pos);
			$padId_pos = strpos($response, 'globalPadId', $cvars_pos);
			$cvars_end = strpos($response, '}', $padId_pos);
			$this->cvars = substr($response, $cvars_start, $cvars_end-$cvars_start+1);
		} else {
			// shouldn't exist, so try to create it
			$options = array(CURLOPT_URL => $this->host.'ep/pad/create',
				 CURLOPT_POST => true,
				 CURLOPT_POSTFIELDS => "createPad=Create%20Pad&padId=".$pad,
				 CURLOPT_USERAGENT => "PubSubHubbub-Publisher-PHP/1.0");


			curl_setopt_array($ch, $options);


			$response = curl_exec($ch);
			curl_close($ch);
		}

		// -- end ensure page
	}
	/* setup user in etherpad db */
	function updateUser() {
		$usercode = $this->usercode;
		$usertrack = $this->usertrack;
		setcookie('ET', $usertrack, time()+60*60*24*30, '/','.'.$this->ns, false);
		$dbe = $this->dbe;
		$sql = "SELECT * FROM pad_guests WHERE userId='$usercode';";
		$res = mysql_query($sql, $dbe);

		if ($res && mysql_num_rows($res) > 0) {
			$sql = "UPDATE pad_guests SET privateKey='-\$$usertrack' WHERE userID='$usercode'";
			$res = mysql_query($sql, $dbe);
			$sql = "UPDATE pad_guests SET createdDate='2010-11-06 11:18:19' WHERE userID='$usercode'";
			$res = mysql_query($sql, $dbe);
			$sql = "UPDATE pad_guests SET lastActiveDate='2010-11-06 11:18:19' WHERE userID='$usercode'";
			$res = mysql_query($sql, $dbe);
			// exists
		}
		else {
			$sql = "SELECT * FROM pad_guests WHERE privateKey='-\$$usertrack';";
			$res = mysql_query($sql, $dbe);
			if ($res  && mysql_num_rows($res) > 0) {
				$sql = "UPDATE pad_guests SET userId='$usercode' WHERE privateKey='-\$$usertrack'";
				$res = mysql_query($sql, $dbe);
			}
			else {
				$sql = "INSERT INTO pad_guests (data, userId, privateKey, createdDate, lastActiveDate) VALUES ('{}', '$usercode', '-\$$usertrack', '2010-11-06 11:18:19', '2010-11-06 11:18:19');";
				$res = mysql_query($sql, $dbe);
			}
			// new
		}
		return $usercode;
	}
	/* get chat history from etherpad db */
	function getChatHistory() {
		$pad = $this->pad;
		$dbe = $this->dbe;
		// -- chat history
		$sql = "SELECT PAD_CHAT_TEXT.DATA FROM PAD_CHAT_TEXT, PAD_CHAT_META WHERE PAD_CHAT_META.ID = '$pad' AND PAD_CHAT_META.NUMID = PAD_CHAT_TEXT.NUMID";
		$res = mysql_query($sql, $dbe);
		$row = mysql_fetch_row($res);
		$chatdata = str_replace('}{','},{',$row[0]);
		return $chatdata;
	}
	/* get chat history from etherpad db */
	function getChatColors() {
		$pad = $this->pad;
		$dbe = $this->dbe;
		// -- chat history
		$sql = "select PAD_AUTHORS_TEXT.DATA from PAD_AUTHORS_TEXT, PAD_AUTHORS_META where PAD_AUTHORS_META.ID = '".$pad."' and PAD_AUTHORS_META.NUMID = PAD_AUTHORS_TEXT.NUMID;";
		$res = mysql_query($sql, $dbe);
		$row = mysql_fetch_row($res);
		$chatdata = str_replace('}{','},{',$row[0]);
		return "[".$chatdata."]";
	}

	/* get revision history from etherpad db */
	function getRevisionHistory() {
		$pad = $this->pad;
		$dbe = $this->dbe;
		// -- revision history
		$sql = "SELECT JSON FROM PAD_META WHERE ID='$pad'";
		$res = mysql_query($sql, $dbe);
		$row = mysql_fetch_row($res);
		$pad_meta_json = $row[0];
		$pad_meta = json_decode($pad_meta_json, TRUE);
		if ($pad_meta['x']['dataRoot']['savedRevisions'])
			$pad_revisions = json_encode($pad_meta['x']['dataRoot']['savedRevisions']);
		else
			$pad_revisions = '[]';
		if ($pad_meta['x']['dataRoot']['savedOptions'])
			$pad_options = json_encode($pad_meta['x']['dataRoot']['padOptions']);
		else
			$pad_options = '{"guestPolicy":"deny"}';
		if ($pad_meta['x']['head'])
			$pad_head = $pad_meta['x']['head'];
		else
			$pad_head = 0;
		if ($pad_meta['x']['keyRevInterval'])
			$pad_interval = $pad_meta['x']['keyRevInterval'];
		else
			$pad_interval = 100;
		if ($pad_head) {
			// this part doesn't work and we extract the values from
			// the first get we do to ensure existance, so don't
			// do this for now, may be useful in the future.

			/*$base = floor($pad_head/$pad_interval)*$pad_interval;
			if ($base > 0) {
				$sql = "select DATA from PAD_REVMETA_TEXT, PAD_REVMETA_META where PAD_REVMETA_TEXT.NUMID = PAD_REVMETA_META.NUMID and PAD_REVMETA_META.ID='".$pad."' and PAD_REVMETA_TEXT.PAGESTART=".$base.";";
				$res = mysql_query($sql, $dbe);
				$row = mysql_fetch_row($res);
				$pad_text_json = str_replace('}{','},{',$row[0]);
				error_log($pad_text_json);
				$pad_text = json_decode("[".$pad_text_json."]");
				$text = $pad_text[0]->atext->text;
				$attribs = $pad_text[0]->atext->attribs;
			}*/
		}

		return array($pad_revisions, $pad_options, $base, $text, $attribs);
	}
}
?>