<?php
/*
Plugin Name: Simple URL Shortener
Plugin URI: http://www.artiss.co.uk/simple-url-shortener
Description: Shorten a URL using one of over 100 shortening services
Version: 1.6.2
Author: David Artiss
Author URI: http://www.artiss.co.uk
*/
function simple_url_shortener($url,$paras_in) {

    // Get parameters and set up initial variable assignments
    $service_name=strtolower(shortener_parameters($paras_in,"service"));
    if ($service_name=="") {
        $service_name=$paras_in;
    } else {
        $cache=strtolower(shortener_parameters($paras_in,"cache"));
        $key=shortener_parameters($paras_in,"apikey");
        $login=shortener_parameters($paras_in,"login");
        $password=shortener_parameters($paras_in,"password");
        $debug=strtolower(shortener_parameters($paras_in,"debug"));
    }
    if ($url=="") {$url=get_permalink($post->ID);}
    $filekey=$url.$service_name.$key.$login;

    // Check if a cached version already exists - if so, return it
    if (($cache!="no")&&(function_exists('plugin_cache_read'))) {
        $return=plugin_cache_read($filekey,"","","surls");
        if ($debug=="yes") {plugin_cache_debug($return);}
        $shorturl=$return['data'];
    }

    // If no cached version returned, fetch and convert
    if ($shorturl=="") {

        // Build service URL
        $service_url=build_shortening_url($debug,$service_name,$key,$login,$password,$url);
        if ($service_url!="") {

            // If I don't yet have the short code data, fetch it
            $file_return=shortener_get_file($service_url);
            $return_data=$file_return['file'];
            if ($debug=="yes") {shortener_read_debug($file_return['rc']);}

            // Convert the returned data into a short URL
            $shorturl=convert_return_format($return_data,$service_name);
        }
    }

    // Return the full URL if no shortened URL was returned
    if ($shorturl=="") {
        $shorturl=$url;
    } else {

        // Update the cache, if required
        if (($cache!="no")&&($return['cache_update']=="Y")&&($shorturl!=$url)&&(function_exists('plugin_cache_update'))) {
            $return=plugin_cache_update($filekey,$shorturl,0,"surls");
            if ($debug=="yes") {plugin_cache_debug($return);}
        }
    }
    return $shorturl;
}

// Function to build the shortening URL
function build_shortening_url($debug,$service_name,$key,$login,$password,$url) {
    
    // Build array of services
    $shortening_services=build_services_array();

    // Get the URL of the required shortening service
    $service_url=$shortening_services[$service_name];
    if ($service_url=="") {
        if ($debug=="yes") {echo "<p>Error: Shortening service not found</p>\n";}
    } else {

        // Make any API key, login, etc changes
        $service_url=str_replace("{key}",$key,$service_url);
        $service_url=str_replace("{login}",$login,$service_url);
        $service_url=str_replace("{password}",$password,$service_url);
        $service_url=str_replace("{blog}",get_bloginfo('url'),$service_url);

        // Access the service API and get the shortened URL
        if (substr($service_url,0,1)=="#") {
            $service_url=substr($service_url,1).$url;
        } else {
            $service_url.=urlencode($url);
        }
        if ($cache=="no") {echo "<p>".$service_url."</p>";}
    }
    return $service_url;
}

// Function to convert return format (if necessary)
function convert_return_format($shorturl,$service_name) {

    // Extract the URL from XML files
    $xml_convert=build_xml_array();
    if ($xml_convert[$service_name]!="") {$shorturl=shortener_extract_xml($shorturl,$xml_convert[$service_name]);}

    // Extract the URL from JSON files
    $json_convert=build_json_array();
    if ($json_convert[$service_name]!="") {$shorturl=shortener_extract_json($shorturl,$json_convert[$service_name]);}

    // If only a short code is returned, append the rest of the URL on
    $url_addition=build_url_array();
    if ($url_addition[$service_name]!="") {$shorturl=$url_addition[$service_name].$shorturl;}

    // For other file modifications, treat them individually
    if (($service_name=="fon.gs")or($service_name=="ln-s.net")) {$shorturl=substr($shorturl,4);}
    if ($service_name=="url.co.uk") {$shorturl=substr($shorturl,9);}
    if ($service_name=="digg.com") {
        $xml_start=strpos($service_name,'short_url="')+11;
        $xml_end=strpos($service_name,'" view_count=')-1;
        if (($xml_end===true)&&($xml_end===true)) {$shorturl=substr($service_name,$xml_start,$xml_end-$xml_start);}
    }
    return $shorturl;
}

// Function to output results of file read, if failed and debug is swithced on
function shortener_read_debug($rc) {
    echo "<p>Fetching file (non-cache): ";
    if ($rc==1) {echo "Info: File fetched successfully with cURL";}
    if ($rc==2) {echo "Info: File fetched successfully with file_get_contents";}
    if ($rc==-1) {echo "Error: cURL active but no file fetched";}
    if ($rc==-2) {echo "Error: file_get_contents allowed but no file fetched";}
    if ($rc==-3) {echo "Error: cURL and file_get_contents not active";}
    echo "</p>\n";
    return;
}

// Function to extract parameters from an input string (1.0)
function shortener_parameters($input,$para) {
    $start=strpos(strtolower($input),$para."=");
    $content="";
    if ($start!==false) {
        $start=$start+strlen($para)+1;
        $end=strpos(strtolower($input),"&",$start);
        if ($end!==false) {$end=$end-1;} else {$end=strlen($input);}
        $content=substr($input,$start,$end-$start+1);
    }
    return $content;
}

// Function to get a file using CURL or alternative (1.4)
function shortener_get_file($filein) {
    $fileout="";
    // Try to get with CURL, if installed
    if (in_array('curl',get_loaded_extensions())===true) {
        $cURL = curl_init();
        curl_setopt($cURL,CURLOPT_URL,$filein);
        curl_setopt($cURL,CURLOPT_RETURNTRANSFER,1);
        $fileout=curl_exec($cURL);
        curl_close($cURL);
        if ($fileout=="") {$rc=-1;} else {$rc=1;}
    }
    // If CURL failed and a url_fopen is allowed, use that
    $fopen_status=strtolower(ini_get('allow_url_fopen'));
    if (($fileout=="")&&(($fopen_status===true)or($fopen_status=="yes")or($fopen_status=="on")or($fopen_status=="1"))) {
        $fileout=file_get_contents($filein);
        if ($fileout=="") {$rc=-2;} else {$rc=2;}
    }
    if ((in_array('curl',get_loaded_extensions())!==true)&&(ini_get('allow_url_fopen')==1)) {$rc==-3;}
    $file_return['file']=$fileout;
    $file_return['rc']=$rc;
    return $file_return;
}

// Function to extract from an XML compatible file (1.1 - modified)
function shortener_extract_xml($filein,$tag) {
    $tag_space=strpos($tag," ",1);
    if ($tag_space!=0) {
        $tag_start=strpos($filein,"<".$tag);
        $bracket_find=strpos($filein,">",$tag_start);
        $tag_end=strpos($filein,"</".substr($tag,1,$tag_space-1).">",$field_start);
        $tag_extend=$bracket_find - $tag_end;
    } else {
        $tag_start=strpos($filein,"<".$tag.">");
        $tag_extend=0;
        $tag_end=strpos($filein,"</".$tag.">",$field_start);
    }
    if (($tag_start===false)or($field_end===false)) {
        if ($debug=="yes") {echo "<p>Error: Could not find XML tag</p>\n";} else {$field="";}
    } else {
        $field_start=$tag_start+strlen($tag)+2;
        $field_end=$tag_end+$tag_extend-1;
        $field=substr($filein,$field_start,$field_end-$field_start+1);
    }
    return $field;
}

// Very simple function to extract from a JSON formtat file (1.0 - modified)
function shortener_extract_json($filein,$tag) {
    $tag_start=strpos($filein,'"'.$tag.'":');
    if ($tag_start!==false) {
        $tag_start=$tag_start+3+strlen($tag);
        $json_start=strpos($filein,'"',$tag_start)+1;
        $json_end=strpos($filein,'"',$json_start)-1;
    } else {
        $tag_start=strpos($filein,"'".$tag."':");
        if ($tag_start!==false) {
            $tag_start=$tag_start+3+strlen($tag);
            $json_start=strpos($filein,"'",$tag_start)+1;
            $json_end=strpos($filein,"'",$json_start)-1;
        }
    }
    if (($tag_start===false)or($json_start===false)or($json_end===false)) {
        if ($debug=="yes") {echo "<p>Error: Could not find JSON tag</p>\n";} else {$field="";}
    } else {
        $field=str_replace("\/","/",substr($filein,$json_start,$json_end-$json_start+1));
    }
    return $field;
}

