<?php
/*
Template Name: Blogroll 5 High Performance
 */
?>
<?php

$GLOBALS['blogs_i_read_min_time']     = 900;
$GLOBALS['external_service_min_time'] = 1800; 
$GLOBALS['external_service_pre_aged'] = 600; 

// retrieve_list();

function resolveUrl($url) {
    try {
        $header = doCurlRequest($url); return $header['redirect_url']; } catch (Exception $ex) {
            _log("error freeing url $url: " . $ex->getMessage()); return $url;
        }
}

function curlDownload($Url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $Url);
    curl_setopt($ch, CURLOPT_REFERER, "https://markus-spring.info");
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0");
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}

function reduce_lines( $html ) {
    $lines = explode("\n", $html);
    $found = 0;
    $bloglist = '';
    for ($i = 0; $i < count($lines); $i++) {
        if ($lines[$i] ==  "<ul id='BlogList1_blogs'>")
            $found = 1;
        if ($found == 1 and $lines[$i] == "</ul>")
            break;
        if ($found == 1) 
            $bloglist .= $lines[$i] . "\n";
    }
    return($bloglist); 
}

function make_timestamp($chunk) {   // 
    preg_match('/vor\s(\d+)\s(\D+)/m', $chunk, $m);
    $t = time() - 20*365*24*3600;
    if ($m) {
        // echo $m[1] . " " . $m[2] . " ";
        if (strpos($m[2], 'Minute') === 0) 
            $t =  time() - $m[1] * 60;
        if (strpos($m[2], 'Stunde') === 0) 
            $t =  time() - $m[1] * 3600;
        elseif (strpos($m[2], 'Tag') === 0) 
            $t =  time() - $m[1] * 24 * 3600;
        elseif (strpos($m[2], 'Woche') === 0) 
            $t =  time() - $m[1] * 7 * 24 * 3600;
        elseif (strpos($m[2], 'Monat') === 0) 
            $t =  time() - $m[1] * 30 * 24 * 3600;
        elseif (strpos($m[2], 'Jahr') === 0) 
            $t =  time() - $m[1] * 365 * 24 * 3600;
        return $t;
    } else
    return 0;
}

function rework_entry ($match, $list, $offset, $housekeeping) {
    $url = $match[1];
    $domain = preg_replace('/(https?:\/\/|\/<?.*?$)/m', "", $match[1]);
    $protocol = preg_replace('/:\/\/.*/', '://', $match[1]); 
    $title = $match[2];
    $lasturl = '';
    $lasttitle = '';
    # match: [0] url [1] blog title [2] post title [3] post url [4] time indicator
    # echo "<pre style='font-size: 10px; font-weight: normal'>$domain: " . $match[3] . "</pre>\n";
    if (preg_match('`href=\'(.*?)\'.*?>\s*(.*?)\s*</a>`m', $match[3], $m)) {
        #echo "<pre style='font-size: 10px; font-weight: normal'>" . $match[3] . "</pre>\n";
        $lasturl  = $m[1];
        $lasttitle  = $m[2];
        /* echo "Last post 1:" . $lasturl . "\n"; */
        $timestamp  = make_timestamp($match[4]) + $offset;
    } else {
        if ( strpos($domain, 'lfi-online.de') === 0 ) 
            list($timestamp, $lasturl, $lasttitle) = update_lfi($url, $list);
        if ( strpos($domain, 'jims-ramblings.blogspot.com') === 0 ) 
            list($timestamp, $lasturl, $lasttitle) = update_jims_ramblings($url, $list);
        if ( strpos($domain, 'www.orengrad.com') === 0) 
            list($timestamp, $lasturl, $lasttitle) = update_oren_grad($url, $domain, $list);
        else {
            // echo "unmatched domain $domain\n";
            $id = array_search($domain, array_column($list, 'domain'));
            $timestamp = $list[$id]['timestamp'];
            // $timestamp  = make_timestamp($match[4]) + $offset;
        }
    }
    return ['domain' => $domain, 'url' => $url, 'title' => $title, 'lasturl' => $lasturl,
            'lasttitle' => $lasttitle, 'timestamp' => $timestamp, 'housekeeping' => $housekeeping];
}

function debug_echo ( $flag, $args ) {
    if ($flag == 1)
        echo "<div>" . $args . "</div>\n";
}

