<?php

/**
 * Functions used by the PivotX Tools extension.
 *
 * $Id: lib.php 3766 2011-07-05 09:46:56Z hansfn $
 */

/**
 * Iterates over a given range of entries in the PivotX database and 
 * returns true if there are more entries to index. For each entry a 
 * function is called. 
 *
 * @param string $func The function called for each entry.
 * @param int $start Code for first entry to index
 * @param int $stop Code for last entry to index
 * @param int $time Indexing time.
 * @return boolean
 */
function _pt_iterate_entries_func($func$start$stop$time) {
    global 
$PIVOTX$output;

    if (
$PIVOTX['config']->get('db_model')=="mysql") {
        
// Work-around since PivotX doesn't create date_index for MySQL database.
        
$sql = new sql('mysql',
            
$PIVOTX['config']->get('db_databasename'),
            
$PIVOTX['config']->get('db_hostname'),
            
$PIVOTX['config']->get('db_username'),
            
$PIVOTX['config']->get('db_password')
        );

        
$entriestable safeString($PIVOTX['config']->get('db_prefix')."entries"true);

        
$sql->query("SELECT uid FROM $entriestable");
        
$rows_entries $sql->fetch_all_rows();
        
$entries = array();
        foreach ( 
$rows_entries as $entry) {
            
$entries[$entry['uid']] = $entry['uid'];
        }
    } else {
        
$entries $PIVOTX['db']->db_lowlevel->date_index;
    }

    
$count 0;

    foreach(
$entries as $key => $value) {

        if ((
$count++)<$start) { continue; }
        if (
$count>$stop) { break; }

        
$ret call_user_func($func$key);
        if (
$ret != '') {
            if (
$output != '') {
                
$output $ret "\n" $output;
            } else {
                
$output $ret;
            }
        }

        if ((
$count 50) == 0) {
            
$output sprintf(__("%1.2f sec: Processed %d entries...\n"), 
                (
timeTaken('int')+$time), $count) . $output;
        }
    }

    
// decide if we need to do some more.
    
if(count($entries) > $stop) {
        return 
true;
    } else {
        return 
false;
    }

}

/**
 * Export the comments for one entry to Disqus. The Disqus settings are 
 * fetched from the "_pt_formdata" session variable. 
 * 
 * The code below is written for the 1.1 version of the Disqus API - see
 * docs at https://groups.google.com/group/disqus-dev/web/api-1-1
 */
function _pt_export_comments2disqus($uid) {
    global 
$PIVOTX;
    
    
$entry $PIVOTX['db']->read_entry($uid);

    
// Skip all entries with no comments since Disqus will automatically 
    // create threads for entries when needed. 
    
if (($entry["status"] != "publish") || empty($entry["comments"])) {
        return;
    }

    
// Fetch form data from the session
    
$formdata $_SESSION['_pt_formdata'];

    
// Create a thread for the entry first.
    
$args = array();
    
$args['identifier'] = 'entry_id_' $entry['code'];
    
$args['title'] = parse_string($entry['title']);
    
$args['create_on_fail'] = 1;
    
$response json_decode(_pt_call_disqus('thread_by_identifier',$formdata,$args,true),TRUE);
    if (
$response['succeeded'] != 1) {
        
$msg "Failed to create thread for entry $uid because:\n" $response['message'];
        
debug($msg);
        return 
$msg;
    } else {
        
$thread_id $response['message']['thread']['id'];
    }

    
$msg '';
    
$i 0;
    
// Then export all the comments (as posts) to the newly created thread.
    
foreach ($entry["comments"] as $comuid => $com) {
        if (
$com['comment'][0] != '@') {
            
$msg .= "Skipped comment $comuid on entry $uid because it doesn't start with @.\n";
            continue;
        }
        
$args = array();
        
$args['thread_id'] = $thread_id;
        if (
$com['email'] == ''){
            
$args['author_email'] = '[email protected]$com['ip'];
        } else {
            
$args['author_email'] = $com['email'];
        }
        
$args['message'] = $com['comment'];
        
$args['author_name'] = $com['name'];
        if (
$com['url'] == ''){
            
$args['author_url'] = $com['url'];
        }
        
$args['ip_address'] = $com['ip'];
        
$args['created_at'] = preg_replace('/^(\d\d\d\d-\d\d-\d\d)[ -](\d\d)[:-](\d\d).*/''$1T$2:$3'$com['date']);
        
$response json_decode(_pt_call_disqus('create_post',$formdata,$args,true),TRUE);
        if (
$response['succeeded'] != 1) {
            
$msg .= "Failed to export comment $comuid on entry $uid because:\n" $response['message'] . "\n";
        } else {
            
$i++;
        }
    }
    
$msg "Exported $i comments for entry $uid\n$msg";
    
debug($msg);
    return 
$msg;
}