// Function to validate a URL shortening service
function validate_url_shortener($validate_text,$validate_mask) {

    // Ensure that the service tag is in the mask
    if (strpos($validate_mask,"{service}")===false) {$validate_mask="{service}";}

    // Build array of services
    $shortening_services = build_services_array();

    // Read through each service name and attempt to find it in the text,
    // applying any masks
    foreach($shortening_services as $key => $value) {
        $find_in_text = str_replace('{service}',$key,$validate_mask);
        if (strpos($validate_text,$find_in_text)!==false) {$shorturl=$key;}
    }
    return $shorturl;
}

// Function to build array of URL shortening services
function build_services_array() {
    $service=array( "1url.com"=>"http://1url.com/?api=1url&u=",
                    "2zeus"=>"http://2ze.us/generate/?url=",
                    "307.to"=>"http://a.307.to/api2/post?format=text&u=",
                    "307.to+key"=>"http://a.307.to/api2/post?format=text&key={key}&u=",
                    "3.ly"=>"http://3.ly/?api=em5893833&u=",
                    "9mp"=>"http://9mp.com/api/shrink.php?username={login}&key={key}&version=1.0&mode=live&url=",
                    "abbrr"=>"http://api.abbrr.com/api.php?out=link&url=",
                    "adjix"=>"http://api.adjix.com/shrinkLink?partnerID={key}&url=",
                    "ad.vu"=>"http://api.adjix.com/shrinkLink?partnerID={key}&ultraShort=y&url=",
                    "a.gd"=>"http://a.gd/?module=ShortURL&file=Add&mode=API&url=",
                    "a.nf"=>"http://a.nf/?module=ShortURL&file=Add&mode=API&url=",
                    "arm.in"=>"#http://arm.in/arminize/",
                    "buk.me"=>"http://buk.me/api.php?url=",
                    "bit.ly+key"=>"http://api.bit.ly/shorten?version=2.0.1&login={login}&apiKey={key}&format=xml&longUrl=",
                    "budurl"=>"http://budurl.com/api/v1/budurls/shrink?api_key={key}&long_url=",
                    "chilp.it"=>"http://chilp.it/api.php?url=",
                    "clck.ru"=>"http://clck.ru/--?url=",
                    "cli.gs"=>"http://cli.gs/api/v1/cligs/create?url=",
                    "coge.la"=>"http://coge.la/api.php?url=",
                    "coge.la+key"=>"http://coge.la/api.php?user={login}&password={password}&url=",
                    "cort.as"=>"http://www.soitu.es/cortas/encode.pl?r=json&u=",
                    "cort.as+key"=>"http://www.soitu.es/cortas/encode.pl?r=json&k={key}&u=",
                    "durl.me"=>"http://durl.me/api/Create.do?type=json&longurl=",
                    "ez.com"=>"http://ez.com/api/v1/ezlinks/shrink?api_key={key}&long_url=",
                    "fa.by"=>"http://fa.by/?module=ShortURL&file=Add&mode=API&url=",
                    "fon.gs"=>"http://fon.gs/create.php?url=",
                    "fwd4.me"=>"http://api.fwd4.me/?url=",
                    "gl.am"=>"http://gl.am/API::shorten?type=plain&url=",
                    "gurl.es"=>"http://gurl.es/api.php?url=",
                    "hex.io"=>"http://hex.io/api-create.php?url=",
                    "hop.im"=>"http://hop.im/api.php?url=",
                    "href.in"=>"http://href.in/api.php?create=",
                    "hurl"=>"http://www.hurl.ws/api/url=",
                    "is.gd"=>"http://is.gd/api.php?longurl=",
                    "idek.net"=>"http://idek.net/shorten/?idek-api=true&idek-url=",
                    "ir.pe"=>"http://ir.pe/?api=1&url=",
                    "ito.mx"=>"http://ito.mx/?module=ShortURL&file=Add&mode=API&url=",
                    "j.mp"=>"http://j.mp/api?url=",
                    "j.mp+key"=>"http://api.j.mp/shorten?version=2.0.1&login={login}&apiKey={key}&format=xml&longUrl=",
                    "kissa.be"=>"http://kissa.be/api/shortener/url?content=",
                    "kl.am"=>"http://kl.am/api/shorten/?format=text&url=",
                    "kore.us"=>"http://kore.us/api.php?type=plain&action=encode&url=",
                    "korta.nu"=>"http://korta.nu/api/api.php?url=",
                    "kots.nu"=>"http://kots.nu/api.php?apikey={key}&url=",
                    "krz.ch"=>"http://krz.ch/?module=ShortURL&file=Add&mode=API&url=",
                    "lincr"=>"http://lin.cr?mode=api&full=1&l=",
                    "linkbee"=>"#http://linkbee.com/api.php?task=quicken&url=",
                    "linkbee+key"=>"#http://linkbee.com/api.php?task=shorten&user={login}&pass={password}&url=",
                    "linkee"=>"http://api.linkee.com/1.0/shorten?format=text&input=",
                    "linxfix"=>"http://linxfix.com/enterlink.php?link=",
                    "liurl.cn"=>"http://liurl.cn/api-create.php?url=",
                    "lnk.by"=>"http://lnk.by/Shorten?format=json&url=",
                    "ln-s.net"=>"http://ln-s.net/home/api.jsp?url=",
                    "ln-s.ru"=>"http://ln-s.ru/?nohtml&u=",
                    "lt.tl"=>"http://lt.tl/api.php?create=",
                    "lurl.no"=>"http://lurl.no/api/0.1/?url=",
                    "merky.de"=>"http://merky.de/api/?short=1&url=",
                    "micurl"=>"http://micurl.com/api.php?url=", 
                    "migre.me"=>"http://migre.me/api.txt?url=",
                    "min2me"=>"http://min2.me/api_new.xml?url=",
                    "minify.us"=>"http://minify.us/api.php?u=",
                    "minilink"=>"http://minilink.org/?xml=1&url=",
                    "minurl"=>"http://www.minu.me/api.php?url=",
                    "nbx.ch"=>"http://nbx.ch/_exec/create.php?service=wordpress_plugin_da&uri=",
                    "ndurl"=>"http://www.ndurl.com/api.generate/?type=web&url=",
                    "pendek.in"=>"http://pendek.in/?url=",
                    "piko.me"=>"http://piko.me/?url_API=",
                    "piurl"=>"#http://www.piurl.com/api.php?url=",
                    "p.ly"=>"http://p.ly/api/shorten?url=",
                    "puke.it"=>"http://puke.it/api.php?apikey={key}&url=",
                    "qlnk.net"=>"http://qlnk.net/api.php?url=",
                    "qr.cx"=>"http://qr.cx/api/?longurl=",
                    "qux.in"=>"http://qux.in/api/shorten?apiKey={key}&longUrl=",
                    "r.im"=>"http://r.im/api/index.cfm?long_url=",
                    "rde.me"=>"http://rde.me/index.php?rdeTask=api&longURL=",
                    "redir.ec"=>"http://redir.ec/_api/rest/redirec/create?url=",
                    "retwt.me"=>"http://api.retwt.me/shorten?longUrl=",
                    "ri.ms"=>"http://ri.ms/api-create.php?url=",
                    "s4c"=>"http://s4c.in/api.php?username=apiconnect&password=nohash&action=shorturl&adtype=2&url=",
                    "safe.mn"=>"http://safe.mn/api/?url=",
                    "sai.ly"=>"http://www.sai.ly/new.txt?href=",
                    "short.ie"=>"http://short.ie/api?format=xml&url=",
                    "short.to"=>"http://short.to/s.txt?url=",
                    "shortn.me"=>"http://shortn.me/api.php?url=",
                    "shw.me"=>"http://shw.me/redirects/api?url=",
                    "sl.ly"=>"http://sl.ly/?module=ShortURL&file=Add&mode=API&url=",
                    "smsh.me"=>"http://smsh.me/?api=xml&url=",
                    "snkr.me"=>"http://snkr.me/api.php?url=",
                    "srnk.net"=>"http://srnk.net/create.php?url=",
                    "srs.li"=>"http://srs.li/api/create?plaintext&url=",
                    "su.pr"=>"http://su.pr/api?url=",
                    "su.pr+key"=>"http://su.pr/api/shorten?login={login}&apiKey={key}&longUrl=",
                    "timesurl"=>"http://timesurl.at/api/rest.php?url=",
                    "tinyarro.ws"=>"http://tinyarro.ws/api-create.php?url=",
                    "tinyurl"=>"http://tinyurl.com/api-create.php?url=",
                    "togoto.us"=>"http://togoto.us/api.php?u=",
                    "to.ly"=>"http://to.ly/api.php?longurl=",
                    "to.vg"=>"http://to.vg/api.php?apiusr={login}&apikey={key}&urlquery=",
                    "tra.kz"=>"http://tra.kz/api/shorten?api={key}&l=",
                    "tr.im"=>"http://api.tr.im/api/trim_simple?url=",
                    "twirl"=>"http://twirl.at/api.php?url=",
                    "twiturl.de"=>"http://api.twiturl.de/friends.php?output=txt&new_url=",
                    "ur.ly"=>"http://ur.ly/new.json?href=",
                    "u.nu"=>"http://u.nu/unu-api-simple?url=",
                    "uiopme"=>"http://uiop.me/api/newlink.php?u=",
                    "unfake.it"=>"http://unfake.it/?a=api&url=",
                    "url.co.uk"=>"http://url.co.uk/api/?ua=Simple+URL+Shortener&key={key}&url=",
                    "urlborg"=>"http://urlborg.com/api/{key}/url/create.xml/",
                    "urlkiss"=>"http://urlkiss.com/api/?x=",
                    "urlshort"=>"http://u.mavrev.com/api.php?url=",
                    "urlg"=>"http://urlg.in/yourls-api.php?action=shorturl&url=",
                    "url.ag"=>"http://url.ag/api.php?create=",
                    "v.gd"=>"http://v.gd/create.php?format=simple&url=",
                    "vb.ly"=>"http://vb.ly/api/?action=shorturl&format=simple&url=",
                    "vl.am"=>"#http://vl.am/api/shorten/plain/",
                    "vtc.es"=>"http://vtc.es/create.php?url=",
                    "wapurl"=>"http://wapURL.co.uk//api.cfm?URLToConvert=",
                    "xrl.us"=>"http://metamark.net/api/rest/simple?long_url=",
                    "xr.com"=>"http://api.xr.com/api?link=",
                    "xxsurl"=>"http://xxsURL.de/api.php?url=",
                    "zi.pe"=>"http://zi.pe/api.php?url=",
                    "zipmyurl"=>"#http://zipmyurl.com/api.do?api=true&url=",
                    "z.pe"=>"http://api.z.pe/new.json?href=",
                    "zz.gd"=>"http://zz.gd/api-create.php?url=");
    return $service;
}

