if AJAX operation succeded * $cause (string) => very quick explanation: " " (ex. "mysql insert user") ** * returns nothing; * > exits execution **/ function respond($success, $cause, $more="") { // respond with normalized JSON format from all files requested by ajax exit(json_encode(array('success'=>$success,'cause'=>$cause,'more'=>$more))); } /** * WORD WRAP FOR UTF-8 STRINGS ** * $str (string) => string to be wrapped * $width (integer) => how often to cut * $break (string) => what to insert in breaks * $cut (boolean) => should function cut words ** * returns cutted string **/ function ww_utf8($str, $width, $break, $cut = false) { // word-wrap for utf-8 text if(!$cut) $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.',}\b#U'; else $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.'}#'; if (function_exists('mb_strlen')) $str_len = mb_strlen($str,'UTF-8'); else $str_len = preg_match_all('/[\x00-\x7F\xC0-\xFD]/', $str, $var_empty); $while_what = ceil($str_len / $width); $i = 1; $return = ''; while($i < $while_what) { preg_match($regexp, $str,$matches); $string = $matches[0]; $return .= $string.$break; $str = substr($str, strlen($string)); $i++; } return $return.$str; } /** * LOGGING FUNCTION ** * $str => string to be logged * $type => type of logging: * - access: all non-error ACTIONS generated by users * - user : same as 'access' * - error : all possible ERRORS generated by users * - admin : all important access/error actions generated by ADMIN ** * returns given string **/ function toLog($str, $type="access", $fid=-1) { // log given string of given type (optional: for given user) // TODO: add error handling !! $log_path = dirname(__FILE__); switch( $type ) { case 'error': $fname = 'err.log'; break; default: case 'access': case 'user': $fname = 'users.log'; break; case 'admin': $fname = 'admin.log'; break; case 'inv': $fname = 'inv.log'; break; } $log_str = date('[Y-m-d H:i:s]') . " " . preg_replace('/\s+/', ' ', str_replace("\n", "", $str))." ip => " . getIP() . ", user-agent => " . $_SERVER['HTTP_USER_AGENT'] . "\n"; // save to general log files $f = fopen($log_path . "/log/" . $fname, "a+"); fwrite($f, $log_str); fclose($f); // save to user log file if($fid != -1 and $fid != "" and ctype_digit($fid)) { $user_log_path = $log_path . '/users-data/' . $fid; if(!file_exists($user_log_path)) mkdir($user_log_path); $g = fopen($user_log_path . '/log_'.$fid.'.log', "a+"); fwrite($g, $log_str); fclose($g); } // return logged string return $str; } /** * GETS CURRENT USER IP ** * returns ip of current user **/ function getIP() { // get IP of current connection; called from toLog $ip = (empty($_SERVER['HTTP_CLIENT_IP']) ? (empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['REMOTE_ADDR'] : $_SERVER['HTTP_X_FORWARDED_FOR']) : $_SERVER['HTTP_CLIENT_IP']); return str_replace("unknown, ", "", $ip); } /** TODO: * - fix counting over 9; * - make more omnipotent; * - use on every picture (at least as a extension checker); * - add date check * - better validate pictures with "_" in name... ** * FUNCTION PUTTING ALWAYS NEWEST VERSION OF REQUESTED PICTURE ** * $name => name of requested picture WITHOUT extension (ex. header, logo100x100) * $rel => states if relative path should be provided ** * returns full path to the newest picture (ex. /images/header_34.jpeg, /images/logo100x100.png) **/ function getPic($name, $rel = true) { // gets file of given name with highest index ex. "kakao_3.jpg" $img_dir = "../images/"; $empty_img = ""; if(($files = @scandir($img_dir,1))===false) { // not critical; it's just a pic; no exit() requied toLog("Error while retreiving contents of '$name'. ", 'error'); return $empty_img; } foreach($files as $file) if(strpos($file, $name.'_') !== false or strpos($file, $name) !== false) return (($rel) ? $img_dir : "images/") . $file; return $empty_img; } /** * CONVERTS TIME GIVEN IN SECONDS INTO WELL FORMATTED STRING IN CURRENT LANGUAGE ** * $seconds => number of seconds since some event ** * returns nationalised, human-readable string of time passed since this event **/ function howLongAgo( $seconds ) { global $F; if( $seconds<60 ) return $seconds . $F['entryAgoSeconds']; elseif ($seconds>=60 && $seconds<120 ) return $F['entryAgoMinute']; elseif ($seconds>=120 && $seconds<3600 ) return round($seconds/60) . $F['entryAgoMinutes']; elseif ($seconds>=3600 && $seconds<7200 ) return $F['entryAgoHour']; elseif ($seconds>=7200 && $seconds<86400 ) return round($seconds/(60*60)) . $F['entryAgoHours']; elseif ($seconds>=86400 && $seconds<172800) return $F['entryAgoDay']; elseif ($seconds>=172800 && $seconds<604800) return round($seconds/(60*60*24)) . $F['entryAgoDays']; else return $F['entryAgoMore']; } // TODO: if voting enabled: add info sbout it on each entry. view_chat(every_entry) + view_panels(large_view) /** * RETURNS STRING CONTAINING HTML OF REQUESTED POSTS IN FORM OF CHAT_VIEW ** * ** * **/ function view_chat( $start_from = 9999999, $count = 8, $skip_entry = 0, $visible = false, $fid = "" ) { global $F, $furl, $app_secret,$db_prefix, $protocol; $added = 0; if(!in_array($fid, $GLOBALS['mods'])) { $e_hidden = "e.hidden = 0 AND"; $w_hidden = "WHERE hidden = 0"; } else $e_hidden = $w_hidden = ""; // retreive all posts from mysql according to given parameters $sql = "SELECT *, TIMESTAMPDIFF(second,e.date_added,current_timestamp()) AS e_age FROM " . $db_prefix . "users AS u, " . $db_prefix . "entries AS e WHERE " . $e_hidden . " eid != $skip_entry AND e.eid < $start_from AND e.fid = u.fid ORDER BY eid DESC LIMIT " . $count . ";"; $result = mysql_query($sql); if(mysql_error()) toLog('MySQL error while "'.$sql.'", post: '.print_r($_POST), 'error', $fid); // print all the posts from a set in $result while($row = mysql_fetch_assoc($result)): $added = $row['eid']; ?>