📄 lib_lace.php
字号:
<?php/* * 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., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//** * userList() * * Returns a JSON or HTML representation of * the current User List */function userList($json = false){ global $A; $users = $A->getUsers(); $output = ''; if ($json === false) { foreach ($users as $name) { $output .= '<li>'.$name.'</li>'; } return $output; } $userHash = postVar('userHash', false); $hash = $A->getHash(); if ($userHash === $hash) { $output = '"user":{"nodata":"1"}'; } else { $output = '['; foreach($users as $name) { $output .= '"'.addslashes(mb_substr($name, 0, 10)).'",'; } $output = rtrim($output, ','); $output .= ']'; $output = '"user":{"hash":"'.$hash.'","data":'.$output.',"userHash":"'.$userHash.'"}'; } return $output;}/** * joinMessage() * * Add a user join message to the log */function joinMessage($name){ if (LACE_SHOW_JOIN_PART) { global $A; if($name && false === $A->keyExists($name)) { $message = array ( 'action' => true, 'time' => time(), 'name' => 'Lace', 'text' => '<strong>'.$name.'</strong> joins the conversation', ); addMessage($message); } }}/** * isFlooding() * * Determine whether a user is flooding */function isFlooding(){ $postCount = cookieVar(LACE_FLOOD_COOKIE); if ($postCount === false) { setCookie(LACE_FLOOD_COOKIE, '1', time() + 9, LACE_URL_REL); return false; } setCookie(LACE_FLOOD_COOKIE, ++$postCount, time() + 9, LACE_URL_REL); if ($postCount > LACE_FLOOD_POST_COUNT) { return true; } return false;}/** * laceListener() * * Checks POST variables for incoming messages or * update requests. */function laceListener($fromListener = true){ $cookie_name = cookieVar(LACE_NAME_COOKIE, false); $post_name = postVar('name', false); // name $post_text = postVar('text', false); // text if ($post_name !== false && $post_text !== false) { if (validateSession() === false) return '"chat":{"nodata":"1"}'; if (isFlooding() === true) return '"chat":{"nodata":"1"}'; $message = prepareMessage($post_name, $post_text); if ($message !== false) { if ($cookie_name && $cookie_name != $post_name) { addNameChange($cookie_name, $post_name); } else { global $A; // Activity object joinMessage($post_name); $A->update($post_name); } // Reset $name just in case it has been changed global $name; $name = $post_name; setcookie(LACE_NAME_COOKIE, $post_name, time() + 259200, LACE_URL_REL); addMessage($message); } } if ($fromListener) { $chatHash = postVar('chatHash', false); if ($chatHash) { $hash = getMessageHash(); if (validateSession() === false || $chatHash == $hash) { return '"chat":{"nodata":""}'; } $json = '"chat":{"hash":"'.$hash.'","data":"'; $json.= addslashes(str_replace("\n", "", printFileContentsHTML())).'"}'; return $json; } return '"chat":{"nodata":""}'; } return '"chat":{"nodata":""}';}/** * getMessageHash() * * Hash the main file for detecting changes */function getMessageHash(){ // hash the main file if (LACE_HASH_MD5 === true) return md5(file_get_contents(LACE_FILE)); else { clearstatcache(); return filemtime(LACE_FILE).':'.filesize(LACE_FILE); }}/** * getFileContentsRaw() * * Retrieve raw file contents as one giant string * (Why? You can't pass arrays between PHP and Javascript, * unless you use something like PHP-JSON/JSON-PHP, of course.) */function getFileContentsRaw($file = LACE_FILE){ $today = date('l'); $dayString = ''; $hourString = ''; $finalOutput = ''; // Read the file $fileContents = file($file); if(is_array($fileContents) && count($fileContents) > 0) { // We want logfiles in reverse order. if ($file != LACE_FILE) $fileContents = array_reverse($fileContents); // Create the proper HTML for each line foreach ($fileContents as $line) { if (0 == preg_match("/^(\d{10})\|\|(.+?)\|\|(.+?)$/", $line)) continue; // Turn the record into an array full of info $line = extractMessageArray($line); $output = ''; // Check for new Day if ($file == LACE_FILE) { if ($line['day'] != $dayString) { $first = ($dayString == '') ? '*' : ''; $dayString = $line['day']; $output .= 'date-'.$line['timestamp'].'||'; $output .= $first.$line['date_full'].'||||'; } } else { // Logfiles don't have multiple days if($hourString == '') $output .= 'date||*' . $line['date_full'] . '||||'; } // Check for new Hour if ( ($file == LACE_FILE && $line['day'] == $today && $line['hour'] != $hourString) || ($file != LACE_FILE && $line['hour'] != $hourString) ) { $first = ($hourString == '') ? '*' : ''; $hourString = $line['hour']; $output .= 'hour-'.$line['hour'].'||'.$first.$hourString.':00||||'; } // Check for Action $action = ($line['action']) ? '*' : ''; $timestr = ($file == LACE_FILE) ? 'Posted about '.$line['age'].' ago at '.$line['time'] : $line['time']; $output .= $line['timestamp'].'||'.$timestr.'||'.$action.$line['name']; $output .= '||'.$line['text'].'||||'; $finalOutput .= $output; } } else // $fileContents array is empty { $finalOutput .= 'date||*' . date('l, d F Y') . '||||'; $finalOutput .= time() . '|| ||!Lace||'; $welcome = ($file == LACE_FILE) ? 'Welcome to '.LACE_SITE_NAME.'. No one has said anything yet.' : 'The current log is empty.'; $finalOutput .= (file_exists($file)) ? $welcome : 'Sorry, the file you asked for doesn\'t exist.'; } return rtrim($finalOutput, '|');}/** * printFileContentsHTML() * * Grab the files's contents and format it with HTML * all in one step. */function printFileContentsHTML($file = LACE_FILE) { return formatFileContents(getFileContentsRaw($file));}/** * formatFileContents() * * Wrap raw file contents in HTML for display */function formatFileContents($rawFileContents){ // break apart the file contents into records $items = explode('||||', $rawFileContents); $count = count($items); $output = ''; for ($i = 0; $i < $count; $i++) { // break record into fields $fields = explode('||', $items[$i]); if (mb_substr($fields[0], 0, 4) == 'date') { // show a date heading // fields[0] = id attribute // fields[1] = date string (a * prefix denotes that it's // class attribute is 'first') $first = ($fields[1]{0} == '*'); $class = ($first) ? ' class="daystamp first"' : ' class="daystamp"'; $date = ($first) ? mb_substr($fields[1], 1) : $fields[1]; $output .= '<div' . $class . '><h4>'.$date.'</h4></div>'."\n"; continue; } if (mb_substr($fields[0], 0, 4) == 'hour') { if (LACE_SHOW_HOUR === true) { // show the hourly timestamp // fields[0] = id attribute // fields[1] = hour string (a * prefix denotes that it's // class attribute is 'first') $first = ($fields[1]{0} == '*'); $class = ($first) ? ' class="hourstamp first"' : ' class="hourstamp"'; $hour = ($first) ? mb_substr($fields[1], 1) : $fields[1]; // Message id attributes sometimes were non-unique because the messages shared // the same timestamp. Until a solution is found - and one may not be necessary - // the id is simply ignored and is not needed. (Also helps keep XHTML valid) //$output .= '<div id="' . $fields[0] . '"' . $class . '><h5>' . $hour . '</h5></div>'."\n"; $output .= '<div' . $class . '><h5>' . $hour . '</h5></div>'."\n"; } continue; } // show the message // $fields[0] = id attribute // $fields[1] = time string // $fields[2] = name (a * prefix denotes an action, a ! denotes a system notice) // $fields[3] = text $action = ($fields[2]{0} == '*'); $notice = ($fields[2]{0} == '!'); $name = ($action || $notice) ? mb_substr($fields[2], 1) : $fields[2]; // A system message is defined by an action by the user Lace $system = ($action && $name == 'Lace'); $class = ($action && !$system) ? 'message action' : 'message'; // Build up message HTML $output .= '<p'; $output .= ($notice) ? ' class="notice"' : ''; $output .= ($system) ? ' class="system"' : ''; $output .= '><span class="name">'; $output .= ($action && !$system) ? ' ' : $name.' <a title="'.$fields[1].'">::</a> '; $output .= '</span><span class="' . $class . '">'; $output .= ($action && !$system) ? '<a title="'.$fields[1].'">'.$name.'</a> ' : ''; $output .= $fields[3] . '</span></p>' . "\n"; } return $output;}/** * getName() * * Attempt to find a user's name in the $_POST * and $_COOKIE variables */function getName(){ // Look for the name in $_POST then in // $_COOKIE, or give a new generic name if (array_key_exists('name', $_POST) && mb_strlen(trim($_POST['name'])) > 0) { $name = urldecode($_POST['name']); setcookie(LACE_NAME_COOKIE, $name, time()+3600*24*30, LACE_URL_REL); } else $name = cookieVar(LACE_NAME_COOKIE, 'Guest ' . mb_substr(rand(0,9999), 0, 4)); return $name;}/** * extractMessageArray() * * Convert a record from the data file * into a usable array of data */function extractMessageArray($line){ $linearray = explode('||', $line); // Snag the unix timestamp and perform some date calculations $datetime = array_shift($linearray); // Time elapsed (e.g. 1.5 hours, 4 days, etc.) $age = duration_str(time() - $datetime, false, 2); // Long format date $date_full = date("l, d F Y", $datetime); // Short format date $date = date('m/d/Y', $datetime); // Time of day $time = date('H:i', $datetime); // Day of week $day = date('l', $datetime); // Hour $hour = date('H', $datetime); // Next snag the name $name = array_shift($linearray); // Check for action or system notice $action = ($name{0} == '*') ? true : false; $notice = ($name{0} == '!') ? true : false; if ($action || $notice) $name = mb_substr($name, 1); // Now put the post back together $words = trim(implode(' ', $linearray)); // return this mess of info return array ( 'timestamp' => $datetime, 'date_full' => $date_full, 'date' => $date, 'time' => $time, 'day' => $day, 'hour' => $hour, 'age' => $age, 'action' => $action,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -