Exemple #1
0
function snitch_read($owner, $threshhold)
{
    if (!$threshhold) {
        $threshhold = '2dr';
    }
    $writer = $_SERVER['USER'];
    if ($_SERVER['USER'] == $owner) {
        if ($threshhold == 'r' . $_SERVER['USERINFO_ARRAY']['snitch_default_days'] . 'd') {
            $mode = 'NORMAL';
        }
        if ($threshhold == 'r2h') {
            $mode = 'BRIEF';
        }
        $last_plan_update = plan_get_last_update($_SERVER['USER']);
        if (strpos($threshhold, 'r') !== FALSE) {
            $newest_first = 'SELECTED';
        } else {
            $oldest_first = 'SELECTED';
        }
        if (strpos($threshhold, 'w') !== FALSE) {
            $weeks_selected = 'SELECTED';
        } elseif (strpos($threshhold, 'h') !== FALSE) {
            $hours_selected = 'SELECTED';
        } elseif (strpos($threshhold, 'm') !== FALSE) {
            $minutes_selected = 'SELECTED';
        } else {
            $days_selected = 'SELECTED';
        }
        $threshvalue = str_replace(array('d', 'r', 'w', 'd', 'h', 'm'), '', $threshhold);
        if ($threshhold == 'sidebar') {
            $threshhold = '1d';
            $reverse = 'true';
            $sidebar = 1;
        }
        if (strstr($threshhold, 'r')) {
            $reverse = 'true';
            $threshhold = str_replace('r', '', $threshhold);
        }
        $threshhold = time_calculate_threshhold($threshhold);
        $threshhold = time() - $threshhold;
        profile('snitch_read');
        $snitch_fn = "{$_SERVER['USER_ROOT']}/stats/planlog.txt";
        if (file_exists($snitch_fn)) {
            if ($mode == 'NORMAL') {
                exec("tail -n 200 {$snitch_fn}", $snitch_array);
            }
            if ($mode == 'BRIEF') {
                exec("tail -n 30 {$snitch_fn}", $snitch_array);
            } else {
                $snitch_array = explode("\n", file_get_contents($snitch_fn));
            }
        } else {
            $snitch_array = array();
        }
        profile('snitch_read');
        if ($reverse) {
            $snitch_array = array_reverse($snitch_array);
        }
        foreach ($snitch_array as $k => $snitch_entry) {
            list($blah, $snitch_user, $blah) = explode(',', $snitch_entry);
            $snitch_users[] = $snitch_user;
        }
        if (is_array($snitch_users)) {
            $snitch_users = array_unique($snitch_users);
        } else {
            $snitch_users = 'No snitch';
        }
        if ($mode) {
            $lastview = plan_get_last_view($snitch_users);
        }
        if ($mode) {
            $lastupdate = plan_get_last_update($snitch_users);
        }
        profile('snitch_format_begin');
        foreach ($snitch_array as $k => $snitch_entry) {
            unset($style);
            unset($class);
            $snitch_entry = explode(',', $snitch_entry);
            if ($snitch_entry[0] > $threshhold) {
                if ($snitch_entry[0] < $last_plan_update) {
                    $content .= "<li style='margin: 15px;'>" . str_replace('&nbsp;', ' ', formattime($last_plan_update)) . " &nbsp;&nbsp; Last Plan Update</li>";
                    $last_plan_update = 0;
                }
                $su_key = array_search($snitch_entry[1], $snitch_users);
                $snitchday = date('d', $snitch_entry[0]);
                if ($last_snitchday && $snitchday != $last_snitchday) {
                    $style = "margin-top: 15px;";
                }
                $time_string = str_replace('&nbsp;', ' ', formattime($snitch_entry[0]));
                if (strlen(date('g', $snitch_entry[0])) == 1) {
                    $time_string .= "&nbsp;";
                }
                if ($lastupdate[$su_key] > 0 && $lastupdate[$su_key] > $lastview[$su_key]) {
                    $class = "unread";
                } else {
                    $class = 'read';
                }
                if (strpos($snitch_entry[1], 'Anon') !== FALSE) {
                    $snitch_ip = str_replace("Anonymous Coward from ", '', $snitch_entry[1]);
                    if ($snitch_ip == 'livejournal.com') {
                        $snitch_entry[1] = "LiveJournal";
                    } elseif (strstr($snitch_ip, 'facebook.com')) {
                        $snitch_entry[1] = "Facebook";
                    } else {
                        if (strpos($_SERVER['REQUEST_URI'], '/snitch') === 0 && $_SERVER['OUTPUT_MODE'] != 'IPHONE') {
                            $ac = "Anonymous Coward ";
                        } else {
                            $ac = "AC ";
                        }
                        $numerical_ip = gethostbyname($snitch_ip);
                        $snitch_entry[1] = "{$ac} from {$snitch_ip}";
                        if ($ac != 'AC ') {
                            $snitch_entry[1] .= " <a href='{$_SERVER['WEB_ROOT']}/trace/{$snitch_ip}'>trace</a> | <a href='{$_SERVER['WEB_ROOT']}/lists/add/blocked/{$numerical_ip}'>block</a>\n";
                        }
                    }
                }
                if (strpos($snitch_entry[2], 'archives') !== FALSE) {
                    preg_match("|archives \\( (r.*d) 3(.*) \\)|", $snitch_entry[2], $matches);
                    $length = $matches[1];
                    $timecode = $matches[2];
                    $url = date("Y/m/d/h:i", $timecode);
                    $snitch_entry[2] = str_replace($matches[0], "<a href='/read/{$_SERVER['USER']}/{$length}/{$url}'>archives ({$length} from " . date("F jS Y g:ia", $timecode) . ")</a>", $snitch_entry[2]);
                }
                if (strpos($snitch_entry[1], 'RSS') !== FALSE) {
                    $snitch_ip = str_replace("RSS Reader from ", '', $snitch_entry[1]);
                    if (strstr($_SERVER['REQUEST_URI'], 'snitch')) {
                        $rr = "RSS Reader ";
                    } else {
                        $rr = "RSS ";
                    }
                    $snitch_entry[1] = "{$rr} <span class='edit_links'>from {$snitch_ip}";
                    if ($rr != 'RSS ') {
                        $snitch_entry[1] .= "[ <a href='{$_SERVER['WEB_ROOT']}/trace/{$snitch_ip}'>trace</a> | <a href='{$_SERVER['WEB_ROOT']}/lists/add/blocked/{$ip}'>block</a> ]</span>\n";
                    }
                }
                if (!strstr($snitch_entry[1], 'AC ') && !strstr($snitch_entry[1], 'Anon') && !strstr($snitch_entry[1], 'RSS') && !strstr($snitch_entry[1], 'LiveJournal') && !strstr($snitch_entry[1], 'Facebook')) {
                    $content .= "<li class='{$class}' style='{$style}'><a href='{$_SERVER['WEB_ROOT']}/read/{$snitch_entry['1']}'>{$time_string} {$snitch_entry['1']}</a> {$snitch_entry['2']}</li>";
                } elseif ($sidebar != 1) {
                    $content .= "<li class='{$class}' style='{$style}'>{$time_string} {$snitch_entry['1']} {$snitch_entry['2']}</li>\n";
                } else {
                    $content .= "<li class='{$class}' style='{$style}'>{$time_string} AC {$snitch_entry['2']}</li>\n";
                }
                $last_snitchday = $snitchday;
            } else {
                $k += 10000;
            }
        }
        profile('snitch_format_end');
    } else {
        $content = "<li class='alert'>you are not the owner of {$owner}'s plan. you are {$user}. please re-login if this is an error.</li>";
    }
    return $content;
}
function list_format_iphone($list = FALSE, $sortby = FALSE)
{
    profile('list_format_html', 'begin');
    profile("prelist");
    if ($_SERVER['USER_ROOT'] && is_dir("{$_SERVER['USER_ROOT']}/sends/")) {
        //		echo $_SERVER['USER_ROOT'];
        $new_sends = files_list("{$_SERVER['USER_ROOT']}/sends/", "*..new");
    }
    if ($new_sends) {
        $watchlist .= "<option value='/send'>sends</option>";
        foreach ($new_sends as $new_send) {
            $sender = files_decode_safe_name(str_replace("..new", '', $new_send));
            $watchlist .= "<option value='/send/{$sender}'>{$sender}</option>\n";
        }
    }
    if (!$list) {
        $list_fn = "{$_SERVER['USER_ROOT']}/watchedlist.txt";
        // reads in the user's watched list
        if (file_exists($list_fn)) {
            $list = file($list_fn);
            if ($list[0] == "sort by time\n") {
                $sortby = 'time';
            } elseif ($list[0] == "sort by name\n") {
                $sortby = 'name';
            } elseif ($list[0] == "sort by none\n") {
                $sortby = 'inorder';
            } else {
                $sortby = 'inorder';
            }
            if (strpos($list[0], 'sort by ') !== FALSE) {
                unset($list[0]);
            }
        } else {
            $list = array();
        }
        $list = array_merge(array("#Watched Plans"), $list);
    }
    profile("prelist");
    profile('list_format_html_prep', 'begin');
    $ptime = plan_get_last_update($list);
    $lastview = plan_get_last_view($list);
    $ordinal = 0;
    foreach ($list as $z => $plan) {
        $plan = urldecode($plan);
        if (strstr($plan, '!!!')) {
            $prune = TRUE;
            $plan = '';
        }
        if (strstr($plan, '!prune')) {
            // 			$prune=TRUE;
            $threshhold = str_replace('!prune', '', $plan);
            $threshhold = time_calculate_threshhold($threshhold);
            $threshhold = time() - $threshhold;
            $plan = '';
        }
        if (trim($plan) == '!onlynew') {
            $onlynew = TRUE;
        }
        if (trim($plan) == '!alwaysnew') {
            $alwaysnew = TRUE;
        }
        $plan = str_replace(array('!alwaysnew', '!onlynew'), '', $plan);
        $alias_array = explode(':', str_replace('!', '', $plan));
        $displayname = end($alias_array);
        $url = $alias_array[0];
        if ($alias_array[1][0] == '/') {
            $url .= ":{$alias_array['1']}";
        }
        if (!is_string($displayname) || $displayname == $url) {
            if (strstr($url, '@')) {
                list($username, $host) = explode("@", $url);
                $displayname = "{$username} <span style='font-size: smaller;'>@{$host}</span>";
            } else {
                $displayname = $url;
            }
        }
        //		else echo $displayname;
        if ($displayname[0] == '#') {
            $groupname = htmlentities(str_replace('#', '', $displayname));
            $grouplist[] = $groupname;
        }
        if (trim($plan)) {
            if ($plan[0] != '#') {
                if (file_exists("{$_SERVER['USER_ROOT']}/send/" . files_encode_safe_name($url) . "..new")) {
                    $send = "<a href='/send/{$url}'>SEND</a>";
                } else {
                    $send = '';
                }
                $biglist[$ordinal] = array("group" => $groupname, "url" => trim($url), "name" => $displayname, "updated" => $ptime[$z], "viewed" => $lastview[$z], "send" => $send);
                $timelist[$ordinal] = $ptime[$z];
                $namelist[$ordinal] = $displayname;
                $ordinal++;
            }
        }
        if (!is_array($grouplist)) {
            $grouplist = array('');
        }
    }
    profile('list_format_html_prep', 'end');
    if (!$prune) {
        $onlynew = FALSE;
        $alwaysnew = FALSE;
        $threshhold = 0;
    }
    profile("buildlist");
    if ($sortby == 'inorder') {
        foreach ($biglist as $i => $plan_details) {
            $plan_details = $biglist[$i];
            if ($plan_details['updated'] > $plan_details['viewed']) {
                $class = '* ';
            } else {
                $class = '';
            }
            if ($plan_details['updated'] > $threshhold || !$prune || $alwaysnew && $class == 'unread') {
                $plan_details['updated'] = formattime($plan_details['updated']);
                $outputlist[$plan_details['group']] .= "<option value='/read/{$plan_details['url']}'>{$class}{$plan_details['name']}: {$plan_details['updated']}</option>\n";
            }
        }
    }
    if ($sortby == 'name') {
        asort($namelist);
        foreach ($namelist as $i => $name) {
            $plan_details = $biglist[$i];
            if ($plan_details['updated'] > $plan_details['viewed']) {
                $class = '* ';
            } else {
                $class = '';
            }
            if ($plan_details['updated'] > $threshhold || !$prune || $alwaysnew && $class == 'unread') {
                $plan_details['updated'] = formattime($plan_details['updated']);
                $outputlist[$plan_details['group']] .= "<option value='/read/{$plan_details['url']}'>{$class}{$plan_details['name']}: {$plan_details['updated']}</option>\n";
            }
        }
    }
    if ($sortby == 'time') {
        arsort($timelist);
        foreach ($timelist as $i => $time) {
            $plan_details = $biglist[$i];
            if ($plan_details['updated'] > $plan_details['viewed']) {
                $class = '* ';
            } else {
                $class = '';
            }
            if ($plan_details['updated'] > $threshhold || !$prune || $alwaysnew && $class == 'unread') {
                $plan_details['updated'] = formattime($plan_details['updated']);
                $outputlist[$plan_details['group']] .= "<option value='/read/{$plan_details['url']}'>{$class}{$plan_details['name']}: {$plan_details['updated']}</option>\n";
            }
        }
    }
    foreach ($grouplist as $groupname) {
        $jsgroupname = trim(str_replace(" ", "_", $groupname));
        if ($outputlist[$groupname] || strtolower($groupname) == 'watched plans') {
            $watchlist .= "\n\t\t<option value=''>---</option><option value='/look/group/" . urlencode(trim($groupname)) . "'>[{$groupname}]</option>\n{$outputlist[$groupname]}";
        }
    }
    profile("buildlist");
    profile('list_format_html', 'end');
    return $watchlist;
}
function plan_read_local($planowner, $threshhold = FALSE, $begindate = '', $source = FALSE)
{
    $prl_rand = rand();
    profile("plan_read_local_{$prl_rand}");
    profile('plan_read_local_head');
    $reader = $_SERVER['USER'];
    if (!$threshhold) {
        $threshhold = $_SERVER['PLANOWNER_INFO_ARRAY']['defaultdays'] . 'd';
    }
    // this also appears in caching
    if (user_is_authorized($planowner, $reader)) {
        $private = "*";
        $private_cache_fn = 'private';
    }
    // css has to be here so it can be placed properly even when the plan is cached.
    // this is especially important for offnode readers for some reason.
    $css_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/plancss.txt";
    if (file_exists($css_filename)) {
        $plan_dressing['css'] = stripslashes(file_get_contents($css_filename));
        $plan_dressing['css'] = str_replace(array("\r", "\n"), " ", $plan_dressing['css']);
        $plan_dressing['css'] = str_replace(array("\r", "\n"), " ", $plan_dressing['css']);
        $plan_dressing['css'] = str_replace(array("\r", "\n"), " ", $plan_dressing['css']);
        $_SERVER['PLANOWNER_INFO']['css'] = strip_tags(trim($plan_dressing['css']));
    }
    //		if ($_SERVER['USER']=='jwdavidson') return "got css $css_filename $plan_dressing[css]";
    // CACHING
    // this tests to see if there's a cached version. if not, it will write
    // one when it's done getting the plan together.
    //----------------------------------------------
    // first figure out the appropriate cache filename
    if ($_SERVER['OUTPUT_MODE'] == 'RSS') {
        $feed = 'feed';
    }
    if ($_SERVER['OUTPUT_MODE'] == 'ATOM') {
        $feed = 'atomfeed';
    }
    if ($_SERVER['OUTPUT_MODE'] == 'ATOM_PRIVATE') {
        $feed = rand(100, 999);
    }
    if ($_SERVER['OUTPUT_MODE'] == 'IPHONE') {
        $feed = 'phonefeed';
    }
    profile('plan_read_local_uia');
    if (user_is_authorized($planowner, $reader)) {
        $private = "*";
        $private_cache_fn = 'private';
    }
    profile('plan_read_local_uia');
    profile('plan_read_local_utp');
    if (!plan_test_privacy($reader, $planowner)) {
        $blocked_cache_fn = 'blocked';
    }
    profile('plan_read_local_utp');
    $fn_username = base64_encode($planowner);
    if ($planowner == $reader) {
        $self = 'self';
    }
    if ($remoteuser == 'rss reader') {
        $feed = 'feed';
    }
    if ($source) {
        $source = "source";
    }
    $cache_fn = "{$_SERVER['FILE_ROOT']}/temp/{$_SERVER['PLANOWNER_INFO_ARRAY']['salt']}.{$self}{$private_cache_fn}{$blocked_cache_fn}{$remote}{$feed}.{$threshhold}.{$begindate}.{$source}.cache";
    // then, if the file exists, read it
    if (file_exists($cache_fn) && plan_get_last_update($planowner) < filemtime($cache_fn) && filesize($cache_fn) > 256) {
        profile('plan_read_local_pis');
        if (plan_is_local($reader)) {
            user_update_lastread($planowner);
        }
        profile('plan_read_local_pis');
        return file_get_contents($cache_fn);
    }
    // END CACHING
    // if no valid cache is found, on with the show
    if ($threshhold[0] != '.') {
        if (strstr($threshhold, 'r')) {
            $threshhold = str_replace('r', '', $threshhold);
            $reverse = 1;
        }
        $threshhold = time_calculate_threshhold($threshhold);
        $threshhold = time() - $threshhold;
        if (!$begindate || $begindate < 100) {
            $begindate = $threshhold;
            $enddate = time();
            $default_view = TRUE;
        } else {
            $enddate = $begindate + (time() - $threshhold);
        }
    }
    profile('plan_read_local_head');
    profile('plan_read_local_styles');
    // if the user has local pref stuff, read it in
    if ($_SERVER['USER_ROOT']) {
        $styles_fn = "{$_SERVER['USER_ROOT']}/styles.txt";
        $skin_fn = "{$_SERVER['USER_ROOT']}/skin.txt";
        $colors_fn = "{$_SERVER['USER_ROOT']}/colors.txt";
        $fonts_fn = "{$_SERVER['USER_ROOT']}/fonts.txt";
        $css_fn = "{$_SERVER['USER_ROOT']}/user_css.txt";
        if (file_exists($styles_fn) && !file_exists($skin_fn) && !file_exists($colors_fn)) {
            parse_str(file_get_contents($styles_fn));
            if ($skin && file_exists("{$_SERVER['FILE_ROOT']}/resources/skins/{$skin}")) {
                @(include $skin);
            }
        }
        if (file_exists($skin_fn)) {
            parse_str(file_get_contents($skin_fn));
            if ($skin) {
                include $skin;
            }
        }
        if (file_exists($colors_fn)) {
            parse_str(file_get_contents($colors_fn));
        }
        if (file_exists($fonts_fn)) {
            parse_str(file_get_contents($fonts_fn));
        }
        if (file_exists($css_fn)) {
            eval(file_get_contents($css_fn));
        }
    }
    profile('plan_read_local_styles');
    // screen out blocked readers, readers that fall below
    // privacy levels set by planowner
    if (!plan_test_privacy($reader, $planowner)) {
        $blocked_fn = "{$_SERVER['PLANOWNER_ROOT']}/blockedmessage.txt";
        if (file_exists($blocked_fn)) {
            $plan = stripslashes(file_get_contents($blocked_fn));
            $plan = str_replace('MYUSER', $planowner, $plan);
            $plan = str_replace('READER', $reader, $plan);
            $plan .= " <!--planowner: {$planowner} | reader: {$reader}-->";
        } else {
            $plan = "{$planowner} has no plan... <!-- reader: {$reader} --- planowner: {$planowner} -->";
        }
    } else {
        // if there's a series of entries listed, break out that list
        if (strstr($threshhold, ',')) {
            $threshhold_array = explode(',', $threshhold);
        } else {
            $threshhold_array = array($threshhold);
        }
        $plan_array = array();
        // this either reads in all the files from the list of entries passed
        // OR it just gets a list of all the entries that pass privacy muster
        foreach ($threshhold_array as $threshholdline) {
            // if the first character of the threshhold is a '.' we
            // want to show the entry indicated by the remainder of the line
            if ($threshholdline[0] == '.') {
                $limiter = $threshholdline;
            } else {
                $limiter = '.';
            }
            //sets dir for reading
            $plan_dir = "{$_SERVER['PLANOWNER_ROOT']}/plan/";
            // gets the entries indicated by $limiter
            // if $limiter is unset, fills the array with all available entries
            $plan_array = array_merge($plan_array, files_list($plan_dir, "plan{$limiter}*.txt{$private}"));
            if (is_array($plan_array) && $threshholdline[0] == '.') {
                $begindate = 1;
                $enddate = time() + 1;
            }
        }
        // get all the plan 'dressing' -- sidebars, header, footer, etc.
        /* CSS taken care of outside of caching.
        		$css_filename="$_SERVER[PLANOWNER_ROOT]/plan/plancss.txt";
        		if (file_exists($css_filename))
        		{
        			$plan_dressing['css']=stripslashes(file_get_contents($css_filename));
        			$plan_dressing['css']=str_replace(array("\r","\n")," ",$plan_dressing['css']);
        			$plan_dressing['css']=str_replace(array("\r","\n")," ",$plan_dressing['css']);
        			$plan_dressing['css']=str_replace(array("\r","\n")," ",$plan_dressing['css']);
        			$_SERVER['PLANOWNER_INFO']['css']=strip_tags(trim($plan_dressing['css']));
        		}
        */
        $header_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/planheader.txt";
        if (file_exists($header_filename)) {
            $plan_dressing['header'] = stripslashes(file_get_contents($header_filename));
            if (strstr($plan_dressing['header'], 'nolinebreaks')) {
                $plan_dressing['header'] = str_replace(array("\r", "\n"), "", $plan_dressing['header']);
                $plan_dressing['header'] = str_replace(array("\r", "\n"), "", $plan_dressing['header']);
                $plan_dressing['header'] = str_replace(array("\r", "\n"), "", $plan_dressing['header']);
            }
            if (strpos($plan_dressing['header'], '<!--markdown-->')) {
                include_once 'markdown.php';
                $plan_dressing['header'] = Markdown(str_replace('<!--markdown-->', '', $plan_dressing['header']));
            }
            $plan_dressing['header'] = "<div id='plan_header_{$_SERVER['PLANOWNER']}' class='plan_header'>{$plan_dressing['header']}</div>";
        }
        $footer_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/planfooter.txt";
        if (file_exists($footer_filename)) {
            $plan_dressing['footer'] = stripslashes(file_get_contents($footer_filename));
            if (strstr($plan_dressing['footer'], 'nolinebreaks')) {
                $plan_dressing['footer'] = str_replace(array("\r", "\n"), "", $plan_dressing['footer']);
                $plan_dressing['footer'] = str_replace(array("\r", "\n"), "", $plan_dressing['footer']);
                $plan_dressing['footer'] = str_replace(array("\r", "\n"), "", $plan_dressing['footer']);
            }
            if (strpos($plan_dressing['footer'], '<!--markdown-->')) {
                include_once 'markdown.php';
                $plan_dressing['footer'] = Markdown($plan_dressing['footer']);
            }
            $plan_dressing['footer'] = "<div id='plan_footer_{$_SERVER['PLANOWNER']}' class='plan_footer'>{$plan_dressing['footer']}</div>";
        }
        $divider_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/plandivider.txt";
        if (file_exists($divider_filename)) {
            $plan_dressing['divider'] = stripslashes(file_get_contents($divider_filename));
        }
        if ($plan_dressing) {
            foreach ($plan_dressing as $area => $content) {
                $content = stripslashes($content);
                if (strpos($content, 'nolinebreaks') !== FALSE) {
                    $content = str_replace('#nolinebreaks#', '', $content);
                } else {
                    $content = smart_nl2br($content);
                }
                $plan_dressing[$area] = $content;
            }
        }
        if (plan_is_journaling($planowner)) {
            $plan_array[] = "plan.{$begindate}.fake";
            $plan_array[] = "plan.{$enddate}.fake";
            sort($plan_array);
            $plan_array = array_values($plan_array);
            // extract the update time for all the plan entries
            foreach ($plan_array as $z => $planfn) {
                $planfn_a = explode(".", $planfn);
                $nextplanfn_a = explode(".", $plan_array[$z + 1]);
                $lastplanfn_a = explode(".", $plan_array[$z - 1]);
                if (($planfn_a[1] >= $begindate && $planfn_a[1] <= $enddate || $nextplanfn_a[1] >= $begindate && $nextplanfn_a[1] <= $enddate || $lastplanfn_a[1] >= $begindate && $lastplanfn_a[1] <= $enddate) && !strstr($planfn, 'fake')) {
                    $plan_index_array[$planfn_a[1]] = $planfn;
                }
            }
            // if we don't have any entries, give up now
            if (!is_array($plan_index_array)) {
                return "no plan entries found.";
            }
            // sort the plan list in order of update time newest to oldest.
            // we'll account for $reverse later, when we're
            // actually writing the entries to strings.
            krsort($plan_index_array);
            foreach ($plan_index_array as $entry_timecode => $entry_filename) {
                if ($entry_timecode >= $begindate && $entry_timecode <= $enddate) {
                    $entry_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/{$entry_filename}";
                    if (file_exists($entry_filename)) {
                        $plan_entries[$entry_timecode] = file_get_contents($entry_filename);
                    }
                }
            }
            // if there were no entries within the threshhold
            // and the threshhold was near now, show the most recent entry
            if (!is_array($plan_entries) && $enddate > time() - 15) {
                // the most recent entry will be just after the beginning of the array
                // because the first two entries will be the $enddate test entry
                reset($plan_index_array);
                while (strpos(current($plan_index_array), 'FAKE')) {
                    next($plan_index_array);
                }
                $entry_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/" . current($plan_index_array);
                $entry_timecode = key($plan_index_array);
                if (file_exists($entry_filename)) {
                    $plan_entries[$entry_timecode] = file_get_contents($entry_filename);
                }
            }
            // if there's still no plan, and we're considering an archival view
            // find the nearest-neighbor plan entry
            if (!is_array($plan_entries) && $enddate < time() - 15) {
                // get the distance to the prev entry
                array_set_current($plan_index_array, $enddate);
                $previous_entry_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/" . prev($plan_index_array);
                $previous_entry_timecode = key($plan_index_array);
                if (file_exists($previous_entry_filename)) {
                    $plan_entries[$previous_entry_timecode] = file_get_contents($previous_entry_filename);
                }
                // get the distance to the next entry
                array_set_current($plan_index_array, $begindate);
                $next_entry_filename = "{$_SERVER['PLANOWNER_ROOT']}/plan/" . next($plan_index_array);
                $next_entry_timecode = key($plan_index_array);
                if (file_exists($next_entry_filename)) {
                    $plan_entries[$next_entry_timecode] = file_get_contents($next_entry_filename);
                }
                $plan_entries[1000000000000000] = "Nothing In Range";
            }
            if ($reverse) {
                ksort($plan_entries);
            } else {
                krsort($plan_entries);
            }
            // if we're ouputting to HTML, put it all together in tasty DIVs.
            if ($_SERVER['OUTPUT_MODE'] == 'HTML' || $_SERVER['OUTPUT_MODE'] == 'IPHONE' || $_SERVER['OUTPUT_MODE'] == 'MOBILE' || $_SERVER['OUTPUT_MODE'] == 'AJAX') {
                foreach ($plan_entries as $entry_time => $entry_text) {
                    $entry_text = trim(stripslashes($entry_text));
                    if (strpos($entry_text, 'nolinebreaks') || strpos($entry_text, '<!--markdown-->')) {
                        $entry_nolinebreaks = 1;
                        $entry_text = str_replace('#nolinebreaks#', '', $entry_text);
                    } else {
                        $entry_nolinebreaks = '';
                        $entry_text = smart_nl2br($entry_text);
                    }
                    if (strpos($entry_text, '<!--markdown-->')) {
                        include_once 'markdown.php';
                        $entry_text = Markdown(str_replace('<!--markdown-->', '', $entry_text));
                    }
                    // pretty up the divider (erm... entry header)
                    $entry_header = plan_prepare_divider($planowner, $reader, $plan_dressing['divider'], $entry_time, $plan_index_array[$entry_time], $entry_text, $entry_nolinebreaks);
                    $plan_content .= plan_prepare_entry($entry_time, $entry_header, $entry_text);
                }
                $plan .= $plan_dressing['header'] . "\n{$new_entry_link}\n<div class='plan_body' id='plan_body_{$_SERVER['PLANOWNER']}'>\n{$plan_content}\n</div>" . $plan_dressing['footer'];
            }
            // if we're building a feed, we want to do valid XML goodness
            if ($_SERVER['OUTPUT_MODE'] == 'RSS') {
                foreach ($plan_entries as $entry_time => $entry_text) {
                    $entry_text = trim(stripslashes($entry_text));
                    if (strpos($entry_text, 'nolinebreaks')) {
                        $entry_text = str_replace('#nolinebreaks#', '', $entry_text);
                    } else {
                        $entry_text = smart_nl2br($entry_text);
                    }
                    $rss_link = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['WEB_ROOT']}/read/{$planowner}";
                    $entry_text = plan_add_user_links(plan_add_alias_links($entry_text, $planowner));
                    list($entry, $li) = plan_encapsulate_rss($planowner, $entry_time, $entry_text);
                    $plan .= $entry;
                    $items .= $li;
                }
                $plan = "{$items}\n<!-- FEED_DIVIDER -->\n{$plan}";
            }
            if (strstr($_SERVER['OUTPUT_MODE'], 'ATOM')) {
                foreach ($plan_entries as $entry_time => $entry_text) {
                    $entry_text = trim(stripslashes($entry_text));
                    if (strpos($entry_text, 'nolinebreaks')) {
                        $entry_text = str_replace('#nolinebreaks#', '', $entry_text);
                    } else {
                        $entry_text = smart_nl2br($entry_text);
                    }
                    $rss_link = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['WEB_ROOT']}/read/{$planowner}";
                    $entry_text = plan_add_user_links(plan_add_alias_links($entry_text, $planowner));
                    $entry = plan_encapsulate_atom($planowner, $entry_time, $entry_text);
                    $plan .= $entry;
                }
                $plan = "{$items}\n<!-- FEED_DIVIDER -->\n{$plan}";
            }
        } else {
            // TODO:(v4.5) RSS for traditional plans
            //if ($_SERVER['USER']=='dskatz04') echo "$threshhold ".(time()-21*24*3600)." this is a traditional plan\n<br />";
            if (strlen($threshhold) < 9) {
                $threshhold = '';
            } elseif (strpos($threshhold, ',')) {
                $threshhold_array = explode(',', $threshhold);
            } else {
                $threshhold_array = array($threshhold);
            }
            if (is_array($threshhold_array)) {
                $threshhold_array = array_reverse($threshhold_array);
            } else {
                $threshhold_array = array("1" => "");
            }
            foreach ($threshhold_array as $z => $threshhold) {
                if ($threshhold != time() - $_SERVER['PLANOWNER_INFO_ARRAY']['defaultdays'] * 24 * 3600) {
                    $plan_filenames = files_list("{$_SERVER['PLANOWNER_ROOT']}/plan", "*{$threshhold}*");
                } else {
                    $plan_filenames = array('plan.txt');
                }
                $entry_time = $threshhold;
                if (count($threshhold_array) > 1) {
                    $plan .= "<hr/>" . date('F jS Y, g:ia', $threshhold_array[$z]) . "<hr/>";
                    $entry_header = plan_prepare_divider($planowner, $reader, $plan_dressing['divider'], $entry_time, $plan_filenames[0], $entry_text, $entry_nolinebreaks);
                }
                if (is_array($plan_filenames)) {
                    foreach ($plan_filenames as $filename) {
                        if (file_exists("{$_SERVER['PLANOWNER_ROOT']}/plan/{$filename}")) {
                            if (strstr($filename, '.gz')) {
                                $plan .= stripslashes(file_get_contents("compress.zlib://{$_SERVER['PLANOWNER_ROOT']}/plan/" . basename($filename)));
                            } else {
                                $plan .= stripslashes(file_get_contents("{$_SERVER['PLANOWNER_ROOT']}/plan/" . basename($filename)));
                            }
                        }
                    }
                }
            }
            if (strlen(trim($plan)) > 10) {
                if (!strstr($plan, 'nolinebreaks')) {
                    $plan = smart_nl2br($plan);
                }
                $plan = "{$plan_dressing['header']}<div class='plan_body' id='plan_body_{$_SERVER['PLANOWNER']}'>{$plan}</div>\n{$plan_dressing['footer']}";
            }
        }
    }
    // MORE CACHING
    if (!file_exists($cache_fn) || plan_get_last_update($planowner) > filemtime($cache_fn) && $remoteuser != 'rss reader') {
        file_put_contents($cache_fn, $plan);
    }
    profile("plan_read_local_{$prl_rand}");
    return "<!-- since " . formattime($threshhold) . " " . formattime($begindate) . " -->\n" . $plan;
}