<commit_before><?php

// $Header: /cvsroot/tikiwiki/tiki/lib/mypage/mypagelib.php,v 1.74 2007-09-15 00:04:36 niclone Exp $
// Copyright (c) 2002-2007, <NAME>, <NAME>, <NAME>, et. al.
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.

/* checks about features */
global $feature_ajax;
if ($feature_ajax != 'y') {
	die("feature ajax is required for mypage");
}

/*
 * convert an array recursively to a javascript array
 */
function phptojsarray($var, $offset="") {
	if (is_array($var)) {
		$offset.="  ";
		$str="{\n".$offset."'COUNT' : ".count($var);
		foreach($var as $k => $v) {
			$str.=",\n".$offset."'$k' : ".phptojsarray($v, $offset);
		}
		$str.=" }";
	} else if (is_numeric($var)) {
		$str="".$var;
	} else if (is_bool($var)) {
		$str=($var ? 'true' : 'false');
	} else if (is_string($var)) {
		$str="'".str_replace(array("\n", "\r", "</"), array("\\n", "\\r", "<'+'/"), addslashes($var))."'";
	} else if (is_null($var)) {
		$str="null";
	} else {
		$str="null";
	}
	
	return $str;
}

/*
 * MyPage object is the container of MyPageWindow
 */
class MyPage {
	var $id;
	var $id_users;
	var $windows;
	var $lastid;
	var $params;
	var $modified;
// 	var $perms;
	var $lasterror;
	var $typeclass;
	var $clonning;

	/* never call this constructor directly */
	function MyPage($id=NULL, $id_users) {
		$this->id=$id;
		$this->id_users=$id_users; //the viewer
		$this->windows=array();
		$this->lastid=0;
		$this->params=array();
		$this->modified=array();
		$this->lasterror=NULL;
		$this->typeclass=NULL;
		$this->clonning=false;
	}

	/*static*/
	function getMyPage_new($id_users, $id_types) {
		$mypage=new MyPage(NULL, $id_users);
		$mypage->params['id_users']=(int)$id_users;
		$mypage->params['id_types']=(int)$id_types;
		$mypage->modified['id_types']=true;
		
		$type=MyPage::getMypageType((int)$id_types);
		if (!is_array($type)) return tra("mypage type unaivalable");
		$classname=MyPage::getTypeClassName($type['name']);
		if ($classname !== NULL)
			$mypage->typeclass=call_user_func(array($classname, 'newInstance_new'), $mypage);
		
		return $mypage;
	}
	
	/*static*/
	function getMyPage_byId($id, $id_users) {
		$mypage=new MyPage($id, $id_users);
		$mypage->checkout();
		if (strlen($mypage->lasterror)) return $mypage->lasterror;
		
		$typeclass=$mypage->getTypeClass();
		if (!is_object($typeclass)) {
			if (is_string($typeclass)) {
				return $typeclass; // return the error returner by type
			} else {
				return "an error occured while making the type instance";
			}
		}
		return $mypage;
	}

	/*static*/
	function getMyPage_byName($name, $id_users) {
		global $tikilib;

		$res=$tikilib->query("SELECT `id` FROM tiki_mypage WHERE `name`=?", array($name));
		if ($line = $res->fetchRow()) {
			$mypage=new MyPage($line['id'], $id_users);
			$mypage->checkout();
			if (strlen($mypage->lasterror)) return $mypage->lasterror;

			$typeclass=$mypage->getTypeClass();
			if (!is_object($typeclass)) {
				if (is_string($typeclass)) {
					return $typeclass; // return the error returner by type
				} else {
					return "an error occured while making the type instance";
				}
			}

			return $mypage;

		} else {
			return "mypage '$name' not found";
		}
	}

	/*static*/
	function getMyPage_clone($mypage_src, $id_users) {
		$id_types=$mypage_src->getParam('id_types');
		$mypage_dst=new MyPage(NULL, $id_users);
		$mypage_dst->params['id_users']=(int)$id_users;
		$mypage_dst->params['id_types']=$id_types;
		$mypage_dst->modified['id_types']=true;
		
		$type=MyPage::getMypageType((int)$id_types);
		if (!is_array($type)) return tra("mypage type unaivalable");
		$classname=MyPage::getTypeClassName($type['name']);
		if ($classname !== NULL)
			$mypage_dst->typeclass=call_user_func(array($classname, 'newInstance_clone'), $mypage_dst, $mypage_src->getTypeClass());

		if (!is_object($typeclass)) {
			if (is_string($typeclass)) {
				return $typeclass; // return the error returner by type
			} else {
				return "an error occured while making the type instance";
			}
		}

		/* copy mypage params */
		$copys=array('width', 'height', 'bgcolor', 'description', 'categories', 'winbgcolor', 'bgimage', 'winbgimage',
					 'bgtype', 'winbgtype');
		foreach($copys as $copy) $mypage_dst->setParam($copy, $mypage_src->getParam($copy));
		$mypage_dst->commit();
		
		foreach($mypage_src->windows as $window_src) {
			$window_dst=MyPageWindow::newInstance_clone($mypage_dst, --$mypage_dst->lastid, $window_src);
			$mypage_dst->windows[$mypage_dst->lastid]=$window_dst;
		}
		$mypage_dst->clonning=false;
		return $mypage_dst;
	}

	function getPerm($for) {
		global $tiki_p_admin;
		switch ($for) {
		case 'edit':
			if ($tiki_p_admin == 'y') return true;
			//echo "(".$this->id_users." / ".$this->params['id_users'].")";
			return ((int)$this->id_users == (int)$this->params['id_users']);
		case 'view':
			return true;
		}
		return false;
	}

	function getWindows() {
		return $this->windows;
	}
	
	function getWindow($id) {
		if (!isset($this->windows[$id])) return tra("window not found");
		return $this->windows[$id];
	}

	function getWindowsOfType($type) {
		$windows=array();
		foreach ($this->windows as $window) {
			if ($window->getParam('contenttype') == $type)
				$windows[]=$window;
		}
		return $windows;
	}
	
	function newWindow($contenttype) {
		$win=MyPageWindow::newInstance_new($this, --$this->lastid, $contenttype);
		$this->windows[$this->lastid]=$win;
		return $win;
	}
	
	function _update_id_win($from, $to) {
		$this->windows[$to]=$this->windows[$from];
		unset($this->windows[$from]);
	}
	
	function destroy() {
		global $tikilib;
		
// 		if ($this->perms['tiki_p_edit_mypage'] != 'y' && !($this->perms['tiki_p_edit_own_mypage'] == 'y' && $this->id_users == $this->getParam('id_users'))) {
// 			$this->lasterror=tra('You do not have permissions to delete the page');
// 			return $this->lasterror;
// 		}

		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		// we firstly destroy every windows that this mypage contain
		foreach($this->windows as $window) {
			$window->destroy();
		}
		
		$typeclass=$this->getTypeClass();
		if (is_object($typeclass)) $typeclass->destroy();

		// finally, we destroy this mypage
		$tikilib->query("DELETE FROM tiki_mypage WHERE `id`=?",
						array($this->id));
	}
	
	function _destroyWindow($window) {
		global $tikilib;
		
		$id_win=0;
		if (is_object($window)) {
			$id_win=$window->id;
		} else if (is_int($window)) {
			$id_win=$window;
		}
		
		if (!isset($this->windows[$id_win])) return;
		
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		if ($id_win > 0) {
// 			if ($this->perms['tiki_p_edit_mypage'] != 'y' && !($this->perms['tiki_p_edit_own_mypage'] == 'y' && $this->id_users == $this->getParam('id_users'))) {
// 				$this->lasterror=tra('You do not have permissions to delete this component');
// 				return $this->lasterror;
// 			}
			$tikilib->query("DELETE FROM tiki_mypagewin WHERE `id`=? AND `id_mypage`=?",
							array($id_win, $this->id));
		}
		
		unset($this->windows[$id_win]);
	}
	
	/* static */
	function isNameFree($name) {
		global $tikilib;
		$r=$tikilib->getOne('SELECT COUNT(*) FROM tiki_mypage WHERE name=?', $name);
		return $r == 0 ? true : false;
	}

	/* static */
	function countPages($id_users, $type=NULL) {
		global $tikilib;
		global $tiki_p_admin;
		
		$query="SELECT count(*) ".
			"FROM tiki_mypage mp ".
			"LEFT JOIN tiki_mypage_types mpt ON mp.id_types = mpt.id WHERE (1=1)";
		$r=array();


		if (($id_users!=-1) || ($tiki_p_admin != 'y')) {
			$query.=" AND `id_users`=?";
			$r[]=(int)$id_users;
		}

		if ($type !== NULL) {
			$query.=" AND mpt.name=?";
			$r[]=$type;
		}

		$res=$tikilib->query($query, $r, $limit, $offset);

		return $tikilib->getOne($query, $r);
	}
	
