TikiDB($db);
$this->now = (int) date('U');
}
/*shared*/
function httprequest($url, $reqmethod = "GET") {
global $prefs;
// test url :
if (!preg_match("/^[-_a-zA-Z0-9:\/\.\?&;=\+~%,]*$/",$url)) return false;
// rewrite url if sloppy # added a case for https urls
if ( (substr($url,0,7) <> "http://") and
(substr($url,0,8) <> "https://")
) {
$url = "http://" . $url;
}
// (cdx) params for HTTP_Request.
// The timeout may be defined by a DEFINE("HTTP_TIMEOUT",5) in some file...
$aSettingsRequest=array("method"=>$reqmethod,"timeout"=>5);
if (substr_count($url, "/") < 3) {
$url .= "/";
}
// Proxy settings
if ($prefs['use_proxy'] == 'y') {
$aSettingsRequest["proxy_host"]=$prefs['proxy_host'];
$aSettingsRequest["proxy_port"]=$prefs['proxy_port'];
}
include_once ('lib/pear/HTTP/Request.php');
$req = &new HTTP_Request($url, $aSettingsRequest);
$data="";
// (cdx) return false when can't connect
// I prefer throw a PEAR_Error. You decide ;)
if (PEAR::isError($oError=$req->sendRequest())) {
return(false);
/* Please people, don't use fopen. It's potentially unsafe
* because if any form does not check the url, you can upload
* /etc/passwd and other file from the local host.
* it's also more safe to use httprequest, because the admin can set
* a proxy so that noone can upload files in tiki from behind a
* firewall (safes the net where tiki runs in).
$fp = fopen($url, "r");
if ($fp) {
$data = '';
while(!feof($fp)) {
$data .= fread($fp,4096);
}
fclose ($fp);
}
if ($data =="") return false;
*/
} else {
$data = $req->getResponseBody();
}
return $data;
}
/*shared*/
function get_dsn_by_name($name) {
if ($name == 'local') {
return true;
}
return $this->getOne("select `dsn` from `tiki_dsn` where `name`='$name'");
}
/* convert data to iso-8601 format */
// used for atom export. date() use is okay, as we use server timezone in such case
function iso_8601 ($timestamp) {
$main_date = $this->date_format("%Y-%m-%d\T%H:%M:%S", $timestamp);
$tz = $this->date("%O", $timestamp);
$return = $main_date . $tz;
return $return;
}
/*shared*/
function check_rules($user, $section) {
// Admin is never banned
if ($user == 'admin')
return false;
$ips = explode('.', $_SERVER["REMOTE_ADDR"]);
$query = "select tb.`message`,tb.`user`,tb.`ip1`,tb.`ip2`,tb.`ip3`,tb.`ip4`,tb.`mode` from `tiki_banning` tb, `tiki_banning_sections` tbs where tbs.`banId`=tb.`banId` and tbs.`section`=? and ( (tb.`use_dates` = ?) or (tb.`date_from` <= ? and tb.`date_to` >= ?))";
$result = $this->query($query,array($section,'n',(int)$this->now,(int)$this->now));
while ($res = $result->fetchRow()) {
if (!$res['message']) {
$res['message'] = tra('You are banned from'). ':' . $section;
}
if ($user && $res['mode'] == 'user') {
// check user
$pattern = '/' . $res['user'] . '/';
if (preg_match($pattern, $user)) {
return $res['message'];
}
} else {
// check ip
if (count($ips) == 4) {
if (($ips[0] == $res['ip1'] || $res['ip1'] == '*') && ($ips[1] == $res['ip2'] || $res['ip2'] == '*')
&& ($ips[2] == $res['ip3'] || $res['ip3'] == '*') && ($ips[3] == $res['ip4'] || $res['ip4'] == '*')) {
return $res['message'];
}
}
}
}
return false;
}
/*shared*/
function replace_note($user, $noteId, $name, $data, $parse_mode = null) {
$size = strlen($data);
if ($noteId) {
$query = "update `tiki_user_notes` set `name` = ?, `data` = ?, `size` = ?, `lastModif` = ?, `parse_mode` = ? where `user`=? and `noteId`=?";
$this->query($query,array($name,$data,(int)$size,(int)$this->now,$parse_mode,$user,(int)$noteId));
} else {
$query = "insert into `tiki_user_notes`(`user`,`noteId`,`name`,`data`,`created`,`lastModif`,`size`,`parse_mode`) values(?,?,?,?,?,?,?,?)";
$this->query($query,array($user,(int)$noteId,$name,$data,(int)$this->now,(int)$this->now,(int)$size,$parse_mode));
$noteId = $this->getOne( "select max(`noteId`) from `tiki_user_notes` where `user`=? and `name`=? and `created`=?",array($user,$name,(int)$this->now));
}
return $noteId;
}
function list_watches($offset, $maxRecords, $sort_mode, $find) {
if ($find) {
$mid = ' where `event` like ? or `email` like ?';
$bindvars = array('%'.$find.'%', '%'.$find.'%');
}
$query = 'select * from `tiki_user_watches`'.$mid.' order by '.$this->convert_sortmode($sort_mode);
$query_cant = 'select count(*) from `tiki_user_watches`'.$mid;
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/*shared*/
function add_user_watch($user, $event, $object, $type, $title, $url, $email='') {
if (empty($email)) {
global $userlib;
$email = $userlib->get_user_email($user);
}
$query = "delete from `tiki_user_watches` where ".$this->convert_binary()." `user`=? and `event`=? and `object`=?";
$this->query($query,array($user,$event,$object));
$query = "insert into `tiki_user_watches`(`user`,`event`,`object`,`email`,`type`,`title`,`url`) ";
$query.= "values(?,?,?,?,?,?,?)";
$this->query($query,array($user,$event,$object,$email,$type,$title,$url));
return true;
}
/*shared*/
function remove_user_watch_by_id($id) {
$query = "delete from `tiki_user_watches` where `watchId`=?";
$this->query($query,array($id));
}
/*shared*/
function remove_user_watch($user, $event, $object) {
$query = "delete from `tiki_user_watches` where ".$this->convert_binary()." `user`=? and `event`=? and `object`=?";
$this->query($query,array($user,$event,$object));
}
/*shared*/
function get_user_watches($user, $event = '') {
$mid = '';
$bindvars=array($user);
if ($event) {
$mid = " and `event`=? ";
$bindvars[]=$event;
}
$query = "select * from `tiki_user_watches` where ".$this->convert_binary()." `user`=? $mid";
$result = $this->query($query,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res;
}
return $ret;
}
/*shared*/
function get_watches_events() {
$query = "select distinct `event` from `tiki_user_watches`";
$result = $this->query($query,array());
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res['event'];
}
return $ret;
}
/*shared*/
function user_watches($user, $event, $object, $type) {
if (is_array($event)) {
$query = "select `event` from `tiki_user_watches` where `user`=? and `object`=? and `type`=? and `event` in (".implode(',',array_fill(0, count($event),'?')).")";
$result = $this->query($query, array_merge(array($user,$object,$type),$event));
if (!$result->numRows()) {
return false;
}
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res['event'];
}
return $ret;
} else {
$query = "select count(*) from `tiki_user_watches` where `user`=? and `object`=? and `type`=? and `event`=? ";
return $this->getOne($query,array($user,$object,$type,$event));
}
}
/*shared*/
function get_user_event_watches($user, $event, $object) {
$query = "select * from `tiki_user_watches` where `user`=? and `event`=? and `object`=?";
$result = $this->query($query,array($user,$event,$object));
if (!$result->numRows())
return false;
$res = $result->fetchRow();
return $res;
}
/*shared*/
function get_event_watches($event, $object, $info=null) {
global $prefs, $dbTiki;
$ret = array();
$where = array();
$mid = '';
if( $prefs['feature_user_watches_translations'] == 'y' && $event == 'wiki_page_changed') {
// If $prefs['feature_user_watches_translations'] is turned on, also look for
// pages in a translation group.
$mid = "`event`=?";
$bindvars[] = $event;
global $multilinguallib;
include_once("lib/multilingual/multilinguallib.php");
$page_info = $this->get_page_info( $object );
$pages = $multilinguallib->getTranslations('wiki page', $page_info['page_id'], $object, '' );
foreach ($pages as $page) {
$mids[] = "`object`=?";
$bindvars[] = $page['objName'];
}
$mid .= 'and ('.implode(' or ', $mids).')';
} else if ( $prefs['feature_user_watches_translations'] == 'y'
&& $event == 'wiki_page_created' ) {
$page_info = $this->get_page_info( $object );
$mid = "`event`='wiki_page_in_lang_created' and `object`=? and `type`='lang'";
$bindvars[] = $page_info['lang'];
} else if ($event == 'forum_post_topic') {
$mid = "(`event`=? or `event`=?) and `object`=?";
$bindvars[] = $event;
$bindvars[] = 'forum_post_topic_and_thread';
$bindvars[] = $object;
} else if ($event == 'forum_post_thread') {
$mid = "(`event`=? and `object`=?) or ( `event`=? and `object`=?)";
$bindvars[] = $event;
$bindvars[] = $object;
$bindvars[] = 'forum_post_topic_and_thread';
$forumId = $info['forumId'];
$bindvars[] = $forumId;
} else {
$mid = "`event`=? and `object`=?";
$bindvars[] = $event;
$bindvars[] = $object;
}
$query = "select tuw.*, tup1.`value` as language, tup2.`value` as mailCharset from `tiki_user_watches` tuw
left join `tiki_user_preferences` tup1 on (tup1.`user`=tuw.`user` and tup1.`prefName`='language')
left join `tiki_user_preferences` tup2 on (tup2.`user`=tuw.`user` and tup2.`prefName`='mailCharset')
where $mid";
$result = $this->query($query,$bindvars);
if ($result->numRows()) {
while ($res = $result->fetchRow()) {
switch($event) {
case 'wiki_page_changed':
case 'wiki_page_created':
$res['perm']=($this->user_has_perm_on_object($res['user'],$object,'wiki page','tiki_p_view') ||
$this->user_has_perm_on_object($res['user'],$object,'wiki page','tiki_p_admin_wiki'));
break;
case 'tracker_modified':
$res['perm'] = $this->user_has_perm_on_object($res['user'],$object,'tracker','tiki_p_view_trackers');
break;
case 'tracker_item_modified':
$res['perm'] = $this->user_has_perm_on_object($res['user'],$info['trackerId'],'tracker','tiki_p_view_trackers');
break;
case 'blog_post':
$res['perm']=($this->user_has_perm_on_object($res['user'],$object,'blog','tiki_p_read_blog') ||
$this->user_has_perm_on_object($res['user'],$object,'blog','tiki_p_admin_blog'));
break;
case 'map_changed':
$res['perm']=$this->user_has_perm_on_object($res['user'],$object,'map','tiki_p_map_view');
break;
case 'forum_post_topic':
$res['perm']=($this->user_has_perm_on_object($res['user'],$object,'forum','tiki_p_forum_read') ||
$this->user_has_perm_on_object($res['user'],$object,'forum','tiki_p_admin_forum'));
break;
case 'forum_post_thread':
$res['perm']=($this->user_has_perm_on_object($res['user'],$forumId,'forum','tiki_p_forum_read') ||
$this->user_has_perm_on_object($res['user'],$object,'forum','tiki_p_admin_forum'));
break;
case 'file_gallery_changed':
$res['perm']=($this->user_has_perm_on_object($res['user'],$object,'file gallery','tiki_p_view_file_gallery') ||
$this->user_has_perm_on_object($res['user'],$object,'file gallery','tiki_p_download_files'));
break;
case 'article_submitted':
case 'topic_article_created':
global $userlib, $topicId;
$res['perm']= ($userlib->user_has_permission($res['user'],'tiki_p_read_article') &&
(empty($topicId) || $this->user_has_perm_on_object($res['user'],$topicId,'topic','tiki_p_topic_read')));
break;
case 'calendar_changed':
$res['perm']= $this->user_has_perm_on_object($res['user'],$object,'calendar','tiki_p_view_calendar');
break;
case 'image_gallery_changed':
$res['perm'] = $this->user_has_perm_on_object($res['user'],$object,'image gallery','tiki_p_view_image_gallery');
break;
case 'category_changed':
global $categlib;
$res['perm']= $categlib->has_view_permission($res['user'],$object);
break;
default:
// for security we deny all others.
$res['perm']=FALSE;
break;
}
if($res['perm']) {
$ret[] = $res;
}
}
}
// Also include users that are watching a category to which this object belongs to.
if ( $event != 'category_changed' ) {
if ($prefs['feature_categories'] == 'y') {
global $categlib; require_once('lib/categories/categlib.php');
$objectType="";
switch($event) {
case 'wiki_page_changed': $objectType="wiki page"; break;
case 'blog_post': $objectType="blog"; break;
case 'map_changed': $objectType="map_changed"; break;
case 'forum_post_topic': $objectType="forum"; break;
case 'forum_post_thread': $objectType="forum"; break;
case 'file_gallery_changed': $objectType="file gallery"; break;
case 'article_submitted': $objectType="topic"; break;
case 'image_gallery_changed': $objectType="image gallery"; break;
case 'tracker_modified': $objectType="tracker"; break;
case 'tracker_item_modified': $objectType="tracker"; break;
case 'calendar_changed': $objectType="calendar"; break;
}
if ( $objectType != "") {
// If a forum post was changed, check the categories of the forum.
if ( $event == "forum_post_thread" ) {
include_once ("lib/commentslib.php");
global $commentslib;
$object = $commentslib->get_comment_forum_id($object);
}
// If a tracker item was changed, check the categories of the tracker.
if ( $event == "tracker_item_modified" ) {
include_once ("lib/trackers/trackerlib.php");
global $trklib;
$object = $trklib->get_tracker_for_item($object);
}
$categs = $categlib->get_object_categories($objectType, $object);
foreach ($categs as $category) {
$watching_users = $this->get_event_watches('category_changed', $category);
// Add all users that are not already included
foreach ($watching_users as $wu) {
$included = false;
foreach ($ret as $item) {
if ($item['user'] == $wu['user']) {
$included = true;
}
}
if (!$included) {
$ret[] = $wu;
}
}
}
}
}
}
return $ret;
}
/*shared*/
function dir_stats() {
$aux = array();
$aux["valid"] = $this->db->getOne("select count(*) from `tiki_directory_sites` where `isValid`=?",array('y'));
$aux["invalid"] = $this->db->getOne("select count(*) from `tiki_directory_sites` where `isValid`=?",array('n'));
$aux["categs"] = $this->db->getOne("select count(*) from `tiki_directory_categories`",array());
$aux["searches"] = $this->db->getOne("select sum(`hits`) from `tiki_directory_search`",array());
$aux["visits"] = $this->db->getOne("select sum(`hits`) from `tiki_directory_sites`",array());
return $aux;
}
/*shared*/
function dir_list_all_valid_sites2($offset, $maxRecords, $sort_mode, $find) {
if ($find) {
$mid = " where `isValid`=? and (`name` like ? or `description` like ?)";
$bindvars=array('y','%'.$find.'%','%'.$find.'%');
} else {
$mid = " where `isValid`=? ";
$bindvars=array('y');
}
$query = "select * from `tiki_directory_sites` $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_directory_sites` $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/*shared*/
function get_directory($categId) {
$query = "select * from `tiki_directory_categories` where `categId`=?";
$result = $this->query($query,array($categId));
if (!$result->numRows()) return false;
$res = $result->fetchRow();
return $res;
}
/*shared*/
function user_unread_messages($user) {
$cant = $this->getOne("select count(*) from `messu_messages` where `user`=? and `isRead`=?",array($user,'n'));
return $cant;
}
/*shared*/
function get_online_users() {
if(!isset($this->online_users_cache)) {
$this->online_users_cache=array();
$query = "select s.`user`, p.`value` as 'realName', `timestamp`, `tikihost` from `tiki_sessions` s left join `tiki_user_preferences` p on s.`user`<>? and s.`user` = p.`user` and p.`prefName` = 'realName' where s.`user` is not null;";
$result = $this->query($query,array(''));
$ret = array();
while ($res = $result->fetchRow()) {
$res['user_information'] = $this->get_user_preference($res['user'], 'user_information', 'public');
$res['allowMsgs'] = $this->get_user_preference($res['user'], 'allowMsgs', 'y');
$this->online_users_cache[$res['user']] = $res;
}
}
return $this->online_users_cache;
}
/*shared*/
function is_user_online($whichuser) {
if(!isset($this->online_users_cache)) {
$this->get_online_users();
}
return(isset($this->online_users_cache[$whichuser]));
}
/*shared*/
function get_user_items($user) {
$items = array();
$query = "select ttf.`trackerId`, tti.`itemId` from `tiki_tracker_fields` ttf, `tiki_tracker_items` tti, `tiki_tracker_item_fields` ttif";
$query .= " where ttf.`fieldId`=ttif.`fieldId` and ttif.`itemId`=tti.`itemId` and `type`=? and tti.`status`=? and `value`=?";
$result = $this->query($query,array('u','o',$user));
$ret = array();
while ($res = $result->fetchRow()) {
$itemId = $res["itemId"];
$trackerId = $res["trackerId"];
// Now get the isMain field for this tracker
$fieldId = $this->getOne("select `fieldId` from `tiki_tracker_fields` ttf where `isMain`=? and `trackerId`=?",array('y',(int)$trackerId));
// Now get the field value
$value = $this->getOne("select `value` from `tiki_tracker_item_fields` where `fieldId`=? and `itemId`=?",array((int)$fieldId,(int)$itemId));
$tracker = $this->getOne("select `name` from `tiki_trackers` where `trackerId`=?",array((int)$trackerId));
$aux["trackerId"] = $trackerId;
$aux["itemId"] = $itemId;
$aux["value"] = $value;
$aux["name"] = $tracker;
if (!in_array($itemId, $items)) {
$ret[] = $aux;
$items[] = $itemId;
}
}
$groups = $this->get_user_groups($user);
foreach ($groups as $group) {
$query = "select ttf.`trackerId`, tti.`itemId` from `tiki_tracker_fields` ttf, `tiki_tracker_items` tti, `tiki_tracker_item_fields` ttif ";
$query .= " where ttf.`fieldId`=ttif.`fieldId` and ttif.`itemId`=tti.`itemId` and `type`=? and tti.`status`=? and `value`=?";
$result = $this->query($query,array('g','o',$group));
while ($res = $result->fetchRow()) {
$itemId = $res["itemId"];
$trackerId = $res["trackerId"];
// Now get the isMain field for this tracker
$fieldId = $this->getOne("select `fieldId` from `tiki_tracker_fields` ttf where `isMain`=? and `trackerId`=?",array('y',(int)$trackerId));
// Now get the field value
$value = $this->getOne("select `value` from `tiki_tracker_item_fields` where `fieldId`=? and `itemId`=?",array((int)$fieldId,(int)$itemId));
$tracker = $this->getOne("select `name` from `tiki_trackers` where `trackerId`=?",array((int)$trackerId));
$aux["trackerId"] = $trackerId;
$aux["itemId"] = $itemId;
$aux["value"] = $value;
$aux["name"] = $tracker;
if (!in_array($itemId, $items)) {
$ret[] = $aux;
$items[] = $itemId;
}
}
}
return $ret;
}
/*shared*/
function get_actual_content($fieldvalue) {
$query = 'SELECT `data` FROM `tiki_programmed_content` WHERE `contentId`=? AND `publishDate`<=? ORDER BY `publishDate` DESC';
$data = $this->getOne($query, array((int)$fieldvalue, $this->now));
return $data;
}
function get_actual_content_by_label($fieldvalue) {
$query = 'SELECT tpc.`data`'
.' FROM `tiki_programmed_content` AS tpc, `tiki_content` AS tc'
.' WHERE tpc.`contentId` = tc.`contentId` AND tc.`contentLabel`=? AND `publishDate`<=? ORDER BY `publishDate` DESC';
$data = $this->getOne($query, array((int)$fieldvalue, $this->now));
return $data;
}
/*shared*/
function get_quiz($quizId) {
$query = "select * from `tiki_quizzes` where `quizId`=?";
$result = $this->query($query,array((int) $quizId));
if (!$result->numRows())
return false;
$res = $result->fetchRow();
return $res;
}
function compute_quiz_stats() {
$query = "select `quizId` from `tiki_user_quizzes`";
$result = $this->query($query,array());
while ($res = $result->fetchRow()) {
$quizId = $res["quizId"];
$quizName = $this->getOne("select `name` from `tiki_quizzes` where `quizId`=?",array((int)$quizId));
$timesTaken = $this->getOne("select count(*) from `tiki_user_quizzes` where `quizId`=?",array((int)$quizId));
$avgpoints = $this->getOne("select avg(`points`) from `tiki_user_quizzes` where `quizId`=?",array((int)$quizId));
$maxPoints = $this->getOne("select max(`maxPoints`) from `tiki_user_quizzes` where `quizId`=?",array((int)$quizId));
$avgavg = ($maxPoints != 0) ? $avgpoints / $maxPoints * 100 : 0.0;
$avgtime = $this->getOne("select avg(`timeTaken`) from `tiki_user_quizzes` where `quizId`=?",array((int)$quizId));
$querydel = "delete from `tiki_quiz_stats_sum` where `quizId`=?";
$resultdel = $this->query($querydel,array((int)$quizId),-1,-1,false);
$query2 = "insert into `tiki_quiz_stats_sum`(`quizId`,`quizName`,`timesTaken`,`avgpoints`,`avgtime`,`avgavg`)
values(?,?,?,?,?,?)";
$result2 = $this->query($query2,array((int)$quizId,$quizName,(int)$timesTaken,(float)$avgpoints,$avgtime,$avgavg));
}
}
/*shared*/
function list_quizzes($offset, $maxRecords, $sort_mode, $find) {
$bindvars = array();
$mid = "";
if ($find) {
$findesc = '%' . $find . '%';
$mid = " where (`name` like ? or `description` like ?)";
$bindvars = array($findesc,$findesc);
}
$query = "select * from `tiki_quizzes` $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_quizzes` $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
global $user;
$add=$this->user_has_perm_on_object($user,$res['quizId'],'quiz',array('tiki_p_take_quiz'));
if ($add) {
$res["questions"] = $this->getOne("select count(*) from `tiki_quiz_questions` where `quizId`=?",array((int) $res["quizId"]));
$res["results"] = $this->getOne("select count(*) from `tiki_quiz_results` where `quizId`=?",array((int) $res["quizId"]));
$ret[] = $res;
}
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/*shared*/
function list_quiz_sum_stats($offset, $maxRecords, $sort_mode, $find) {
$this->compute_quiz_stats();
if ($find) {
$findesc = '%' . $find . '%';
$mid = " `quizName` like ? ";
$bindvars=array($findesc);
} else {
$mid = " ";
$bindvars=array();
}
$query = "select * from `tiki_quiz_stats_sum` $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_quiz_stats_sum` $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
function get_tracker($trackerId) {
$query = "select * from `tiki_trackers` where `trackerId`=?";
$result = $this->query($query,array((int) $trackerId));
if (!$result->numRows()) return false;
$res = $result->fetchRow();
return $res;
}
/*shared*/
function list_trackers($offset=0, $maxRecords=-1, $sort_mode='name_asc', $find='') {
if ($find) {
$findesc = '%' . $find . '%';
$mid = " where (`name` like ? or `description` like ?)";
$bindvars=array($findesc,$findesc);
} else {
$mid = "";
$bindvars=array();
}
$query = "select * from `tiki_trackers` $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_trackers` $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
$list = array();
while ($res = $result->fetchRow()) {
global $user;
$add=$this->user_has_perm_on_object($user,$res['trackerId'],'tracker','tiki_p_view_trackers');
if ($add) {
$qu = "select count(*) from`tiki_tracker_items` where `trackerId`=? ";
$res['items'] = $this->getOne($qu,array((int)$res['trackerId']));
$ret[] = $res;
$list[$res['trackerId']] = $res['name'];
}
}
$retval = array();
$retval["list"] = $list;
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/*shared*/
function list_surveys($offset, $maxRecords, $sort_mode, $find) {
if ($find) {
$findesc = '%' . $find . '%';
$mid = " where (`name` like ? or `description` like ?)";
$bindvars=array($findesc,$findesc);
} else {
$mid = " ";
$bindvars=array();
}
$query = "select * from `tiki_surveys` $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_surveys` $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
global $user;
$add=$this->user_has_perm_on_object($user,$res['surveyId'],'survey',array('tiki_p_take_survey','tiki_p_view_survey_stats'));
if ($add) {
$res["questions"] = $this->getOne("select count(*) from `tiki_survey_questions` where `surveyId`=?",array((int) $res["surveyId"]));
$ret[] = $res;
}
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/* experimental shared */
function get_item_id($trackerId,$fieldId,$value) {
$query = "select ttif.`itemId` from `tiki_tracker_items` tti, `tiki_tracker_fields` ttf, `tiki_tracker_item_fields` ttif ";
$query.= " where tti.`trackerId`=ttf.`trackerId` and ttif.`fieldId`=ttf.`fieldId` and ttf.`trackerId`=? and ttf.`fieldId`=? and ttif.`value`=?";
$itemId = $this->getOne($query,array((int) $trackerId,(int)$fieldId,$value));
return $itemId;
}
/*shared*/
function list_tracker_items($trackerId, $offset, $maxRecords, $sort_mode, $fields, $status = '', $initial = '') {
$filters = array();
if ($fields) {
$temp_max = count($fields["data"]);
for ($i = 0; $i < $temp_max; $i++) {
$fieldId = $fields["data"][$i]["fieldId"];
$filters[$fieldId] = $fields["data"][$i];
}
}
$csort_mode = '';
if (substr($sort_mode,0,2) == "f_") {
list($a,$csort_mode,$corder) = split('_',$sort_mode);
}
$trackerId = (int) $trackerId;
if ($trackerId == -1) {
$mid = " where 1=1 ";
$bindvars = array();
} else {
$mid = " where tti.`trackerId`=? ";
$bindvars = array($trackerId);
}
if ($status) {
$mid.= " and tti.`status`=? ";
$bindvars[] = $status;
}
if ($initial) {
$mid.= "and ttif.`value` like ?";
$bindvars[] = $initial.'%';
}
if (!$sort_mode) {
$temp_max = count($fields["data"]);
for ($i = 0; $i < $temp_max; $i++) {
if ($fields['data'][$i]['isMain'] == 'y') {
$csort_mode = $fields['data'][$i]['name'];
break;
}
}
}
if ($csort_mode) {
$sort_mode = $csort_mode."_desc";
$bindvars[] = $csort_mode;
$query = "select tti.*, ttif.`value` from `tiki_tracker_items` tti, `tiki_tracker_item_fields` ttif, `tiki_tracker_fields` ttf ";
$query.= " $mid and tti.`itemId`=ttif.`itemId` and ttf.`fieldId`=ttif.`fieldId` and ttf.`name`=? order by ttif.`value`";
$query_cant = "select count(*) from `tiki_tracker_items` tti, `tiki_tracker_item_fields` ttif, `tiki_tracker_fields` ttf ";
$query_cant.= " $mid and tti.`itemId`=ttif.`itemId` and ttf.`fieldId`=ttif.`fieldId` and ttf.`name`=? ";
} else {
if (!$sort_mode) {
$sort_mode = "lastModif_desc";
}
$query = "select * from `tiki_tracker_items` tti $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_tracker_items` tti $mid ";
}
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$fields = array();
$itid = $res["itemId"];
$query2 = "select ttif.`fieldId`,`name`,`value`,`type`,`isTblVisible`,`isMain`,`position`
from `tiki_tracker_item_fields` ttif, `tiki_tracker_fields` ttf
where ttif.`fieldId`=ttf.`fieldId` and `itemId`=? order by `position` asc";
$result2 = $this->query($query2,array((int) $res["itemId"]));
$pass = true;
$kx = "";
while ($res2 = $result2->fetchRow()) {
// Check if the field is visible!
$fieldId = $res2["fieldId"];
if (count($filters) > 0) {
if (isset($filters["$fieldId"]["value"]) and $filters["$fieldId"]["value"]) {
if ($filters["$fieldId"]["type"] == 'a' || $filters["$fieldId"]["type"] == 't') {
if (!stristr($res2["value"], $filters["$fieldId"]["value"]))
$pass = false;
} else {
if (strtolower($res2["value"]) != strtolower($filters["$fieldId"]["value"])) {
$pass = false;
}
}
}
if (ereg_replace("[^a-zA-Z0-9]","",$res2["name"]) == $csort_mode) {
$kx = $res2["value"].$itid;
}
}
$fields[] = $res2;
}
$res["field_values"] = $fields;
$res["comments"] = $this->getOne("select count(*) from `tiki_tracker_item_comments` where `itemId`=?",array((int) $itid));
if ($pass) {
$kl = $kx.$itid;
$ret["$kl"] = $res;
}
}
ksort($ret);
//$ret=$this->sort_items_by_condition($ret,$sort_mode);
$retval = array();
$retval["data"] = array_values($ret);
$retval["cant"] = $cant;
return $retval;
}
/*
* Score methods begin
*/
// All information about an event type
// shared
function get_event($event) {
$query = "select * from `tiki_score` where `event`=?";
$result = $this->query($query,array($event));
return $result->fetchRow();
}
/*
* Checks if an event should be scored and grants points to proper user
* $multiplier is for rating events, in which the score will
* be multiplied by other user's rating. Not yet used
*
* shared
*/
function score_event($user, $event_type, $id = '', $multiplier=false) {
global $scorelib,$prefs;
if (!is_object($scorelib)) {
include_once("lib/score/scorelib.php");
}
if ($user == 'admin' || !$user) { return true; }
$event = $scorelib->get_event($event_type);
if (!$event || !$event['score']) {
return true;
}
$score = $event['score'];
if ($multiplier) {
$score *= $multiplier;
}
if ($id || $event['expiration']) {
$expire = $event['expiration'];
$event_id = $event_type . '_' . $id;
$query = "select count(*) from `tiki_users_score` where `user`=? and `event_id`=?";
$bindvars = array($user, $event_id);
if ($expire) {
$query .= " and `expire` > ?";
$bindvars[] = time();
}
if ($this->getOne($query, $bindvars)) {
return true;
}
$query = "delete from `tiki_users_score` where `user`=? and `event_id`=?";
$this->query($query, array($user, $event_id));
$query = "insert into `tiki_users_score` (`user`, `event_id`, `expire`) values (?, ?, ?)";
$this->query($query, array($user, $event_id, time() + ($expire*60)));
}
// Perform check to make sure score does not go below 0 with negative scores
if( $prefs['fgal_prevent_negative_score'] == 'y' && strpos( $event_type, 'fgallery' ) === 0 ) {
$result = $this->query( "select userId from users_users where score + ? >= 0 and login = ?",
array( $score, $user ) );
if( ! $row = $result->fetchRow( $result ) )
return false;
}
$query = "update `users_users` set `score` = `score` + ? where `login`=?";
$event['id'] = $id; // just for debug
$this->query($query, array($score, $user));
return true;
}
// List users by best scoring
// shared
function rank_users($limit = 10, $start = 0) {
if (!$start) {
$start = "0";
}
// admin doesn't go on ranking
$query = "select `userId`, `login`, `score` from `users_users` where `login` <> 'admin' order by `score` desc";
$result = $this->query($query,array(),$limit,$start);
$ranking = array();
while ($res = $result->fetchRow()) {
$res['position'] = ++$start;
$ranking[] = $res;
}
return $ranking;
}
// Returns html tag to star corresponding to user's score
// shared
function get_star($score) {
$star = '';
$star_colors = array(0 => 'grey',
100 => 'blue',
500 => 'green',
1000 => 'yellow',
2500 => 'orange',
5000 => 'red',
10000 => 'purple');
foreach ($star_colors as $boundary => $color) {
if ($score >= $boundary) {
$star = 'star_'.$color.'.gif';
}
}
if (!empty($star)) {
$alt = sprintf(tra("%d points"), $score);
$star = " ";
}
return $star;
}
/*
* Score methods end
*/
//shared
// \todo remove all hardcoded html in get_user_avatar()
function get_user_avatar($user, $float = "") {
global $userlib;
if (empty($user))
return '';
$query = "select `login`,`avatarType`,`avatarLibName` from `users_users` where `login`=?";
$result = $this->query($query,array($user));
$res = $result->fetchRow();
if (!$res) {
return '';
}
$type = $res["avatarType"];
$libname = $res["avatarLibName"];
$ret = '';
$style = '';
if (strcasecmp($float, "left") == 0) {
$style = "style='float:left;margin-right:5px;'";
} else if (strcasecmp($float, "right") == 0) {
$style = "style='float:right;margin-left:5px;'";
}
switch ($type) {
case 'n':
$ret = '';
break;
case 'l':
$ret = "";
break;
case 'u':
$ret = "";
break;
}
return $ret;
}
/*shared*/
function get_forum_sections() {
$query = "select distinct `section` from `tiki_forums` where `section`<>?";
$result = $this->query($query,array(''));
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res["section"];
}
return $ret;
}
/* Referer stats */
/*shared*/
function register_referer($referer) {
$cant = $this->getOne("select count(*) from `tiki_referer_stats` where `referer`=?",array($referer));
if ($cant) {
$query = "update `tiki_referer_stats` set `hits`=`hits`+1,`last`=? where `referer`=?";
} else {
$query = "insert into `tiki_referer_stats`(`last`,`referer`,`hits`) values(?,?,1)";
}
$result = $this->query($query,array((int)$this->now,$referer));
}
// File attachments functions for the wiki ////
/*shared*/
function add_wiki_attachment_hit($id) {
global $prefs, $user;
if ($prefs['count_admin_pvs'] == 'y' || $user != 'admin') {
$query = "update `tiki_wiki_attachments` set `hits`=`hits`+1 where `attId`=?";
$result = $this->query($query,array((int)$id));
}
return true;
}
/*shared*/
function get_wiki_attachment($attId) {
$query = "select * from `tiki_wiki_attachments` where `attId`=?";
$result = $this->query($query,array((int)$attId));
if (!$result->numRows()) return false;
$res = $result->fetchRow();
return $res;
}
/*shared*/
function get_random_image($galleryId = -1) {
$whgal = "";
$bindvars = array();
if (((int)$galleryId) != -1) {
$whgal = " where `galleryId`=? ";
$bindvars[] = (int) $galleryId;
}
$query = "select count(*) from `tiki_images` $whgal";
$cant = $this->getOne($query,$bindvars);
$ret = array();
if ($cant) {
$pick = rand(0, $cant - 1);
$query = "select `imageId` ,`galleryId`,`name` from `tiki_images` $whgal";
$result = $this->query($query,$bindvars,1,$pick);
$res = $result->fetchRow();
$ret["galleryId"] = $res["galleryId"];
$ret["imageId"] = $res["imageId"];
$ret["name"] = $res["name"];
$query = "select `name` from `tiki_galleries` where `galleryId` = ?";
$ret["gallery"] = $this->getOne($query,array((int)$res["galleryId"]));
} else {
$ret["galleryId"] = 0;
$ret["imageId"] = 0;
$ret["name"] = tra("No image yet, sorry.");
}
return ($ret);
}
/*shared*/
function get_gallery($id) {
$query = "select * from `tiki_galleries` where `galleryId`=?";
$result = $this->query($query,array((int) $id));
$res = $result->fetchRow();
return $res;
}
// Last visit module ////
/*shared*/
function get_news_from_last_visit($user) {
if (!$user) return false;
$last = $this->getOne("select `lastLogin` from `users_users` where `login`=?",array($user));
$ret = array();
if (!$last) {
$last = time();
}
$ret["lastVisit"] = $last;
$ret["images"] = $this->getOne("select count(*) from `tiki_images` where `created`>?",array((int)$last));
$ret["pages"] = $this->getOne("select count(*) from `tiki_pages` where `lastModif`>?",array((int)$last));
$ret["files"] = $this->getOne("select count(*) from `tiki_files` where `created`>?",array((int)$last));
$ret["comments"] = $this->getOne("select count(*) from `tiki_comments` where `commentDate`>?",array((int)$last));
$ret["users"] = $this->getOne("select count(*) from `users_users` where `registrationDate`>?",array((int)$last));
$ret["trackers"] = $this->getOne("select count(*) from `tiki_tracker_items` where `lastModif`>?",array((int)$last));
$ret["calendar"] = $this->getOne("select count(*) from `tiki_calendar_items` where `lastmodif`>?",array((int)$last));
return $ret;
}
// Templates ////
/*shared*/
function list_templates($section, $offset, $maxRecords, $sort_mode, $find) {
$bindvars = array($section);
if ($find) {
$findesc = '%'.$find.'%';
$mid = " and (`content` like ?)";
$bindvars[] = $findesc;
} else {
$mid = "";
}
$query = "select `name` ,`created`,tcts.`templateId` from `tiki_content_templates` tct, `tiki_content_templates_sections` tcts ";
$query.= " where tcts.`templateId`=tct.`templateId` and `section`=? $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_content_templates` tct, `tiki_content_templates_sections` tcts ";
$query_cant.= "where tcts.`templateId`=tct.`templateId` and `section`=? $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$query2 = "select `section` from `tiki_content_templates_sections` where `templateId`=?";
$result2 = $this->query($query2,array((int)$res["templateId"]));
$sections = array();
while ($res2 = $result2->fetchRow()) {
$sections[] = $res2["section"];
}
$res["sections"] = $sections;
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/*shared*/
function get_template($templateId) {
$query = "select * from `tiki_content_templates` where `templateId`=?";
$result = $this->query($query,array((int)$templateId));
if (!$result->numRows()) return false;
$res = $result->fetchRow();
return $res;
}
// templates ////
/*shared*/
function list_games($offset, $maxRecords, $sort_mode, $find) {
$bindvars = array();
if ($find) {
$findesc = '%'.$find.'%';
$mid = " where (`gameName` like ?)";
$bindvars[] = $findesc;
} else {
$mid = "";
}
$query = "select * from `tiki_games` $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_games` $mid";
$result = $this->query($query,$bindvars,$maxRecords,$offset);
$cant = $this->getOne($query_cant,$bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$parts = explode('.', $res["gameName"]);
$res["thumbName"] = $parts[0];
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/*shared*/
function pick_cookie() {
$cant = $this->getOne("select count(*) from `tiki_cookies`",array());
if (!$cant) return '';
$bid = rand(0, $cant - 1);
//$cookie = $this->getOne("select `cookie` from `tiki_cookies` limit $bid,1"); getOne seems not to work with limit
$result = $this->query("select `cookie` from `tiki_cookies`",array(),1,$bid);
if ($res = $result->fetchRow()) {
$cookie = str_replace("\n", "", $res['cookie']);
return preg_replace('/^(.+?)(\s*--.+)?$/','"$1"$2',$cookie);
}
else
return "";
}
function get_pv_chart_data($days) {
$now = $this->make_time(0, 0, 0, $this->date_format("%m"), $this->date_format("%d"), $this->date_format("%Y"));
$dfrom = 0;
if ($days != 0) $dfrom = $now - ($days * 24 * 60 * 60);
$query = "select `day`, `pageviews` from `tiki_pageviews` where `day`<=? and `day`>=?";
$result = $this->query($query,array((int)$now,(int)$dfrom));
$ret = array();
$n = ceil($result->numRows() / 10);
$i = 0;
$xdata=array();
$ydata=array();
while ($res = $result->fetchRow()) {
if ($i % $n == 0) {
$xdata[] = $this->date_format("%e %b", $res["day"]);
} else {
$xdata = '';
}
$ydata[] = $res["pageviews"];
}
$ret['xdata']=$xdata;
$ret['ydata']=$ydata;
return $ret;
}
function add_pageview() {
$dayzero = $this->make_time(0, 0, 0, $this->date_format("%m",$this->now), $this->date_format("%d",$this->now), $this->date_format("%Y",$this->now));
$cant = $this->getOne("select count(*) from `tiki_pageviews` where `day`=?",array((int)$dayzero));
if ($cant) {
$query = "update `tiki_pageviews` set `pageviews`=`pageviews`+1 where `day`=?";
} else {
$query = "insert into `tiki_pageviews`(`day`,`pageviews`) values(?,1)";
}
$result = $this->query($query,array((int)$dayzero),-1,-1,false);
}
function get_usage_chart_data() {
$this->compute_quiz_stats();
$data['xdata'][] = tra('wiki');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_pages`',array());
$data['xdata'][] = tra('img-g');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_galleries`',array());
$data['xdata'][] = tra('file-g');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_file_galleries`',array());
$data['xdata'][] = tra('faqs');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_faqs`',array());
$data['xdata'][] = tra('quizzes');
$data['ydata'][] = $this->getOne('select sum(`timesTaken`) from `tiki_quiz_stats_sum`',array());
$data['xdata'][] = tra('arts');
$data['ydata'][] = $this->getOne('select sum(`nbreads`) from `tiki_articles`',array());
$data['xdata'][] = tra('blogs');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_blogs`',array());
$data['xdata'][] = tra('forums');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_forums`',array());
$data['xdata'][] = tra('games');
$data['ydata'][] = $this->getOne('select sum(`hits`) from `tiki_games`',array());
return $data;
}
// User assigned modules ////
/*shared*/
function get_user_login($id) {
$login = $this->getOne("select `login` from `users_users` where `userId`=?", array((int)$id));
return $login;
}
function get_user_id($u) {
// Anonymous is not in db
if ( $u == '' ) return -1;
// If we ask for the current user id and if we already know it in session
$current = ( $u == $_SESSION['u_info']['login'] );
if ( isset($_SESSION['u_info']['id']) && $current ) return $_SESSION['u_info']['id'];
// In other cases, we look in db
$id = $this->getOne("select `userId` from `users_users` where `login`=?", array($u));
$id = ($id === NULL) ? -1 : $id;
if ( $current ) $_SESSION['u_info']['id'] = $id;
return $id;
}
/*shared*/
function get_groups_all($group) {
$query = "select `groupName` from `tiki_group_inclusion` where `includeGroup`=?";
$result = $this->query($query, array($group));
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res["groupName"];
$ret2 = $this->get_groups_all($res["groupName"]);
$ret = array_merge($ret, $ret2);
}
return array_unique($ret);
}
/*shared*/
function get_included_groups($group) {
$query = "select `includeGroup` from `tiki_group_inclusion` where `groupName`=?";
$result = $this->query($query, array($group));
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res["includeGroup"];
$ret2 = $this->get_included_groups($res["includeGroup"]);
$ret = array_merge($ret, $ret2);
}
return array_unique($ret);
}
/*shared*/
function get_user_groups($user) {
global $prefs;
if (!$user) {
$ret = array();
$ret[] = "Anonymous";
return $ret;
} elseif ($prefs['feature_intertiki'] == 'y' and empty($prefs['feature_intertiki_mymaster']) and strstr($user,'@')) {
$realm = substr($user,strpos($user,'@')+1);
$user = substr($user,0,strpos($user,'@'));
if (isset($prefs['interlist'][$realm])) {
$groups = $prefs['interlist'][$realm]['groups'].',Anonymous';
return split(',',$prefs['interlist'][$realm]['groups']);
}
} elseif (!isset($this->usergroups_cache[$user])) {
$userid = $this->get_user_id($user);
$query = "select `groupName` from `users_usergroups` where `userId`=?";
$result=$this->query($query,array((int) $userid));
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res["groupName"];
$included = $this->get_included_groups($res["groupName"]);
$ret = array_merge($ret, $included);
}
$ret[] = "Registered";
$ret[] = "Anonymous";
$ret = array_unique($ret);
$this->usergroups_cache[$user] = $ret;
return $ret;
} else {
return $this->usergroups_cache[$user];
}
}
function invalidate_usergroups_cache($user) {
unset($this->usergroups_cache[$user]);
}
function get_user_cache_id($user) {
$groups = $this->get_user_groups($user);
sort($groups, SORT_STRING);
$cacheId = implode(":", $groups);
if ($user == 'admin') {
// in this case user get permissions from no group
$cacheId = 'ADMIN:'.$cacheId;
}
return $cacheId;
}
// Functions for FAQs ////
/*shared*/
function list_faqs($offset, $maxRecords, $sort_mode, $find) {
$mid = '';
if ( $find ) {
$findesc = '%' . $find . '%';
$mid = ' where (`title` like ? or `description` like ?)';
$bindvars = array($findesc, $findesc);
} else $bindvars = array();
$query = "select * from `tiki_faqs` $mid order by ".$this->convert_sortmode($sort_mode);
$result = $this->query($query, $bindvars, $maxRecords, $offset);
$ret = array();
while ( $res = $result->fetchRow() ) {
global $user;
$add = $this->user_has_perm_on_object($user, $res['faqId'], 'faq', 'tiki_p_view_faqs');
if ($add) {
$res['suggested'] = $this->getOne('select count(*) from `tiki_suggested_faq_questions` where `faqId`=?', array((int) $res['faqId']));
$res['questions'] = $this->getOne('select count(*) from `tiki_faq_questions` where `faqId`=?', array((int) $res['faqId']));
$ret[] = $res;
}
}
$retval['data'] = $ret;
$retval['cant'] = count($ret);
return $retval;
}
/*shared */
function get_faq($faqId) {
$query = "select * from `tiki_faqs` where `faqId`=?";
$result = $this->query($query,array((int)$faqId));
if (!$result->numRows()) return false;
$res = $result->fetchRow();
return $res;
}
// End Faqs ////
/*shared*/
function genPass() {
$length=8;
$vocales = "aeiouAEIOU";
$consonantes = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ0123456789_";
$r = '';
for ($i = 0; $i < $length; $i++) {
if ($i % 2) {
$r .= $vocales{rand(0, strlen($vocales) - 1)};
} else {
$r .= $consonantes{rand(0, strlen($consonantes) - 1)};
}
}
return $r;
}
// generate a random string (for unsubscription code etc.)
function genRandomString($base="") {
if ($base == "") $base = $this->genPass();
$base .= microtime();
return md5($base);
}
// This function calculates the pageRanks for the tiki_pages
// it can be used to compute the most relevant pages
// according to the number of links they have
// this can be a very interesting ranking for the Wiki
// More about this on version 1.3 when we add the pageRank
// column to tiki_pages
function pageRank($loops = 16) {
$query = "select `pageName` from `tiki_pages`";
$result = $this->query($query,array());
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res["pageName"];
}
// Now calculate the loop
$pages = array();
foreach ($ret as $page) {
$val = 1 / count($ret);
$pages[$page] = $val;
// Fixed query. -rlpowell
$query = "update `tiki_pages` set `pageRank`=? where `pageName`= ?";
$result = $this->query($query, array((int)$val, $page) );
}
for ($i = 0; $i < $loops; $i++) {
foreach ($pages as $pagename => $rank) {
// Get all the pages linking to this one
// Fixed query. -rlpowell
$query = "select `fromPage` from `tiki_links` where `toPage` = ? and `fromPage` not like 'objectlink:%'";
// page rank does not count links from non-page objects TODO: full feature allowing this with options
$result = $this->query($query, array( $pagename ) );
$sum = 0;
while ($res = $result->fetchRow()) {
$linking = $res["fromPage"];
if (isset($pages[$linking])) {
// Fixed query. -rlpowell
$q2 = "select count(*) from `tiki_links` where `fromPage`= ? and `fromPage` not like 'objectlink:%'";
// page rank does not count links from non-page objects TODO: full feature allowing this with options
$cant = $this->getOne($q2, array($linking) );
if ($cant == 0) $cant = 1;
$sum += $pages[$linking] / $cant;
}
}
$val = (1 - 0.85) + 0.85 * $sum;
$pages[$pagename] = $val;
// Fixed query. -rlpowell
$query = "update `tiki_pages` set `pageRank`=? where `pageName`=?";
$result = $this->query($query, array((int)$val, $pagename) );
// Update
}
}
arsort ($pages);
return $pages;
}
// Spellchecking routine
// Parameters:
// what: what to spell check (a text)
// where: where to replace (maybe the same text)
// language: language to use
// element: element where the text is going to be replaced (a textarea or similar)
/*shared*/
// \todo replace the hardcoded html by smarty template
function spellcheckreplace($what, $where, $language, $element) {
global $smarty,$headerlib;
$words = preg_split("/\s/", $what);
foreach ($words as $word) {
if (preg_match("/^[A-Z]?[a-z]+$/", $word) && strlen($word) > 1) {
$result = $this->spellcheckword($word, $language);
if (count($result) > 0) {
// Replace the word with a warning color in the edit_data
// Prepare the replacement
$sugs = $result[$word];
$first = 1;
$repl = '';
$popup_text = '';
if (count($sugs) > 0) {
$asugs = array_keys($sugs);
$temp_max = count($asugs);
for ($i = 0; $i < $temp_max && $i < 5; $i++) {
$sug = $asugs[$i];
// If you want to use the commented out line below, please remove the \ in <\/script>; it was breaking vim highlighting. -rlpowell
// $repl.="";
else
$replacements[] = "\\1\\2@\\3";
$patterns[] = "#([\n ])magnet\:\?([^,< \n\r]+)#i";
$replacements[] = "\\1magnet:?\\2";
$text = preg_replace($patterns, $replacements, $text);
// strip the space we added
$text = substr($text, 1);
return $text;
// } else {
// return $text;
// }
}
//Updates a dynamic variable found in some object
/*Shared*/ function update_dynamic_variable($name,$value) {
$query = "delete from `tiki_dynamic_variables` where `name`=?";
$this->query($query,array($name),-1,-1,false);
$query = "insert into `tiki_dynamic_variables`(`name`,`data`) values(?,?)";
$this->query($query,Array($name,$value));
return true;
}
// split string into a list of
function split_tag( $string, $cleanup = TRUE ) {
$_splts = split('"', $string);
$inside = FALSE;
$parts = array();
$index=0;
foreach ($_splts as $i) {
if ($cleanup) {
$i = str_replace('}', '', $i);
$i = str_replace('{', '', $i);
$i = str_replace('\'', '', $i);
$i = str_replace('"', '', $i);
// IE silently removes null-byte html char \0, so let's remove it anyways
$i = str_replace('\\0', '', $i);
}
if ($inside) { // inside "foo bar" - append
if ($index>0) {
$parts[$index-1] .= $i;
} else { // else: first element (should never happen)
$parts[] = $i;
}
} else { //
$_spl = split(" ", $i);
foreach($_spl as $j) {
$parts[$index++] = $j;
}
}
$inside = ! $inside;
}
return $parts;
}
function split_assoc_array($parts, $assoc) {
//$assoc = array();
foreach($parts as $part) {
$res=array();
$assoc[$part] = '';
preg_match("/(\w+)\s*=\s*(.*)/", $part, $res);
if ($res) {
$assoc[$res[1]] = $res[2];
}
}
return $assoc;
}
/**
* close_blocks - Close out open paragraph, lists, and div's
*
* During parse_data, information is kept on blocks of text (paragraphs, lists, divs)
* that need to be closed out. This function does that, rather than duplicating the
* code inline.
*
* @param $data - Output data
* @param $in_paragraph - TRUE if there is an open paragraph
* @param $listbeg - array of open list terminators
* @param $divdepth - array indicating how many div's are open
* @param $close_paragraph - TRUE if open paragraph should be closed.
* @param $close_lists - TRUE if open lists should be closed.
* @param $close_divs - TRUE if open div's should be closed.
*/
/* private */
function close_blocks(&$data,
&$in_paragraph,
&$listbeg,
&$divdepth,
$close_paragraph,
$close_lists,
$close_divs)
{
$closed = 0; // Set to non-zero if something has been closed out
// Close the paragraph if inside one.
if ($close_paragraph && $in_paragraph) {
$data .= "
";
$in_paragraph = 0;
$closed++;
}
// Close open lists
if ($close_lists) {
while (count($listbeg)) {
$data .= array_shift($listbeg);
$closed++;
}
}
// Close open divs
if ($close_divs) {
$temp_max = count($divdepth);
for ($i = 1; $i <= $temp_max; $i++) {
$data .= '';
$closed++;
}
}
if ($closed) {
$data .= "\n";
}
return $closed;
}
//PARSEDATA
function parse_data($data,$is_html=false,$absolute_links=false,$noparseplugins=false) {
// Don't bother if there's nothing...
if (function_exists('mb_strlen')) {
if( mb_strlen( $data ) < 1 )
{
return;
}
}
global $page_regex, $slidemode, $prefs, $ownurl_father, $tiki_p_admin_drawings, $tiki_p_edit_drawings, $tiki_p_edit_dynvar, $tiki_p_upload_picture, $page, $page_ref_id, $rsslib, $dbTiki, $structlib, $user, $tikidomain, $tikiroot;
global $wikilib; include_once('lib/wiki/wikilib.php');
// if simple_wiki is tru, disable some wiki syntax
// basically, allow wiki plugins, wiki links and almost
// everything between {}
$simple_wiki = false;
if ($prefs['feature_wysiwyg'] == 'y' and $is_html) {
if ($prefs['wysiwyg_wiki_semi_parsed'] == 'y') {
$simple_wiki = true;
} elseif ($prefs['wysiwyg_wiki_parsed'] == 'n') {
return $data;
}
}
/* XSS Sanitization handling */
// Converts <x> ( tag using HTML entities) into the tag . This tag comes from the input sanitizer (XSS filter).
// This is not HTML valid and avoids using in a wiki text,
// but hide '' text inside some words like 'style' that are considered as dangerous by the sanitizer.
$data = str_replace( array( '<x>', '~np~', '~/np~' ), array( '', ' ~np~', '~/np~ ' ), $data );
// Fix false positive in wiki syntax
// It can't be done in the sanitizer, that can't know if the input will be wiki parsed or not
$data = preg_replace('/(\{img [^\}]+li)(nk[^\}]+\})/i', '\\1\\2', $data);
// Replace dynamic content occurrences
if (preg_match_all("/\{content +id=([0-9]+)\}/", $data, $dcs)) {
$temp_max = count($dcs[0]);
for ($i = 0; $i < $temp_max; $i++) {
$repl = $this->get_actual_content($dcs[1][$i]);
$data = str_replace($dcs[0][$i], $repl, $data);
}
}
// Replace Dynamic content with random selection
if (preg_match_all("/\{rcontent +id=([0-9]+)\}/", $data, $dcs)) {
global $dcslib; include_once("dcs/dcslib.php");
$temp_max = count($dcs[0]);
for ($i = 0; $i < $temp_max; $i++) {
$repl = $dcslib->get_random_content($dcs[1][$i]);
$data = str_replace($dcs[0][$i], $repl, $data);
}
}
// Process pre_handlers here
if (is_array($this->pre_handlers)) {
foreach ($this->pre_handlers as $handler) {
$data = $handler($data);
}
}
// Handle pre- and no-parse sections and plugins
$preparsed = array('data'=>array(),'key'=>array());
$noparsed = array('data'=>array(),'key'=>array());
if (!$noparseplugins) {
$this->parse_first($data, $preparsed, $noparsed);
}
// Handle |# anchor links by turning them into ALINK module calls.
preg_match_all("/\(\(([^)]*\|#[^)]*)\)\)/", $data, $anchors);
foreach( array_unique($anchors[1]) as $anchor_line )
{
$parts1 = explode( "|#", $anchor_line );
$anchor_page = "";
$anchor_desc = "";
$anchor = "";
// Break out |desc bits from whatever section they happen to be in
if( strpos( $parts1[0], "|" ) )
{
$parts2 = explode( "|", $parts1[0] );
$anchor_page = $parts2[0];
$anchor_desc = $parts2[1];
$anchor = $parts1[1];
} elseif( strpos( $parts1[1], "|" ) ) {
$parts2 = explode( "|", $parts1[1] );
$anchor_page = $parts1[0];
$anchor = $parts2[0];
$anchor_desc = $parts2[1];
} else {
// No |desc bit
$anchor_page = $parts1[0];
$anchor_desc = $parts1[0];
$anchor = $parts1[1];
}
if ( !$anchor_page && $page ) {
$anchor_page = $page;
if ( !$anchor_desc ) $anchor_desc = $page;
}
$repl = "{ALINK(pagename=>".$anchor_page.",aname=>".$anchor.")}".$anchor_desc."{ALINK}";
$data = str_replace( "((".$anchor_line."))", $repl, $data);
}
if( $prefs['feature_wiki_attachments'] == 'y' )
{
// Handle wiki file links by turning them into ATTACH module calls.
preg_match_all("/(\{file [^\}]+})/", $data, $pages);
foreach (array_unique($pages[1])as $page_parse) {
$parts = $this->split_tag( $page_parse, FALSE );
$filedata = array(); // pre-set preferences
$filedata["name"] = '';
$filedata["desc"] = '';
$filedata["showdesc"] = '';
$filedata["page"] = '';
$filedata["image"] = '';
$filedata = $this->split_assoc_array( $parts, $filedata);
$middle = "";
if( ! $filedata["name"] )
{
continue;
}
$repl = "{ATTACH(file=>".$filedata["name"];
if ($filedata["desc"])
{
$repl .= ",inline=>1";
$middle = $filedata["desc"];
}
if ($filedata["page"])
{
$repl .= ",page=>" . $filedata["page"];
}
if ($filedata["showdesc"])
{
$repl .= ",showdesc=>1";
}
if( $filedata["image"])
{
$repl .= ",image=>1";
}
$repl .= ")}$middle{ATTACH}";
$data = str_replace($page_parse, $repl, $data);
}
}
if (!$noparseplugins) {
$this->parse_first($data, $preparsed, $noparsed);
}
// Handle ~pre~...~/pre~ sections
$data = preg_replace(';~pre~(.*?)~/pre~;s', '
$1
', $data);
// Handle comment sections
$data = preg_replace(';~tc~(.*?)~/tc~;s', '', $data);
$data = preg_replace(';~hc~(.*?)~/hc~;s', '', $data);
// Extract [link] sections (to be re-inserted later)
$noparsedlinks = array();
// This section matches [...].
// Added handling for [[foo] sections. -rlpowell
if (!$simple_wiki) {
preg_match_all("/(?genPass());
$aux["key"] = $key;
$aux["data"] = $np;
$noparsedlinks[] = $aux;
$data = str_replace("$np", $key, $data);
}
}
// Replace special characters
// done after url catching because otherwise urls of dyn. sites will be modified
// not done in wysiwyg mode, i.e. $prefs['feature_wysiwyg'] set to something other than 'no' or not set at all
// if (!$simple_wiki and $prefs['feature_wysiwyg'] == 'n') {
//above line changed by mrisch - special functions were not parsing when wysiwyg is set but wysiswyg is not enabled
// further changed by nkoth - why not parse in wysiwyg mode as well, otherwise it won't parse for display/preview?
if (!$simple_wiki) {
$this->parse_htmlchar($data);
}
// Now replace a TOC
preg_match_all("/\{toc\s?(order=(desc|asc))?\s?(showdesc=(0|1))?\s?(shownum=(0|1))?\s?(type=(plain|fancy))?\s?(structId=([0-9a-z]+))?\s?(maxdepth=(\d+))?\s?\}/i", $data, $tocs);
// Loop over all the case-specific versions of {toc} used
// (if the user is consistent, this is a loop of count 1)
$temp_max = count($tocs[0]);
for ($i = 0; $i < $temp_max; $i++) {
//If there are instances of {toc} on this page
if (count($tocs[0]) > 0) {
$order = 'asc';
$showdesc = false;
$shownum = false;
$type = 'plain';
$structId = '';
$maxdepth = 0;
if ($tocs[2][$i] == 'desc') {
$order = 'desc';
}
if ($tocs[4][$i] == 1) {
$showdesc = true;
}
if ($tocs[6][$i] == 1) {
$shownum = true;
}
if ($tocs[8][$i] == 'fancy') {
$type = 'fancy';
}
if (isset($tocs[10][$i]) and !empty($tocs[10][$i])) {
$structId = $tocs[10][$i];
}
if ($tocs[12][$i] != '') {
$maxdepth = $tocs[12][$i];
}
include_once ("lib/structures/structlib.php");
if ($structId == '') {
//And we are currently viewing a structure
$page_info = $structlib->s_get_page_info($page_ref_id);
$structure_info = $structlib->s_get_structure_info($page_ref_id);
if (isset($page_info)) {
$html = $structlib->get_toc($page_ref_id,$order,$showdesc,$shownum,'',$type,'',$maxdepth, $structure_info['pageName']);
$data = str_replace($tocs[0][$i], $html, $data);
} else {
//Dont display the {toc} string for non structure pages
$data = str_replace($tocs[0][$i], '', $data);
}
} else {
$html = $structlib->fetch_toc($structlib->build_subtree_toc($structId),$showdesc,$shownum,$type,'',$maxdepth, 0, $structure_info['pageName']);
$data = str_replace($tocs[0][$i], $html, $data);
}
}
}
// Now search for images uploaded by users
if ($prefs['feature_wiki_pictures'] == 'y') {
preg_match_all("/\{picture file=([^\}]+)\}/", $data, $pics);
$temp_max = count($pics[0]);
for ($i = 0; $i < $temp_max; $i++) {
// Check if the image exists
$name = $pics[1][$i];
if ($tikidomain && !preg_match('|^https?:|', $name)) {
$name = preg_replace("~img/wiki_up/~","img/wiki_up/$tikidomain/",$name);
}
if (file_exists($name) and (preg_match('/(gif|jpe?g|png)$/i',$name))) {
// Replace by the img tag to show the image
$repl = "";
} else {
$repl = tra('picture not found')." $name";
}
// Replace by $repl
$data = str_replace($pics[0][$i], $repl, $data);
}
}
//$data = strip_tags($data);
// BiDi markers
$bidiCount = 0;
$bidiCount = preg_match_all("/(\{l2r\})/", $data, $pages);
$bidiCount += preg_match_all("/(\{r2l\})/", $data, $pages);
$data = preg_replace("/\{l2r\}/", "
", $data);
$data = preg_replace("/\{r2l\}/", "
", $data);
$data = preg_replace("/\{lm\}/", "", $data);
$data = preg_replace("/\{rm\}/", "", $data);
// smileys
$data = $this->parse_smileys($data);
// Replace links to slideshows
if ($prefs['feature_drawings'] == 'y') {
// Replace drawings
// Replace rss modules
$pars = parse_url($_SERVER["REQUEST_URI"]);
$pars_parts = split('/', $pars["path"]);
$pars = array();
$temp_max = count($pars_parts) - 1;
for ($i = 0; $i < $temp_max; $i++) {
$pars[] = $pars_parts[$i];
}
$pars = join('/', $pars);
if (preg_match_all("/\{draw +name=([A-Za-z_\-0-9]+) *\}/", $data, $draws)) {
//$this->invalidate_cache($page);
$temp_max = count($draws[0]);
for ($i = 0; $i < $temp_max; $i++) {
$id = $draws[1][$i];
$repl = '';
if ($tikidomain) {
$name = $tikidomain.'/'.$id . '.gif';
} else {
$name = $id . '.gif';
}
if (file_exists("img/wiki/$name")) {
if ($tiki_p_edit_drawings == 'y' || $tiki_p_admin_drawings == 'y') {
$repl = "";
} else {
$repl = "";
}
} else {
if ($tiki_p_edit_drawings == 'y' || $tiki_p_admin_drawings == 'y') {
$repl = "click here to create draw $id";
} else {
$repl = tra('drawing not found');
}
}
$data = str_replace($draws[0][$i], $repl, $data);
}
}
}
// Replace cookies
if (preg_match_all("/\{cookie\}/", $data, $rsss)) {
$temp_max = count($rsss[0]);
for ($i = 0; $i < $temp_max; $i++) {
$cookie = $this->pick_cookie();
$data = str_replace($rsss[0][$i], $cookie, $data);
}
}
// Replace dynamic variables
// Dynamic variables are similar to dynamic content but they are editable
// from the page directly, intended for short data, not long text but text
// will work too
// Now won't match HTML-style '%nn' letter codes and some special utf8 situations...
if (preg_match_all("/%([^% 0-9A-Z][^% 0-9A-Z][^% ]*)%/",$data,$dvars)) {
// remove repeated elements
$dvars = array_unique($dvars[1]);
// Now replace each dynamic variable by a pair composed of the
// variable value and a text field to edit the variable. Each
foreach($dvars as $dvar) {
$query = "select `data` from `tiki_dynamic_variables` where `name`=?";
$result = $this->query($query,Array($dvar));
if($result->numRows()) {
$value = $result->fetchRow();
$value = $value["data"];
} else {
//Default value is NULL
$value = "NaV";
}
// Now build 2 divs
$id = 'dyn_'.$dvar;
if(isset($tiki_p_edit_dynvar)&& $tiki_p_edit_dynvar=='y') {
$span1 = "$value";
$span2 = "".'';
} else {
$span1 = "$value";
$span2 = '';
}
$html = $span1.$span2;
//It's important to replace only once
$dvar_preg = preg_quote( $dvar );
$data = preg_replace("+%$dvar_preg%+",$html,$data,1);
//Further replacements only with the value
$data = str_replace("%$dvar%",$value,$data);
}
//At the end put an update button
//
$data='';
}
if (!$simple_wiki) {
// Replace boxes
$data = preg_replace("/\^([^\^]+)\^/", "
$1
", $data);
// Replace colors ~~color:text~~
$data = preg_replace("/\~\~([^\:]+):([^\~]+)\~\~/", "$2", $data);
// Underlined text
$data = preg_replace("/===([^\=]+)===/", "$1", $data);
// Center text
$data = preg_replace("/::(.+?)::/", "
$1
", $data);
}
// definitively put out the protected words ))protectedWord((
preg_match_all("/\)\)(\S*?)\(\(/", $data, $matches);
$noParseWikiLinksK = array();
$noParseWikiLinksT = array();
foreach ($matches[0] as $mi=>$match) {
do {
$randNum = chr(0xff).rand(0, 1048576).chr(0xff);
} while (strstr($data, $randNum));
$data = str_replace($match, $randNum, $data);
$noParseWikiLinksK[] = $randNum;
$noParseWikiLinksT[] = $matches[1][$mi];
}
// New syntax for wiki pages ((name|desc)) Where desc can be anything
// preg_match_all("/\(\(($page_regex)\|(.+?)\)\)/", $data, $pages);
// match ((name|desc)) as well as ((name|))
preg_match_all("/\(\(($page_regex)\|([^\)]*?)\)\)/", $data, $pages);
$temp_max = count($pages[1]);
for ($i = 0; $i < $temp_max; $i++) {
$pattern = $pages[0][$i];
$pattern = preg_quote($pattern, "/");
$pattern = "/" . $pattern . "/";
// Replace links to external wikis
$repl2 = true;
if (strstr($pages[1][$i], ':')) {
$wexs = explode(':', $pages[1][$i]);
if (count($wexs) == 2) {
$wkname = $wexs[0];
if ($this->db->getOne("select count(*) from `tiki_extwiki` where `name`=?",array($wkname)) == 1) {
$wkurl = $this->db->getOne("select `extwiki` from `tiki_extwiki` where `name`=?",array($wkname));
$wkurl = '' . $wexs[1] . '';
$data = preg_replace($pattern, "$wkurl", $data);
$repl2 = false;
}
}
}
if ($repl2) {
// 24-Jun-2003, by zaufi
// TODO: future optimize: get page description and modification time at once.
// text[0] = link description (previous format)
// text[1] = timeout in seconds (new field)
// text[2..N] = drop
$text = explode("|", $pages[5][$i]);
if ($desc = $this->page_exists_desc($pages[1][$i])) {
// why the preg_replace? ex: ((page||Page-Desc)) the desc must stay Page-Desc, and not ))Page-Desc((
$desc1 = $desc;
$desc = preg_replace("/([ \n\t\r\,\;]|^)([A-Z][a-z0-9_\-]+[A-Z][a-z0-9_\-]+[A-Za-z0-9\-_]*)($|[ \n\t\r\,\;\.])/s", "$1))$2(($3", $desc);
$bestLang = ($prefs['feature_multilingual'] == 'y' && $prefs['feature_best_language'] == 'y')? "&bl=y" : "";
$uri_ref = $wikilib->sefurl($pages[1][$i]).$bestLang;
// check to see if desc is blank in ((page|desc))
if (strlen(trim($text[0])) > 0) {
$linktext = $text[0];
} elseif ($desc != $pages[1][$i]) {
// desc is blank; use the page description instead
$linktext = $pages[1][$i] . ': ' . $desc;
} else {
// there is no page description
$linktext = $pages[1][$i];
}
$repl = '' . $linktext . '';
// Check is timeout expired?
if (isset($text[1]) && (time() - intval($this->page_exists_modtime($pages[1][$i]))) < intval($text[1]))
// Append small 'new' image. TODO: possible 'updated' image more suitable...
$repl .= ' ';
} else {
$uri_ref = "tiki-editpage.php?page=" . urlencode($pages[1][$i]);
if( $prefs['feature_multilingual'] == 'y' && isset( $GLOBALS['pageLang'] ) )
$uri_ref .= '&lang=' . urlencode($GLOBALS['pageLang']);
$repl = (strlen(trim($text[0])) > 0 ? $text[0] : $pages[1][$i]) . '?';
}
$data = preg_replace($pattern, "$repl", $data);
}
}
// New syntax for wiki pages ((name)) Where name can be anything
preg_match_all("/\(\( *($page_regex) *\)\)/", $data, $pages);
foreach (array_unique($pages[1]) as $page_parse) {
$repl2 = true;
if (strstr($page_parse, ':')) {
$wexs = explode(':', $page_parse);
if (count($wexs) == 2) {
$wkname = $wexs[0];
if ($this->db->getOne("select count(*) from `tiki_extwiki` where `name`=?",array($wkname)) == 1) {
$wkurl = $this->db->getOne("select `extwiki` from `tiki_extwiki` where `name`=?",array($wkname));
$wkurl = '' . $wexs[1] . '';
$data = preg_replace("/\(\($page_parse\)\)/", "$wkurl", $data);
$repl2 = false;
}
}
}
if ($repl2) {
if ($desc = $this->page_exists_desc($page_parse)) {
// why the preg_replace? ex: ((page||Page-Desc)) the desc must stay Page-Desc in the title, and not ))Page-Desc((
//$desc = preg_replace("/([ \n\t\r\,\;]|^)([A-Z][a-z0-9_\-]+[A-Z][a-z0-9_\-]+[A-Za-z0-9\-_]*)($|[ \n\t\r\,\;\.])/s", "$1))$2(($3", $desc);
$bestLang = ($prefs['feature_multilingual'] == 'y' && $prefs['feature_best_language'] == 'y')? "&bl=y" : ""; // to choose the best page language
$repl = "$page_parse";
} else {
$repl = $page_parse.'?';
}
$page_parse_pq = preg_quote($page_parse, "/");
$data = preg_replace("/\(\($page_parse_pq\)\)/", "$repl", $data);
}
}
// Links to internal pages
// If they are parenthesized then don't treat as links
// Prevent ))PageName(( from being expanded \"\'
//[A-Z][a-z0-9_\-]+[A-Z][a-z0-9_\-]+[A-Za-z0-9\-_]*
if ( ! $simple_wiki && $prefs['feature_wikiwords'] == 'y' ) {
// The first part is now mandatory to prevent [Foo|MyPage] from being converted!
if ($prefs['feature_wikiwords_usedash'] == 'y') {
preg_match_all("/(?<=[ \n\t\r\,\;]|^)([A-Z][a-z0-9_\-\x80-\xFF]+[A-Z][a-z0-9_\-\x80-\xFF]+[A-Za-z0-9\-_\x80-\xFF]*)(?=$|[ \n\t\r\,\;\.])/", $data, $pages);
} else {
preg_match_all("/(?<=[ \n\t\r\,\;]|^)([A-Z][a-z0-9\x80-\xFF]+[A-Z][a-z0-9\x80-\xFF]+[A-Za-z0-9\x80-\xFF]*)(?=$|[ \n\t\r\,\;\.])/", $data, $pages);
}
//TODO to have a real utf8 Wikiword where the capitals can be a utf8 capital
$words = $this->get_hotwords();
foreach (array_unique($pages[1])as $page_parse) {
if (!array_key_exists($page_parse, $words)) {
if ($desc = $this->page_exists_desc($page_parse)) {
//$desc = preg_replace("/([ \n\t\r\,\;]|^)([A-Z][a-z0-9_\-]+[A-Z][a-z0-9_\-]+[A-Za-z0-9\-_]*)($|[ \n\t\r\,\;\.])/s", "$1))$2(($3", $desc);
$repl = '' . $page_parse . '';
} elseif ($prefs['feature_wiki_plurals'] == 'y') {
# Link plural topic names to singular topic names if the plural
# doesn't exist, and the language is english
$plural_tmp = $page_parse;
# Plurals like policy / policies
$plural_tmp = preg_replace("/ies$/", "y", $plural_tmp);
# Plurals like address / addresses
$plural_tmp = preg_replace("/sses$/", "ss", $plural_tmp);
# Plurals like box / boxes
$plural_tmp = preg_replace("/([Xx])es$/", "$1", $plural_tmp);
# Others, excluding ending ss like address(es)
$plural_tmp = preg_replace("/([A-Za-rt-z])s$/", "$1", $plural_tmp);
if($desc = $this->page_exists_desc($plural_tmp)) {
// $desc = preg_replace("/([ \n\t\r\,\;]|^)([A-Z][a-z0-9_\-]+[A-Z][a-z0-9_\-]+[A-Za-z0-9\-_]*)($|[ \n\t\r\,\;\.])/s", "$1))$2(($3", $desc);
// $repl = "$page_parse";
$repl = "$page_parse";
} else {
$repl = $page_parse.'?';
}
} else {
$repl = $page_parse.'?';
}
$data = preg_replace("/(?<=[ \n\t\r\,\;]|^)$page_parse(?=$|[ \n\t\r\,\;\.])/", "$1" . "$repl" . "$2", $data);
//$data = str_replace($page_parse,$repl,$data);
}
}
}
// Reinsert ))Words((
$data = str_replace($noParseWikiLinksK, $noParseWikiLinksT, $data);
// reinsert hash-replaced links into page
foreach ($noparsedlinks as $np) {
$data = str_replace($np["key"], $np["data"], $data);
}
// Images
preg_match_all("/(\{img [^\}]+\})/", $data, $pages);
foreach (array_unique($pages[1])as $page_parse) {
$parts = $this->split_tag( $page_parse);
$imgdata = array(); // pre-set preferences
$imgdata["src"] = '';
$imgdata["height"] = '';
$imgdata["width"] = '';
$imgdata["lnk"] = '';
$imgdata["rel"] = '';
$imgdata["title"] = '';
$imgdata["align"] = '';
$imgdata["desc"] = '';
$imgdata["imalign"] = '';
$imgdata["alt"] = '';
$imgdata["usemap"] = '';
$imgdata["class"] = '';
$imgdata = $this->split_assoc_array( $parts, $imgdata );
// Support both 'link' and 'lnk' syntax
if ( isset($imgdata['link']) && $imgdata['lnk'] == '' ) $imgdata['lnk'] = $imgdata['link'];
if (stristr(str_replace(' ', '', $imgdata["src"]),'javascript:')) {
$imgdata["src"] = '';
}
if ($tikidomain && !preg_match('|^https?:|', $imgdata['src'])) {
$imgdata["src"] = preg_replace("~img/wiki_up/~","img/wiki_up/$tikidomain/",$imgdata["src"]);
}
if (strstr($imgdata["src"],'javascript:')) {
$imgdata["src"] = '';
}
// Handle absolute links (e.g. to send a newsletter with images that remains on the tiki site)
if ( $imgdata['src'] != '' && $absolute_links && ! preg_match('|^[a-zA-Z]+:\/\/|', $imgdata['src']) ) {
global $base_host, $url_path;
$imgdata['src'] = $base_host.( $imgdata['src'][0] == '/' ? '' : $url_path ).$imgdata['src'];
}
$detected_lib = '';
$imgdata_dim = '';
if ( $prefs['feature_filegals_manager'] == 'y' ) {
include_once('lib/images/images.php');
}
if ( $detected_lib != '' && ereg('^'.$tikiroot.'tiki-download_file.php\?', $imgdata['src']) ) {
// If an image lib has been detected and if we are using an image from a file gallery,
// then also resize the image server-side, because it will generally imply less data to download from the user
// (i.e. speed up the page download) and a better image quality (browser resize algorithms are quick but bad)
//
// Note: ctype_digit is used to ensure there is only digits in width and height strings (e.g. to avoid '50%', ...)
//
if ( (int)$imgdata['width'] > 0 && ctype_digit($imgdata['width']) ) $imgdata['src'] .= '&x='.$imgdata['width'];
if ( (int)$imgdata['height'] > 0 && ctype_digit($imgdata['height']) ) $imgdata['src'] .= '&y='.$imgdata['height'];
}
if ( $imgdata['width'] ) $imgdata_dim .= ' width="' . $imgdata['width'] . '"';
if ( $imgdata['height'] ) $imgdata_dim .= ' height="' . $imgdata['height'] . '"';
$repl = '' . $repl . '';
}
if ($imgdata["desc"]) {
$repl = '
';
$data = str_replace($tables[0][$i], $repl, $data);
}
}
}
}
if (!$simple_wiki) {
$need_maketoc = strpos($data, '{maketoc');
$need_autonumbering = ( preg_match('/^\!+[\-\+]?#/m', $data) > 0 );
$anch = array();
$pageNum = 1;
// 08-Jul-2003, by zaufi
// HotWords will be replace only in ordinal text
// It looks __really__ goofy in Headers or Titles
if ( $prefs['feature_hotwords'] == 'y' ) {
// Get list of HotWords
$words = $this->get_hotwords();
}
// Now tokenize the expression and process the tokens
// Use tab and newline as tokenizing characters as well ////
$lines = explode("\n", $data);
$data = '';
$listbeg = array();
$divdepth = array();
$hdr_structure = array();
$show_title_level = array();
$last_hdr = array();
$nb_last_hdr = 0;
$nb_hdrs = 0;
$inTable = 0;
$inPre = 0;
$inComment = 0;
$inTOC = 0;
$title_text = '';
// loop: process all lines
$in_paragraph = 0;
foreach ($lines as $line) {
$current_title_num = '';
$numbering_remove = 0;
$line = rtrim($line); // Trim off trailing white space
// Check for titlebars...
// NOTE: that title bar should start at the beginning of the line and
// be alone on that line to be autoaligned... otherwise, it is an old
// styled title bar...
if (substr(ltrim($line), 0, 2) == '-=' && substr($line, -2, 2) == '=-') {
// Close open paragraph and lists, but not div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 1, 0);
//
$align_len = strlen($line) - strlen(ltrim($line));
// My textarea size is about 120 space chars.
//define('TEXTAREA_SZ', 120);
// NOTE: That strict math formula (split into 3 areas) gives
// bad visual effects...
// $align = ($align_len < (TEXTAREA_SZ / 3)) ? "left"
// : (($align_len > (2 * TEXTAREA_SZ / 3)) ? "right" : "center");
//
// Going to introduce some heuristic here :)
// Visualy (remember that space char is thin) center starts at 25 pos
// and 'right' from 60 (HALF of full width!) -- thats all :)
//
// NOTE: Guess align only if more than 10 spaces before -=title=-
if ($align_len > 10) {
$align = ($align_len < 25) ? "left" : (($align_len > 60) ? "right" : "center");
$align = ' style="text-align: ' . $align . ';"';
} else
$align = '';
//
$line = trim($line);
$line = '
' . substr($line, 2, strlen($line) - 4). '
';
$data .= $line . "\n";
// TODO: Case is handled ... no need to check other conditions
// (it is apriori known that they are all false, moreover sometimes
// check procedure need > O(0) of compexity)
// -- continue to next line...
// MUST replace all remaining parse blocks to the same logic...
continue;
}
// Replace old styled titlebars
if (strlen($line) != strlen($line = preg_replace("/-=(.+?)=-/", "
$1
", $line))) {
// Close open paragraph, but not lists (why not?) or div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 0, 0);
$data .= $line . "\n";
continue;
}
// check if we are inside a ~hc~ block and, if so, ignore
// monospaced and do not insert
$inComment += substr_count(strtolower($line), "");
// check if we are inside a ~pre~ block and, if so, ignore
// monospaced and do not insert
$inPre += substr_count(strtolower($line), "
$inTable += substr_count(strtolower($line), "
$inTOC += substr_count(strtolower($line), "
close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 1, 0);
// If the first character is space then make font monospaced.
// For fixed formatting, use ~pp~...~/pp~
$line = '' . $line . '';
}
if ($prefs['feature_hotwords'] == 'y') {
// Replace Hotwords before begin
$line = $this->replace_hotwords($line, $words);
}
// Make plain URLs clickable hyperlinks
if ($prefs['feature_autolinks'] == 'y') {
$line = $this->autolinks($line);
}
// Replace monospaced text
$line = preg_replace("/(^|\s)-\+(.*?)\+-/", "$2", $line);
// Replace bold text
$line = preg_replace("/__(.*?)__/", "$1", $line);
// Replace italic text
$line = preg_replace("/\'\'(.*?)\'\'/", "$1", $line);
// Replace definition lists
$line = preg_replace("/^;([^:]*):([^\/\/].*)/", "
", $line);
}
*/
// This line is parseable then we have to see what we have
if (substr($line, 0, 3) == '---') {
// This is not a list item --- close open paragraph and lists, but not div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 1, 0);
$line = '';
} else {
$litype = substr($line, 0, 1);
if ($litype == '*' || $litype == '#') {
// Close open paragraph, but not lists or div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 0, 0);
$listlevel = $this->how_many_at_start($line, $litype);
$liclose = '';
$addremove = 0;
if ($listlevel < count($listbeg)) {
while ($listlevel != count($listbeg)) $data .= array_shift($listbeg);
if (substr(current($listbeg), 0, 5) != '') $liclose = '';
} elseif ($listlevel > count($listbeg)) {
$listyle = '';
while ($listlevel != count($listbeg)) {
array_unshift($listbeg, ($litype == '*' ? '
') array_unshift($listbeg, '' . array_shift($listbeg));
} elseif ($litype == '+') {
// Close open paragraph, but not list or div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 0, 0);
$listlevel = $this->how_many_at_start($line, $litype);
// Close lists down to requested level
while ($listlevel < count($listbeg)) $data .= array_shift($listbeg);
// Must append paragraph for list item of given depth...
$listlevel = $this->how_many_at_start($line, $litype);
if (count($listbeg)) {
if (substr(current($listbeg), 0, 5) != '') {
array_unshift($listbeg, '' . array_shift($listbeg));
$liclose = '
';
} else $liclose = ' ';
} else $liclose = '';
$line = $liclose . substr($line, count($listbeg));
} else {
// This is not a list item - close open lists,
// but not paragraph or div's. If we are
// closing a list, there really shouldn't be a
// paragraph open anyway.
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 0, 1, 0);
// Get count of (possible) header signs at start
$hdrlevel = $this->how_many_at_start($line, '!');
// If 1st char on line is '!' and its count less than 6 (max in HTML)
if ($litype == '!' && $hdrlevel > 0 && $hdrlevel <= 6) {
/*
* Handle headings autonumbering syntax (i.e. !#Text, !!#Text, ...)
* Note :
* this needs to be done even if the current header has no '#'
* in order to generate the right numbers when they are not specified for every headers.
* This is the case, for example, when you want to add numbers to headers of level 2 but not to level 1
*/
$line_lenght = strlen($line);
// Generate an array containing the squeleton of maketoc (based on headers levels)
// i.e. hdr_structure will contain something lile this :
// array( 1, 2, 2.1, 2.1.1, 2.1.2, 2.2, ... , X.Y.Z... )
//
$hdr_structure[$nb_hdrs] = '';
// Generate the number (e.g. 1.2.1.1) of the current title, based on the previous title number :
// - if the current title deepest level is lesser than (or equal to)
// the deepest level of the previous title : then we increment the last level number,
// - else : we simply add new levels with value '1' (only if the previous level number was shown),
//
if ( $nb_last_hdr > 0 && $hdrlevel <= $nb_last_hdr ) {
$hdr_structure[$nb_hdrs] = array_slice($last_hdr, 0, $hdrlevel);
if ( $show_title_level[$hdrlevel] || ! $need_autonumbering ) {
//
// Increment the level number only if :
// - the last title of the same level number has a displayed number
// or - no title has a displayed number (no autonumbering)
//
$hdr_structure[$nb_hdrs][$hdrlevel - 1]++;
}
} else {
if ( $nb_last_hdr > 0 ) {
$hdr_structure[$nb_hdrs] = $last_hdr;
}
for ( $h = 0 ; $h < $hdrlevel - $nb_last_hdr ; $h++ ) {
$hdr_structure[$nb_hdrs][$h + $nb_last_hdr] = '1';
}
}
$show_title_level[$hdrlevel] = ereg('^!+[\+\-]?#', $line);
// Update last_hdr info for the next header
$last_hdr = $hdr_structure[$nb_hdrs];
$nb_last_hdr = count($last_hdr);
$current_title_real_num = implode('.', $hdr_structure[$nb_hdrs]).'. ';
// Update the current title number to hide all parents levels numbers if the parent has no autonumbering
$hideall = false;
for ( $j = $hdrlevel ; $j > 0 ; $j-- ) {
if ( $hideall || ! $show_title_level[$j] ) {
unset($hdr_structure[$nb_hdrs][$j - 1]);
$hideall = true;
}
}
// Store the title number to use only if it has to be shown (if the '#' char is used)
$current_title_num = $show_title_level[$hdrlevel] ? implode('.', $hdr_structure[$nb_hdrs]).'. ' : '';
$nb_hdrs++;
// Close open paragraph (lists already closed above)
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 0, 0);
// Close lower level divs if opened
for (;current($divdepth) >= $hdrlevel; array_shift($divdepth)) $data .= '
';
// Remove possible hotwords replaced :)
// Umm, *why*? Taking this out lets page
// links in headers work, which can be nice.
// -rlpowell
// $line = strip_tags($line);
// OK. Parse headers here...
$anchor = '';
$aclose = '';
$aclose2 = '';
$addremove = $show_title_level[$hdrlevel] ? 1 : 0; // If needed, also remove '#' sign from title beginning
// May be special signs present after '!'s?
$divstate = substr($line, $hdrlevel, 1);
if ($divstate == '+' || $divstate == '-') {
// OK. Must insert flipper after HEADER, and then open new div...
$thisid = 'id' . ereg_replace('[^a-zA-z0-9]', '',urlencode($page)) .$nb_hdrs;
$aclose = '[' . ($divstate == '-' ? '+' : '-') . ']';
$aclose2 = '
';
$aclose2 = $aclose2 . '';
array_unshift($divdepth, $hdrlevel);
$addremove += 1;
}
// Generate the final title text
$title_text_base = substr($line, $hdrlevel + $addremove);
$title_text = $current_title_num.$title_text_base;
// create stable anchors for all headers
// use header but replace non-word character sequences
// with one underscore (for XHTML 1.0 compliance)
$thisid = ereg_replace('[^a-zA-Z0-9]+', '_', $title_text);
$thisid = ereg_replace('^_', '', $thisid);
// Add a number to the anchor if it already exists, to avoid duplicated anchors
if ( isset($all_anchors[$thisid]) ) {
$all_anchors[$thisid]++;
$thisid .= '_'.$all_anchors[$thisid];
} else {
$all_anchors[$thisid] = 1;
}
// Collect TOC entry if any {maketoc} is present on the page
if ( $need_maketoc !== false ) {
array_push($anch, array(
'id' => $thisid,
'hdrlevel' => $hdrlevel,
'pagenum' => $pageNum,
'title' => $title_text_base,
'title_displayed_num' => $current_title_num,
'title_real_num' => $current_title_real_num
));
}
global $tiki_p_edit, $section;
if ($prefs['wiki_edit_section'] == 'y' && $section == 'wiki page' && $tiki_p_edit == 'y') {
global $smarty;
include_once('lib/smarty_tiki/function.icon.php');
$button = '
';
} else {
$button = '';
}
// Use $hdrlevel + 1 because the page title is H1, so none of the other headers should be.
if ( $prefs['feature_wiki_show_hide_before'] == 'y' ) {
$line = $button.''.$aclose.' '.$title_text.''.$aclose2;
} else {
$line = $button.''.$title_text.''.$aclose.$aclose2;
}
} elseif (!strcmp($line, $prefs['wiki_page_separator'])) {
// Close open paragraph, lists, and div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 1, 1);
// Leave line unchanged... tiki-index.php will split wiki here
$line = $prefs['wiki_page_separator'];
$pageNum += 1;
} else {
/** Usual paragraph.
*
* If the
* $prefs['feature_wiki_paragraph_formatting']
* is on, then consecutive lines of
* text will be gathered into a block
* that is surrounded by HTML
* paragraph tags. One or more blank
* lines, or another special Wiki line
* (e.g., heading, titlebar, etc.)
* signifies the end of the
* paragraph. If the paragraph
* formatting feature is off, the
* original Tikiwiki behavior is used,
* in which each line in the source is
* terminated by an explicit line
* break (br tag).
*
* @since Version 1.9
*/
if ($inTable == 0 && $inPre == 0 && $inComment == 0 && $inTOC == 0
// Don't put newlines at comments' end!
&& ! substr_count(strtolower($line), "-->")
) {
if ($prefs['feature_wiki_paragraph_formatting'] == 'y') {
if ($in_paragraph && ( 0 == strcmp("", trim($line)) || substr(trim($line),0,5) == '
close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 0, 0);
} elseif (!$in_paragraph && (0 != strcmp("", trim($line))) && substr(trim($line),0,4) != '' . $line;
} else {
// A normal in-paragraph line or a consecutive blank line.
// Leave it as is.
}
} else {
$line .= ' ';
}
}
}
}
}
$data .= $line . "\n";
}
// Close open paragraph, lists, and div's
$this->close_blocks($data, $in_paragraph, $listbeg, $divdepth, 1, 1, 1);
/*
* Replace special "maketoc" plugins
* Valid arguments :
* - type (look of the maketoc),
* - maxdepth (max level displayed),
* - title (replace the default title),
* - showhide (if set to y, add the Show/Hide link)
* - nolinks (if set to y, don't add links on toc entries)
* - nums :
* * 'n' means 'no title autonumbering' in TOC,
* * 'force' means :
* ~ same as 'y' if autonumbering is used in the page,
* ~ 'number each toc entry as if they were all autonumbered'
* * any other value means 'same as page's headings autonumbering',
*
* (Note that title will be translated if a translation is available)
*
* Examples: {maketoc}, {maketoc type=box maxdepth=1 showhide=y}, {maketoc title="Page Content" maxdepth=3}, ...
* Obsolete syntax: {maketoc:box}
*/
$new_data = '';
$search_start = 0;
while ( ($maketoc_start = strpos($data, '{maketoc', $search_start)) !== false ) {
$maketoc_length = strpos($data, '}', $maketoc_start) + 1 - $maketoc_start;
$maketoc_string = substr($data, $maketoc_start, $maketoc_length);
// Handle old type definition for type "box" (and preserve environment for the title also)
if ( $maketoc_length > 12 && strtolower(substr($maketoc_string, 8, 4)) == ':box' ) {
$maketoc_string = '{maketoc type=box showhide=y title="'.tra('index','',true).'"'.substr($maketoc_string, 12);
}
$maketoc_string = str_replace('"', '"', $maketoc_string);
$maketoc_regs = array();
if ( $maketoc_length == 9 || preg_match_all('/([^\s=\(]+)=([^"\s=\)\}]+|"[^"]*")/', $maketoc_string, $maketoc_regs) ) {
if ( $maketoc_start > 0 ) {
$new_data .= substr($data, 0, $maketoc_start);
}
// Set maketoc default values
$maketoc_args = array(
'type' => '',
'maxdepth' => 0, // No limit
'title' => tra("Table of contents","",true),
'showhide' => '',
'nolinks' => '',
'nums' => ''
);
// Build maketoc arguments list (and remove " chars if they are around the value)
if ( isset($maketoc_regs[1]) ) {
$nb_args = count($maketoc_regs[1]);
for ( $a = 0; $a < $nb_args ; $a++ ) {
$maketoc_args[strtolower($maketoc_regs[1][$a])] = trim($maketoc_regs[2][$a], '"');
}
}
if ( $maketoc_args['title'] != '' ) {
// Translate maketoc title
$maketoc_summary = ' summary="'.tra($maketoc_args['title'],'',true).'"';
$maketoc_title = "
';
$data = str_replace($rsss[0][$i], $repl, $data);
}
}
// linebreaks using %%%
$data = str_replace("%%%", " ", $data);
// Close BiDi DIVs if any
for ($i = 0; $i < $bidiCount; $i++) {
$data .= "
";
}
// Put removed strings back.
$this->replace_preparse($data, $preparsed, $noparsed);
// Process pos_handlers here
foreach ($this->pos_handlers as $handler) {
$data = $handler($data);
}
return $data;
}
function parse_smileys($data) {
global $prefs;
if ($prefs['feature_smileys'] == 'y') {
$data = preg_replace("/\(:([^:]+):\)/", "", $data);
}
return $data;
}
function get_pages($data) {
global $page_regex, $prefs;
if ($prefs['feature_wikiwords'] == 'y') {
preg_match_all("/\(\( *($page_regex) *\)\)/", $data, $pages2);
preg_match_all("/\(\( *($page_regex) *\|(.+?)\)\)/", $data, $pages3);
preg_match_all("/([ \n\t\r\,\;]|^)?([A-Z][a-z0-9_\-]+[A-Z][a-z0-9_\-]+[A-Za-z0-9\-_]*)($|[ \n\t\r\,\;\.])/", $data, $pages);
$pages = array_unique(array_merge($pages[2], $pages2[1], $pages3[1]));
} else {
preg_match_all("/\(\( *($page_regex) *\)\)/", $data, $pages);
preg_match_all("/\(\( *($page_regex) *\|(.+?)\)\)/", $data, $pages2);
$pages = array_unique(array_merge($pages[1], $pages2[1]));
}
return $pages;
}
function clear_links($page) {
$query = "delete from `tiki_links` where `fromPage`=?";
$result = $this->query($query, array($page));
}
function replace_link($pageFrom, $pageTo) {
$query = "delete from `tiki_links` where `fromPage`=? and `toPage`=?";
$result = $this->query($query, array($pageFrom,$pageTo));
$query = "insert into `tiki_links`(`fromPage`,`toPage`) values(?, ?)";
$result = $this->query($query, array($pageFrom,$pageTo));
}
function invalidate_cache($page) {
$query = "update `tiki_pages` set `cache_timestamp`=? where `pageName`=?";
$this->query($query, array(0,$page) );
}
/** Update a wiki page
@param array $hash- lock_it,contributions, contributors
**/
function update_page($pageName, $edit_data, $edit_comment, $edit_user, $edit_ip, $description = '', $minor = false, $lang='', $is_html=false, $hash=null, $saveLastModif=null, $wysiwyg='', $wiki_authors_style) {
global $smarty, $prefs, $dbTiki, $histlib, $quantifylib;
include_once ("lib/wiki/histlib.php");
include_once ("lib/commentslib.php");
$commentslib = new Comments($dbTiki);
if (!$edit_user) $edit_user = 'anonymous';
$this->invalidate_cache($pageName);
// Collect pages before modifying edit_data (see update of links below)
$pages = $this->get_pages($edit_data);
if (!$this->page_exists($pageName))
return false;
// Get this page information
$info = $this->get_page_info($pageName);
// Use largest version +1 in history table rather than tiki_page because versions used to be bugged
// tiki_history is also bugged as not all changes get stored in the history, like minor changes
// and changes that do not modify the body of the page. Both numbers are wrong, but the largest of
// them both is right.
$old_version = max(
$info["version"],
$histlib->get_page_latest_version($pageName) + 1
);
$lastModif = $info["lastModif"];
$user = $info["user"];
if (!$user) $user = 'anonymous';
$ip = $info["ip"];
$comment = $info["comment"];
$data = $info["data"];
// WARNING: POTENTIAL BUG
// The line below is not consistent with the rest of Tiki
// (I commented it out so it can be further examined by CVS change control)
//$pageName=addslashes($pageName);
// But this should work (comment added by redflo):
$version = $old_version + 1;
if( $prefs['quantify_changes'] == 'y' && $prefs['feature_multilingual'] == 'y' )
{
include_once 'lib/wiki/quantifylib.php';
$quantifylib->recordChangeSize( $info['page_id'], $version, $info['data'], $edit_data );
}
$html=$is_html?1:0;
if ($html && $prefs['feature_purifier'] != 'n') {
require "HTMLPurifier.auto.php";
$purifier = new HTMLPurifier();
$edit_data = $purifier->purify($edit_data);
}
$mid = '';
if( is_null( $saveLastModif ) ) {
$saveLastModif = $this->now;
}
$bindvars = array($description,$edit_data,$edit_comment,(int) $saveLastModif,$version,$edit_user,$edit_ip,(int)strlen($data),$html,$wysiwyg, $wiki_authors_style);
if ($lang) {
$mid .= ', `lang`=? ';
$bindvars[] = $lang;
}
if (!empty($hash['lock_it']) && ($hash['lock_it'] == 'y' || $hash['lock_it'] == 'on')) {
$mid .= ', `flag`=?, `lockedby`=? ';
$bindvars[] = 'L';
$bindvars[] = $user;
} else if (empty($hash['lock_it']) || $hash['lock_it'] == 'n') {
$mid .= ', `flag`=?, `lockedby`=? ';
$bindvars[] = '';
$bindvars[] = '';
}
if (empty($hash['contributions'])) {
$hash['contributions'] = '';
}
if (empty($hash['contributors'])) {
$hash2 = '';
} else {
foreach ($hash['contributors'] as $c) {
$hash3['contributor'] = $c;
$hash2[] = $hash3;
}
}
$bindvars[] = $pageName;
$query = "update `tiki_pages` set `description`=?, `data`=?, `comment`=?, `lastModif`=?, `version`=?, `user`=?, `ip`=?, `page_size`=?, `is_html`=?, `wysiwyg`=?, `wiki_authors_style`=? $mid where `pageName`=?";
$result = $this->query($query,$bindvars);
// Parse edit_data updating the list of links from this page
$this->clear_links($pageName);
// Pages collected above
foreach ($pages as $page) {
$this->replace_link($pageName, $page);
}
if (strtolower($pageName) != 'sandbox' && !$minor) {
$maxversions = $prefs['maxVersions'];
if ($maxversions && ($nb = $histlib->get_nb_history($pageName)) > $maxversions) {
// Select only versions older than keep_versions days
$keep = $prefs['keep_versions'];
$oktodel = $saveLastModif - ($keep * 24 * 3600);
$query = "select `pageName` ,`version`, `historyId` from `tiki_history` where `pageName`=? and `lastModif`<=? order by `lastModif` asc";
$result = $this->query($query,array($pageName,$oktodel),$nb - $maxversions);
$toelim = $result->numRows();
while ($res = $result->fetchRow()) {
$page = $res["pageName"];
$version = $res["version"];
$query = "delete from `tiki_history` where `pageName`=? and `version`=?";
$this->query($query,array($pageName,$version));
if ($prefs['feature_contribution'] == 'y') {
global $contributionlib; include_once('lib/contribution/contributionlib.php');
$contributionlib->remove_history($res['historyId']);
}
}
}
}
// This if no longer checks for minor-ness of the change; sendWikiEmailNotification does that.
if( $prefs['feature_wiki_history_full'] == 'y' || $data != $edit_data || $description != $info["description"] || $comment != $edit_comment ) {
if (strtolower($pageName) != 'sandbox') {
$query = "insert into `tiki_history`(`pageName`, `version`, `lastModif`, `user`, `ip`, `comment`, `data`, `description`)
values(?,?,?,?,?,?,?,?)";
# echo "
";print_r(get_defined_vars());echo "
";die();
$result = $this->query($query,array($pageName,(int) $old_version,(int) $lastModif,$user,$ip,$comment,$data,$description));
if ($prefs['feature_contribution'] == 'y') {// transfer page contributions to the history
global $contributionlib; include_once('lib/contribution/contributionlib.php');
$query = 'select max(`historyId`) from `tiki_history`where `pageName`=? and `version`=?';
$historyId = $this->getOne($query, array($pageName,(int) $old_version));
$contributionlib->change_assigned_contributions($pageName, 'wiki page', $historyId, 'history', '', $pageName.'/'.$old_version, "tiki-pagehistory.php?page=$pageName&preview=$old_version");
}
/* the following doesn't work because tiki dies if the above query fails
if (!$result) {
$query2 = "delete from `tiki_history` where `pageName`=? and `version`=?";
$result = $this->query($query2,array($pageName,(int) $version));
$result = $this->query($query,array($pageName,(int) $version,(int) $lastModif,$user,$ip,$comment,$data,$description));
}
*/
}
if (strtolower($pageName) != 'sandbox') {
global $logslib; include_once('lib/logs/logslib.php');
include_once('lib/diff/difflib.php');
$bytes = diff2($data , $edit_data, 'bytes');
$logslib->add_action('Updated', $pageName, 'wiki page', $bytes, $edit_user, $edit_ip, '', $this->now, $hash['contributions'], $hash2);
if ($prefs['feature_contribution'] == 'y') {
global $contributionlib; include_once('lib/contribution/contributionlib.php');
$contributionlib->assign_contributions($hash['contributions'], $pageName, 'wiki page', $description, $pageName, "tiki-index.php?page=".urlencode($pageName));
}
}
if ($prefs['feature_multilingual'] == 'y' && $lang )
{
// Need to update the translated objects table when an object's language changes.
$this->query( "UPDATE tiki_translated_objects SET lang = ? WHERE objId = ? AND type = 'wiki page'",
array( $lang, $info['page_id'] ) );
}
if ($prefs['feature_user_watches'] == 'y' && ($prefs['wiki_watch_minor'] != 'n' || $minor != true)) {
// Deal with mail notifications.
include_once('lib/notifications/notificationemaillib.php');
global $histlib; include_once ("lib/wiki/histlib.php");
$old = $histlib->get_version($pageName, $old_version);
$foo = parse_url($_SERVER["REQUEST_URI"]);
$machine = $this->httpPrefix(). dirname( $foo["path"] );
require_once('lib/diff/difflib.php');
$diff = diff2($old["data"] , $edit_data, "unidiff");
sendWikiEmailNotification('wiki_page_changed', $pageName, $edit_user, $edit_comment, $old_version, $edit_data, $machine, $diff, $minor, $hash['contributions']);
}
$query = "delete from `tiki_page_drafts` where `user`=? and `pageName`=?";
$this->query($query, array($GLOBALS['user'], $pageName));
if ($prefs['feature_score'] == 'y') {
$this->score_event($user, 'wiki_edit');
}
}
if ( $prefs['feature_search'] == 'y' && $prefs['feature_search_fulltext'] != 'y' && $prefs['search_refresh_index_mode'] == 'normal' ) {
require_once('lib/search/refresh-functions.php');
refresh_index('pages', $pageName);
}
}
function update_page_version($pageName, $version, $edit_data, $edit_comment, $edit_user, $edit_ip, $lastModif, $description = '', $lang='') {
global $smarty;
if (strtolower($pageName) == 'sandbox')
return;
// Collect pages before modifying edit_data
$pages = $this->get_pages($edit_data);
if (!$this->page_exists($pageName))
return false;
$query = "delete from `tiki_history` where `pageName`=? and `version`=?";
$result = $this->query($query, array($pageName,(int) $version));
$query = "insert into `tiki_history`(pageName, version, lastModif, user, ip, comment, data,description) values(?,?,?, ?,?,?, ?,?)";
$result = $this->query($query, array($pageName,(int) $version, (int) $lastModif, $edit_user, $edit_ip, $edit_comment, $edit_data, $description)
);
//print("version: $version ");
// Get this page information
$info = $this->get_page_info($pageName);
if ($version >= $info["version"]) {
if ($lang) { // not sure it is necessary
$query = "update `tiki_pages` set `data`=?, `comment`=?, `lastModif`=?, `version`=?, `user`=?, `ip`=?, `description`=?,`page_size`=?,`lang`=? where `pageName`=?";
$result = $this->query($query, array($edit_data, $edit_comment, (int) $this->now, (int) $version, $edit_user, $edit_ip, $description, (int) strlen($edit_data), $lang, $pageName));
} else {
$query = "update `tiki_pages` set `data`=?, `comment`=?, `lastModif`=?, `version`=?, `user`=?, `ip`=?, `description`=?,`page_size`=? where `pageName`=?";
$result = $this->query($query, array($edit_data, $edit_comment, (int) $this->now, (int) $version, $edit_user, $edit_ip, $description, (int) strlen($edit_data), $pageName));
}
// Parse edit_data updating the list of links from this page
$this->clear_links($pageName);
// Pages are collected at the top of the function before adding slashes
foreach ($pages as $page) {
$this->replace_link($pageName, $page);
}
}
}
function get_display_timezone($_user = false) {
global $prefs, $user;
if ( $_user === false || $_user == $user ) {
// If the requested timezone is the current user timezone
$tz = $prefs['display_timezone'];
} elseif ( $_user ) {
// ... else, get the user timezone preferences from DB
$tz = $this->get_user_preference($_user, 'display_timezone');
if ( ! Date_TimeZone::isValidID($tz) ) {
$tz = $prefs['server_timezone'];
}
}
return $tz;
}
function get_long_date_format() {
global $prefs;
return $prefs['long_date_format'];
}
function get_short_date_format() {
global $prefs;
return $prefs['short_date_format'];
}
function get_long_time_format() {
global $prefs;
return $prefs['long_time_format'];
}
function get_short_time_format() {
global $prefs;
return $prefs['short_time_format'];
}
function get_long_datetime_format() {
static $long_datetime_format = false;
if (!$long_datetime_format) {
$t = trim($this->get_long_time_format());
if (!empty($t)) {
$t = ' ['.$t.']';
}
$long_datetime_format = $this->get_long_date_format().$t;
}
return $long_datetime_format;
}
function get_short_datetime_format() {
static $short_datetime_format = false;
if (!$short_datetime_format) {
$t = trim($this->get_short_time_format());
if (!empty($t)) {
$t = ' ['.$t.']';
}
$short_datetime_format = $this->get_short_date_format().$t;
}
return $short_datetime_format;
}
function date_format($format, $timestamp = false, $_user = false, $input_format = DATE_FORMAT_UNIXTIME) {
global $tikidate, $tikilib;
if ( ! $timestamp ) {
$timestamp = time();
}
$tikidate->setTZbyID('UTC');
$tikidate->setDate($timestamp, $input_format);
$tz = $tikilib->get_display_timezone($_user);
// If user timezone is not also in UTC, convert the date
if ( $tz != 'UTC' ) {
$tikidate->convertTZByID($tz);
}
return $tikidate->format($format);
}
function make_time($hour,$minute,$second,$month,$day,$year) {
global $tikidate, $tikilib, $prefs;
$display_tz = $tikilib->get_display_timezone();
if ( $display_tz == '' ) $display_tz = 'UTC';
$tikidate->setTZbyID($display_tz);
$tikidate->setLocalTime($day,$month,$year,$hour,$minute,$second,0);
return $tikidate->getTime();
}
function get_long_date($timestamp, $user = false) {
return $this->date_format($this->get_long_date_format(), $timestamp, $user);
}
function get_short_date($timestamp, $user = false) {
return $this->date_format($this->get_short_date_format(), $timestamp, $user);
}
function get_long_time($timestamp, $user = false) {
return $this->date_format($this->get_long_time_format(), $timestamp, $user);
}
function get_short_time($timestamp, $user = false) {
return $this->date_format($this->get_short_time_format(), $timestamp, $user);
}
function get_long_datetime($timestamp, $user = false) {
return $this->date_format($this->get_long_datetime_format(), $timestamp, $user);
}
function get_short_datetime($timestamp, $user = false) {
return $this->date_format($this->get_short_datetime_format(), $timestamp, $user);
}
/**
Per http://www.w3.org/TR/NOTE-datetime
*/
function get_iso8601_datetime($timestamp, $user = false) {
return $this->date_format('%Y-%m-%dT%H:%M:%S%O', $timestamp, $user);
}
function get_compact_iso8601_datetime($timestamp, $user = false) {
// no dashes and no tz info - latter should be fixed
return $this->date_format('%Y%m%dT%H%M%S', $timestamp, $user);
}
function list_languages($path = false, $short=null, $all=false) {
$languages = array();
if (!$path)
$path = "lang";
if (!is_dir($path))
return array();
$h = opendir($path);
while ($file = readdir($h)) {
if (strpos($file,'.') === false && $file != 'CVS' && $file != 'index.php' && is_dir("$path/$file") && file_exists("$path/$file/language.php")) {
$languages[] = $file;
}
}
closedir ($h);
// Format and return the list
return $this->format_language_list($languages, $short, $all);
}
function is_valid_language( $language ) {
return preg_match("/^[a-zA-Z-_]*$/", $language)
&& file_exists('lang/' . $language . '/language.php');
}
function list_styles() {
global $tikidomain;
$sty = array();
if (is_dir("styles/")) {
$h = opendir("styles/");
while ($file = readdir($h)) {
if (ereg("\.css$", $file)) {
$sty[$file] = 1;
}
}
closedir($h);
}
/* What is this $tikidomain section?
* Some files that call this method used to list styles without considering
* $tikidomain, now they do. They're listed below:
*
* tiki-theme_control.php
* tiki-theme_control_objects.php
* tiki-theme_control_sections.php
* tiki-my_tiki.php
* modules/mod-switch_theme.php
*
* lfagundes
*/
if ($tikidomain) {
if (is_dir("styles/$tikidomain")) {
$h = opendir("styles/$tikidomain");
while ($file = readdir($h)) {
if (strstr($file, ".css") and substr($file,0,1) != '.') {
$sty["$file"] = 1;
}
}
closedir($h);
}
}
$styles = array_keys($sty);
sort($styles);
return $styles;
}
// Comparison function used to sort languages by their name in the
// current locale.
function formatted_language_compare($a, $b) {
return strcmp($a['name'], $b['name']);
}
// Returns a list of languages formatted as a twodimensionel array
// with 'value' being the language code and 'name' being the name of
// the language.
// if $short is 'y' returns only the localized language names array
function format_language_list($languages, $short=null, $all=false) {
// The list of available languages so far with both English and
// translated names.
global $langmapping, $prefs;
include_once("lang/langmapping.php");
$formatted = array();
// run through all the language codes:
if (isset($short) && $short == "y") {
foreach ($languages as $lc) {
if (!count($prefs['available_languages']) or (!$all and in_array($lc,$prefs['available_languages']))) {
if (isset($langmapping[$lc]))
$formatted[] = array('value' => $lc, 'name' => $langmapping[$lc][0]);
else
$formatted[] = array('value' => $lc, 'name' => $lc);
}
usort($formatted, array('TikiLib', 'formatted_language_compare'));
}
return $formatted;
}
foreach ($languages as $lc) {
if (!count($prefs['available_languages']) or (!$all and in_array($lc,$prefs['available_languages'])) or $all) {
if (isset($langmapping[$lc])) {
// known language
if ($langmapping[$lc][0] == $langmapping[$lc][1]) {
// Skip repeated text, 'English (English, en)' looks silly.
$formatted[] = array(
'value' => $lc,
'name' => $langmapping[$lc][0] . " ($lc)"
);
} else {
$formatted[] = array(
'value' => $lc,
'name' => $langmapping[$lc][1] . ' (' . $langmapping[$lc][0] . ', ' . $lc . ')'
);
}
} else {
// unknown language
$formatted[] = array(
'value' => $lc,
'name' => tra("Unknown language"). " ($lc)"
);
}
}
}
// Sort the languages by their name in the current locale
usort($formatted, array('TikiLib', 'formatted_language_compare'));
return $formatted;
}
function get_language($user = false) {
global $prefs;
static $language = false;
if (!$language) {
if ($user) {
$language = $this->get_user_preference($user, 'language', 'default');
if (!$language || $language == 'default') {
$language = $prefs['language'];
}
} else {
$language = $prefs['language'];
}
}
return $language;
}
function read_raw($text) {
$file = split("\n",$text);
$back = '';
foreach ($file as $line) {
$r = $s = '';
if (substr($line,0,1) != "#") {
if( ereg("^\[([A-Z0-9]+)\]",$line,$r) ) {
$var = strtolower($r[1]);
}
if (isset($var) and (ereg("^([-_/ a-zA-Z0-9]+)[ \t]+[:=][ \t]+(.*)",$line,$s))) {
$back[$var][trim($s[1])] = trim($s[2]);
}
}
}
return $back;
}
function httpScheme() {
global $url_scheme;
return $url_scheme;
}
function httpPrefix() {
global $url_scheme, $url_host, $url_port;
return $url_scheme.'://'.$url_host.(($url_port!='')?":$url_port":'');
}
function distance($lat1,$lon1,$lat2,$lon2) {
// This function uses a pure spherical model
// it could be improved to use the WGS84 Datum
// Franck Martin
$lat1rad=deg2rad($lat1);
$lon1rad=deg2rad($lon1);
$lat2rad=deg2rad($lat2);
$lon2rad=deg2rad($lon2);
$distance=6367*acos(sin($lat1rad)*sin($lat2rad)+cos($lat1rad)*cos($lat2rad)*cos($lon1rad-$lon2rad));
return($distance);
}
/**
* returns a list of usergroups where the user is a member and the group has the right perm
* sir-b
**/
function get_groups_to_user_with_permissions($user,$perm) {
$userid = $this->get_user_id($user);
$query = "SELECT DISTINCT `users_usergroups`.`groupName` AS `groupName`";
$query.= "FROM `users_grouppermissions`, `users_usergroups` ";
$query.= "WHERE `users_usergroups`.`userId` = ? AND ";
$query.= "`users_grouppermissions`.`groupName` = `users_usergroups`.`groupName` AND ";
$query.= "`users_grouppermissions`.`permName` = ? ";
$query.= "ORDER BY `groupName`";
$result = $this->query($query, array((int)$userid, $perm));
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res;
}
return $ret;
}
function other_value_in_tab_line($tab, $valField1, $field1, $field2) {
foreach ($tab as $line) {
if ($line[$field1] == $valField1)
return $line[$field2];
}
}
function attach_file($file_name, $file_tmp_name, $store_type) {
global $prefs;
$tmp_dest = $prefs['tmpDir'] . "/" . $file_name.".tmp";
if (!move_uploaded_file($file_tmp_name, $tmp_dest))
return array("ok"=>false, "error"=>tra('Errors detected'));
$fp = fopen($tmp_dest, "rb");
$data = '';
$fhash = '';
$chunk = '';
if ($store_type == 'dir') {
$fhash = md5($name = $file_name.date('U'));
$fw = fopen($prefs['w_use_dir'].$fhash, "wb");
if (!$fw)
return array("ok"=>false, "error"=>tra('Cannot write to this file:').$fhash);
}
while(!feof($fp)) {
$chunk = fread($fp, 8192*16);
if ($store_type == 'dir') {
fwrite($fw, $chunk);
}
$data .= $chunk;
}
fclose($fp);
unlink($tmp_dest);
if ($store_type == 'dir') {
fclose($fw);
$data = "";
}
return array("ok"=>true, "data"=>$data, "fhash"=>$fhash);
}
/* to get the length of a data without the quoted part (very approximative) */
function strlen_quoted($data) {
global $prefs;
$data = preg_replace('/{QUOTE\([^\)]*\)}.*{QUOTE}/Ui', '', $data);
if ($prefs['feature_use_quoteplugin'] != 'y') {
$data = preg_replace('/^>.*\\n?/m', '', $data);
}
return strlen($data);
}
function list_votes($id, $offset=0, $maxRecords=-1, $sort_mode='user_asc', $find='', $table='', $column='') {
$mid = 'where `id`=?';
$bindvars[] = $id;
$select = '';
$join = '';
if (!empty($find)) {
$mid .= " and `user` like ?";
$bindvars[] = '%'.$find.'%';
}
if (!empty($table) && !empty($column)) {
$select = ", `$table`.`$column` as title";
$join = "left join `$table` on (`tiki_user_votings`.`optionId` = `$table`.`optionId`)";
}
$query = "select * $select from `tiki_user_votings` $join $mid order by ".$this->convert_sortmode($sort_mode);
$query_cant = "select count(*) from `tiki_user_votings` $mid";
$result = $this->query($query, $bindvars, $maxRecords, $offset);
$cant = $this->getOne($query_cant, $bindvars);
$ret = array();
while ($res = $result->fetchRow()) {
$ret[] = $res;
}
$retval = array();
$retval["data"] = $ret;
$retval["cant"] = $cant;
return $retval;
}
/* get explicit message on upload problem */
function uploaded_file_error($iError) {
switch($iError) {
case 0: return tra('You are not allowed to upload this type of file.');
case 1: return tra('Cannot upload this file maximum upload size exceeded').'(upload_max_filesize)';
case 2: return tra('Cannot upload this file maximum upload size exceeded');
case 3: return tra('The file you are trying upload was only partially uploaded.');
case 4: return tra('You must select a file.');
default: return tra('The file you are trying upload was only partially uploaded.');
}
}
function get_flags($with_names = false, $translate = false, $sort_names = false) {
$flags = array();
$h = opendir("img/flags/");
while ($file = readdir($h)) {
if (strstr($file, ".gif")) {
$parts = explode('.', $file);
$flags[] = $parts[0];
}
}
closedir ($h);
sort($flags);
if ( $with_names ) {
$ret = array();
foreach ( $flags as $f ) {
$ret[$f] = strtr($f, '_', ' ');
if ( $translate ) {
$ret[$f] = tra($ret[$f]);
}
}
if ( $sort_names ) {
asort($ret, SORT_STRING);
}
return $ret;
}
return $flags;
}
function get_snippet($data, $is_html='n', $highlight='', $length=240) {
global $prefs;
if ($prefs['search_parsed_snippet'] == 'y') {
$_REQUEST['redirectpage'] = 'y'; //do not interpret redirect
$data = $this->parse_data($data, $is_html);
$data = strip_tags($data);
}
return substr($data, 0, $length);
}
function htmldecode($string, $quote_style = ENT_COMPAT, $translation_table = HTML_ENTITIES) {
if ( $translation_table == HTML_ENTITIES && version_compare(phpversion(), '5', '>=') ) {
// Use html_entity_decode with UTF-8 only with PHP 5.0 or later, since
// this function was available in PHP4 but _without_ multi-byte charater sets support
$string = html_entity_decode($string, $quote_style, 'utf-8');
} elseif ( $translation_table == HTML_SPECIALCHARS && version_compare(phpversion(), '5.1.0', '>=') ) {
// Only available in PHP 5.1.0 or later
$string = htmlspecialchars_decode($string, $quote_style);
} else {
// For compatibility purposes with php < 5
$trans_tbl = array_flip(get_html_translation_table($translation_table));
// Not translating double quotes
if ($quote_style & ENT_NOQUOTES) {
// Remove double quote from translation table
unset($trans_tbl['"']);
}
$string = strtr($string, $trans_tbl);
if (function_exists('recode_string')) {
$string = recode_string('iso-8859-15..utf-8', $string);
}
}
$string = preg_replace('~([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
$string = preg_replace('~([0-9]+);~e', 'chr(\\1)', $string);
return $string;
}
function take_away_accent($str) {
$accents = explode(' ', 'À Á Â Ã Ä Å Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ù Ú Û Ü Ý ß à á â ã ä å ç è é ê ë ì í î ï ñ ò ó ô õ ö ù ú û ü ý Æ æ');
$convs = explode(' ', 'A A A A A A C E E E E I I I I D N O O O O O U U U U Y s a a a a a a c e e e e i i i i n o o o o o u u u u y AE ae');
return str_replace($accents, $convs, $str);
}
/* return the positions in data where the hdr-nth header is find
*/
function get_wiki_section($data, $hdr) {
$start = 0;
$end = strlen($data);
$lines = explode("\n", $data);
$header = 0;
for ($i = 0; $i < count($lines); ++$i) {
if (substr($lines[$i], 0, 1) == '!') {
++$header;
if ($header == $hdr) { // we are on it - now find the next header at same or lower level
$level = $this->how_many_at_start($lines[$i], '!');
$end = strlen($lines[$i]) + 1;
for (++$i; $i < count($lines); ++$i) {
if (substr($lines[$i], 0, 1) == '!' && $level >= $this->how_many_at_start($lines[$i], '!')) {
return (array($start, $end));
}
$end += strlen($lines[$i]) + 1;
}
break;
}
}
$start += strlen($lines[$i]) + 1;
}
return (array($start, $end));
}
}
// end of class ------------------------------------------------------
// function to check if a file or directory is in the path
// returns FALSE if incorrect
// returns the canonicalized absolute pathname otherwise
function inpath($file,$dir) {
$realfile=realpath($file);
$realdir=realpath($dir);
if (!$realfile) return (FALSE);
if (!$realdir) return (FALSE);
if (substr($realfile,0,strlen($realdir))!= $realdir) {
return(FALSE);
} else {
return($realfile);
}
}
function compare_links($ar1, $ar2) {
return $ar1["links"] - $ar2["links"];
}
function compare_backlinks($ar1, $ar2) {
return $ar1["backlinks"] - $ar2["backlinks"];
}
function r_compare_links($ar1, $ar2) {
return $ar2["links"] - $ar1["links"];
}
function r_compare_backlinks($ar1, $ar2) {
return $ar2["backlinks"] - $ar1["backlinks"];
}
function compare_images($ar1, $ar2) {
return $ar1["images"] - $ar2["images"];
}
function r_compare_images($ar1, $ar2) {
return $ar2["images"] - $ar1["images"];
}
function compare_files($ar1, $ar2) {
return $ar1["files"] - $ar2["files"];
}
function r_compare_files($ar1, $ar2) {
return $ar2["files"] - $ar1["files"];
}
function compare_versions($ar1, $ar2) {
return $ar1["versions"] - $ar2["versions"];
}
function r_compare_versions($ar1, $ar2) {
return $ar2["versions"] - $ar1["versions"];
}
function compare_changed($ar1, $ar2) {
return $ar1["lastChanged"] - $ar2["lastChanged"];
}
function r_compare_changed($ar1, $ar2) {
return $ar2["lastChanged"] - $ar1["lastChanged"];
}
function chkgd2() {
if (!isset($_SESSION['havegd2'])) {
# TODO test this logic in PHP 4.3
# if (version_compare(phpversion(), "4.3.0") >= 0) {
# $_SESSION['havegd2'] = true;
# } else {
ob_start();
phpinfo (INFO_MODULES);
$_SESSION['havegd2'] = preg_match('/GD Version.*2.0/', ob_get_contents());
ob_end_clean();
# }
}
return $_SESSION['havegd2'];
}
function detect_browser_language() {
// Get supported languages
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
$supported = preg_split('/\s*,\s*/', preg_replace('/;q=[0-9.]+/','',$_SERVER['HTTP_ACCEPT_LANGUAGE']));
else
return '';
// Get available languages
$available = array();
$available_aprox = array();
if (is_dir("lang")) {
$dh = opendir("lang");
while ($lang = readdir($dh)) {
if (!strpos($lang,'.') and is_dir("lang/$lang") and file_exists("lang/$lang/language.php")) {
$available[strtolower($lang)] = $lang;
$available_aprox[substr(strtolower($lang), 0, 2)] = $lang;
}
}
}
// Check better language
// Priority has been changed in 2.0 to that defined in RFC 4647
$aproximate_lang = '';
foreach ($supported as $supported_lang) {
$lang = strtolower($supported_lang);
if (in_array($lang, array_keys($available))) {
// exact match is always good
return $available[$lang];
} elseif (in_array($lang, array_keys($available_aprox))) {
// otherwise if supported language matches any available dialect, ok also
return $available_aprox[$lang];
} elseif ($aproximate_lang == '') {
// otherwise if supported dialect matches language, store as possible fallback
$lang = substr($lang, 0, 2);
if (in_array($lang, array_keys($available_aprox))) {
$aproximate_lang = $available_aprox[$lang];
}
}
}
return $aproximate_lang;
}
if (!function_exists('file_get_contents')) {
function file_get_contents($f) {
if (is_file($f)) {
ob_start();
$retval = @readfile($f);
if (false !== $retval) { // no readfile error
$retval = ob_get_contents();
}
ob_end_clean();
return $retval;
} else {
return false;
}
}
}
/**
* Replace floatval()
*
* Borrowed from PEAR:PHP_Compat
* @author David Irvine
* @author Aidan Lister
*/
if (!function_exists('floatval')) {
function floatval($var) {
return (float) $var;
}
}
function alterprefs() {
global $tikilib;
if (!$tikilib->query( "ALTER TABLE `tiki_preferences` MODIFY `value` BLOB", array())) {
$smarty->assign("msg", tra('Altering database table failed'));
$smarty->display("error.tpl");
die;
}
return true;
}
function validate_email($email,$checkserver='n') {
$valid_syntax = eregi("^[_a-z0-9\+\.\-]+@[_a-z0-9\.\-]+\.[a-z]{2,4}$",$email);
if (!$valid_syntax) {
return false;
} elseif ($checkserver == 'y') {
include_once('Net/DNS.php');
$resolver = new Net_DNS_Resolver();
$domain = substr(strstr($email,'@'),1);
$answer = $resolver->query($domain,'MX');
if (!$answer) {
return false;
} else {
foreach ($answer->answer as $server) {
$mxserver[$server->preference] = $server->exchange;
}
krsort($mxserver);
foreach ($mxserver as $server) {
$test = fsockopen($server,25,$errno,$errstr,15);
if ($test) {
fclose($test);
return true;
}
fclose($test);
}
return false;
}
} else {
return true;
}
}
function tiki_get_remote_file( $url )
{
if( ini_get( 'allow_url_fopen' ) )
return file_get_contents( $url );
elseif( function_exists( 'curl_init' ) )
{
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_HEADER, false );
curl_setopt( $ch, CURLOPT_NOBODY, false );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
return curl_exec( $ch );
}
else
return false;
}
/* Editor configuration
Local Variables:
tab-width: 4
c-basic-offset: 4
End:
* vim: fdm=marker tabstop=4 shiftwidth=4 noet:
*/
?>