// Function to build array of XML tags for URL extraction
function build_xml_array() {
    $xml_convert=array( "arm.in"=>"arminized_url",
                        "9mp"=>"short",
                        "bit.ly+key"=>"shortUrl",
                        "j.mp+key"=>"shortUrl",
                        "min2me"=>"min2me",
                        "minilink"=>"minilink",
                        "retwt.me"=>"shortUrl",
                        "short.ie"=>"shortened",
                        "shw.me"=>"shwme-url",
                        "smse.me"=>"body",
                        "urlborg"=>"s_url",
                        "wapurl"=>"wapURL",
                        "xxsurl"=>"shortlink");
    return $xml_convert;
}

// Function to build array of JSON tags for URL extraction
function build_json_array() {
    $json_convert=array("2zeus"=>"shortcut",
                        "budurl"=>"budurl",
                        "cort.as"=>"urlCortas",
                        "cort.as+key"=>"urlCortas",
                        "durl.me"=>"shortUrl",
                        "ez.com"=>"ezlink",
                        "linkbee"=>"link",
                        "lnk.by"=>"shortUrl",
                        "ndurl"=>"shortURL",
                        "su.pr+key"=>"shortUrl",
                        "tra.kz"=>"s",
                        "ur.ly"=>"code",
                        "z.pe"=>"code",
                        "zipmyurl"=>"zipURL");
    return $json_convert;
}

// Function to build array of URLs to be appended to the beginning of short codes
function build_url_array() {
    $url_addition=array("micurl"=>"http://micurl.com/",
                        "tra.kz"=>"http://tra.kz/",
                        "ur.ly"=>"http://ur.ly/",
                        "z.pe"=>"http://z.pe/",
                        "zipmyurl"=>"http://zipmyurl.com/");
    return $url_addition;
}
?>