	/* static */
	function listPages($id_users, $type=NULL, $offset=-1, $limit=-1, $sort_mode='mp.name') {
		global $tikilib;
		global $tiki_p_admin;

		$pages=array();

		$query="SELECT mp.*, ".
			"mpt.name as type_name, ".
			"mpt.description as type_description, ".
			"mpt.section as type_section, ".
			"mpt.permissions as type_permissions ".
			"FROM tiki_mypage mp ".
			"LEFT JOIN tiki_mypage_types mpt ON mp.id_types = mpt.id WHERE (1=1)";
		$r=array();

		if (($id_users!=-1) || ($tiki_p_admin != 'y')) {
			$query.=" AND `id_users`=?";
			$r[]=(int)$id_users;
		}

		if ($type !== NULL) {
			$query.=" AND mpt.name=?";
			$r[]=$type;
		}

		$sortstr='';
		if (is_array($sort_mode)) {
			foreach($sort_mode as $k => $v) $sort_mode[$k]=$tikilib->convert_sortmode($v);
			$sortstr=implode(', ', $sort_mode);
		} else $sortstr=$sort_mode;

		$query.=" ORDER BY ".$sortstr;
		$res=$tikilib->query($query, $r, $limit, $offset);

		while ($line = $res->fetchRow()) {
// 			$line['perms'] = $tikilib->get_perm_object($line['id'], 'mypage', false);
			$pages[]=$line;
		}

		return $pages;
	}
	
	function setParams($id_mypage, $vals) {
		foreach($vals as $k=>$v) {
			$err=$this->setParam($k, $v);
			if ($err) return $err;
		}
	}
	function setParam($param, $value) {
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		$allowed=array('width', 'height', 'wintitlecolor', 'wintextcolor', 'winbgcolor',
					   'name', 'description', 'bgcolor', 'categories', 'bgimage', 'winbgimage',
					   'bgtype', 'winbgtype');

		if ($param == 'categories') {
			if (is_null($value)) $value=array();
			else if (!is_array($value)) {
				if (empty($value)) $value=array();
				else $value=array($value);
			}
		}
		
		$typeclass=$this->getTypeClass();
		if (in_array($param, $allowed)) {
			// TODO: verify permissions when changing id_users or id_types !
			$this->params[$param]=$value;
			$this->modified[$param]=true;
			if (is_object($typeclass)) $typeclass->mypage_setParam($param, $value);
		} else {
			$this->lasterror=tra("Parameter not found :").$param;
			return $this->lasterror;
		}
	}
	
	function _getcateg() {
		global $categlib; include_once ('lib/categories/categlib.php');

		if (array_key_exists('categories', $this->params)) return $this->params['categories'];
 	    $cat=$categlib->get_object_categories('mypage', $this->id, -1);
		return $cat;
	}

	function getParam($param, $default=NULL) {
		if ($param=='categories') {
			if (array_key_exists($param['categories']))
				return $param['categories'];
			else
				return $param['categories']=$this->_getcateg();
		} else {
			if (!isset($this->params[$param]))
				return $default;
			else
				return $this->params[$param];
		}
	}
	
	function checkout() {
		global $tikilib;
		
		$this->windows=array();
		
		if (!is_null($this->id)) {
			$res=$tikilib->query("SELECT * FROM tiki_mypage WHERE `id`=?", array($this->id));
			if ($line = $res->fetchRow()) {
				$this->params=$line;
				$this->modified=array();
			} else { // bad... no mypage found
				$this->id=0;
				return $this->lasterror="MyPage not found";
			}
			$this->perms = $tikilib->get_perm_object($this->id, 'mypage', false);
// 			if ($this->perms['tiki_p_view_mypage'] != 'y' && !($this->perms['tiki_p_edit_own_mypage'] == 'y' && $this->id_users == $this->getParam('id_users'))) {
// 				$this->lasterror=tra('You do not have permissions to view the page');
// 				return $this->lasterror;
// 			}
			
			$res=$tikilib->query("SELECT * FROM tiki_mypagewin WHERE `id_mypage`=?", array($this->id));
			while ($line = $res->fetchRow()) {
				$instance=MyPageWindow::newInstance_load($this, $line);
				if (!is_object($instance)) return $this->lasterror="can't load window: $instance";
				$this->windows[$line['id']]=$instance;
			}
		}
	}
	
	function commit() {
		global $tikilib, $tiki_p_edit_mypage, $tiki_p_edit_own_mypage;
		
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		if (is_null($this->id)) {
// 			if ($tiki_p_edit_mypage != 'y' && $tiki_p_edit_own_mypage != 'y') {
// 				$this->lasterror=tra('You do not have permissions to edit the page');
// 				return $this->lasterror;
// 			}
			
			$this->params['created']=$tikilib->now;
			$this->modified['created']=1;

			// verify that we have a category if mandatory
			global $feature_mypage_mandatory_category;
			$categories = $this->getParam('categories');
			if (($feature_mypage_mandatory_category > 0) && (count($categories) == 0)) {
				return $this->lasterror = tra('A category is mandatory');
			}

			// create a new mypage id
			
			$res=$tikilib->query("INSERT INTO tiki_mypage (`id_users`) values (?)",
								 array($this->id_users));
			if (!$res) return;
			
			$id=$tikilib->getOne("SELECT LAST_INSERT_ID()");
			if (!$id) return;
			
			$this->id=$id;
			
			$typeclass=$this->getTypeClass();
			if (is_object($typeclass)) $typeclass->create();
			else return $this->lasterror="commit failed: $typeclass";

			// now run again for update ;)
			$res=$this->commit();
			if (is_string($res)) {
				$tikilib->query("DELETE FROM tiki_mypage WHERE `id`=?",
								array($this->id));
				$this->id=NULL;
				return $res;
			}
			return $res;
			
		} else {
			
			if (count($this->modified) > 0) {
				if (isset($this->modified['name'])) {
					$c=$tikilib->getOne('SELECT COUNT(*) FROM tiki_mypage WHERE `name`=? AND `id`!=?',
										array($this->params['name'], $this->id));
					if ($c != 0)
						return $this->lasterror=tra(sprintf('Name "%s" already exists', $this->params['name']));
				}
				$this->params['modified']=$tikilib->now;
				$this->modified['modified']=1;

				$l=array();
				$r=array();
				foreach($this->modified as $k => $v) {
					if ($k=='categories') continue; // categories is handled separatly
					$l[]="`$k`=?";
					$r[]=$this->params[$k];
				}

				global $feature_mypage_mandatory_category;
				$categories = $this->getParam('categories');
				if ($feature_mypage_mandatory_category > 0 && count($categories) == 0) {
					return $this->lasterror = tra('A category is mandatory');
				}

				$query="UPDATE tiki_mypage SET ".implode(',', $l)." WHERE `id`=?";
				$r[]=$this->id;
				
				$res=$tikilib->query($query, $r);

				if ($this->modified['categories'] || $this->modified['name'] || $this->modified['description']) {
					global $categlib; include_once ('lib/categories/categlib.php');
					foreach($this->params['categories'] as $categid) {
						$categlib->update_object_categories($categid, $this->id, 'mypage',
															$this->params['description'], $this->params['name'],
															"tiki-mypage.php?id_mypage=".$this->id);
					}
				}

				$typeclass=$this->getTypeClass();
			}

			if (is_object($typeclass)) $typeclass->commit();
			$this->modified=array();

			foreach($this->windows as $window) {
				if (!is_object($window)) return "window is not an object: $window";
				$window->commit();
			}
		}
	}
	
	/*
	 * increment viewed count
	 */
	function viewed() {
		global $tikilib;
		if ($this->id > 0) {
			$this->params['viewed']++;
			$tikilib->query('UPDATE tiki_mypage SET `viewed`=? WHERE `id`=?',
							array($this->params['viewed'], $this->id));
		}
	}

	function getJSCode($editable=false) {
		$js="/* windows creation */\n";
		foreach($this->windows as $win) {
			$js.=$win->getJSCode($editable);
		}
		$js.="/* end of windows creation */\n";
		return $js;
	}

	/*
	 * one day, i'll make a libcomponents...
	 *
	 * if called by the static way, it will return every available component
	 * if called by the instance way, it will return every available component for this type of mypage
	 */
	/* static or not static ! */
	function getAvailableComponents() {
		$r=array();
		$d=opendir("components");
		if ($d === FALSE) return $r;

		if (isset($this)) $cft=$this->getComponentsFromTypes();
		else $cft=NULL;

		while (($file = readdir($d)) !== false) {
			if (preg_match('/^comp-[a-zA-Z0-9_-]+\.php$/', $file)) {
				$compname=substr($file, 5, -4);
				if ($cft !== NULL) {
					foreach($cft as $l) {
						if ($l['compname'] == $compname)
							$r[]=$compname;
					}
				} else $r[]=$compname;
			}
        }
		return $r;
	}

	function getComponentsFromTypes() {
		global $tikilib;
		$query="select c.compname, c.mincount, c.maxcount ".
			" FROM tiki_mypage_types t ".
			" LEFT JOIN tiki_mypage_types_components c ON c.id_mypage_types=t.id ".
			" WHERE t.id=?";
		$result=$tikilib->query($query, array($this->getParam('id_types')));
		$lines=array();
		while ($line=$result->fetchRow()) {
			$lines[]=$line;
		}
		return $lines;
	}

	/* static */
	function countMypageTypes() {
		global $tikilib;
		
		$pages=array();
		return $tikilib->getOne("SELECT COUNT(*) FROM tiki_mypage_types");
	}
	