function update_oren_grad($url, $domain, $list) {
    $debug = 0;
    // foreach($list as $l)
    //     debug_echo($l['domain']);
    // echo '<pre>'; echo print_r($list); echo '</pre>';
    $id = array_search($url, array_column($list, 'url'));
    // $id = array_search($domain, array_column($list, 'domain'));
    $lasttitle = '';
    if ( $id === false ) { // not found in list
        debug_echo($debug, "OG: $domain not found in list");
        preg_match('/bodycontent[\'"]>\s*<p><img src=[\'"](pictures\/.*)[\'"] alt=[\'"]/ms', curlDownload($url), $m);
        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
        $lasturl   = $url . '/' . $m[1];
    } else { // found
        debug_echo($debug, "OG: $domain found in list");
        $timestamp = $list[$id]['timestamp'];
        $lasturl   = $list[$id]['lasturl'];
    }
    debug_echo($debug, "OG: lasturl age " . (time() - $timestamp ) . "s");
    if ( (time() - $timestamp ) > $GLOBALS['external_service_min_time'] ) {
        debug_echo($debug, "OG: $domain found in list but outdated");
        preg_match('/bodycontent[\'"]>\s*<p><img src=[\'"](pictures\/.*)[\'"] alt=[\'"]/ms', curlDownload($url), $m);
        $lasturl   = $url . '/' . $m[1];
        if ( $lasturl == $list[$id]['lasturl'] ) {
            debug_echo( $debug, "OG: lasturl unchanged, timestamp unchanged: " . (time() - $timestamp) . "s");
            $timestamp = $list[$id]['timestamp'];
        } else {
            debug_echo($debug, "OG: lasturl CHANGED, timestamp unchanged: " . (time() - $timestamp) . "s");
            $timestamp = time() - $GLOBALS['external_service_pre_aged'];
        }
    }
    debug_echo( $debug, "OG: $domain final timestamp: " . (time() - $timestamp) . "s");
    return [$timestamp, $lasturl, $lasttitle];
}

function update_jims_ramblings($url, $list) {
    $id = array_search($url, array_column($list, 'url'));
    if ( $id === false ) { // not found in list
        // echo "$url not found in list\n";
        preg_match('/<h3 class=\'post-title entry-title\'>\s*?<a href=\'(.*?)\'>(.*?)<\/a/', curlDownload($url), $m);
        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
        $lasturl   = $m[1];
        $lasttitle = $m[2];
    } else { // found
        // echo "$url found in list\n";
        $timestamp = $list[$id]['timestamp'];
        $lasturl   = $list[$id]['lasturl'];
        $lasttitle = $list[$id]['lasttitle'];
    }
    // echo "lasturl age " . (time() - $timestamp - 600 ) . "s\n";
    if ( (time() - $timestamp ) > $GLOBALS['external_service_min_time'] + 600 ) {
        // echo "$url found in list but outdated\n";
        preg_match('/<h3 class=\'post-title entry-title\'>\s*?<a href=\'(.*?)\'>(.*?)<\/a/', curlDownload($url), $m);
        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
        $lasturl   = $m[1];
        $lasttitle = $m[2];
        if ( $lasttitle == $list[$id]['lasttitle'] )
            $timestamp = $list[$id]['timestamp'];
    }
    return [$timestamp, $lasturl, $lasttitle];
}

function update_lfi($url, $list) {
    $id = array_search($url, array_column($list, 'url'));
    if ( $id === false ) { // not found in list
        // echo "$url not found in list\n";
        preg_match('/location = \'(.*?)\'">\s*?<h1 class="typo-\d+">(.*?)</msi', curlDownload($url), $m);
        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
    } else { // found
        // echo "$url found in list\n";
        $timestamp = $list[$id]['timestamp'];
        $lasturl   = $list[$id]['lasturl'];
        $lasttitle = $list[$id]['lasttitle'];
    }
    // echo "lasturl age " . (time() - $timestamp - 600 ) . "s\n";
    if ( (time() - $timestamp ) > $GLOBALS['external_service_min_time'] + 600 ) {
        // echo "$url found in list but outdated\n";
        preg_match('/location = \'(.*?)\'">\s*?<h1 class="typo-\d+">(.*?)</msi', curlDownload($url), $m);
        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
        $lasturl   = $m[1];
        $lasttitle = $m[2];
        if ( $lasttitle == $list[$id]['lasttitle'] )
            $timestamp = $list[$id]['timestamp'];
    }
    return [$timestamp, $lasturl, $lasttitle];
}

