ejabberd-contrib/jorge/func.php

933 lines
21 KiB
PHP

<?
/*
Jorge - frontend for mod_logdb - ejabberd server-side message archive module.
Copyright (C) 2009 Zbigniew Zolkiewski
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
if (__FILE__==$_SERVER['SCRIPT_FILENAME']) {
header("Location: index.php?act=logout");
exit;
}
function get_user_agent($_SERVER) {
if (preg_match("/Macintosh/i",$_SERVER['HTTP_USER_AGENT'])) {
return true;
}
else{
return false;
}
return false;
}
function getmicrotime(){
list($usec, $sec) = explode(" ",microtime());
return ((float)$usec + (float)$sec);
}
function query_nick_name($ejabberd_roster,$talker, $server="") {
$nickname = $ejabberd_roster->get_nick("$talker"."@"."$server");
if ($nickname=="") {
$nickname=$talker;
}
return $nickname;
}
function validate_date($tslice) {
list($ye, $mo, $da) = split("-", $tslice);
return checkdate($mo,$da,$ye);
}
function check_registered_user ($sess,$ejabberd_rpc,$enc) {
if (!$sess->is_registered('uid_l') OR !$sess->is_registered('uid_p')) {
return false;
}
else {
if ($enc->decrypt_url($sess->get('uid_p')) === true) {
$uid_p = $enc->single;
}
else {
return false;
}
$ejabberd_rpc->set_user($sess->get('uid_l'),$uid_p);
if ($ejabberd_rpc->auth() === true) {
return true;
}
else {
return false;
}
}
return false;
}
function is_query_from($query) {
list($from,$talker,$query_p) = split(":",$query);
$from=trim($from);
if ($from=="from") {
$qquery[from] = "t";
$qquery[talker] = trim($talker);
$qquery[talker] = str_replace("//","@",$qquery[talker]); // hack for parametrized search
if ($query_p) {
$qquery[query] = $query_p;
$qquery[words] = "t";
return $qquery;
}
else {
$qquery[words] = "f";
return $qquery;
}
}
else {
// normal search
return "f";
}
}
function verbose_date($raw_date,$months_names = null,$weekdays = null,$t = false,$y = false) {
// English calendar arrays. Here we convert names from english calendar to other language. Make sure your locale in php work with default set to english.
$english_months = array("January","February", "March", "April", "May","June","July","August","September","October", "November","December");
$english_days = array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
// Various formats
if ($t === true) {
return str_replace($english_days,$weekdays,strftime("%e.%m (%A)",strtotime("$raw_date")));
}
elseif($y === true) {
return str_replace($english_months,$months_names,strftime("%B %Y", strtotime("$raw_date")));
}
else{
return str_replace($english_months,$months_names,strftime("%e %B %Y", strtotime("$raw_date")));
}
}
function validate_start($start) {
if (!ctype_digit($start)) {
return false;
}
if (fmod($start,10)=="0") {
return true;
}
else {
return false;
}
}
function db_size() {
$result = mysql_query("show table status");
$size = 0;
while($row = mysql_fetch_array($result)) {
$size += $row["Data_length"];
}
$size = round(($size/1024)/1024, 1);
return $size;
}
function verbose_split_line($in_minutes,$verb_h,$in_min) {
if ($in_minutes>60) {
return $verb_h;
}
elseif ($in_minutes<60) {
return $in_minutes." ".$in_min;
}
}
function cut_nick($nick) {
if (strlen($nick)> 25) {
$nick=substr($nick,0,25)."...";
}
return $nick;
}
function new_parse_url($text) {
$text = ereg_replace("([[:alpha:]]+://www|[[:alpha:]]+://)[^<>[:space:]]+[[:alnum:]/]",
"<a class=\"clickl\" href=\"\\0\" target=\"_blank\">\\0</a>", $text);
// disabled for now
#$text = ereg_replace("[^://]?www[^<>[:space:]]+[[:alnum:]/]",
# "<a class=\"clickl\" href=\"http://\\0\" target=\"_blank\">\\0</a>", $text);
return $text;
}
function calendar($db,$user_id,$xmpp_host,$y,$m,$days,$token,$url_key,$left,$right,$selected,$lang,$view_type,$c_type,$name_peer=0,$server_peer=0,$cal_days=0,$enc=null,$months_names,$weekdays) {
$days=$days;
$month = $m;
$year = $y;
//create arrays for the calendar
$months_days = array("31","28","31","30","31","30","31","31",
"30","31","30","31");
$days_array = array("Mon","Tue","Wed","Thu","Fri","Sat","Sun");
//removes the 0 from start of month - can't find array key with 0
if(strlen($month)==1){
$month= str_replace("0","",$month);
}
else{
$month=$month;
}
//reset month to the array key match (array starts at 0)
$month= $month-1;
//find the days in the month
$days_in_month = $months_days[$month];
//$m is used to find month
$m = $month+1;
//find the first day of the month
$time = date("M D Y H:i:s", mktime(0, 0, 0, $m, 1, $year));
$first_day = explode(" ",$time);
$time = $first_day[1];
//create the links to next and previous months
$next = $month+2;
$x = $year;
//if month is 13 then new year
if($next==13){
$next=1;
$x = $x+1;
}
$prev = $month;
$y = $year;
//if month is 0, then previous year
if($prev==0){
$prev=12;
$y=$y-1;
}
$calendar = "";
//Build the calendar with css
//links to next and previous month only for browser
if ($c_type=="1") {
// encode links
$link_left = $enc->crypt_url("tslice=$y-$prev");
$link_right = $enc->crypt_url("tslice=$x-$next");
// check if we have chats in prev and next mo
$db->is_left_or_right("$y-$prev");
$i_left = $db->result;
$db->is_left_or_right("$x-$next");
$i_right = $db->result;
}
else {
$i_left=0;
$i_right=0;
}
$calendar .='
<table width="200" border="0" cellpadding="0" cellspacing="0" class="calbck">
<tr>
<td><img src="img/cal_corn_11.png" width="15" height="7" alt="cal_img"></td>
<td style="background-image: url(img/cal_bck_top.gif);"></td>
<td><img src="img/cal_corn_12.png" width="14" height="7" alt="cal_img"></td>
</tr>
<tr>
<td width="15" valign="top" class="calbckleft"><img src="img/cal_bck_left.png" width="15" height="116" alt="cal_img">
</td>
<td width="100%" valign="top">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td height="15" align="center" class="caldays">
';
if ($i_left!=0) { $calendar.='<a href="?left='.$link_left.'"><<<</a>'; }
$verb_date = "$year-$m-1";
$calendar.='
&nbsp;</td>
<td colspan="5" align="center" class="calhead">'.verbose_date($verb_date,$months_names,$weekdays,false,true).'</td>
<td align="center" class="caldays">&nbsp;
';
if ($i_right!=0) { $calendar.='<a href="?right='.$link_right.'">>>></a>'; }
$calendar.='
</td>
</tr>
<tr align="center" class="calweek">
<td width="14%" height="15">'.$cal_days[$lang][1].'</td>
<td width="14%">'.$cal_days[$lang][2].'</td>
<td width="14%">'.$cal_days[$lang][3].'</td>
<td width="14%">'.$cal_days[$lang][4].'</td>
<td width="14%">'.$cal_days[$lang][5].'</td>
<td width="14%">'.$cal_days[$lang][6].'</td>
<td width="14%">'.$cal_days[$lang][7].'</td>
</tr>
';
//checks for leap years and add 1 to February
if(($year % 4 =="") && ($month==1)){
$days_in_month=$days_in_month+1;
}
else{
$days_in_month=$days_in_month;
}
$new_time="";
//find how many blank spaces at beginning of the month
foreach($days_array as $key=>$value){
if($value == $time){
$new_time .= $key+1;
}
else{
$new_time .="";
}
}
//loop through the days in the month
$c=0;
for($k=1;$k<($days_in_month+$new_time);$k++){
$c++;
if ($c==1) { $calendar.='<tr align="center" class="caldays">'; }
//blank space
if($k<$new_time){
$calendar.='<td height="15">&nbsp;</td>
';
continue;
}
//start the actual days
$n = $k-$new_time+1;
if(in_array($n,$days)){
if ($c_type=="1") {
$to_base = $enc->crypt_url("tslice=$year-$m-$n");
$loc_orign="";
}
elseif($c_type=="2") {
$to_base = $enc->crypt_url("tslice=$year-$m-$n&peer_name_id=$name_peer&peer_server_id=$server_peer");
$loc_orign="&amp;loc=2";
}
if ($selected==$n) { $bgcolor = 'bgcolor="#6daae7"'; } else { $bgcolor=""; }
$calendar .= '<td height="15" '.$bgcolor.' onclick="window.location=\''.$view_type.'?a='.$to_base.$loc_orign.'\'"><b><a class="caldays2" href="'.$view_type.'?a='.$to_base.$loc_orign.'">'.$n.'</a></b></td>
';
}
else{
$calendar .= '<td height="15">'.$n.'</td>
';
}
if ($c==7) { $calendar.='</tr>'; $c=0; }
}
$calendar .= '
</table>
</td>
<td width="14" valign="top" class="calbckright"><img src="img/cal_bck_right.png" width="14" height="116" alt="cal_img"></td>
</tr>
<tr>
<td><img src="img/cal_corn_21.png" width="15" height="16" alt="cal_img"></td>
<td style="background-image: url(img/cal_bck_bot.png);"></td>
<td><img src="img/cal_corn_22.png" width="14" height="16" alt="cal_img"></td>
</tr>
</table>
';
return($calendar);
}
function check_thread($db,$peer_name_id,$peer_server_id,$at,$xmpp_host,$dir=NULL) {
#adjust this hours as needed, we assume if chat is +/- 1 hour on the edge of day, then chat is related
if ($dir=="1") {
$day="+1 day";
$bhour="00:00:00";
$ehour="00:30:00";
}
elseif($dir=="2"){
$day="-1 day";
$bhour="23:30:00";
$ehour="23:59:59";
}
$get_date = date("Y-n-j", strtotime($day, strtotime(date("$at"))));
$db->check_thread($get_date,$peer_name_id,$peer_server_id,$bhour,$ehour);
if ($db->result > 0) {
return true;
}
else{
return false;
}
return false;
}
function check_rpc_server($rpc_arr,$rpc_port) {
foreach($rpc_arr as $rpc_host) {
// assume if response time is greater then 1 second RPC server is down
$fp=fsockopen("$rpc_host", $rpc_port, $errno, $errstr, 1);
if ($fp!=false) {
return $rpc_host;
}
}
return false;
}
function debug($debug=false,$string) {
if ($debug===true) {
print "<small>".htmlspecialchars($string)."</small><br>";
}
return;
}
function message_processor($tslice,$server_name,$start,$nickname,$result_messages,$db,$html,$enc,$token,$split_line,$lang_pack,$lang,$spec_mark,$e_string,$to_base_prev,$to_base_next) {
/*
This function perform message processing for message archives
tslice - date of chat
server_name - name of server
start - from what point of time of day should chat be displayed
nickname - peer nickname
result_messages - array of messages to be parsed
db - database object
html - html object
enc - encryption object
token - owner name
split_line - config option
lang_pack - array of translations
lang - language pack
spec_mark - marker used to distinguish what we are doing
e_string - url
*/
// Check if user have set up OwnName
$db->get_own_name();
if ($db->result->own_name) {
$own_name = $db->result->own_name;
}
else{
$own_name = false;
}
// Main loop
foreach($result_messages as $entry) {
// always get resource_id if message is type of groupchat
if ($entry[type] !== "groupchat") {
if ($resource_last !== $entry[peer_resource_id]) {
if ($db->get_resource_name($entry[peer_resource_id]) === false) {
return false;
}
$resource = $db->result->resource_name;
}
}
else{
if ($db->get_resource_name($entry[peer_resource_id]) === false) {
return false;
}
$resource = $db->result->resource_name;
}
$resource_last = $entry[peer_resource_id];
$licz++;
// marking messages
if ($entry["type"] === "chat" OR $entry["type"] == "") {
if ($entry["direction"] === "to") {
$col="main_row_a";
}
else {
$col="main_row_b";
}
}
elseif($entry["type"] === "error") {
$col="main_row_error";
}
elseif($entry["type"] === "normal") {
$col="main_row_message";
}
elseif($entry["type"] === "headline") {
$col="main_row_headline";
}
$ts = strstr($entry["ts"], ' ');
// time calc
$pass_to_next = $entry["ts"];
$new_d = $entry["ts"];
$time_diff = abs((strtotime("$old_d") - strtotime(date("$new_d"))));
$old_d = $pass_to_next;
// end time calc
if ($time_diff>$split_line AND $licz>1) {
$in_minutes = round(($time_diff/60),0);
$html->set_body('<tr class="splitl">
<td colspan="7" style="font-size: 10px;"><i>'.verbose_split_line($in_minutes,$lang_pack[7],$lang_pack[8]).'</i>
<hr size="1" noshade="noshade" style="color: #cccccc;"></td></tr>
');
}
// check if chat is continuation from previous day (work only for calendar view)
if ($to_base_prev !== NULL) {
if ($ts_mark!="1" AND substr($ts, 0 , strpos($ts, ":")) == 00 ) {
if ( check_thread($db,$talker,$server,$tslice,$xmpp_host,2) === true) {
$html->set_body('<tr><td colspan="6" style="text-align: left; padding-left: 5px;" class="message"><a href="calendar_view.php?a='.$to_base_prev.'">'.$lang_pack[0].'</a></td></tr>');
}
// check only first line
$ts_mark="1";
}
}
// run code only if type is not groupchat
if ($entry["type"] !== "groupchat") {
// setting subject
if ($col==="main_row_message" OR $col==="main_row_headline") {
if ($entry["subject"]) {
$subject = ": ".$entry["subject"];
}
else{
unset($subject);
}
}
// add line in case of special message
if ($col==="main_row_message") {
$html->set_body('<tr class="main_row_message"><td colspan="7" class="main_row_special">'.$lang_pack[1].' '.htmlspecialchars($subject).'</td></tr>');
}
if ($col==="main_row_error") {
$html->set_body('<tr class="main_row_error"><td colspan="7" class="main_row_special">'.$lang_pack[2].'</td></tr>');
}
if ($col==="main_row_headline") {
$html->set_body('<tr class="main_row_headline"><td colspan="7" class="main_row_special">'.$lang_pack[3].' '.htmlspecialchars($subject).'</td></tr>');
}
}
// calculate chat direction, whether to display nick...
if ($entry["direction"] == "from") {
$out=$nickname;
$tt=$tt+1;
$aa=0;
}
else{
$out = $token;
$aa=$aa+1;
$tt=0;
}
// timestamp, beginning of the chatline
if ($entry["type"] !== "groupchat") {
$html->set_body('<tr class="'.$col.'"><td class="time_chat" style="padding-left: 10px; padding-right: 10px;";>'.$ts.'</td>');
}
else{
if ($out!==$token) {
// colorize
if ($resource_group === $resource OR !$resource_group) {
if (!$col) {
$col = "main_row_group_to";
}
$col=$col;
}
else{
if($col === "main_row_group_from") {
$col="main_row_group_to";
}
else{
$col="main_row_group_from";
}
}
$html->set_body('<tr class="'.$col.'"><td class="time_chat" style="padding-left: 10px; padding-right: 10px;";>'.$ts.'</td>');
}
}
// different bahaviour for groupchat and other messages
if ($entry["type"] !== "groupchat") {
if ($aa<2 AND $tt<2) {
$html->set_body('<td style="padding-left: 5px; padding-right: 10px; nowrap="nowrap">');
if ($out === TOKEN) {
// display of Own Name
if ($own_name !== false) {
$html->set_body(cut_nick(htmlspecialchars($own_name)));
}
else{
$html->set_body(cut_nick(htmlspecialchars($out)));
}
}
else{
$html->set_body(cut_nick(htmlspecialchars($out)));
}
$html->set_body('<a name="'.$licz.'"></a>');
if ($out !== $token) {
if ($spec_mark === false) {
$html->set_body('
<br><div style="text-align: left; padding-left: 5px;">
<a class="export" id="pretty" title="'.$lang_pack[4].'" href="?a='.$e_string.'&amp;b='.$entry[peer_resource_id].'">
<small><i>'.cut_nick(htmlspecialchars($resource)).'</i></small></a></div>
');
}
else{
$html->set_body('<br><div style="text-align: left; padding-left: 5px;">
<small><i>'.cut_nick(htmlspecialchars($server_name)).'</i></small></div>
');
}
}
$html->set_body('</td>');
$here = "1";
}
else {
$html->set_body('<td style="text-align: right; padding-right: 5px">-</td>');
$here = "0";
}
}
else{
// do not display own chats sent to MUC. Here resource is actualy nickname as MUC standard specify
if ($out !== $token) {
if ($resource_group !== $resource) {
// if message is sent without resource, that must be channel message, advise user.
if ($resource === "") {
$resource = $lang_pack[5];
}
$html->set_body('<td style="padding-left: 5px; padding-right: 10px; nowrap="nowrap"><small>MUC: <i>'.cut_nick($out).'</i></small><a name="'.$licz.'"></a>
<br><div style="text-align: left; padding-left: 5px;">'.cut_nick(htmlspecialchars($resource)).'</div></td>
');
$here = "1";
$resource_group = $resource;
}
else{
$html->set_body('<td style="text-align: right; padding-right: 5px">-</td>');
$here = "0";
}
}
else{
$here = "0";
}
}
// process body part, do not show chat if message is type of groupchat
// this is sadly funny i write this 'if' and i dont know what exacly it do :/
if ($out !== $token OR $entry["type"] !== "groupchat") {
// prepare body
$new_s = htmlspecialchars($entry["body"]);
$to_r = array("\n");
$t_ro = array("<br>");
$new_s = str_replace($to_r,$t_ro,$new_s);
$new_s = wordwrap($new_s,107,"<br>",true);
$new_s = new_parse_url($new_s);
$html->set_body('<td width="800" colspan="3">'.$new_s.'</td>');
// generate mylink only on selected lines
if ($here==="1") {
$lnk = $enc->crypt_url("tslice=$tslice&peer_name_id=$entry[peer_name_id]&peer_server_id=$entry[peer_server_id]");
$to_base2 = $enc->crypt_url("tslice=$tslice&peer_name_id=$entry[peer_name_id]&peer_server_id=$entry[peer_server_id]&ismylink=1&linktag=$licz&lnk=$lnk&strt=$start");
$html->set_body('<td colspan="2" style="padding-left: 2px; font-size: 9px;"><a style="color: #1466bc" href="my_links.php?a='.$to_base2.'">'.$lang_pack[6].'</a></td>');
}
else {
$html->set_body('<td></td>');
}
if ($t=2) { $c=1; $t=0; } // WTF!?
$html->set_body('</tr>');
}
}
$html->set_body('</tbody>');
// Check thread. Work only for calendar view.
if ($to_base_next !== NULL) {
if (substr($ts, 0 , strpos($ts, ":")) == 23 AND date("Y-n-j") !== $tslice) {
if ( check_thread($db,$talker,$server,$tslice,$xmpp_host,1) === true) {
$html->set_body('<tr><td colspan="6" style="text-align: right; padding-right: 5px;" class="message"><a href="calendar_view.php?a='.$to_base_next.'">'.$lang_pack[9].'</a></td></tr>');
}
}
}
return true;
}
function is_language_supported($l_query,$language_support,$l_key = 0, $return_val = false) {
while (array_keys($language_support)) {
$lang_key = key($language_support);
if ($l_query === $language_support[$lang_key][$l_key]) {
if ($return_val === true) {
return $language_support[$lang_key][0];
}
else {
return true;
}
}
array_shift($language_support);
}
return false;
}
?>