	/* static */
	function listMypageTypes($offset=-1, $limit=-1) {
		global $tikilib;

		$lines=array();
		$res=$tikilib->query("SELECT ".
							 " mpt.id as id, ".
							 " mpt.name as name, ".
							 " mpt.description as description, ".
							 " mpt.section as section, ".
							 " mpt.permissions as permissions, ".
							 " mpt.def_width as def_width, ".
							 " mpt.def_height as def_height, ".
							 " mpt.fix_dimensions as fix_dimensions, ".
							 " mpt.def_bgcolor as def_bgcolor, ".
							 " mpt.fix_bgcolor as fix_bgcolor, ".
							 " mpt.templateuser as templateuser, ".
							 " mptc.compname as compname, ".
							 " mptc.mincount as mincount, ".
							 " mptc.maxcount as maxcount ".
							 "FROM tiki_mypage_types as mpt ".
							 "LEFT JOIN tiki_mypage_types_components as mptc ".
							 "ON mptc.id_mypage_types = mpt.id ".
							 "ORDER BY mpt.id ",
							 array(), $limit, $offset);
		$lastid=0;
		$lastline=NULL;
		while ($line = $res->fetchRow()) {
			if ($line['id'] != $lastid) {
				if ($lastline !== NULL) $lines[]=$lastline;
				$lastid=$line['id'];
				$lastline=array('id' => $line['id'],
								'name' => $line['name'],
								'description' => $line['description'],
								'section' => $line['section'],
								'permissions' => $line['permissions'],
								'def_width' => $line['def_width'],
								'def_height' => $line['def_height'],
								'fix_dimensions' => $line['fix_dimensions'],
								'def_bgcolor' => $line['def_bgcolor'],
								'fix_bgcolor' => $line['fix_bgcolor'],
								'templateuser' => $line['templateuser'],
								'components' => array());
			}
			$lastline['components'][]=array('compname' => $line['compname'],
											'mincount' => $line['mincount'],
											'maxcount' => $line['maxcount']);
		}
		if ($lastline !== NULL) $lines[]=$lastline;
		
		return $lines;
	}

	/* static */
	function getMypageType($id) {
		global $tikilib;

		$lines=array();
		$res=$tikilib->query("SELECT ".
							 " mpt.id as id, ".
							 " mpt.name as name, ".
							 " mpt.description as description, ".
							 " mpt.section as section, ".
							 " mpt.permissions as permissions, ".
							 " mpt.def_width as def_width, ".
							 " mpt.def_height as def_height, ".
							 " mpt.fix_dimensions as fix_dimensions, ".
							 " mpt.def_bgcolor as def_bgcolor, ".
							 " mpt.fix_bgcolor as fix_bgcolor, ".
							 " mpt.templateuser as templateuser, ".
							 " mptc.compname as compname, ".
							 " mptc.mincount as mincount, ".
							 " mptc.maxcount as maxcount ".
							 "FROM tiki_mypage_types as mpt ".
							 "LEFT JOIN tiki_mypage_types_components as mptc ".
							 "ON mptc.id_mypage_types = mpt.id ".
							 "WHERE mpt.id=? ".
							 "ORDER BY mpt.id ",
							 array((int)$id));
		$lastid=0;
		$lastline=NULL;
		while ($line = $res->fetchRow()) {
			if ($line['id'] != $lastid) {
				if ($lastline !== NULL) $lines[]=$lastline;
				$lastid=$line['id'];
				$lastline=array('id' => $line['id'],
								'name' => $line['name'],
								'description' => $line['description'],
								'section' => $line['section'],
								'permissions' => $line['permissions'],
								'def_width' => $line['def_width'],
								'def_height' => $line['def_height'],
								'fix_dimensions' => $line['fix_dimensions'],
								'def_bgcolor' => $line['def_bgcolor'],
								'fix_bgcolor' => $line['fix_bgcolor'],
								'templateuser' => $line['templateuser'],
								'components' => array());
			}
			$lastline['components'][]=array('compname' => $line['compname'],
											'mincount' => $line['mincount'],
											'maxcount' => $line['maxcount']);
		}
		if ($lastline !== NULL) $lines[]=$lastline;
		
		if (count($lines) == 1) return $lines[0];
		else return NULL;
	}

	/* static */
	function deleteMypageType($id) {
		global $tikilib;

		$res=$tikilib->query("DELETE FROM tiki_mypage_types_components ".
							 "WHERE id_mypage_types=?", array((int)$id));

		$res=$tikilib->query("DELETE FROM tiki_mypage_types ".
							 "WHERE id=?", array((int)$id));
	}
	
	/* static */
	function createMypageType() {
		global $tikilib;

		$res=$tikilib->query("INSERT INTO tiki_mypage_types (created,modified) VALUES (?,?)",
							 array($tikilib->now, $tikilib->now));
		return $tikilib->getOne("SELECT LAST_INSERT_ID()");
	}

	/* static */
	function updateMypageType($id, $vals) {
		global $tikilib;

		$cols=array("name", "description", "section", "permissions",
					"def_width", "def_height", "fix_dimensions",
					"def_bgcolor", "fix_bgcolor", "modified", "templateuser");

		$vals['modified']=$tikilib->now;
		$tvals=$vals;
		// we remove unauthorized cols
		foreach($tvals as $k => $v)
			if (!in_array($k, $cols)) unset($tvals[$k]);

		if (array_key_exists('def_width', $tvals) && empty($tvals['def_width'])) $tvals['def_width']=NULL;
		if (array_key_exists('def_height', $tvals) && empty($tvals['def_height'])) $tvals['def_height']=NULL;
		if (array_key_exists('def_bgcolor', $tvals) && empty($tvals['def_bgcolor'])) $tvals['def_bgcolor']=NULL;

		if (count($tvals) > 0) {
			$l=array();
			$r=array();
			foreach($tvals as $k => $v) {
				$l[]="`$k`=?";
				$r[]=$v;
			}
			
			$query="UPDATE tiki_mypage_types SET ".implode(', ', $l)." WHERE `id`=?";
			$r[]=(int)$id;
			
			$res=$tikilib->query($query, $r);
		}

		if (isset($vals['components'])) {
			$res=$tikilib->query("DELETE FROM tiki_mypage_types_components ".
								 "WHERE id_mypage_types=?", array((int)$id));
			foreach($vals['components'] as $component) {
				$res=$tikilib->query("INSERT INTO tiki_mypage_types_components".
									 " (`id_mypage_types`, `compname`)".
									 " VALUES (?,?)", array((int)$id, $component));
			}
		}
	}

	/* static */
	function getTypeHTMLConfig($type=NULL) {
		if (isset($this)) {
			$typeclass=$this->getTypeClass();
			return (is_object($typeclass) ? $typeclass->getHTMLConfig() : NULL);
		} else {
			$classname=MyPage::getTypeClassName($type);
			if (($classname !== NULL) && is_callable(array($classname, 'getHTMLConfig')))
				return call_user_func(array($classname, 'getHTMLConfig'));
			else
				return NULL;
		}
	}

	/* static */
	function getTypeClassName($type) {
		if (!preg_match('/^[a-zA-Z0-9_-]+$/', $type))
			return NULL;
		if (file_exists("lib/mypage/types/type-".$type.".php")) {
			require_once("lib/mypage/types/type-".$type.".php");
			$classname="Mypagetype_".$type;
			return $classname;
		}
		return NULL;		
	}

	function getTypeClass() {
		if ($this->typeclass) return $this->typeclass;
		$type=MyPage::getMypageType((int)$this->getParam('id_types'));
		if (!is_array($type)) return "class not found: $type";
		$classname=MyPage::getTypeClassName($type['name']);
		if ($classname === NULL) return "class ".$type['name']." not found";
		$this->typeclass=call_user_func(array($classname, 'newInstance_load'), $this);

		if (!is_object($this->typeclass))
			return $this->lasterror=$this->typeclass;

		return $this->typeclass;
	}
}

class MyPageWindow {
	var $mypage;
	var $id;
	var $params;
	var $modified;
	var $comp;
	var $lasterror;

	/*
	 * this constructor may be called only by the MyPage class
	 * you should not create a new instance of this object directly
	 */
	function MyPageWindow($mypage, $id) {
		$this->mypage=$mypage;
		$this->id=$id;
		$this->params=$line;
		$this->modified=array();
		$this->comp=NULL;
	}

	/*
	 * construct a new instance for creating new window, should be called only by MyPage
	 */
	/* static */
	function newInstance_new($mypage, $id, $contenttype) {
		$win=new MyPageWindow($mypage, $id);
		$win->params['contenttype']=$contenttype;
		$win->modified['contenttype']=true;

			// some default values...
		$win->setParam('top',0);
		$win->setParam('left',0);
		$win->setParam('width',100);
		$win->setParam('height',100);

		$classname=MyPageWindow::getComponentClass($contenttype);
		if ($classname) {
			$win->comp=call_user_func(array($classname, 'newInstance_new'), $win);
			if (!is_object($win->comp)) return tra("component error: ").$win->comp;
		} else return tra("component not found");

		return $win;
	}

	/*
	 * construct a new instance for an existing window, should be called only by MyPage
	 */
	/* static */
	function newInstance_load($mypage, $line) {
		$win=new MyPageWindow($mypage, $line['id']);
		$win->params['contenttype']=$line['contenttype'];
		$win->modified['contenttype']=true;

		$allowed=array('title', 'inbody', 'modal', 'left', 'top', 'width', 'height', 'config', 'content');
		foreach($line as $k => $v) {
			if (in_array($k, $allowed))
				$win->params[$k]=$v;
		}
		return $win;
	}

	/*
	 * construct a new instance for clonning an existing window, should be called only by MyPage
	 */
	/* static */
	function newInstance_clone($mypage, $id, $win_src) {
		$win=new MyPageWindow($mypage, $id);
		$win->params['contenttype']=$win_src->getParam('contenttype');
		$win->modified['contenttype']=true;

		$allowed=array('title', 'inbody', 'modal', 'left', 'top', 'width', 'height', 'config', 'content');
		foreach($allowed as $k) {
				$win->setParam($k, $win_src->getParam($k));
		}

		$comp_src=$win_src->getComponent();

		$classname=MyPageWindow::getComponentClass($win_src->getParam('contenttype'));
		if ($classname) {
			$win->comp=call_user_func(array($classname, 'newInstance_clone'), $win, $comp_src);
			if (!is_object($win->comp)) return tra("can't make new instance of component: ").$win->comp;
		} else return tra('class of component not found');

		return $win;
	}

	function destroy() {
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		$comp=$this->getComponent();
		if (is_object($comp)) $comp->destroy();
		return $this->mypage->_destroyWindow($this);
	}


	function getPerm($for) {
		switch ($for) {
		case 'edit':
			return $this->mypage->getPerm('edit');
		case 'view':
			return $this->mypage->getPerm('edit');
		}
		return false;
	}

	
	function commit() {
		global $tikilib;
		/*		
		if ($this->mypage->perms['tiki_p_view_mypage'] != 'y' && !($this->mypage->perms['tiki_p_edit_own_mypage'] == 'y' && $this->mypage->id_users == $this->mypage->getParam('id_users'))) {
			$this->lasterror=tra('You do not have permissions to edit the component');
			return $this->lasterror;
		}
		*/
		
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');


		if ($this->id < 0) {
			// create a new mypagewin id
			
			$this->params['created']=$tikilib->now;
			$this->modified['created']=1;

			$res=$tikilib->query("INSERT INTO tiki_mypagewin (`id_mypage`) values (?)",
								 array($this->mypage->id));
			if (!$res) return;
			
			$id=$tikilib->getOne("SELECT LAST_INSERT_ID()");
			if (!$id) return;
			
			$oldid=$this->id;
			$this->id=$id;
			$this->mypage->_update_id_win($oldid, $this->id);
			
			// now run again for update ;)
			$r=$this->commit();
			if (is_string($r)) {
				$tikilib->query("DELETE FROM tiki_mypagewin WHERE `id`=?", array($this->id));
				$this->id=$oldid;
				$this->mypage->_update_id_win($this->id, $oldid);
				return $r;
			}
			$comp=$this->getComponent();
			if (is_object($comp) && is_callable(array($comp, 'create'))) $comp->create();

		} else {
			
			if (count($this->modified) > 0) {
				$this->params['modified']=$tikilib->now;
				$this->modified['modified']=1;

				$l=array();
				$r=array();
				foreach($this->modified as $k => $v) {
					$l[]="`$k`=?";
					$r[]=$this->params[$k];
				}
				
				$query="UPDATE tiki_mypagewin SET ".implode(',', $l)." WHERE `id`=?";
				$r[]=$this->id;
				
				$res=$tikilib->query($query, $r);
				
				$this->modified=array();
			}

			$comp=$this->getComponent();
			if (is_object($comp) && is_callable(array($comp, 'commit'))) $comp->commit();
		}
	}
	
	function setParam($param, $value) {
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');
		$this->params[$param]=$value;
		$this->modified[$param]=true;
	}
	
	function getParam($param) {
		return $this->params[$param];
	}
	
	/*
	 * $contenttype: must be 'iframe' or 'wiki'
	 */
	function setContentType($contenttype) {
		return $this->setParam('contenttype', $contenttype);
	}
	
	function setContent($content) {
		return $this->setParam('content', $content);
	}
	
	function setConfig($config) {
		return $this->setParam('config', $config);
	}
	
	function setPosition($left, $top) {
		$err=$this->setParam('left', (int)$left);
		if (is_string($err)) return $err;
		return $this->setParam('top', (int)$top);
	}

	function setSize($width, $height) {
		$err=$this->setParam('width', (int)$width);
		if (is_string($err)) return $err;
		return $this->setParam('height', (int)$height);
	}

	function setRect($left, $top, $width, $height) {
		$err=$this->setPosition($left, $top);
		if (is_string($err)) return $err;
		return $this->setSize($width, $height);
	}

	function setTitle($title) {
		return $this->setParam('title', $title);
	}

	/* static */
	function isComponentConfigurable($compname=NULL) {
		if (!empty($compname)) {
			$classname=MyPageWindow::getComponentClass($compname);
			if (($classname !== NULL) && is_callable(array($classname, 'isConfigurable')))
				return call_user_func(array($classname, 'isConfigurable'));
		}
		return false;
	}

	/* static or not static */
	function getComponentConfigureDiv($compname=NULL) {
		if (isset($this)) { // we are not static
			$comp=$this->getComponent();
			if ($comp) return $comp->getConfigureDiv();
			return NULL;
		} else if (!empty($compname)) { // we are static
			$classname=MyPageWindow::getComponentClass($compname);
			if (($classname !== NULL) && is_callable(array($classname, 'getConfigureDiv')))
				return call_user_func(array($classname, 'getConfigureDiv'));
		}
		return NULL;
	}
	
	/* static */
	function getComponentClass($compname) {
		if (!preg_match('/^[a-zA-Z0-9_-]+$/', $compname))
			return NULL;
		if (file_exists("components/comp-".$compname.".php")) {
			require_once("components/comp-".$compname.".php");
			$classname="Comp_".$compname;
			return $classname;
		}
	}

	function getComponent() {
		if ($this->comp) return $this->comp;
		$classname=MyPageWindow::getComponentClass($this->params['contenttype']);
		if ($classname) {
			$this->comp=call_user_func(array($classname, 'newInstance_load'), $this);
			return $this->comp;
		}
		return NULL;
	}

	function getJSCode($editable=false) {
		global $tikilib;

		$comp=$this->getComponent();
		if (!is_object($comp)) {
			$this->lasterror=tra('Component not available: ').$this->params['contenttype']." -> ".$comp;
			return 'alert("'.addslashes($this->lasterror).'");';
		}

		if (is_callable(array($comp, 'getPerm')) && !$comp->getPerm('view')) {
			$this->lasterror=tra("You do not have permission to view this part of content");
			return 'alert("'.addslashes($this->lasterror).'");';
		}

		$v="tikimypagewin[".$this->id."]";

		$winparams=array('left'	     => (int)$this->params['left'],
						 'top'	     => (int)$this->params['top'],
						 'width'	 => (int)$this->params['width'],
						 'height'	 => (int)$this->params['height'],
						 'title'	 => $this->params['title'],
						 'position'  => false,
						 'theme'	 => 'mypage',
						 'container' => 'mypage',
						 'buttons'   => array()
						 );

		if (is_callable(array($comp, 'isResizeable'))) {
			if (!$comp->isResizeable()) {
				$winparams['resizable']  = false;
				$winparams['buttons']['maximize'] = false;
				$winparams['buttons']['minimize'] = false;
			}
		}

		if (is_callable(array($comp, 'isResizeable'))) {
			if (!$comp->isCloseable()) $winparams['buttons']['close'] = false;
		}

		if (!$editable) {
			$winparams['theme']	  = 'mypage_view';
			$winparams['resizable']  = false;
			$winparams['draggable']  = false;
			$winparams['buttons']	 = array('close'	=> false,
											 'minimize' => false,
											 'maximize' => false);
		}
	
		if ($this->params['contenttype'] == 'iframe') {
			$winparams['type']="iframe";
			$winparams['url']=$this->params['config'];
		}
	
		$js =$v."=new Windoo(".phptojsarray($winparams).");\n";
		if ($editable) {
			$js.=$v.".addEvent('onResizeComplete', function(){ state=$v.getState(); xajax_mypage_win_setrect(".$this->mypage->id.", ".$this->id.", state.outer); });\n";
			$js.=$v.".addEvent('onDragComplete', function(){ state=$v.getState(); xajax_mypage_win_setrect(".$this->mypage->id.", ".$this->id.", state.outer); });\n";
			$js.=$v.".addEvent('onClose', function(){ xajax_mypage_win_destroy(".$this->mypage->id.", ".$this->id."); });\n";
			$js.=$v.".addEvent('onFocus', function(){ windooFocusChanged(".$this->id."); });\n";
			$js.=$v.".addEvent('onStartDrag', function() { windooStartDrag(".$this->id."); });\n";
		}

		if ($this->params['contenttype'] != 'iframe') {
			$js.=$v.".setHTML(".phptojsarray($comp->getHTMLContent()).");\n";
		}
		
		$js.=$v.".show();\n";

		if (is_callable(array($comp, 'getOnOpenJSCode'))) {
			$js.=$comp->getOnOpenJSCode().";\n";
		}
		
		return $js;
	}
}

/* For the emacs weenies in the crowd.
Local Variables:
   tab-width: 4
   c-basic-offset: 4
End:
*/

?><commit_msg>[FIX] mypage: define the now commons border with of the mypage and mypage_view theme<commit_after><?php

// $Header: /cvsroot/tikiwiki/tiki/lib/mypage/mypagelib.php,v 1.75 2007-09-15 03:19:14 niclone Exp $
// Copyright (c) 2002-2007, <NAME>, <NAME>, <NAME>, et. al.
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.

