<?php
/**
 * Trackback CExt
 */
require_once 'Platy/CExt.php';

class Platy_CExt_Trackback extends Platy_CExt
{
    function install() 
    {
        global $db;
        
        $sql[] = "CREATE TABLE Platy_CExt_Trackback("
             . "id          integer NOT NULL,"
             . "title       varchar(255),"
             . "excerpt     varchar(255),"
             . "url         varchar(255),"
             . "blog_name   varchar(255),"
             . "created     datetime,"
             . "ip_addr     varchar(32));";
        $sql[]= "INSERT INTO Platy_Config(name,value) VALUES('P_TRACKBACK_PROHIBITION_PERIOD', '180')";
        $sql[]= "INSERT INTO Platy_Config(name,value) VALUES('P_TRACKBACK_AUTO_DISCOVERY', 'yes')";
        for ($i = 0; $i < count($sql); $i++) {
            $db->query($sql[$i]);
        }
        return true;
    }
    
    function uninstall() 
    {
        global $db;
        
        $sql[] = "DROP TABLE Platy_CExt_Trackback";
        $sql[] = "DELETE FROM Platy_Config WHERE name='P_TRACKBACK_PROHIBITION_PERIOD'";
        $sql[] = "DELETE FROM Platy_Config WHERE name='P_TRACKBACK_AUTO_DISCOVERY'";
        for ($i = 0; $i < count($sql); $i++) {
            $db->query($sql[$i]);
        }
        return true;
    }
    
    // イベントハンドラ
    
    function event_PostContentFooter() 
    {
        global $db, $currentContent, $Me;
        
        $sql = "SELECT COUNT(*) "
             . "FROM Platy_CExt_Trackback "
             . "WHERE id={$currentContent['id']} ";
        $row = $db->fetchRow($sql);
        echo '<a href="' . $currentContent['url'] . '#trackback">';
        echo 'Trackback(' . $row['COUNT(*)'] . ')';
        echo '</a>' . "\n";
    }
    
    function event_PostContent() {
        global $db, $currentContent, $Me;
        
        $id = $currentContent['id'];
        
        echo 'この記事に対するトラックバックURL:' . "\n";
        echo '<input type="text" size="60" value="';
        echo BASE_FULL_URL . 'Trackback/ping/id/' . $id;
        echo '">';
        echo "<br />\n";
        
        $sql = "SELECT title, excerpt, url, blog_name, created FROM Platy_CExt_Trackback WHERE id={$id} ORDER BY created DESC";
        $rows = $db->fetchAll($sql);
        
        echo '<a name="trackback"></a>' . "\n";   // ページ内リンク
        echo '<h4>Trackbacks(' . count($rows) . ')</h4>' . "\n";
        for ($i = 0; $i < count($rows); $i++) {
            $row = $rows[$i];
            echo '<a href="' . $row['url'] . '">';
            echo $row['title'];
            echo '</a>';
            echo '&nbsp;&nbsp;';
            echo $row['blog_name'];
            echo "<br />\n";
            echo $row['excerpt'];
            echo "<br />\n";
            echo "受信:" . $row['created'] . "<br />\n";
        }
    }
    
    function event_AddContentFormExtras()
    {
        echo '<tr><th>トラックバック送信先URL</th><td>';
        echo '<input type="text" name="CExt_Trackback" size="60" />' . "\n";
        echo '</td></tr>' . "\n";
    }
    
    function event_PostAddContent()
    {
        $this->event_PostEditContent();
    }
    
    function event_EditContentFormExtras()
    {
        echo '<tr><th>トラックバック送信先URL</th><td>';
        echo '<textarea name="CExt_Trackback" rows="2" cols="60">';
        echo '</textarea>' . "\n";
        echo '</td></tr>' . "\n";
    }
    
    function event_PostEditContent()
    {
        global $db, $currentContent, $Me, $config;
        
        //# htmlspecialchar しないこと(URLの & が amp; などに変換されると動作しなくなる)
        $ping_url = $_POST['CExt_Trackback'];
        $id = $currentContent['id'];
        
        $sql = "SELECT title, summary FROM Platy_Content_Base WHERE id={$id}";
        $row = $db->fetchRow($sql);
        $title = $row['title'];
        $excerpt = $row['summary'];
        $blog_name = $config['S_SITE_NAME'];
        $content = getContentFromId($id);
        $url = BASE_FULL_URL . $content['url'];
        //---
        $fp = fopen(BASE_PATH . 'private/log.txt', 'a');
        if ($fp) {
            fprintf($fp, "%s\n", $url);
            fclose($fp);
        }
        //---
                    
        $ping_url_list = split("\n", $ping_url);
        foreach ($ping_url_list as $item) {
            $ping_url = trim($item);
            if ($ping_url != '') {
                $error = $this->sendPing($title, $url, $excerpt, $blog_name, $ping_url);
                if ($error) {
                    //---
                    $fp = fopen(BASE_PATH . 'private/log.txt', 'a');
                    if ($fp) {
                        fprintf($fp, "%s:%s\n", $ping_url, $error);
                        fclose($fp);
                    }
                    //---
                }
            }
        }
    }
    
