*/ class helper_plugin_xfortune extends Plugin { /** * Get a random cookie properly escaped * * @param string $cookieID the media file id to the cookie file * @param int $maxlines * @return string */ public static function getCookieHTML($cookieID, $maxlines = 0, $maxchars = 0) { if ($maxlines) { $cookie = self::getSmallCookie($cookieID, $maxlines, $maxchars); } else { $cookie = self::getCookie($cookieID); } return nl2br(hsc($cookie)); } /** * Tries to find a cookie with a maximum number of lines * * gives up after a 100 tries * * @param $cookieID * @param int $maxlines maximum lines to return * @return string */ public static function getSmallCookie($cookieID, $maxlines, $maxchars) { $runaway = 100; $tries = 0; if ($maxlines < 1) $maxlines = 1; if ($maxchars < 1) $maxlines = 250; do { $cookie = self::getCookie($cookieID); $lines = count(explode("\n", $cookie)); } while (($lines > $maxlines || strlen($cookie) > $maxchars) && $tries++ < $runaway); return $cookie; } /** * Get a file for the given ID * * If the ID ends with a colon a namespace is assumed and a random txt file is picked from there * * @param $cookieID * @return string * @throws Exception */ public static function id2file($cookieID) { $file = mediaFN($cookieID); $isns = is_dir($file); if ($isns) $cookieID .= ':dir'; if (auth_quickaclcheck($cookieID) < AUTH_READ) throw new Exception("No read permissions for $cookieID"); if ($isns) { $dir = $file; $files = glob("$dir/*.txt"); if (!count($files)) throw new Exception("Could not find fortune files in $cookieID"); $file = $files[array_rand($files)]; } // we now should have a valid file if (!file_exists($file)) throw new Exception("No fortune file at $cookieID"); return $file; } /** * Returns one random cookie * * @param string $cookieID the media file id to the cookie file * @return string */ public static function getCookie($cookieID) { try { $file = self::id2file($cookieID); } catch (Exception $e) { return 'ERROR: ' . $e->getMessage(); } $dim = filesize($file); if ($dim < 2) return "ERROR: invalid cookie file $file"; mt_srand((double) microtime() * 1000000); $rnd = mt_rand(0, $dim); $fd = fopen($file, 'r'); if (!$fd) return "ERROR: reading cookie file $file failed"; // jump to random place in file fseek($fd, $rnd); $text = ''; $cookie = false; while (true) { $seek = ftell($fd); $line = fgets($fd, 1024); if ($seek == 0) { // start of file always starts a cookie $cookie = true; if ($line == "%\n") { // ignore delimiter if exists continue; } else { // part of the cookie $text .= $line; continue; } } if (feof($fd)) { if ($cookie) { // we had a cookie already, stop here break; } else { // no cookie yet, wrap around fseek($fd, 0); continue; } } if ($line == "%\n") { if ($cookie) { // we had a cookie already, stop here break; } elseif ($seek == $dim - 2) { // it's the end of file delimiter, wrap around fseek($fd, 0); continue; } else { // start of the cookie $cookie = true; continue; } } // part of the cookie? if ($cookie) { $text .= $line; } } fclose($fd); $text = trim($text); // if it is not valid UTF-8 assume it's latin1 if (!Clean::isUtf8($text)) return utf8_encode($text); return $text; } }