/* checks about features */
global $feature_ajax;
if ($feature_ajax != 'y') {
	die("feature ajax is required for mypage");
}

define('MYPAGEBORDER_W', 10);
define('MYPAGEBORDER_H', 20);

/*
 * convert an array recursively to a javascript array
 */
function phptojsarray($var, $offset="") {
	if (is_array($var)) {
		$offset.="  ";
		$str="{\n".$offset."'COUNT' : ".count($var);
		foreach($var as $k => $v) {
			$str.=",\n".$offset."'$k' : ".phptojsarray($v, $offset);
		}
		$str.=" }";
	} else if (is_numeric($var)) {
		$str="".$var;
	} else if (is_bool($var)) {
		$str=($var ? 'true' : 'false');
	} else if (is_string($var)) {
		$str="'".str_replace(array("\n", "\r", "</"), array("\\n", "\\r", "<'+'/"), addslashes($var))."'";
	} else if (is_null($var)) {
		$str="null";
	} else {
		$str="null";
	}
	
	return $str;
}

/*
 * MyPage object is the container of MyPageWindow
 */
class MyPage {
	var $id;
	var $id_users;
	var $windows;
	var $lastid;
	var $params;
	var $modified;
// 	var $perms;
	var $lasterror;
	var $typeclass;
	var $clonning;

	/* never call this constructor directly */
	function MyPage($id=NULL, $id_users) {
		$this->id=$id;
		$this->id_users=$id_users; //the viewer
		$this->windows=array();
		$this->lastid=0;
		$this->params=array();
		$this->modified=array();
		$this->lasterror=NULL;
		$this->typeclass=NULL;
		$this->clonning=false;
	}

	/*static*/
	function getMyPage_new($id_users, $id_types) {
		$mypage=new MyPage(NULL, $id_users);
		$mypage->params['id_users']=(int)$id_users;
		$mypage->params['id_types']=(int)$id_types;
		$mypage->modified['id_types']=true;
		
		$type=MyPage::getMypageType((int)$id_types);
		if (!is_array($type)) return tra("mypage type unaivalable");
		$classname=MyPage::getTypeClassName($type['name']);
		if ($classname !== NULL)
			$mypage->typeclass=call_user_func(array($classname, 'newInstance_new'), $mypage);
		
		return $mypage;
	}
	
	/*static*/
	function getMyPage_byId($id, $id_users) {
		$mypage=new MyPage($id, $id_users);
		$mypage->checkout();
		if (strlen($mypage->lasterror)) return $mypage->lasterror;
		
		$typeclass=$mypage->getTypeClass();
		if (!is_object($typeclass)) {
			if (is_string($typeclass)) {
				return $typeclass; // return the error returner by type
			} else {
				return "an error occured while making the type instance";
			}
		}
		return $mypage;
	}

	/*static*/
	function getMyPage_byName($name, $id_users) {
		global $tikilib;

		$res=$tikilib->query("SELECT `id` FROM tiki_mypage WHERE `name`=?", array($name));
		if ($line = $res->fetchRow()) {
			$mypage=new MyPage($line['id'], $id_users);
			$mypage->checkout();
			if (strlen($mypage->lasterror)) return $mypage->lasterror;

			$typeclass=$mypage->getTypeClass();
			if (!is_object($typeclass)) {
				if (is_string($typeclass)) {
					return $typeclass; // return the error returner by type
				} else {
					return "an error occured while making the type instance";
				}
			}

			return $mypage;

		} else {
			return "mypage '$name' not found";
		}
	}

	/*static*/
	function getMyPage_clone($mypage_src, $id_users) {
		$id_types=$mypage_src->getParam('id_types');
		$mypage_dst=new MyPage(NULL, $id_users);
		$mypage_dst->params['id_users']=(int)$id_users;
		$mypage_dst->params['id_types']=$id_types;
		$mypage_dst->modified['id_types']=true;
		
		$type=MyPage::getMypageType((int)$id_types);
		if (!is_array($type)) return tra("mypage type unaivalable");
		$classname=MyPage::getTypeClassName($type['name']);
		if ($classname !== NULL)
			$mypage_dst->typeclass=call_user_func(array($classname, 'newInstance_clone'), $mypage_dst, $mypage_src->getTypeClass());

		if (!is_object($typeclass)) {
			if (is_string($typeclass)) {
				return $typeclass; // return the error returner by type
			} else {
				return "an error occured while making the type instance";
			}
		}

		/* copy mypage params */
		$copys=array('width', 'height', 'bgcolor', 'description', 'categories', 'winbgcolor', 'bgimage', 'winbgimage',
					 'bgtype', 'winbgtype');
		foreach($copys as $copy) $mypage_dst->setParam($copy, $mypage_src->getParam($copy));
		$mypage_dst->commit();
		
		foreach($mypage_src->windows as $window_src) {
			$window_dst=MyPageWindow::newInstance_clone($mypage_dst, --$mypage_dst->lastid, $window_src);
			$mypage_dst->windows[$mypage_dst->lastid]=$window_dst;
		}
		$mypage_dst->clonning=false;
		return $mypage_dst;
	}

	function getPerm($for) {
		global $tiki_p_admin;
		switch ($for) {
		case 'edit':
			if ($tiki_p_admin == 'y') return true;
			//echo "(".$this->id_users." / ".$this->params['id_users'].")";
			return ((int)$this->id_users == (int)$this->params['id_users']);
		case 'view':
			return true;
		}
		return false;
	}

	function getWindows() {
		return $this->windows;
	}
	
	function getWindow($id) {
		if (!isset($this->windows[$id])) return tra("window not found");
		return $this->windows[$id];
	}

	function getWindowsOfType($type) {
		$windows=array();
		foreach ($this->windows as $window) {
			if ($window->getParam('contenttype') == $type)
				$windows[]=$window;
		}
		return $windows;
	}
	
	function newWindow($contenttype) {
		$win=MyPageWindow::newInstance_new($this, --$this->lastid, $contenttype);
		$this->windows[$this->lastid]=$win;
		return $win;
	}
	
	function _update_id_win($from, $to) {
		$this->windows[$to]=$this->windows[$from];
		unset($this->windows[$from]);
	}
	
	function destroy() {
		global $tikilib;
		
// 		if ($this->perms['tiki_p_edit_mypage'] != 'y' && !($this->perms['tiki_p_edit_own_mypage'] == 'y' && $this->id_users == $this->getParam('id_users'))) {
// 			$this->lasterror=tra('You do not have permissions to delete the page');
// 			return $this->lasterror;
// 		}

		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		// we firstly destroy every windows that this mypage contain
		foreach($this->windows as $window) {
			$window->destroy();
		}
		
		$typeclass=$this->getTypeClass();
		if (is_object($typeclass)) $typeclass->destroy();

		// finally, we destroy this mypage
		$tikilib->query("DELETE FROM tiki_mypage WHERE `id`=?",
						array($this->id));
	}
	
	function _destroyWindow($window) {
		global $tikilib;
		
		$id_win=0;
		if (is_object($window)) {
			$id_win=$window->id;
		} else if (is_int($window)) {
			$id_win=$window;
		}
		
		if (!isset($this->windows[$id_win])) return;
		
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		if ($id_win > 0) {
// 			if ($this->perms['tiki_p_edit_mypage'] != 'y' && !($this->perms['tiki_p_edit_own_mypage'] == 'y' && $this->id_users == $this->getParam('id_users'))) {
// 				$this->lasterror=tra('You do not have permissions to delete this component');
// 				return $this->lasterror;
// 			}
			$tikilib->query("DELETE FROM tiki_mypagewin WHERE `id`=? AND `id_mypage`=?",
							array($id_win, $this->id));
		}
		
		unset($this->windows[$id_win]);
	}
	
	/* static */
	function isNameFree($name) {
		global $tikilib;
		$r=$tikilib->getOne('SELECT COUNT(*) FROM tiki_mypage WHERE name=?', $name);
		return $r == 0 ? true : false;
	}

	/* static */
	function countPages($id_users, $type=NULL) {
		global $tikilib;
		global $tiki_p_admin;
		
		$query="SELECT count(*) ".
			"FROM tiki_mypage mp ".
			"LEFT JOIN tiki_mypage_types mpt ON mp.id_types = mpt.id WHERE (1=1)";
		$r=array();


		if (($id_users!=-1) || ($tiki_p_admin != 'y')) {
			$query.=" AND `id_users`=?";
			$r[]=(int)$id_users;
		}

		if ($type !== NULL) {
			$query.=" AND mpt.name=?";
			$r[]=$type;
		}

		$res=$tikilib->query($query, $r, $limit, $offset);

		return $tikilib->getOne($query, $r);
	}
	