function create_linklist ($list, $housekeeping) {
    // echo '<pre>' . $housekeeping . '<pre>';
    $debug = 0;
    $hurl = "http://spring2life-links.blogspot.de";
    debug_echo($debug, $hurl);
    $html = curlDownload($hurl);
    $bloglines = reduce_lines($html);
    // debug_echo($debug, $bloglines);
    # matches: 1: url 2: blog title 3. post title 4. time indicator
    $re = '/<div class=\'blog-title\'>\s*<a href=\'(.*?)\'.*?>\s*(.*?)<\/a>.*?\'item-title\'>\s*(.*?)\s*<\/span.*?\'item-time\'>\s*(.*?)\s*<\/div>/ms';
    preg_match_all($re, $bloglines, $matches, PREG_SET_ORDER, 0);
    $offset = 0;
    for ($i = 0; $i < count($matches); $i++) {
        $result = rework_entry($matches[$i], $list, $offset, $housekeeping);
        // print_r($result['domain'] . "\n");
        $id = array_search( $result['domain'], array_column( $list, 'domain' ));
        // debug_echo($debug, $result['domain']);
        if ( is_int($id) ) {
            $list[$id]['lasturl'] = $result['lasturl'];
            $list[$id]['lasttitle'] = $result['lasttitle'];
            $list[$id]['timestamp'] = $result['timestamp'];
            $list[$id]['housekeeping'] = $housekeeping;
        } else {
            array_push($list, $result);
        }
        $offset += 1;
    }
    $hk = $housekeeping - 2;
    $op = array_search('www.ruedulavoir.com', array_column($list, 'domain'));
    echo "<pre>$op</pre>";
    unset($list[$op]);
    // while ( $hk < $housekeeping ) {
    //     debug_echo($debug, $hk);
    //     while ( is_int($to_delete = array_search($hk, array_column($list, 'housekeeping' ))) ) {
    //         echo '<pre style="color:green;">' . $hk . ' ';
    //         echo print_r( $list[$to_delete] );
    //         echo '</pre>';
    //         unset($list[$to_delete]);
    //     }
    //     // while ( $to_delete = array_search($hk, array_column($list, 'housekeeping' )) !== NULL) {
    //     //     debug_echo(1, $to_delete);
    //         // unset($list[$to_delete]);
    //     // }
    //     $hk = $hk + 1;
    // }
    return $list;
}

function retrieve_list() {
    $debug = 0;
    $time1 = (float) microtime(true);
    // echo "getting content from stored list " . (time() - filemtime('/tmp/file.ser')) . "s\n";
    // $str = file_get_contents('/tmp/file.ser');
    // $str = get_transient( $hurl + "_hp" );
    // if ( $str === false ) { // not found
    //     $list = create_linklist([]);
    // } else {                    // found
    //     // $list = unserialize( $str );
    //     $list = create_linklist($str);
    // }
    $queried_object = get_queried_object();
    if ( $queried_object ) {
        $post_id = $queried_object->ID;
    }
    // $post_id = 23342;           // for testing, fixed to the blogs-i-read page id
    debug_echo($debug, $post_id);
    $cache_key = '_blogs_i_read';
    $cache = get_post_meta( $post_id, $cache_key, true );
    $housekeeping = -1;
    // $cache = [];
    if ( empty( $cache ) || $cache['expires'] < time() ) {
        debug_echo($debug, 'empty or expired');
        if (empty($cache)) {
            $list = [];
            $housekeeping = 0;
        } else {
            debug_echo($debug, 'expired');
            $housekeeping = $cache['housekeeping'] + 1;
            debug_echo($debug, 'housekeeping:' . $housekeeping);
            $list = $cache['data'];
        }
        $list = create_linklist($list, $housekeeping);
        debug_echo($debug, 'after creating linklist');
        $cache = array( 
            'expires' => time() + $GLOBALS['blogs_i_read_min_time'],
            'data' => $list,
            'housekeeping' => $housekeeping );
        update_post_meta( $post_id, $cache_key, $cache );
        debug_echo($debug, 'after updating post meta');
    } else {
        debug_echo($debug, 'neither empty nor expired');
        $housekeeping = $cache['housekeeping'];
        create_linklist($cache['data'], $housekeeping);
    }
    debug_echo($debug, 'before printing');
    return(print_list( $cache['data'], $time1 ));
}