    function event_DeleteContent() 
    {
        global $db, $currentContent, $Me;
        $sql = "DELETE "
             . "FROM Platy_CExt_Trackback "
             . "WHERE cid={$currentContent['id']} ";
        $db->exec($sql);
    }
    
    function event_PreViewContent()
    {
        global $db, $currentContent, $Me;
        $content = getContentFromId($currentContent['id']);
        // RDF表示
        echo '<!--' . "\n";
        echo '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' . "\n";
        echo '         xmlns:dc="http://purl.org/dc/elements/1.1/"' . "\n";
        echo '         xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">' . "\n";
        echo '<rdf:Description' . "\n";
        echo '    rdf:about="' . BASE_FULL_URL . $content['url'] . '"' . "\n";
        echo '    dc:identifier="' . BASE_FULL_URL . $content['url'] . '"' . "\n";
        echo '    dc:title="' . $content['title'] . '"' . "\n";
        //dc:description=""
        //dc:creator=""
        //dc:date="2007-10-02T21:00:59+09:00" />
        echo '    trackback:ping="' . BASE_FULL_URL . 'Trackback/ping/id/' . $currentContent['id'] . '" />' . "\n";
        echo '</rdf:RDF>' . "\n";
        echo '-->' . "\n";
    }
    
    function deleteCType($name) 
    {
    }
    
    /**
     * 設定
     */
    function config() {
        global $db, $config;
        
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        }
        else {
        }
    }
    
    public function getSummary()
    {
        return 'コンテンツにトラックバックを付加します';
    }
    
    /**
     * ping送信
     * nucleus:plugin:NP_TrackBack code
     */
    private function sendPing($title, $url, $excerpt, $blog_name, $ping_url)
    {
        //# Check some basic things
        if ($ping_url == '') {
            return 'No ping URL';
        }
        
        //# Check if protocol is correct http URL
        $parsed_url = parse_url($ping_url);

        if ($parsed_url['scheme'] != 'http' || $parsed_url['host'] == '') {
            return 'Bad ping URL';
        }
        $port = ($parsed_url['port']) ? $parsed_url['port'] : 80;
        
        //# Create contents
        $content  = 'title=' . urlencode($title);
        $content .= '&url=' . urlencode($url);
        $content .= '&excerpt=' . urlencode($excerpt);
        $content .= '&blog_name=' . urlencode($blog_name);
        
        $user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)';
        
        //# Prepare HTTP request
        $request  = 'POST ' . $parsed_url['path'];
        if ($parsed_url['query'] != '') {
            $request .= '?' . $parsed_url['query'];
        }
        
        $request .= " HTTP/1.1\r\n";
        $request .= "Accept: */*\r\n";
        $request .= "User-Agent: " . $user_agent . "\r\n";
        $request .= ( $port == 80 ) ? 
                    "Host: " . $parsed_url['host'] . "\r\n":
                    "Host: " . $parsed_url['host'] . ":" . $port . "\r\n";
        $request .= "Connection: Keep-Alive\r\n";
        $request .= "Cache-Control: no-cache\r\n";
        $request .= "Connection: Close\r\n";
        $request .= "Content-Length: " . strlen( $content ) . "\r\n";
        $request .= "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
        $request .= "\r\n";
        $request .= $content;
        
        $socket = fsockopen($parsed_url['host'], $port, $errno, $errstr);
        if (!$socket) {
            return 'Could not send ping: '.$errstr.' ('.$errno.')';
        }
        
        //# Execute HTTP request
        fputs($socket, $request);
        
        //---
        $fp = fopen(BASE_PATH . 'private/log.txt', 'a');
        if ($fp) {
            fprintf($fp, "request=\n%s\n", $request);
            fclose($fp);
        }
        //---
        
        //# Receive response
        $result = '';
        while (!feof($socket)) {
            $result .= fgets($socket, 4096);
        }
        fclose($socket);
        
        //---
        $fp = fopen(BASE_PATH . 'private/log.txt', 'a');
        if ($fp) {
            fprintf($fp, "%s\n", $result);
            fclose($fp);
        }
        //---
        
        $DATA = split("\r\n\r\n", $result, 2);
        preg_match("/HTTP\/1\.[0-1] ([0-9]+) ([^\r\n]*)\r?\n/",$DATA[0],$httpresp);
        $respCd = $httpresp[1];
        $respMsg = $httpresp[2];

        if ($respCd != 200) {
            return 'An error occurred: HTTP Error: [' . $respCd . '] ' . $respMsg;
        }
        if (strstr($DATA[1],'<error>0</error>') === false) {
            preg_match("/<message>(.*?)<\/message>/",$DATA[1],$error_message);
            if ($error_message[1]) {
                return 'An error occurred: '.htmlspecialchars($error_message[1], ENT_QUOTES);
            }
            else {
                return 'An error occurred: fatal error.';
            }
        }
    }
}
?>