	/* static */
	function listPages($id_users, $type=NULL, $offset=-1, $limit=-1, $sort_mode='mp.name') {
		global $tikilib;
		global $tiki_p_admin;

		$pages=array();

		$query="SELECT mp.*, ".
			"mpt.name as type_name, ".
			"mpt.description as type_description, ".
			"mpt.section as type_section, ".
			"mpt.permissions as type_permissions ".
			"FROM tiki_mypage mp ".
			"LEFT JOIN tiki_mypage_types mpt ON mp.id_types = mpt.id WHERE (1=1)";
		$r=array();

		if (($id_users!=-1) || ($tiki_p_admin != 'y')) {
			$query.=" AND `id_users`=?";
			$r[]=(int)$id_users;
		}

		if ($type !== NULL) {
			$query.=" AND mpt.name=?";
			$r[]=$type;
		}

		$sortstr='';
		if (is_array($sort_mode)) {
			foreach($sort_mode as $k => $v) $sort_mode[$k]=$tikilib->convert_sortmode($v);
			$sortstr=implode(', ', $sort_mode);
		} else $sortstr=$sort_mode;

		$query.=" ORDER BY ".$sortstr;
		$res=$tikilib->query($query, $r, $limit, $offset);

		while ($line = $res->fetchRow()) {
// 			$line['perms'] = $tikilib->get_perm_object($line['id'], 'mypage', false);
			$pages[]=$line;
		}

		return $pages;
	}
	
	function setParams($id_mypage, $vals) {
		foreach($vals as $k=>$v) {
			$err=$this->setParam($k, $v);
			if ($err) return $err;
		}
	}
	function setParam($param, $value) {
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		$allowed=array('width', 'height', 'wintitlecolor', 'wintextcolor', 'winbgcolor',
					   'name', 'description', 'bgcolor', 'categories', 'bgimage', 'winbgimage',
					   'bgtype', 'winbgtype');

		if ($param == 'categories') {
			if (is_null($value)) $value=array();
			else if (!is_array($value)) {
				if (empty($value)) $value=array();
				else $value=array($value);
			}
		}
		
		$typeclass=$this->getTypeClass();
		if (in_array($param, $allowed)) {
			// TODO: verify permissions when changing id_users or id_types !
			$this->params[$param]=$value;
			$this->modified[$param]=true;
			if (is_object($typeclass)) $typeclass->mypage_setParam($param, $value);
		} else {
			$this->lasterror=tra("Parameter not found :").$param;
			return $this->lasterror;
		}
	}
	
	function _getcateg() {
		global $categlib; include_once ('lib/categories/categlib.php');

		if (array_key_exists('categories', $this->params)) return $this->params['categories'];
 	    $cat=$categlib->get_object_categories('mypage', $this->id, -1);
		return $cat;
	}

	function getParam($param, $default=NULL) {
		if ($param=='categories') {
			if (array_key_exists($param['categories']))
				return $param['categories'];
			else
				return $param['categories']=$this->_getcateg();
		} else {
			if (!isset($this->params[$param]))
				return $default;
			else
				return $this->params[$param];
		}
	}
	
	function checkout() {
		global $tikilib;
		
		$this->windows=array();
		
		if (!is_null($this->id)) {
			$res=$tikilib->query("SELECT * FROM tiki_mypage WHERE `id`=?", array($this->id));
			if ($line = $res->fetchRow()) {
				$this->params=$line;
				$this->modified=array();
			} else { // bad... no mypage found
				$this->id=0;
				return $this->lasterror="MyPage not found";
			}
			$this->perms = $tikilib->get_perm_object($this->id, 'mypage', false);
// 			if ($this->perms['tiki_p_view_mypage'] != 'y' && !($this->perms['tiki_p_edit_own_mypage'] == 'y' && $this->id_users == $this->getParam('id_users'))) {
// 				$this->lasterror=tra('You do not have permissions to view the page');
// 				return $this->lasterror;
// 			}
			
			$res=$tikilib->query("SELECT * FROM tiki_mypagewin WHERE `id_mypage`=?", array($this->id));
			while ($line = $res->fetchRow()) {
				$instance=MyPageWindow::newInstance_load($this, $line);
				if (!is_object($instance)) return $this->lasterror="can't load window: $instance";
				$this->windows[$line['id']]=$instance;
			}
		}
	}
	
	function commit() {
		global $tikilib, $tiki_p_edit_mypage, $tiki_p_edit_own_mypage;
		
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		if (is_null($this->id)) {
// 			if ($tiki_p_edit_mypage != 'y' && $tiki_p_edit_own_mypage != 'y') {
// 				$this->lasterror=tra('You do not have permissions to edit the page');
// 				return $this->lasterror;
// 			}
			
			$this->params['created']=$tikilib->now;
			$this->modified['created']=1;

			// verify that we have a category if mandatory
			global $feature_mypage_mandatory_category;
			$categories = $this->getParam('categories');
			if (($feature_mypage_mandatory_category > 0) && (count($categories) == 0)) {
				return $this->lasterror = tra('A category is mandatory');
			}

			// create a new mypage id
			
			$res=$tikilib->query("INSERT INTO tiki_mypage (`id_users`) values (?)",
								 array($this->id_users));
			if (!$res) return;
			
			$id=$tikilib->getOne("SELECT LAST_INSERT_ID()");
			if (!$id) return;
			
			$this->id=$id;
			
			$typeclass=$this->getTypeClass();
			if (is_object($typeclass)) $typeclass->create();
			else return $this->lasterror="commit failed: $typeclass";

			// now run again for update ;)
			$res=$this->commit();
			if (is_string($res)) {
				$tikilib->query("DELETE FROM tiki_mypage WHERE `id`=?",
								array($this->id));
				$this->id=NULL;
				return $res;
			}
			return $res;
			
		} else {
			
			if (count($this->modified) > 0) {
				if (isset($this->modified['name'])) {
					$c=$tikilib->getOne('SELECT COUNT(*) FROM tiki_mypage WHERE `name`=? AND `id`!=?',
										array($this->params['name'], $this->id));
					if ($c != 0)
						return $this->lasterror=tra(sprintf('Name "%s" already exists', $this->params['name']));
				}
				$this->params['modified']=$tikilib->now;
				$this->modified['modified']=1;

				$l=array();
				$r=array();
				foreach($this->modified as $k => $v) {
					if ($k=='categories') continue; // categories is handled separatly
					$l[]="`$k`=?";
					$r[]=$this->params[$k];
				}

				global $feature_mypage_mandatory_category;
				$categories = $this->getParam('categories');
				if ($feature_mypage_mandatory_category > 0 && count($categories) == 0) {
					return $this->lasterror = tra('A category is mandatory');
				}

				$query="UPDATE tiki_mypage SET ".implode(',', $l)." WHERE `id`=?";
				$r[]=$this->id;
				
				$res=$tikilib->query($query, $r);

				if ($this->modified['categories'] || $this->modified['name'] || $this->modified['description']) {
					global $categlib; include_once ('lib/categories/categlib.php');
					foreach($this->params['categories'] as $categid) {
						$categlib->update_object_categories($categid, $this->id, 'mypage',
															$this->params['description'], $this->params['name'],
															"tiki-mypage.php?id_mypage=".$this->id);
					}
				}

				$typeclass=$this->getTypeClass();
			}

			if (is_object($typeclass)) $typeclass->commit();
			$this->modified=array();

			foreach($this->windows as $window) {
				if (!is_object($window)) return "window is not an object: $window";
				$window->commit();
			}
		}
	}
	
	/*
	 * increment viewed count
	 */
	function viewed() {
		global $tikilib;
		if ($this->id > 0) {
			$this->params['viewed']++;
			$tikilib->query('UPDATE tiki_mypage SET `viewed`=? WHERE `id`=?',
							array($this->params['viewed'], $this->id));
		}
	}

	function getJSCode($editable=false) {
		$js="/* windows creation */\n";
		foreach($this->windows as $win) {
			$js.=$win->getJSCode($editable);
		}
		$js.="/* end of windows creation */\n";
		return $js;
	}

	/*
	 * one day, i'll make a libcomponents...
	 *
	 * if called by the static way, it will return every available component
	 * if called by the instance way, it will return every available component for this type of mypage
	 */
	/* static or not static ! */
	function getAvailableComponents() {
		$r=array();
		$d=opendir("components");
		if ($d === FALSE) return $r;

		if (isset($this)) $cft=$this->getComponentsFromTypes();
		else $cft=NULL;

		while (($file = readdir($d)) !== false) {
			if (preg_match('/^comp-[a-zA-Z0-9_-]+\.php$/', $file)) {
				$compname=substr($file, 5, -4);
				if ($cft !== NULL) {
					foreach($cft as $l) {
						if ($l['compname'] == $compname)
							$r[]=$compname;
					}
				} else $r[]=$compname;
			}
        }
		return $r;
	}

	function getComponentsFromTypes() {
		global $tikilib;
		$query="select c.compname, c.mincount, c.maxcount ".
			" FROM tiki_mypage_types t ".
			" LEFT JOIN tiki_mypage_types_components c ON c.id_mypage_types=t.id ".
			" WHERE t.id=?";
		$result=$tikilib->query($query, array($this->getParam('id_types')));
		$lines=array();
		while ($line=$result->fetchRow()) {
			$lines[]=$line;
		}
		return $lines;
	}

	/* static */
	function countMypageTypes() {
		global $tikilib;
		
		$pages=array();
		return $tikilib->getOne("SELECT COUNT(*) FROM tiki_mypage_types");
	}
	