function print_list ( $list, $time1 ) {
    $list2 = array_msort($list, array('timestamp' => SORT_DESC));
    $s = '';
    $dayflag = $weekflag = $monthflag = $yearflag = false;
    foreach ($list2 as $l) {
        if ( ! $dayflag and ((time() - $l['timestamp']) > 24*3600) ) {
            $s .= "<!-- " . (time() - $l['timestamp']) . " // " . 24*3600 . " -->\n";
            $s .= "</ul>\n<li style='font-weight: bold;'>A day and older</li>\n<ul>\n";
            $dayflag = true;
        } elseif ( ! $weekflag and ((time() - $l['timestamp']) > 7*24*3600) ) {
            $s .= "</ul>\n<li style='font-weight: bold;'>Less than a month</li>\n<ul>\n";
            $weekflag = true;
        } elseif ( ! $monthflag and ((time() - $l['timestamp']) > 30*24*3600) ) {
            $s .= "</ul>\n<li style='font-weight: bold;'>Older</li>\n<ul>\n";
            $monthflag = true;
        } elseif ( ! $yearflag and ((time() - $l['timestamp']) > 365*24*3600) ) {
            $s .= "</ul>\n<li style='font-weight: bold;'>From medieval times</li>\n<ul>\n";
            $yearflag = true;
        } 
        $s .= '<li>';
        // $s .= '<span style="color:green">' . (time() - $l['timestamp']) . '</span>; ';
        // $s .= '<span style="color:blue">' . $l['housekeeping'] . '</span>; ';
        $s .= '<a target="_blank" href="' . $l['url'] . '">' . $l['title'] . '</a> // <a target="_blank" href="'
           . $l['lasturl'] . '">' . $l['lasttitle'] . "</a></li>\n";
    }
    $timespent = microtime(true) - $time1;
    return $s . "<!-- Duration $timespent sec -->\n";
}

// function store_list($list) {
//     // anpassen für wordpress, zum testen schreiben in Datei
//     // $ser = serialize($list);
//     // $file = fopen('/tmp/file.ser', 'wb');
    
//     // fwrite($file, $ser); 
//     set_transient( $hurl + "_hp", $list, 600 );
// }

function array_msort($array, $cols) {
    $colarr = array();
    foreach ($cols as $col => $order) {
        $colarr[$col] = array();
        foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
    }
    $eval = 'array_multisort(';
    foreach ($cols as $col => $order) {
        $eval .= '$colarr[\''.$col.'\'],'.$order.',';
    }
    $eval = substr($eval,0,-1).');';
    eval($eval);
    $ret = array();
    foreach ($colarr as $col => $arr) {
        foreach ($arr as $k => $v) {
            $k = substr($k,1);
            if (!isset($ret[$k])) $ret[$k] = $array[$k];
            $ret[$k][$col] = $array[$k][$col];
        }
    }
    return $ret;
}

?>
<?php get_header(); ?>
<div id="content" class="site-content">
  <div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">
      <article id="post--31201" class="post--31201 post type-post status-publish format-image hentry category-vernacular post_format-post-format-image entry">
        <header class="entry-header">
	  <h2 class="entry-title default-max-width">Blogs I read</h2>
	</header><!-- .entry-header -->
        
        <div id="content" class="site-content">
          <div id="primary" class="content-area">
            <main id="main" class="site-main" role="main">
	
	      <div class="entry-content">
                <ul class="linktable">
                  <li style="font-weight: bold;">Hot from the Sphere</li>
                  <ul>
                  <?php echo retrieve_list (); ?>
                  </ul>
                </ul>
              </div><!-- .entry-content -->
            </main>
          </div>
        </div>
      </article><!-- #post-31164 -->
    </main><!-- #main -->
  </div><!-- #primary -->
</div><!-- #content -->
<?php get_footer(); ?>

<?php
// Local variables:
// compile-command: "php linkpage5.php"
// End:
?>