/**
 * Iterates over all entries, but only loading them in batches.
 * For each entry a function is called.
 */
function _pt_handle_entries($function$formdata$batch_size 0$filter = array()) {
    global 
$PIVOTX;

    if (
$batch_size 1) {
        
$batch_size 100;
    }
    
$entries_count $PIVOTX['db']->get_entries_count();
    
$batches ceil($entries_count/$batch_size);
    
$offset 0;
    
$params = array('show' => $batch_size'full' => false'status'=>'publish');
    if (
count($filter) > 0) {
        
$params array_merge($params$filter);
    }
    for (
$i 0$i $batches$i++) {

        
$params['offset'] = $offset
        
$entries $PIVOTX['db']->read_entries($params);
        
$offset += $batch_size;
        foreach (
$entries as $entry) {
            
$ret call_user_func($function$formdata$entry['uid']);
        }
    }
    return 
$ret;
}

/** 
 * Iterates through all the (chapters and) pages.
 * For each entry a function is called.
 */
function _pt_handle_pages($function$formdata) {
    global 
$PIVOTX;

    
$chapters $PIVOTX['pages']->getIndex();
    foreach (
$chapters as $key => $chapter) {

        
// If there is no pages, we skip this chapter
        
if (count($chapter['pages']) == 0) {
            continue;
        }

        
// Iterate through the pages
        
foreach ($chapter['pages'] as $page) {
            
$ret call_user_func($function$formdata$page['uri']);
        }
    }
    return 
$ret;
}

/**
 * The function that calls Disqus through the API (version 1.1).
 */
function _pt_call_disqus($method$formdata$args=array(), $post=false) {

    
$url 'http://disqus.com/api/' $method '/';
    
$args['user_api_key'] = $formdata['disqus_user_api_key'];
    
$args['forum_api_key'] = $formdata['disqus_forum_api_key'];
    
$args['api_version'] = '1.1';

    foreach (
$args as $key=>$value) {
        if (empty(
$value)) unset($args[$key]);
    }

    if (!
$post) {
        return 
_pt_curl_urlopen($url '?' http_build_query($args), "GET");
    } else {
        return 
_pt_curl_urlopen($url,"POST",$args);
    }
}

/**
 * Fetches an URL with cURL as a GET or POST request. Does not handle file 
 * uploads.
 */
function _pt_curl_urlopen($url,$type "GET",$fields = array()){
 
    if (!
function_exists('curl_init')){ 
        die(
'cURL is not installed!');
    }
 
    
$ch curl_init();
    
curl_setopt($chCURLOPT_URL$url);
    
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
    
$useragent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1";
    
curl_setopt($chCURLOPT_USERAGENT$useragent);

    if (
$type == "POST"){
        
curl_setopt($chCURLOPT_POST);
        if (
is_array($fields)) {
            
$fields http_build_query($fields);
        }
        
curl_setopt($chCURLOPT_POSTFIELDS$fields);
        
curl_setopt($chCURLOPT_FOLLOWLOCATION,1);
    } else {
        
curl_setopt($chCURLOPT_HEADER0);
        
curl_setopt($chCURLOPT_TIMEOUT10);
    }

    
// download the given URL
    
$output curl_exec($ch);

    if (
$output === false) {
        
debug("cURL error: " curl_error($ch));
    }

    
curl_close($ch);
 
    return 
$output;
}

/**
 * Outputs the Javascript functions used for batch processing of entries.
 */
function _pt_batch_js_functions($error='Something went wrong.') {
    
$output = <<<EOM
        function pt_ajaxBatchCall(func, start, time) {
            $.ajax({
                type: "POST",
                url: "extensions/pivotx_tools/ajaxhelper.php",
                data: "function="+func+"&start="+start+"&time="+time,
                dataType: "json",
                success: pt_batchHelper,
                error: function() { humanMsg.displayMsg("
$error") }
            });
        }
        function pt_batchHelper(data) {
            if (data.done) {
                humanMsg.displayMsg(data.text);
            } else {
                humanMsg.displayMsg(data.text);
                pt_ajaxBatchCall(data.func,data.start,data.time);
            }
        }
EOM;
    return 
$output;
}