	/* static */
	function listMypageTypes($offset=-1, $limit=-1) {
		global $tikilib;

		$lines=array();
		$res=$tikilib->query("SELECT ".
							 " mpt.id as id, ".
							 " mpt.name as name, ".
							 " mpt.description as description, ".
							 " mpt.section as section, ".
							 " mpt.permissions as permissions, ".
							 " mpt.def_width as def_width, ".
							 " mpt.def_height as def_height, ".
							 " mpt.fix_dimensions as fix_dimensions, ".
							 " mpt.def_bgcolor as def_bgcolor, ".
							 " mpt.fix_bgcolor as fix_bgcolor, ".
							 " mpt.templateuser as templateuser, ".
							 " mptc.compname as compname, ".
							 " mptc.mincount as mincount, ".
							 " mptc.maxcount as maxcount ".
							 "FROM tiki_mypage_types as mpt ".
							 "LEFT JOIN tiki_mypage_types_components as mptc ".
							 "ON mptc.id_mypage_types = mpt.id ".
							 "ORDER BY mpt.id ",
							 array(), $limit, $offset);
		$lastid=0;
		$lastline=NULL;
		while ($line = $res->fetchRow()) {
			if ($line['id'] != $lastid) {
				if ($lastline !== NULL) $lines[]=$lastline;
				$lastid=$line['id'];
				$lastline=array('id' => $line['id'],
								'name' => $line['name'],
								'description' => $line['description'],
								'section' => $line['section'],
								'permissions' => $line['permissions'],
								'def_width' => $line['def_width'],
								'def_height' => $line['def_height'],
								'fix_dimensions' => $line['fix_dimensions'],
								'def_bgcolor' => $line['def_bgcolor'],
								'fix_bgcolor' => $line['fix_bgcolor'],
								'templateuser' => $line['templateuser'],
								'components' => array());
			}
			$lastline['components'][]=array('compname' => $line['compname'],
											'mincount' => $line['mincount'],
											'maxcount' => $line['maxcount']);
		}
		if ($lastline !== NULL) $lines[]=$lastline;
		
		return $lines;
	}

	/* static */
	function getMypageType($id) {
		global $tikilib;

		$lines=array();
		$res=$tikilib->query("SELECT ".
							 " mpt.id as id, ".
							 " mpt.name as name, ".
							 " mpt.description as description, ".
							 " mpt.section as section, ".
							 " mpt.permissions as permissions, ".
							 " mpt.def_width as def_width, ".
							 " mpt.def_height as def_height, ".
							 " mpt.fix_dimensions as fix_dimensions, ".
							 " mpt.def_bgcolor as def_bgcolor, ".
							 " mpt.fix_bgcolor as fix_bgcolor, ".
							 " mpt.templateuser as templateuser, ".
							 " mptc.compname as compname, ".
							 " mptc.mincount as mincount, ".
							 " mptc.maxcount as maxcount ".
							 "FROM tiki_mypage_types as mpt ".
							 "LEFT JOIN tiki_mypage_types_components as mptc ".
							 "ON mptc.id_mypage_types = mpt.id ".
							 "WHERE mpt.id=? ".
							 "ORDER BY mpt.id ",
							 array((int)$id));
		$lastid=0;
		$lastline=NULL;
		while ($line = $res->fetchRow()) {
			if ($line['id'] != $lastid) {
				if ($lastline !== NULL) $lines[]=$lastline;
				$lastid=$line['id'];
				$lastline=array('id' => $line['id'],
								'name' => $line['name'],
								'description' => $line['description'],
								'section' => $line['section'],
								'permissions' => $line['permissions'],
								'def_width' => $line['def_width'],
								'def_height' => $line['def_height'],
								'fix_dimensions' => $line['fix_dimensions'],
								'def_bgcolor' => $line['def_bgcolor'],
								'fix_bgcolor' => $line['fix_bgcolor'],
								'templateuser' => $line['templateuser'],
								'components' => array());
			}
			$lastline['components'][]=array('compname' => $line['compname'],
											'mincount' => $line['mincount'],
											'maxcount' => $line['maxcount']);
		}
		if ($lastline !== NULL) $lines[]=$lastline;
		
		if (count($lines) == 1) return $lines[0];
		else return NULL;
	}

	/* static */
	function deleteMypageType($id) {
		global $tikilib;

		$res=$tikilib->query("DELETE FROM tiki_mypage_types_components ".
							 "WHERE id_mypage_types=?", array((int)$id));

		$res=$tikilib->query("DELETE FROM tiki_mypage_types ".
							 "WHERE id=?", array((int)$id));
	}
	
	/* static */
	function createMypageType() {
		global $tikilib;

		$res=$tikilib->query("INSERT INTO tiki_mypage_types (created,modified) VALUES (?,?)",
							 array($tikilib->now, $tikilib->now));
		return $tikilib->getOne("SELECT LAST_INSERT_ID()");
	}

	/* static */
	function updateMypageType($id, $vals) {
		global $tikilib;

		$cols=array("name", "description", "section", "permissions",
					"def_width", "def_height", "fix_dimensions",
					"def_bgcolor", "fix_bgcolor", "modified", "templateuser");

		$vals['modified']=$tikilib->now;
		$tvals=$vals;
		// we remove unauthorized cols
		foreach($tvals as $k => $v)
			if (!in_array($k, $cols)) unset($tvals[$k]);

		if (array_key_exists('def_width', $tvals) && empty($tvals['def_width'])) $tvals['def_width']=NULL;
		if (array_key_exists('def_height', $tvals) && empty($tvals['def_height'])) $tvals['def_height']=NULL;
		if (array_key_exists('def_bgcolor', $tvals) && empty($tvals['def_bgcolor'])) $tvals['def_bgcolor']=NULL;

		if (count($tvals) > 0) {
			$l=array();
			$r=array();
			foreach($tvals as $k => $v) {
				$l[]="`$k`=?";
				$r[]=$v;
			}
			
			$query="UPDATE tiki_mypage_types SET ".implode(', ', $l)." WHERE `id`=?";
			$r[]=(int)$id;
			
			$res=$tikilib->query($query, $r);
		}

		if (isset($vals['components'])) {
			$res=$tikilib->query("DELETE FROM tiki_mypage_types_components ".
								 "WHERE id_mypage_types=?", array((int)$id));
			foreach($vals['components'] as $component) {
				$res=$tikilib->query("INSERT INTO tiki_mypage_types_components".
									 " (`id_mypage_types`, `compname`)".
									 " VALUES (?,?)", array((int)$id, $component));
			}
		}
	}

	/* static */
	function getTypeHTMLConfig($type=NULL) {
		if (isset($this)) {
			$typeclass=$this->getTypeClass();
			return (is_object($typeclass) ? $typeclass->getHTMLConfig() : NULL);
		} else {
			$classname=MyPage::getTypeClassName($type);
			if (($classname !== NULL) && is_callable(array($classname, 'getHTMLConfig')))
				return call_user_func(array($classname, 'getHTMLConfig'));
			else
				return NULL;
		}
	}

	/* static */
	function getTypeClassName($type) {
		if (!preg_match('/^[a-zA-Z0-9_-]+$/', $type))
			return NULL;
		if (file_exists("lib/mypage/types/type-".$type.".php")) {
			require_once("lib/mypage/types/type-".$type.".php");
			$classname="Mypagetype_".$type;
			return $classname;
		}
		return NULL;		
	}

	function getTypeClass() {
		if ($this->typeclass) return $this->typeclass;
		$type=MyPage::getMypageType((int)$this->getParam('id_types'));
		if (!is_array($type)) return "class not found: $type";
		$classname=MyPage::getTypeClassName($type['name']);
		if ($classname === NULL) return "class ".$type['name']." not found";
		$this->typeclass=call_user_func(array($classname, 'newInstance_load'), $this);

		if (!is_object($this->typeclass))
			return $this->lasterror=$this->typeclass;

		return $this->typeclass;
	}
}

class MyPageWindow {
	var $mypage;
	var $id;
	var $params;
	var $modified;
	var $comp;
	var $lasterror;

	/*
	 * this constructor may be called only by the MyPage class
	 * you should not create a new instance of this object directly
	 */
	function MyPageWindow($mypage, $id) {
		$this->mypage=$mypage;
		$this->id=$id;
		$this->params=$line;
		$this->modified=array();
		$this->comp=NULL;
	}

	/*
	 * construct a new instance for creating new window, should be called only by MyPage
	 */
	/* static */
	function newInstance_new($mypage, $id, $contenttype) {
		$win=new MyPageWindow($mypage, $id);
		$win->params['contenttype']=$contenttype;
		$win->modified['contenttype']=true;

			// some default values...
		$win->setParam('top',0);
		$win->setParam('left',0);
		$win->setParam('width',100);
		$win->setParam('height',100);

		$classname=MyPageWindow::getComponentClass($contenttype);
		if ($classname) {
			$win->comp=call_user_func(array($classname, 'newInstance_new'), $win);
			if (!is_object($win->comp)) return tra("component error: ").$win->comp;
		} else return tra("component not found");

		return $win;
	}

	/*
	 * construct a new instance for an existing window, should be called only by MyPage
	 */
	/* static */
	function newInstance_load($mypage, $line) {
		$win=new MyPageWindow($mypage, $line['id']);
		$win->params['contenttype']=$line['contenttype'];
		$win->modified['contenttype']=true;

		$allowed=array('title', 'inbody', 'modal', 'left', 'top', 'width', 'height', 'config', 'content');
		foreach($line as $k => $v) {
			if (in_array($k, $allowed))
				$win->params[$k]=$v;
		}
		return $win;
	}

