<?php

define( 'DEBUG_SPIN', TRUE );
define( 'TIMEOUT',    20 );
define( 'LOCAL_SPIN', TRUE );

class Spin
{
    public $spinHost,
           $spinUser,
           $spinPass,
           $session,
           $error,
           $errno,
           $exarr = array(),
           $hideKeys = array();

    function __construct( $host, $user, $pass ) {

        $this->spinHost = $host;
        $this->spinUser = $user;
        $this->spinPass = $pass;

        if( !function_exists('curl_init') OR !function_exists('curl_exec') ) {
            die( "<font color='red'>CURL disabled on this server" );
        }
    }

    function auth() {

        $data = array( 'action' => 'authenticate',
                       'format' => 'php',
                       'username' => $this->spinUser,
                       'password' => $this->spinPass );
        $result = unserialize( $this->postData( $this->spinHost, $data ) );

        if( $result['success'] == 'true' ) {
            $this->session = $result['session'];
            return $this->session;
        }
        return 0;

    }

    function postData( $url, $data ) {

        $cleanData = "";
        foreach( $data as $key=>$var ) { 
            //if( $key == 'text' ) echo "<br>T0: ".urldecode(urlencode($var))."<br>";
            $cleanData .= "$key=".urlencode($var)."&"; 
        }
        
        if( DEBUG_SPIN ) $this->debugLog( "POST: $cleanData" );
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $cleanData);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_REFERER, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, TIMEOUT);
        $html = trim(curl_exec($ch));
        
        if(curl_errno($ch)) {
            $this->errno = curl_errno($ch);
            $this->error = curl_errno($ch);
            
            if( $this->errno == 28 ) { // Timeout
                if( LOCAL_SPIN AND ( $data['method'] == 'replaceEveryonesFavorites' OR $data['method'] == 'identifySynonyms' ) ) {
                    $this->localSpinText = $this->localSpinTextFile( $data['text'], $data['maxsyns'] );
                    
                    if( DEBUG_SPIN ) $this->debugLog( "Timeout! Go LocalSpin:\n".$this->localSpinText );
                    
                    return 0;
                }
            }
        }

        if( DEBUG_SPIN ) $this->debugLog( "Result:\n$html" );

        curl_close($ch);

        return $html;

    }

    function spinText( $text, $method, $maxsyns = 1, $quality = 1, $excluded = FALSE, $session = FALSE, $showone = TRUE ) {

        if( $excluded ) {
            $text = $this->exText( $text, $excluded );
        }
        
        if( $session ) {
            $this->session = $session;
        }
        $data = array( 'session' => $this->session,
                       'format' => 'php',
                       'text' => $this->hideText($this->delTags($this->cleanText($text))),
                       'action' => $method );

        switch( $method ) {
            case "replaceEveryonesFavorites":
                $data['maxsyns'] = $maxsyns;
                $data['quality'] = $quality;
                break;
            case "identifySynonyms":
                $data['maxsyns'] = $maxsyns;
                break;
            case "randomSpin":
                //
                break;
            default:
                return 0;
        }

        $result = unserialize( $this->postData( $this->spinHost, $data ) );
        
        // LOCAL SPIN
        if( !$result AND isset( $this->localSpinText ) ) {
            return $this->localSpinText;
        }

        if( $result['success'] == 'true' ) {
            $result = str_replace("\r", "<br>", $result['output']);

            if( $showone AND $data['maxsyns'] == 1 ) {
                preg_match_all("|{(.*)}|U",$result,$out);
                if( DEBUG_SPIN ) $this->debugLog( "Result [1] :\n$result" );
                foreach( $out[1] as $synonyms ) {
                    $synonym = explode( "|", $synonyms );
                    $randSynonym = $synonym[rand(0,(count($synonym)-1))];
                    if( $lastR == $randSynonym ) $randSynonym = $synonym[rand(0,(count($synonym)-1))];
                    $result = str_replace( '{'.$synonyms.'}', $randSynonym, $result );
                    $lastR = $randSynonym;
                }
                if( DEBUG_SPIN ) $this->debugLog( "Result [1] :\n$result" );
            }

            if( $excluded ) {
                $result = $this->unText( $result );
            }
            $return = preg_replace( '|\s+|', ' ', $return );
            $return = $this->unHideText(stripslashes($this->cleanText($result)));
            
            if( DEBUG_SPIN ) $this->debugLog( "Return:\n$return" );
            
            return $return;
        } else {
            return 0;
        }

    }

    function getQuota() {
        $data = array( 'session' => $this->session,
                       'action' => 'apiQuota');
        $result = unserialize( $this->postData( $this->spinHost, $data ) );
        if( $result['success'] == 'true' ) {
            return $result['output'];
        } else {
            return 0;
        }
    }

    function exText( $text, $excluded ) {
        $words = explode( "\n", $excluded );
        foreach( $words as $word ) {
            $word = trim( $word );
            $md5 = md5($word);
            $md5_word = $md5[1].$md5[2].$md5[3].$md5[4].$md5[5].$md5[6].$md5[7];
            $this->exarr[$md5_word] = $word;
            $text = str_replace( $word, $md5_word, $text );
        }
        return $text;
    }

    function unText( $text ) {
        foreach( $this->exarr as $md5=>$word ) {
            $text = str_replace( $md5, $word, $text );
        }
        return $text;
    }
    
    function getError($error=FALSE) {
        if( $error ) return $this->error;
        return $this->errno;
    }
    
    function hideText( $text ) {
        preg_match_all("|{(.*)}|U",$text,$out);
        if( count($out[1]) ) {
            foreach( $out[1] as $i=>$synonyms ) {
                $this->hideKeys[$i] = $synonyms;
                $text = str_replace( $synonyms, '{%hk'.$i.'%}', $text );
            }
        }
        return $text;
    }

    function unHideText( $text ) {
        foreach( $this->hideKeys as $i=>$synonyms ) {
            $text = str_replace( '%hk'.+$i.'%', $synonyms, $text );
        }
        //$this->hideKeys = array();
        $text = str_replace( '{{', '{', str_replace( '}}', '}', $text ) );
        return $text;
    }
    
    function cleanText( $text ) {
        $text = str_replace( '%u2018', '\'', $text );
        $text = str_replace( "%u201D", '"', $text );
        $text = str_replace( "%u201C", '"', $text );
        $text = str_replace( "&nbsp;", '', $text );
        //$text = preg_replace('!\s+!', ' ', $text);
        
        return $text;
    }
    
    function localSpinTextFile( $textbody, $maxsyns = 1 ) {
        // loading synonyms
        $synonyms = file( 'clean.txt', FILE_SKIP_EMPTY_LINES );
        $textbody = str_replace( '<p>', '', $textbody );
        $textbody = str_replace( '</p>', '', $textbody );
        
        $textbody = str_replace( '<span class="selected_tinymce_content">', '^@@#@@^', $textbody );
        
        $hashArray = array();
    
        foreach( $synonyms as $group ) {
            $group = trim( $group );
            $synonym = explode( '|', $group );
            foreach( $synonym as $word ) {
                $word = trim( $word );
                if( $word ) {
                    //preg_match("/[\s|\W]{0,1}".$word."[\W|_]{0,1}/i", $textbody, $matches, PREG_OFFSET_CAPTURE);
                    preg_match("/[\W|\s]".$word."[\W|\s]/i", $textbody, $matches, PREG_OFFSET_CAPTURE);
                    $match = $matches[0][1];
                    if ( isset($match) ) {
                        if ($match != 0) $match++;
                        $found = trim( substr( $textbody, $match, (strlen($word)+1) ) );
                        $hash = $this->generateHash();
                        //$group = str_ireplace( $found, "<b>$found</b>", $group );
                    
                        if( $maxsyns == 1 ) $maxsyns++;
                        
                        if( $maxsyns == 1 ) $group = $synonym[rand(0,count($synonym)-1)];
                        else {
                            $group = '{';
                        
                            if( $maxsyns > count($synonym) ) $max = count($synonym);
                            else $max = $maxsyns;
                        
                            for( $i=0; $i<$max; $i++ ) $group.= $synonym[$i].'|';
                            $group = preg_replace('/\|$/', '}', $group);
                        }
                    
                        $hashArray[$hash] = $group;
                        $textbody = str_replace( $found, " $hash ", $textbody ); 
                    }
                }
            }
        }
    
        foreach( $hashArray as $hash=>$var ) $textbody = str_replace( " $hash ", $var, $textbody );
        $textbody = str_replace( '^@@#@@^', '<span class="selected_tinymce_content">', $textbody );
        $textbody = str_replace( '}/span>', '}</span>', $textbody );
        
        return $textbody;
    }

    function generateHash() {
        $str = '!@#()^&()&@(#&';
        return '#'.$str[rand(1,15)].$str[rand(1,15)].$str[rand(1,15)].$str[rand(1,15)].$str[rand(1,15)].$str[rand(1,15)].'^';
    }
    
    function debugLog( $log ) {
        $fp = fopen( dirname(__FILE__).'/logs_spinner.txt', 'a' );
        fwrite( $fp, "\n[".date("Y-m-d H:i:s")."] $log\n" );
        fclose( $fp );
    }
    
    function delTags( $text ) {
        if( DEBUG_SPIN ) $this->debugLog( "Fucking tags:\n$text" );
        if( !preg_match_all( '|<[a\|A].* href=(.*)rel=[\'\|\"]tag[\'\|\"]>(.*)</[a\|A]>|U', $text, $out ) )
            if( !preg_match_all( '|<[a\|A] rel=[\'\|\"]tag[\'\|\"].* href=(.*)>(.*)</[a\|A]>|U', $text, $out ) )
                return $text;
                
        //print_r( $out ); exit;
                
        $countTags = count( $out[0] );
        $randCount = rand( 1,$countTags );
        if( $countTags > 6 AND $randCount > 6 ) $randCount = 6;
        for( $i = 0; $i < $randCount; $i++ ) {
            $randTag = rand(0,($countTags-1));
            $tag = $out[0][$randTag];
            $liveTags[$randTag] = $tag;
            $text = str_replace( $tag, '*lt'.$randTag.'*', $text );
        }
        
        foreach( $out[0] as $i=>$tags ) {
            $text = str_replace( 'Tags:  '.$tags.',', '', $text );
            $text = str_replace( 'Tags:  '.$tags, '', $text );
            $text = str_replace( $tags.',', '', $text );
            $text = str_replace( $tags, '', $text );
        }
        
        foreach( $liveTags as $i=>$tag ) $text = str_replace( '*lt'.$i.'*', $tag, $text );
        
        return $text;
    }
    
}

?>