	/*
	 * construct a new instance for clonning an existing window, should be called only by MyPage
	 */
	/* static */
	function newInstance_clone($mypage, $id, $win_src) {
		$win=new MyPageWindow($mypage, $id);
		$win->params['contenttype']=$win_src->getParam('contenttype');
		$win->modified['contenttype']=true;

		$allowed=array('title', 'inbody', 'modal', 'left', 'top', 'width', 'height', 'config', 'content');
		foreach($allowed as $k) {
				$win->setParam($k, $win_src->getParam($k));
		}

		$comp_src=$win_src->getComponent();

		$classname=MyPageWindow::getComponentClass($win_src->getParam('contenttype'));
		if ($classname) {
			$win->comp=call_user_func(array($classname, 'newInstance_clone'), $win, $comp_src);
			if (!is_object($win->comp)) return tra("can't make new instance of component: ").$win->comp;
		} else return tra('class of component not found');

		return $win;
	}

	function destroy() {
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');

		$comp=$this->getComponent();
		if (is_object($comp)) $comp->destroy();
		return $this->mypage->_destroyWindow($this);
	}


	function getPerm($for) {
		switch ($for) {
		case 'edit':
			return $this->mypage->getPerm('edit');
		case 'view':
			return $this->mypage->getPerm('edit');
		}
		return false;
	}

	
	function commit() {
		global $tikilib;
		/*		
		if ($this->mypage->perms['tiki_p_view_mypage'] != 'y' && !($this->mypage->perms['tiki_p_edit_own_mypage'] == 'y' && $this->mypage->id_users == $this->mypage->getParam('id_users'))) {
			$this->lasterror=tra('You do not have permissions to edit the component');
			return $this->lasterror;
		}
		*/
		
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');


		if ($this->id < 0) {
			// create a new mypagewin id
			
			$this->params['created']=$tikilib->now;
			$this->modified['created']=1;

			$res=$tikilib->query("INSERT INTO tiki_mypagewin (`id_mypage`) values (?)",
								 array($this->mypage->id));
			if (!$res) return;
			
			$id=$tikilib->getOne("SELECT LAST_INSERT_ID()");
			if (!$id) return;
			
			$oldid=$this->id;
			$this->id=$id;
			$this->mypage->_update_id_win($oldid, $this->id);
			
			// now run again for update ;)
			$r=$this->commit();
			if (is_string($r)) {
				$tikilib->query("DELETE FROM tiki_mypagewin WHERE `id`=?", array($this->id));
				$this->id=$oldid;
				$this->mypage->_update_id_win($this->id, $oldid);
				return $r;
			}
			$comp=$this->getComponent();
			if (is_object($comp) && is_callable(array($comp, 'create'))) $comp->create();

		} else {
			
			if (count($this->modified) > 0) {
				$this->params['modified']=$tikilib->now;
				$this->modified['modified']=1;

				$l=array();
				$r=array();
				foreach($this->modified as $k => $v) {
					$l[]="`$k`=?";
					$r[]=$this->params[$k];
				}
				
				$query="UPDATE tiki_mypagewin SET ".implode(',', $l)." WHERE `id`=?";
				$r[]=$this->id;
				
				$res=$tikilib->query($query, $r);
				
				$this->modified=array();
			}

			$comp=$this->getComponent();
			if (is_object($comp) && is_callable(array($comp, 'commit'))) $comp->commit();
		}
	}
	
	function setParam($param, $value) {
		if (!$this->getPerm('edit'))
			return $this->lasterror=tra('You are not the owner of this page');
		$this->params[$param]=$value;
		$this->modified[$param]=true;
	}
	
	function getParam($param) {
		return $this->params[$param];
	}
	
	/*
	 * $contenttype: must be 'iframe' or 'wiki'
	 */
	function setContentType($contenttype) {
		return $this->setParam('contenttype', $contenttype);
	}
	
	function setContent($content) {
		return $this->setParam('content', $content);
	}
	
	function setConfig($config) {
		return $this->setParam('config', $config);
	}
	
	function setPosition($left, $top) {
		$err=$this->setParam('left', (int)$left);
		if (is_string($err)) return $err;
		return $this->setParam('top', (int)$top);
	}

	function setSize($width, $height) {
		$err=$this->setParam('width', (int)$width);
		if (is_string($err)) return $err;
		return $this->setParam('height', (int)$height);
	}

	function setRect($left, $top, $width, $height) {
		$err=$this->setPosition($left, $top);
		if (is_string($err)) return $err;
		return $this->setSize($width, $height);
	}

	function setTitle($title) {
		return $this->setParam('title', $title);
	}

	/* static */
	function isComponentConfigurable($compname=NULL) {
		if (!empty($compname)) {
			$classname=MyPageWindow::getComponentClass($compname);
			if (($classname !== NULL) && is_callable(array($classname, 'isConfigurable')))
				return call_user_func(array($classname, 'isConfigurable'));
		}
		return false;
	}

	/* static or not static */
	function getComponentConfigureDiv($compname=NULL) {
		if (isset($this)) { // we are not static
			$comp=$this->getComponent();
			if ($comp) return $comp->getConfigureDiv();
			return NULL;
		} else if (!empty($compname)) { // we are static
			$classname=MyPageWindow::getComponentClass($compname);
			if (($classname !== NULL) && is_callable(array($classname, 'getConfigureDiv')))
				return call_user_func(array($classname, 'getConfigureDiv'));
		}
		return NULL;
	}
	
	/* static */
	function getComponentClass($compname) {
		if (!preg_match('/^[a-zA-Z0-9_-]+$/', $compname))
			return NULL;
		if (file_exists("components/comp-".$compname.".php")) {
			require_once("components/comp-".$compname.".php");
			$classname="Comp_".$compname;
			return $classname;
		}
	}

	function getComponent() {
		if ($this->comp) return $this->comp;
		$classname=MyPageWindow::getComponentClass($this->params['contenttype']);
		if ($classname) {
			$this->comp=call_user_func(array($classname, 'newInstance_load'), $this);
			return $this->comp;
		}
		return NULL;
	}

	function getJSCode($editable=false) {
		global $tikilib;

		$comp=$this->getComponent();
		if (!is_object($comp)) {
			$this->lasterror=tra('Component not available: ').$this->params['contenttype']." -> ".$comp;
			return 'alert("'.addslashes($this->lasterror).'");';
		}

		if (is_callable(array($comp, 'getPerm')) && !$comp->getPerm('view')) {
			$this->lasterror=tra("You do not have permission to view this part of content");
			return 'alert("'.addslashes($this->lasterror).'");';
		}

		$v="tikimypagewin[".$this->id."]";

		$winparams=array('left'	     => (int)$this->params['left'],
						 'top'	     => (int)$this->params['top'],
						 'width'	 => (int)$this->params['width'],
						 'height'	 => (int)$this->params['height'],
						 'title'	 => $this->params['title'],
						 'position'  => false,
						 'theme'	 => 'mypage',
						 'container' => 'mypage',
						 'buttons'   => array()
						 );

		if (is_callable(array($comp, 'isResizeable'))) {
			if (!$comp->isResizeable()) {
				$winparams['resizable']  = false;
				$winparams['buttons']['maximize'] = false;
				$winparams['buttons']['minimize'] = false;
			}
		}

		if (is_callable(array($comp, 'isResizeable'))) {
			if (!$comp->isCloseable()) $winparams['buttons']['close'] = false;
		}

		if (!$editable) {
			$winparams['theme']	  = 'mypage_view';
			$winparams['resizable']  = false;
			$winparams['draggable']  = false;
			$winparams['buttons']	 = array('close'	=> false,
											 'minimize' => false,
											 'maximize' => false);
		}
	
		if ($this->params['contenttype'] == 'iframe') {
			$winparams['type']="iframe";
			$winparams['url']=$this->params['config'];
		}
	
		$js =$v."=new Windoo(".phptojsarray($winparams).");\n";
		if ($editable) {
			$js.=$v.".addEvent('onResizeComplete', function(){ state=$v.getState(); xajax_mypage_win_setrect(".$this->mypage->id.", ".$this->id.", state.outer); });\n";
			$js.=$v.".addEvent('onDragComplete', function(){ state=$v.getState(); xajax_mypage_win_setrect(".$this->mypage->id.", ".$this->id.", state.outer); });\n";
			$js.=$v.".addEvent('onClose', function(){ xajax_mypage_win_destroy(".$this->mypage->id.", ".$this->id."); });\n";
			$js.=$v.".addEvent('onFocus', function(){ windooFocusChanged(".$this->id."); });\n";
			$js.=$v.".addEvent('onStartDrag', function() { windooStartDrag(".$this->id."); });\n";
		}

		if ($this->params['contenttype'] != 'iframe') {
			$js.=$v.".setHTML(".phptojsarray($comp->getHTMLContent()).");\n";
		}
		
		$js.=$v.".show();\n";

		if (is_callable(array($comp, 'getOnOpenJSCode'))) {
			$js.=$comp->getOnOpenJSCode().";\n";
		}
		
		return $js;
	}
}

/* For the emacs weenies in the crowd.
Local Variables:
   tab-width: 4
   c-basic-offset: 4
End:
*/

?>
{'fraction_non_alphanumeric': 0.2070804040881432, 'fraction_numerical': 0.002333549949784368, 'mean_word_length': 3.8561285232733273, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 821, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2609676', 'n_tokens_mistral': 28688, 'n_tokens_neox': 24102, 'n_words': 4641}