'Date added', 'lastchecked' => 'Date checked', 'rpagerank' => 'Inbound Pagerank', 'rdom' => 'Inbound Domain', 'rdomip' => 'Inbound IP', 'rindexed' => 'Inbound Indexed Pages', 'lpagerank' => 'Outbound Pagerank', 'ldom' => 'Outbound Domain', 'ldomip' => 'Outbound IP', 'lindexed' => 'Outbound Indexed Pages', 'link' => 'Link', 'anchor' => 'Anchor', 'title' => 'Title', 'status' => 'Status' ); // {{{ Session hijack check $myuid = md5( linkex::get( 'REMOTE_ADDR', $_SERVER ) . linkex::get( 'HTTP_USER_AGENT', $_SERVER ) ); if ( ( $hash = linkex::get( 'hash', $_SESSION, false ) ) !== false ) { if ( ( $hash != $myuid ) || ( ( ( $ss = linkex::get( 'sid', $_GET, false ) ) !== false ) && ( $ss != session_id() ) ) ) { session_destroy(); session_id( md5( uniqid() ) ); setcookie( 'sid', '', time() - 1, '/' ); linkex::redirect( BASEURI ); } } // }}} // {{{ Strip slashes from userinput if ( get_magic_quotes_gpc() ) { function stripslashes_deep( $value ) { if( is_array( $value ) ) { $value = linkex::map( 'stripslashes_deep', $value ); } elseif ( !empty( $value ) && is_string( $value ) ) { $value = stripslashes( $value ); } return $value; } $_POST = stripslashes_deep($_POST); $_GET = stripslashes_deep($_GET); $_COOKIE = stripslashes_deep($_COOKIE); } // }}} // {{{ Std. includes class linkex { function arraychunk( $array, $size, $fill=false ) { // {{{ $i = $j = 0; $retval=array(); if ( is_array( $size ) ) { $i = $k = 0; foreach( $size AS $s ) { $s = ( $s == '' ) ? ( sizeof($array)-$i ) : intval( $s ); for( $n=0; $n<$s; $n++, $i++ ) { $retval[$k][] = $array[$i]; } $k++; } } else { if ( $fill !== false ) { $count = ceil(sizeof($array)/$size)*$size; } else { $count = sizeof( $array ); } for ($i=0; $i<$count;$i++) { if ($i>0 && ($i%$size)==0) { $j++; } $retval[$j][$i%$size] = (empty($array[$i])) ? $fill : $array[$i]; } } return $retval; } // }}} function authorized() { // {{{ global $config; $r=$u=$p=$a=false; $remember = ( linkex::get( 'remember', $_REQUEST, 0 ) == 1 ); if ( ( $u = linkex::get( 'username', $_POST, false ) ) && ( $p = linkex::get( 'password', $_POST, false ) ) ) { $r=true; } else if ( $a = linkex::get( '_authcookie', $_SESSION, false ) ) { $r=false; } else if ( $a = linkex::get( '_authcookie', $_COOKIE, false ) ) { $remember=true; $r=false; } $path = dirname( linkex::get( 'SCRIPT_NAME', $_SERVER, '/' ) ); if ( ( $u !== false && $p !== false ) || ( $a !== false ) ) { if ( md5( $u .'---'. $p ) == $config->password || $a == $config->password ) { $_SESSION['_authcookie'] = $config->password; if ( $remember ) { setcookie( '_authcookie', $config->password, time()+60*60*24*30, $path ); } if ( $r ) { linkex::redirect( $_SERVER['REQUEST_URI'] ); } return true; } else { setcookie( '_authcookie', '', time() - 3600, $path ); unset( $_SESSION['_authcookie'] ); return false; } } else { setcookie( '_authcookie', '', time() - 3600, $path ); unset( $_SESSION['_authcookie'] ); return false; } } // }}} function buildquery( $array ) { // {{{ $retval = array(); foreach( $array AS $k=>$v ) { $retval[] = urlencode( $k ).'='.urlencode( $v ); } return join( '&', $retval ); } // }}} function categories( $all = false, $checkslots=false ) { // {{{ $categories = array(); $cids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ); foreach( $cids AS $cid ) { $c = new category( $cid ); if ( ( $all || $c->public == 1 ) && ( !$checkslots || ( $checkslots && $c->slots > 0 && $c->links() < $c->slots ) ) ) { $categories{ $cid } = $c->name; } unset( $c ); } return $categories; } // }}} function compareIPs( $a, $b ) { // {{{ a can be 127., 127.0, 127.0.0, 127.0.0.1, or a hostname if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $a ) ) { $a = linkex::gethostbyname( $a ); } if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $b ) ) { $b = linkex::gethostbyname( $b ); } $a = explode( '.', $a ); $b = explode( '.', $b ); for( $i=0; $ilinkbotdisregardwww == 1 ) { $a = str_replace( 'www.', '', $a ); $b = str_replace( 'www.', '', $b ); } if ( $config->linkbotignoretrailingslash == 1 ) { $a = rtrim( $a, '/' ); $b = rtrim( $b, '/' ); } return strcmp( $a, $b ); } // }}} function checkbox( $val ) { // {{{ return ( intval( $val ) != 0 ) ? 'checked="checked"':''; } // }}} function du( $dir ) { // {{{ $s = @stat( $dir ); $space = linkex::get( 'size', $s, 0 ); if ( is_dir( $dir ) ) { $dh = opendir( $dir ); while ( ( $file = readdir( $dh ) ) !== false ) { if ( !in_array( $file, array( '.', '..' ) ) ) { $space += linkex::du( rtrim( $dir, '/' ) .'/'. $file ); } } closedir( $dh ); } return $space; } // }}} function elapsed( $seconds ) { // {{{ $retval = array( 'Y' => 0, 'm' => 0, 'd' => 0, 'H' => 0, 'i' => 0, 's' => 0, 'nice' => '' ); // Years ( 60*60*24*365 ) = 31536000 seconds if ( $seconds > 31536000 ) { $retval{'Y'} = floor( $seconds / 31536000 ); $seconds = $seconds - ( $retval{'Y'} * 31536000 ); $retval{'nice'} = $retval{'Y'} . ' year' . ( $retval{'Y'}>1?'s':'' ); } // Months ( 60*60*24*30 ) = 2592000 if ( $seconds > 2592000 ) { $retval{'m'} = floor( $seconds / 2592000 ); $seconds = $seconds - ( $retval{'m'} * 2592000 ); $retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . $retval{'m'} . ' month' . ( $retval{'m'}>1?'s':'' ); } // Days ( 60*60*24 ) = 86400 if ( $seconds > 86400 ) { $retval{'d'} = floor( $seconds / 86400 ); $seconds = $seconds - ( $retval{'d'} * 86400 ); $retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . $retval{'d'} . ' day' . ( $retval{'d'}>1?'s':'' ); } // Hours ( 60*60 ) = 3600 if ( $seconds > 3600 ) { $retval{'H'} = floor( $seconds / 3600 ); $seconds = $seconds - ( $retval{'H'} * 3600 ); $retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . $retval{'H'} . ' hour' . ( $retval{'H'}>1?'s':'' ); } // Minutes ( 60 ) = 60 if ( $seconds > 60 ) { $retval{'i'} = floor( $seconds / 60 ); $seconds = $seconds - ( $retval{'i'} * 60 ); $retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . $retval{'i'} . ' minute' . ( $retval{'i'} > 1 ? 's':'' ); } // Seconds 0 if ( $seconds >= 0 ) { $retval{'s'} = $seconds; $retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . $retval{'s'} . ' second' . ( $retval{'s'}>1?'s':'' ); } return $retval; } // }}} function expandlink( $link, $baseurl ) { // {{{ preg_match( "'^[^\?]+'", $baseurl.'/', $res ); $res = preg_replace( "|/[^\/\.]+\.[^\/\.]+$|", '', $res[0] ); $res = rtrim( $res, '/' ); if ( ( $root = @parse_url( $res ) ) ) { $root = $root['scheme'] .'://'. $root['host']; } else { // fixme // die( 'Unable to parse: '.$res ); $root = 'http://'; } $search = array( "|^(\/)|i", "|^(?!http://)(?!mailto:)|i", "|/\./|", "|/[^\/]+/\.\./|" ); $replace = array( $root .'/', $res . '/', '/', '/' ); return preg_replace( $search, $replace, $link ); } // }}} function fetch( $url, $params=array() ) { // {{{ global $config; if ( ( $host = @parse_url( $url ) ) && linkex::get( 'host', $host, false ) !== false ) { $po = linkex::get( 'port', $host, '80' ); $ho = linkex::get( 'host', $host, '' ); $pa = linkex::get( 'path', $host ); $pa = ( strlen( $pa ) == 0 ) ? '/':$pa; $qu = linkex::get( 'query', $host, '' ); $pa.= ( strlen( $qu ) == 0 ) ? '':'?'.$qu; $cua = array_map( 'trim', explode("\n", $config->linkbotagent ) ); shuffle($cua); $cua = $cua[0]; $ua = linkex::get( 'agent', $params, $cua ); $h = array(); $h[]= linkex::get( 'method', $params, 'GET' ).' '.$pa.' HTTP/1.0'; $h[]= 'Host: '.$ho; $h[]= 'User-Agent: '.$ua; $h[]= 'Connection: close'; if ( ( $ref = linkex::get( 'referer', $params, false ) ) !== false ) { $h[] = 'Referer: '.$ref; } if ( linkex::get( 'method', $params, 'GET' ) == 'POST' && strlen( linkex::get( 'data', $params, '' ) ) > 0 ) { $h[]= 'Content-Length: '.strlen( linkex::get( 'data', $params, '' ) ); $h[] = 'Content-Type: application/x-www-form-urlencoded'; } $header = join( "\r\n", $h ) . "\r\n\r\n"; if ( ( $data = linkex::get( 'data', $params, false ) ) !== false ) { $header .= $data; } $buffer = ''; $fp = @fsockopen ( $ho, $po, $errno, $error, linkex::get( 'timeout', $params, 3 ) ); if ( !$fp ) { return array( 'URL' => $url, 'error' => 'Socket error: '.$error.' ['.$errno.']' ); } else { @stream_set_timeout($fp, linkex::get( 'timeout', $params, 3 ) ); fputs( $fp, $header ); while( !feof( $fp ) ) { $buffer .= fgets( $fp, 1024 ); } fclose( $fp ); /// buffer holder nu hele resultatet, incl headers etc if ( preg_match( '/^HTTP\/(\d+\.\d+)\s+(\d{3})\s+(.*)/i', $buffer, $res ) === false ) { return array( 'URL' => $url, 'error' => 'Invalid HTTP response ('.substr( $buffer,0,30).')' ); } else { switch ( $res[2] ) { case 200: /// ok /// strip off the headers $res = explode( "\n\n", str_replace( chr( 13 ), '', $buffer ) ); if ( sizeof( $res ) >= 2 ) { $headers = array_shift( $res ); if ( function_exists( 'utf8_encode' ) ) { $contents = utf8_encode( join( "\n\n", $res ) ); } else { $contents = join( "\n\n", $res ); } return array( 'URL' => $url, 'headers' => $headers, 'contents' => $contents ); } else { return array( 'URL' => $url, 'contents' => utf8_encode( $buffer ) ); } break; case 301: case 302: /// maybe redirect? if ( !preg_match( '/location\:\s+(.*)/i', $buffer, $redir ) ) { return array( 'URL' => $url, 'error' => $res[2].' but no redirect' ); } else { $url = rtrim( $redir[1] ); if ( !preg_match( '"^http"i', $url ) ) { $url = 'http://'.$ho.'/'.ltrim( $url, '/' ); } if ( ( $h = @parse_url( $url ) ) === false ) { return array( 'URL' => $url, 'error' => $res[2].' but unparsable URL' ); } else { if ( str_replace( 'www.', '', strtolower( linkex::get( 'host', $h, '' ) ) ) != str_replace( 'www.','', strtolower( $ho ) ) ) { return array( 'URL' => $url, 'error' => $res[2].' but to external site ('.linkex::get( 'host', $h, '' ).')' ); } else { return linkex::fetch( trim( $url ) ); } } } break; default: /// not good return array( 'URL' => $url, 'error' => $res[2].' '.trim( $res[3] ) ); break; } } } } else { return array( 'URL' => $url, 'error' => 'Unparsable URL' ); } } // }}} function fileget( $file, $default=null ) { // {{{ if ( file_exists( $file ) ) { if ( $fp = @fopen( $file, 'r' ) ) { $locked = ( @flock( $fp, LOCK_EX ) ) ? true:false; // $default = fread( $fp, filesize( $file ) ); $default = ''; while ( !feof( $fp ) ) { $default .= fread( $fp, 1024*1024 ); } if ( $locked ) { @flock( $fp, LOCK_UN ); } fclose( $fp ); } } return $default; } // }}} function fileput( $file, $con ) { // {{{ if ( $fp = @fopen( $file, 'w' ) ) { $locked = ( @flock( $fp, LOCK_EX ) ) ? true:false; $default = fwrite( $fp, $con ); if ( $locked ) { @flock( $fp, LOCK_UN ); } @fclose( $fp ); return ( intval( $default ) > 0 ); } else { return false; } } // }}} function flush() { // {{{ echo str_pad('',4096)."\n"; flush(); usleep( 500000 ); } // }}} function genID() { // {{{ $id = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR .'uid' ); $id++; linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR .'uid', $id ) or die( "[Fatal Error: Unable to write to UID file]" ); return $id; } // }}} function get( $key, $array, $default=null ) { // {{{ if ( is_array( $array ) && in_array( $key, array_keys( $array ) ) ) { $default = $array{ $key }; } return $default; } // }}} function getDomain( $var ) { // {{{ $var = strtolower( $var ); if ( ( $pos = strpos( $var, '@' ) ) !== false ) { // Email $domain = substr( $var, $pos + 1 ); } else { // URL $domain = @parse_url( $var ); $domain = linkex::get( 'host', $domain, 'unparseable' ); } return $domain; } // }}} function gethostbyname( $dom, $force=false ) { // {{{ $dom = strtolower( trim( $dom ) ); $data = array(); if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'ips' ) && ( $data = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'ips' ) ) && ( $data = linkex::unserialize( $data ) ) ) { if ( ( $force === false ) && ( $ipinfo = linkex::get( $dom, $data, false ) ) !== false && ( time() - linkex::get( 'date', $ipinfo, 0 ) ) < 604800 && ( $ip = linkex::get( 'ip', $ipinfo, false ) ) !== false && preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $ip ) == 1 ) { unset( $data ); return $ip; } } $ip = @gethostbyname( $dom ); if ( $dom != $ip ) { $data{ $dom } = array( 'date' => time(), 'ip' => $ip ); linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'ips', trim( serialize( $data ) ) ); unset( $data ); } return $ip; } // }}} function getLinks( $str, $baseurl ) { // {{{ $thisdom = linkex::getDomain( $baseurl ); preg_match_all( "'<\s*a.*>(.*)<\s*/\s*a\s*>'Umis", $str, $res ); $links = array(); for( $i=0; $i' ); } $retval = ''; for($i=$pos+$d;$i0 && $haystack{$i-1} == '\\' ) );$retval.=$haystack{$i}, $i++ ) {} foreach( $end AS $c ) { $retval = str_replace( '\\'.$c, $c, $retval ); } return $retval; } else { return $default; } } /// }}} function glob( $dir, $regex ) { // {{{ $files = array(); if ( $d = @opendir( $dir ) ) { while ( false !== ( $file = readdir( $d ) ) ) { if ( preg_match( '|' . $regex . '|i', $file ) ) { $files[] = $file; } } } return $files; } // }}} function installed() { // {{{ return ( is_dir( BASEDIR . DIRECTORY_SEPARATOR .'data' ) && is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR ) && is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR ) && is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ) && is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ) && is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ) && is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR ) ); } // }}} function listfiles( $dir, $ext=array() ) { // {{{ $retval = array(); if ( is_dir( $dir ) ) { if ( $dh = opendir( $dir ) ) { while ( ( $file = readdir( $dh ) ) !== false ) { if ( filetype( rtrim( $dir, DIRECTORY_SEPARATOR ) .DIRECTORY_SEPARATOR. $file ) == 'file' ) { $retval[] = $file; } } } } return $retval; } // }}} function log( $level, $type, $str ) { // {{{ $file = 'linkex.log'; $log = sprintf( "[%s] [level=%d] [%s] %s\n", date( 'Y-m-d H:i:s' ), $level, $type, $str ); $fp = fopen( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . $file, 'a' ); flock( $fp, LOCK_EX ); fwrite( $fp, $log ); fclose( $fp ); } // }}} function map( $fun, $arr ) { // {{{ $retval = array(); foreach( $arr AS $k=>$v ) { $retval[ $k ] = $fun( $v ); } return $retval; } // }}} function mail( $to, $sub, $body ) { // {{{ global $config; $headers = array(); $headers[] = 'X-Mailer: LinkEX/20100226'; if ( strlen( $config->email ) > 0 ) { $headers[] = sprintf( 'From: LinkEX @ %s <%s>', linkex::get( 'HTTP_HOST', $_SERVER, linkex::getdomain( $config->url ) ), $config->email ); $headers[] = sprintf( 'Reply-To: %s', trim( $config->email ) ); } return mail( $to, $sub, $body, join( str_replace( array( '\r', '\n' ), array( "\r", "\n" ), $config->emailcrlf ), $headers ) ); } // }}} function redirect( $url, $code=301 ) { // {{{ $resp = array( 301 => 'HTTP/1.1 301 Moved Permanently', 404 => 'HTTP/1.1 404 Not Found' ); if ( ( $resp = linkex::get( $code, $resp, false ) ) !== false ) { header( $resp ); } header( 'location: '.$url ); exit; } // }}} function selector( $name, $list, $selected=null, $multiple=true, $forcetype=null, $extra=null, $sep='
' ) { /// {{{ $type = ( $multiple ) ? 'checkbox':'radio'; $type = ( sizeof( $list ) > 5 ) ? 'select':$type; if ( $forcetype && in_array( $forcetype, array( 'checkbox', 'radio', 'select' ) ) ) { $type = $forcetype; } $extra['class'] = $type.' '.linkex::get( 'class', $extra, '' ); if ( $extra ) { $buffer=array(); foreach( $extra AS $k=>$v ) { $buffer[] = sprintf( '%s="%s"', $k, $v ); } $extra=' '.join( ' ', $buffer ); } else { $extra=''; } $formname = ( $multiple ) ? $name.'[]' : $name; $buffer = ''; if ( $type == 'select' ) { $buffer .= sprintf( ' %s%s', $formname, $id, ($ck)?' checked="checked"':'', $extra, $txt, $sep ); } elseif ( $type == 'radio' ) { $buffer .= sprintf( '%s', $formname, $id, ($ck)?' checked="checked"':'', $extra, $txt, $sep ); } } if ( $type == 'select' ) { $buffer .= ''; } return $buffer; } /// }}} function serialize( $val ) { // {{{ return serialize( $val ); } // }}} function sort( &$array, $field, $order='desc' ) { // {{{ if ( $field == 'random' ) { shuffle( $array ); } else { $GLOBALS['sortby'] = $field; usort( $array, array( 'linkex', 'usort' ) ); if ( $order == 'desc' ) { $array = array_reverse( $array ); } } } // }}} function stripcomments( $con ) { // {{{ $con = preg_replace( '||Umis', '', $con ); $con = preg_replace( '||Umis', '', $con ); $con = preg_replace( '||Umis', '', $con ); return $con; } // }}} function substr( $str, $len, $pad='..' ) { // {{{ if ( strlen( $str ) > $len ) { return substr( $str, 0, $len - strlen( $pad ) ) . $pad; } else { return $str; } } // }}} function truncate( $str, $len, $txt='..' ) { // {{{ if ( strlen( $str ) > ( $len-strlen( $txt ) ) ) { return substr( $str, 0, $len-strlen( $txt ) ).$txt; } else { return $str; } } // }}} function unserialize( $str ) { // {{{ $retval = @unserialize( $str ); if ( $retval !== false ) { return $retval; } else { // Attempt to fix it $str = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", trim( $str ) ); $retval = @unserialize( $str ); if ( $retval !== false ) { return $retval; } else { echo '[Fatal error in linkex::unserialize( "'. $str .'" )]'; } } } // }}} function usort( $a, $b ) { // {{{ if ( isset( $GLOBALS['sortby'] ) && strlen( $GLOBALS['sortby'] ) > 0 ) { $f = $GLOBALS['sortby']; if ( is_object( $a ) && isset( $a->$f ) ) { $aa = $a->$f; } else if ( is_array( $a ) && isset( $a[$f] ) ) { $aa = $a[$f]; } else { $aa = $a; } if ( is_object( $b ) && isset( $b->$f ) ) { $bb = $b->$f; } else if ( is_array( $b ) && isset( $b[$f] ) ) { $bb = $b[$f]; } else { $bb = $b; } switch( $f ) { case 'ldomip': case 'rdomip': $aa = sprintf( '%u', ip2long( $aa ) ); $bb = sprintf( '%u', ip2long( $bb ) ); break; case 'ldom': case 'rdom': $aa = str_replace( 'www.', '', strtolower( $aa ) ); $bb = str_replace( 'www.', '', strtolower( $bb ) ); break; case 'title': case 'link': case 'anchor': $aa = strtolower( $aa ); $bb = strtolower( $bb ); break; } if ($aa == $bb) { return 0; } return ($aa < $bb) ? -1 : 1; } else { return 0; } } // }}} function verifybacklinks( $ids=array(), $callback=null ) { // {{{ global $config; $retval = array( 'starttime' => time(), 'links' => array(), 'categories' => array() ); foreach( $ids AS $id ) { $l = new link( $id, false ); $l->updateIPs(true); $buffer = array( 'action' => 'link', 'id' => $l->id, 'rdom' => $l->rdom, 'rdomip' => $l->rdomip, 'rurl' => $l->rurl, 'skipcheck' => $l->skipcheck, 'skippagerank' => $l->skippagerank, 'minpagerank' => ( $l->minpagerank != -1 ) ? $l->minpagerank : $config->minpagerank, 'oldstatus' => $l->status, 'oldpagerank' => $l->pagerank ); if ( $l->skipcheck == 0 ) { $pr = $l->getRPageRank(); $l->getLPageRank(); $l->getRIndexedPages(); $l->getLIndexedPages(); $buffer{'res'} = $l->hasBacklink(); $buffer{'code'} = ( !is_string( linkex::get( 'reason', $buffer{'res'}, null ) ) ) ? '200 OK' : $l->laststatus; if ( $l->status != 4 ) { $l->status = ( ( $pr >= ( ( $l->minpagerank != -1 ) ? $l->minpagerank : $config->minpagerank ) ) && ( linkex::get( 'res', $buffer{'res'}, -1 ) == 0 ) ) ? 1:2; } if ( intval( $config->disableblacklisted ) == 1 && ( ( $b = $l->blacklisted() ) !== false )) { $l->status = 2; $buffer{'res'} = 64; $buffer{'code'} = $b; $l->log[] = array( 'date' => time(), 'res' => '64', 'reason' => $b ); } } else { $l->lastcheked = time(); $l->log[] = array( 'date' => time(), 'res' => '32', 'reason' => '' ); } $l->save( false ); $buffer{'status'} = $l->status; $buffer{'pagerank'} = $l->getRPageRank(false); $retval{'links'}[] = $buffer; unset( $l ); if ( $callback != null && function_exists( $callback ) ) { call_user_func( $callback, $buffer ); } unset( $buffer ); } // Rebuild categories $categories = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ); foreach( $categories AS $cid ) { $c = new category( $cid ); $c->generate(); $buffer = array( 'action' => 'category', 'id' => $cid, 'name' => $c->name ); $retval{'categories'}[] = $buffer; unset( $c ); if ( $callback != null && function_exists( $callback ) ) { call_user_func( $callback, $buffer ); } unset( $buffer ); } $retval{'endtime'} = time(); return $retval; } // }}} function sum( $array = array() ) { // {{{ $retval = 0; foreach( $array AS $a ) { $retval += $a; } return $retval; } // }}} function yesno( $val ) { // {{{ return ( $val ) ? 'Yes':'No'; } // }}} } class template { function about() { // {{{ global $config; if ( LOGGEDIN ) { $phpver = phpversion(); $umask = sprintf( "%04o", umask() ); $zendver = zend_version(); $uname = php_uname( "s" )." ".php_uname( "r" )." ".php_uname( "m" ); $du = round( linkex::du( BASEDIR . DIRECTORY_SEPARATOR . 'data' ) / 1024, 2 ).'KB'; $links = sizeof( linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ) ); $installdate = date( $config->dateformat, $config->installdate ); $precision = ini_get( 'precision' ); if ( function_exists( 'gd_info' ) ) { $gd = gd_info(); $gd = sprintf( '%s - GIF Support: %s', $gd{'GD Version'}, ( ( $gd{'GIF Create Support'} ) ? 'enabled':'unsupported, using plain text for CAPTCHA if used' ) ); } else { $gd = 'Not installed, using plain text for CAPTCHA if used.'; } echo "
Server info
PHP version: {$phpver}
Zend version: {$zendver}
GD Info: {$gd}
Server OS: {$uname}
php.precision {$precision}
umask {$umask}
LinkEX info
LinkEX version: 20100226
Current version: stand by..
Database size: {$du}
Links: {$links}
Install date: {$installdate}
LinkEX info
"; } else { echo "
Powered by LinkEX
This site is powered by LinkEX, a free script that will take care of accepting link exchange requests, and, if needed, making sure a link back is present.

If you run a website, you can have this script also. Head over to linkex.dk, and get your free copy.

Features
  • Free! This script is free. No hidden fees, no nothing.
  • Easy to install - upload 1 (one) file, fill out the basic settings, and you are good to go.
  • One click updates. Update the script, just by a single click. The script will fetch the latest release, install it, making sure you are up to date at all times.
  • Advancend link robot. You choose what sites to check for backlinks, and the bot will make sure the link is present.
  • Google PageRank™ check. The script will show you the PageRank™ of all your link partners.
  • And much much more..
Head over to linkex.dk to read more
"; } } // }}} function footer() { // {{{ $params = array( 'BASEURI' => BASEURI ); return "
v.20100226 © linkex.dk 2006-2010
"; } // }}} function header( $params = array() ) { // {{{ global $errors, $config; $params = array_merge( array( 'BASEURI' => BASEURI, 'menu' => Template::menu(), 'title' => '', 'onload' => '', 'metadescription' => '' ), $params ); if ( isset( $params{'metarobots'} ) && strpos( $params{'metarobots'}, '<' ) === false ) { $params{'metarobots'} = sprintf( '', strtoupper( $params{'metarobots'} ) ); } else { $params{'metarobots'} = ''; } $error = ''; $charset = isset( $config->charset ) ? $config->charset : 'utf-8'; if ( linkex::get( 'noerrors', $params, true ) && sizeof( $errors ) > 0 ) { $error = join( '
', $errors ); $error = "
Error
{$error}
"; } return " LinkEX » {$params{'title'}} {$params{'metarobots'}}
 
    {$params{'menu'}}
{$error} "; } // }}} function linkdetails() { // {{{ global $config; $url = $config->url; $anchor = $config->anchor; $anchor = $anchor[ mt_rand( 0, sizeof( $anchor )-1 ) ]; $title = $config->title; $title = $title[ mt_rand( 0, sizeof( $title )-1 ) ]; $description = $config->description; $htmlcode = str_replace( array( '{$URL}', '{$ANCHOR}', '{$DESCRIPTION}', '{$TITLE}' ), array( htmlentities( $url ), htmlentities( $anchor ), htmlentities( $description ), htmlentities( $title ) ), $config->htmlcode ); // {{{ Show the email if ( intval( $config->showemail ) == 1 ) { $email = " Email: {$config->email} "; } else { $email = ''; } // }}} return "
Our linking details {$email}
URL: {$url}
Site title: {$anchor}
Site description: {$description}
HTML code:
{$htmlcode}
"; } // }}} function linkform() { // {{{ global $config; $_POST['email'] = htmlentities( linkex::get( 'email', $_POST, ( (LOGGEDIN)?$config->email:'') ) ); $_POST['lurl'] = htmlentities( linkex::get( 'lurl', $_POST, '' ) ); $_POST['rurl'] = htmlentities( linkex::get( 'rurl', $_POST, '' ) ); $_POST['anchor'] = htmlentities( linkex::get( 'anchor', $_POST, '' ) ); $_POST['description'] = htmlentities( linkex::get( 'description', $_POST, '' ) ); // {{{ Show the recip field if public or loggedin if ( intval( $config->disablerecipfield ) == 0 || intval( $config->samedomain ) == 2 ) { $extra=''; switch( intval( $config->samedomain ) ) { case 1: $extra = 'Must be on the same domain as above'; break; case 2: $extra = 'Must be on a different domain as above'; break; } $recipfield = " Reciprocal link URL: {$extra} "; } else { $recipfield = ''; } // }}} // {{{ Show the categories if loggedin or public if ( ( $cat = linkex::get( 'categories', $_REQUEST, false ) ) !== false ) { if ( !is_array( $cat ) ) { $cat = linkex::map( 'trim', explode( ',', $cat ) ); } } else { $cat = $config->defaultcategories; } if ( intval( $config->publiccategories ) == 1 || LOGGEDIN ) { $categories = linkex::categories( LOGGEDIN ); $cats = array(); foreach( $categories AS $cid=>$name ) { $cats[] = new Category( $cid ); } $categories = $cats; unset( $cats ); linkex::sort( $categories, 'name', 'asc' ); $cats = array(); foreach( $categories AS $c ) { $cats{ $c->id } = $c->name; } $categories = $cats; unset( $cats ); $categories = linkex::selector( 'categories', $categories, linkex::get( 'categories', $_POST, $cat ), LOGGEDIN, null, array( 'style' => 'width:auto;max-width:300px;' ) ); $categories = " Category: {$categories} "; } else { $categories = ''; } // }}} // {{{ CAPTCHA html tag put into => $captcha (the class will know weathe to use img or html if ( intval( $config->usecaptcha ) == 1 && !LOGGEDIN ) { $c = new captcha; $captchatag = $c->html(); $captcha = " Spam check:
{$captchatag}
"; } else { $captcha = ''; } // }}} if ( LOGGEDIN ) { $skipbacklinkcheck = linkex::checkbox( linkex::get( 'skipbacklinkcheck', $_POST, 0 ) ); $skippagerank = linkex::checkbox( linkex::get( 'skippagerank', $_POST, 0 ) ); $skipblacklist = linkex::checkbox( linkex::get( 'skipblacklist', $_POST, 0 ) ); $skiplengths = linkex::checkbox( linkex::get( 'skiplengths', $_POST, 0 ) ); $skipdupes = linkex::checkbox( linkex::get( 'skipdupes', $_POST, 0 ) ); $adminoptions = "
Since you are logged in, you have additional options: "; } else { $adminoptions = ''; } // Lengths $anchorlength = ( $config->anchorlength > 0 ) ? ( 'max. '.$config->anchorlength.' '.(( $config->anchorlengthtype == 'w' )?'words':'characters' )) : ''; $titlelength = ( $config->titlelength > 0 ) ? ( 'max. '.$config->titlelength.' '.(( $config->titlelengthtype == 'w' )?'words':'characters' )) : ''; $descriptionlength = ( $config->descriptionlength > 0 ) ? ( 'max. '.$config->descriptionlength.' '.(( $config->descriptionlengthtype == 'w' )?'words':'characters' )) : ''; return "
Your linking details
{$recipfield} {$captcha} {$categories} {$adminoptions}
Site title: {$titlelength}
Your URL:
Your email:
Site description: {$descriptionlength}

"; } // }}} function menu() { // {{{ if ( linkex::installed() ) { if ( defined( 'LOGGEDIN' ) && LOGGEDIN ) { $menu = "
  • » Add link
  • » Home
  • » Tools
  • » Categories
  • » Blacklist
  • » Settings
  • » Log out
  • » About
  • "; } else { $menu = "
  • » Add link
  • » Admin
  • » About
  • "; } } else { $menu = ' '; } return $menu; } // }}} function navigation( $start, $pages, $uri ) { // {{{ $retval = ''; if ( $pages > 1 ) { if ( $start > 1 ) { $retval .= "« prev"; } else { $retval .= "« prev"; } for( $i=1; $i<=$pages; $i++ ) { $retval .= " "; if ( $i == $start ) { $retval .= ''. $i .''; } else { $retval .= "".$i.""; } } $retval .= " "; if ( $start < $pages ) { $retval .= "next »"; } else { $retval .= "next »"; } } return $retval; } // }}} function pagerank( $pr ) { // {{{ $pr = max( min( intval( $pr ), 10 ), 0 ); $perc = $pr * 10; return "
     
    {$pr}
    "; } // }}} function progress( $progress ) { // {{{ echo " "; linkex::flush(); } // }}} function report( $report ) { // {{{ $startdate = date( 'Y-m-d H:i:s', $report{'starttime'} ); $enddate = date( 'Y-m-d H:i:s', $report{'endtime'} ); $elapsed = linkex::elapsed( $report{'endtime'} - $report{'starttime'} ); $elapsed = $elapsed{'nice'}; $sp = "% 6s % -20s % -15s % 6s => % -10s % 10s => % -10s\n"; $links = sprintf( $sp, 'ID', 'Domain', 'IP', 'Old PR', 'New PR', 'Old Status', 'New status' ) . "==========================================================================================\n"; foreach( $report{'links'} AS $data ) { $links .= sprintf( $sp, $data{'id'}, linkex::truncate( $data{'rdom'}, 20 ), $data{'rdomip'}, $data{'oldpagerank'}, $data{'pagerank'}, link::statusOptions( $data{'oldstatus'} ), link::statusOptions( $data{'status'} ) ); } $sp = "% 6s % -20s % -10s\n"; $categories = sprintf( $sp, 'ID', 'Name', 'Status' ) . "==========================================================================================\n"; foreach( $report{'categories'} AS $data ) { $categories .= sprintf( $sp, $data{'id'}, linkex::truncate( $data{'name'}, 20 ), 'done' ); } return "LinkEX verification output. =========================== verification started on: {$startdate} verification ended on: {$enddate} verification elapsed: {$elapsed} * Verifying backlinks.. {$links} * Rebuilding categories.. {$categories} "; } // }}} function rules() { // {{{ global $config; $linkback = ( intval( $config->linkbackrequired ) == 1 ) ? 'R'.'equired':'Not r'.'equired'; $rules = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules', "We are constantly looking for new perm link exchanges to improve link popularity and page rank.
    Please remember that this is not about traffic, it's about the link.
    Play fair! " ); $maxoutboundlinks = ( $config->maxoutboundlinks>0 ) ? " Max. links: {$config->maxoutboundlinks} external links on reciprocal link URL " : ''; return "
    Rules {$maxoutboundlinks}
    {$rules}
    Linkback: {$linkback}
    Min. PageRank™:
    minpagerank}\">
    "; } // }}} } if ( linkex::get( 'page', $_REQUEST ) == 'file' ) { switch( linkex::get( 'view', $_REQUEST ) ) { case 'sprite': $image = base64_decode('R0lGODlhNwD9AOZ/AP///6qqql6qXsVvCJGw0q7H49HR0b6+vpWVlfTZWIWFhQAAANra2vKIdpXIhkycKbHbpvvx0d7e3nO1auHh4c3NzV+Jt2qWw+3t7enp6eN7dtbW1vOzrHPGZih+JE9wqDCGDvDw8IO4aFCzLulbUO7Msz2GN1WW0HaizvXNyfalne3JdcnJyUBalHl5eaOjo4bGdfaWh9Hc6KXWmdaiPanKktjq1O/QjP366slmU8PDw91tZ+Tk5Oj25O1rXGykOpSVorfcsUyXQ53Sk2vGTOi5Q222VmVlZVmgQ1tbW57Imvn5+dvg5/778uGqMPno5Pbkt/nolHO7W+Ts9dabUvH47+rw9t2xR8LlukeQGZG8jdqbJf39/WSlR6HHis+FG4vIgcNSOcLM2thcUPb4+uXp72GeMenBXqTA3vz8++Dm6/P09pjOjeHv3/3+/bCwsFy+PH+xWP/+/P7//79bQMTT4t+om5273GGvVK7Nlfj79nSrT/z9/kGCwFmlT////yH5BAEAAH8ALAAAAAA3AP0AAAf/gAGCg4SFhoeIiH+LjI1/AQCRkpOUlZaXlQGOm5CYnp+fmosLC5ygp6iSoqV/rIydqbGYq6OOsLK4k7Sttrm+qoyknInExcaim6/Hy8zIyY+/v87JkALWAtGpq66N1dfZqMjcrwDX2OCg4tTl3+ihwevu2qPCts33xM/K+PyF+ou35L37582cNYGUto2DZrAdwkjTxhU0+BAYPVMND1YEsMvUxln06u3rR/LfI5IoTQb8qEslu4wO3SnECDMmuoi9atoEJ27hRJgIcXZjeWmmPZT9VCJNSpCopWk0dZq7WcvnS6kas9GyinUqz6pRu1JtRUqi00yNfC7lp3TtPZdn/1s27ZpRWkizdBva5bUuL0VfRof69ZpLKLm4FssOc9usLeNlcBFzdDm4bqyeYStnDVerr2bCnMly/bxzICuzkidfPPr4mOPWxSIjhpqTtN50d2vbBg0yre7dm3t3Fgy8NNrhQ1OrWww7NsHmxmTHpU28+N+nwUZb5y339O/t57Cvrg4+/HHvySVjZg1d0fP2iaSfpU6uvGWLZDPbN68aff39vPWEF4A2GQZQaqrlxx58/rzHoCHyOUXfgQTWtc14P1WIjTroZVhhgqV0eJWGG8IjonIhKXjSgxCa5OKLMMYo44w01mjjjTjmqOOOPPbo448yAiHkkEAAOSMQlhRpJP+MQHDh5AJOkqHkki4CscQSZCxAxhplTEnlP0BkWdYCanj55TNhrhHCAlaUwYSZZ24CRBlqMLEAEzLIAGecjQAhQx1iBBronnwyQuSQhSaq6KKMNuroo5BGiuahhCaKZCWV8tmkk5xKCamVWJKxZZefillWmaWqGUKbb35KJxOw5plpnH4CKqgYs9JKqaS89urrr8AGK+ywxM4YwrHIJqvsssw26+yzIWAg7bTUVmvttdhmi2202nbr7bfZZiDuuOSWa+656KaLLgbqtuvuu+nyIO+89NZr77345ptvBvr26++/+VIg8MAEF2zwwQgnnDAPFEjg8MMQRyzxxBRXTHH/wxZnrPHGFDPg8ccghyzyyCSXXLIEJqes8somb+DyyzDHLPPMNNdMMwM256zzzjYb4PPPQAct9NBEF030BkYnrfTSRlfg9NNQRy311FRXTbUBVmet9dZXV8DC12CHLfbYZJdtdtlOn6322myTXUGxcMct99x01z1jDxAQAQccRMzQwzNPcKDBDjtowMETz1hRAAonNI7GFDBiQYQUM0AAwQxGjIDFJiloEEMKoHNAeAqbyHACCmgUUMAdF/RRh4tYwAFGEEPAAMMQQcDwQBCNpLDD4RyoEIMKnedAOiOmE7A6ASgoT8AHr+vTAxGzd2D99bk/0MYiT2igwhMxxNBA//gNiJ4D4n9YcYLyKKBQABrto/E85M9AIEUQ11+PBQxBdOHAIhxoQArI14ACNsAHHAiDHRZRgAssrn2iah/qLEAAffRtCPnrABYA0AM2sEEIizCcChpAghKa0Acx0EAOFnGCOzAvfmi4gAwJcIcP6GMEEIBBB4JgAw0CIA1s6AAEPLCI34mvEiTwgQrCsIg+PFCGAJiDDGVYgBbcMIcwqAIAtAhEKYhgiEUcYQOQqEQm/sGJKJiiDMggQws40IrPgMMQMJhFALjBAUaQggMcYIIQjs8HJgxkA1TIQheqkQwWSGTzbPiMIeABAh2QAgxswAYj5BECQtACAMegAh8AMv+QJFjiAv9wBwvE0IF8mIMMEvm8Cj6jDQ+Agf2kYMlLisAE2/vDEwinAlCGcgx0QN8UPoAC1iXymMxrQRn+EQQQfJENIhCBAyAgAg/wjhEpyMEORgjIBqhgDGEoQSPE0IJioiCRF0imGFwUBBMgwQEzmIEDhGBNzuUgDJ5LYRjoIE5HiOEDFESD/D7QgnW+qA1aMIEHPGACLeRyE0+wQw7oEIYc2AF9myjD81rQgg8QYJl2C6lIR3qjJejgBW94AQ/WgNIX6GAJjEpDAF6AAR5U4AUBoAAPDIDTNKTFFYrxkQ4QQAEEHMEFL0CAC46AgKGyAB588c+OEIAABiwhCSz/YEAFDpCEJTCAqtmpR1B79AYFfDUJSTjCEdBaVQW8AaroWQiOJOCCABzgAAFQAALsilcXSACuKfIRF+iqgMJmtbAK8CsXSMrYkZq0pStt6UtjOtOa3jSnO+3pT8O6WRwNtahHTepSm4qAp3YmrqfFEVWtilWtctWrYM2NaKCao7KeNa1rTUJb35raqPbWRnTla173etcA+BWws81OjgbrAsQetrCKbax06/bYlEY2pZNdlExpalOc6pSnAfCpcgM7nrHC6LNGRapSmepU5KLWt3yB0WqvmtWtdvWrCAjraUQyDqm6yLYIQKta2coAt7q3t++FUXCLq1fhHhfBIlGR/3lfxFznFhi6EljsdDfM4RfJ4QwrkIOvbkBiKORICUrYUROK0IQIsPhGSpiAADSZoxXcoAk4IHGN3BBjD87YDTdysRyiEAUcOCECNAqCCCYwRxmn2EZngAIOaECDCNzgDDbCwwyGgAQcQSHECaByAnAQ5RppeQh+uNGKI4CDMNMgARGAAg2aQCMmz2ACT6aRjXEQhQRc4c1jXsEKaOTBIbABzzQycosTwOgzMLrIX8Bo5GAQz0MjQQiYNoGmTXKGG/CZ0WJmdARWQIUZVYEN8JyjBx0ABjDAoI/6gMIZmgAFRtv61jigQj9j1AY2wCDVq241rJ9RBCg04djIPjYOltbdhBJ8gUZVwIID8IAHP/jh0kIYdjJW4AQnbOHb3/6CuAdA7gGUusPoTre64/QAM5jhBz/oVRZqkIc8xJtXWfCCCOzdKxDouwZmkBQIQGCGf8cB3o/SAwjeKYI4iKAGcQj4o9oAAv+JwAt7eIAeImWDijugC1nYuKQ6jgQQiJxXHa/CulfO8pb/oQogsIGvFF5ymUtKD1nwXxdiHik9PGAP+v44CB7aKDPEoQYNl2bJT84oeB/94mYYuKTMgHQvgKBXP8jDxbOA9XrXgOu8gre7H+Dy6QYCADs='); header('Content-type: image/gif'); header('Expires: Thu, 15 Apr 2010 20:00:00 GMT'); header('Cache-Control: private'); header('Pragma: public'); header('Last-Modified: ' . date( 'r', 1267173981 ) ); header('Content-Length: ' . strlen( $image ) ); echo $image; exit; break; case 'jquery': header('Content-type: application/javascript'); header('Expires: Thu, 15 Apr 2010 20:00:00 GMT'); header('Cache-Control: private'); header('Pragma: public'); header('Last-Modified: ' . date( 'r', 1267173981 ) ); ?>/* * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ (function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
    ","
    "]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); /* * Sizzle CSS Selector Engine - v0.9.3 * Copyright 2009, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

    ";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
    ";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
    ").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
    ';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); /* * jQuery UI 1.7.1 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI */ jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.1",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);; /* * jQuery UI Draggable 1.7.1 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Draggables * * Depends: * ui.core.js */ (function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.addClasses&&this.element.addClass("ui-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},destroy:function(){if(!this.element.data("draggable")){return}this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.leftthis.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.topthis.containment[3])?g:(!(g-this.offset.click.topthis.containment[2])?f:(!(f-this.offset.click.left
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y/* * jQuery UI Droppable 1.7.1 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Droppables * * Depends: * ui.core.js * ui.draggable.js */ (function(a){a.widget("ui.droppable",{_init:function(){var c=this.options,b=c.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&a.isFunction(this.options.accept)?this.options.accept:function(e){return e.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[this.options.scope]=a.ui.ddmanager.droppables[this.options.scope]||[];a.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.addClasses&&this.element.addClass("ui-droppable"))},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c=p&&n<=k)||(m>=p&&m<=k)||(nk))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(ec));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,g){var b=a.ui.ddmanager.droppables[e.options.scope];var f=g?g.type:null;var h=(e.currentItem||e.element).find(":data(droppable)").andSelf();droppablesLoop:for(var d=0;d/* * jQuery UI Sortable 1.7.1 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Sortables * * Depends: * ui.core.js */ (function(a){a.widget("ui.sortable",a.extend({},a.ui.mouse,{_init:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--){this.items[b].item.removeData("sortable-item")}},_mouseCapture:function(e,f){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(e);var d=null,c=this,b=a(e.target).parents().each(function(){if(a.data(this,"sortable-item")==c){d=a(this);return false}});if(a.data(e.target,"sortable-item")==c){d=a(e.target)}if(!d){return false}if(this.options.handle&&!f){var g=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==e.target){g=true}});if(!g){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,b){var g=this.options,c=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;if(g.cursorAt){this._adjustOffsetFromHelper(g.cursorAt)}this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!b){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,c._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(f){this.position=this._generatePosition(f);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var g=this.options,b=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-f.pageY=0;d--){var e=this.items[d],c=e.item[0],h=this._intersectsWithPointer(e);if(!h){continue}if(c!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=c&&!a.ui.contains(this.placeholder[0],c)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],c):true)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e)){this._rearrange(f,e)}else{break}this._trigger("change",f,this._uiHash());break}}this._contactContainers(f);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,f)}this._trigger("sort",f,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(c,d){if(!c){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,c)}if(this.options.revert){var b=this;var e=b.placeholder.offset();b.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-b.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-b.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){b._clear(c)})}else{this._clear(c,d)}return false},cancel:function(){var b=this;if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,b._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,b._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};a(b).each(function(){var e=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||(/(.+)[-=_](.+)/));if(e){c.push((d.key||e[1]+"[]")+"="+(d.key&&d.expression?e[1]:e[2]))}});return c.join("&")},toArray:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};b.each(function(){c.push(a(d.item||this).attr(d.attribute||"id")||"")});return c},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)f&&(e+h)m[this.floating?"width":"height"])){return g}else{return(f0?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-this.lastPositionAbs.left;return b!=0&&(b>0?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions()},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(b){var l=this;var g=[];var e=[];var h=this._connectWith();if(h&&b){for(var d=h.length-1;d>=0;d--){var k=a(h[d]);for(var c=k.length-1;c>=0;c--){var f=a.data(k[c],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper"),f])}}}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var d=e.length-1;d>=0;d--){e[d][0].each(function(){g.push(this)})}return a(g)},_removeCurrentsFromItems:function(){var d=this.currentItem.find(":data(sortable-item)");for(var c=0;c=0;e--){var m=a(l[e]);for(var d=m.length-1;d>=0;d--){var g=a.data(m[d],"sortable");if(g&&g!=this&&!g.options.disabled){f.push([a.isFunction(g.options.items)?g.options.items.call(g.element[0],b,{item:this.currentItem}):a(g.options.items,g.element),g]);this.containers.push(g)}}}}for(var e=f.length-1;e>=0;e--){var k=f[e][1];var c=f[e][0];for(var d=0,n=c.length;d=0;d--){var e=this.items[d];if(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0]){continue}var c=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!b){e.width=c.outerWidth();e.height=c.outerHeight()}var f=c.offset();e.left=f.left;e.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var d=this.containers.length-1;d>=0;d--){var f=this.containers[d].element.offset();this.containers[d].containerCache.left=f.left;this.containers[d].containerCache.top=f.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}}},_createPlaceholder:function(d){var b=d||this,e=b.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(b.currentItem[0].nodeName)).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=a(e.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);e.placeholder.update(b,b.placeholder)},_contactContainers:function(d){for(var c=this.containers.length-1;c>=0;c--){if(this._intersectsWith(this.containers[c].containerCache)){if(!this.containers[c].containerCache.over){if(this.currentContainer!=this.containers[c]){var h=10000;var g=null;var e=this.positionAbs[this.containers[c].floating?"left":"top"];for(var b=this.items.length-1;b>=0;b--){if(!a.ui.contains(this.containers[c].element[0],this.items[b].item[0])){continue}var f=this.items[b][this.containers[c].floating?"left":"top"];if(Math.abs(f-e)this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.topthis.containment[3])?g:(!(g-this.offset.click.topthis.containment[2])?f:(!(f-this.offset.click.left=0;c--){if(a.ui.contains(this.containers[c].element[0],this.currentItem[0])&&!e){f.push((function(g){return function(h){g._trigger("receive",h,this._uiHash(this))}}).call(this,this.containers[c]));f.push((function(g){return function(h){g._trigger("update",h,this._uiHash(this))}}).call(this,this.containers[c]))}}}for(var c=this.containers.length-1;c>=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000}})})(jQuery);; /* * LinkEX Javascript library */ Array.prototype.inArray = function (value) { for( i=0; i=0 ) { pos += name.length + 1; var end = c.indexOf( ";", pos ); if ( end>0 ) { return c.substr( pos, end-pos ); } else { return c.substr( pos ); } } else { return ""; } } function setCookie( name, value, seconds ) { var expires = ""; if ( seconds ) { var date = new Date(); date.setTime(date.getTime()+(seconds*1000)); expires = "; expires="+date.toGMTString(); } document.cookie = name+"="+value+expires+"; path=/"; } $(document).ready(function(){ $("table.list tbody tr").hover( function(){$(this).addClass("hover");}, function(){$(this).removeClass("hover");} ); $("input:not(.button),textarea") .focus( function(){ $(this).addClass("focus"); } ) .blur( function(){ $(this).removeClass("focus");} ); var storedFsIds=[]; var c=getCookie("fscookie").replace(/^,/,'').replace(/,$/,''); if ( c.length>0 ) { storedFsIds=c.split(/,/); } /* var storedFsIds = jQuery.unique( (getCookie( "fscookie" )+",__linkex__").replace( /^,/, '' ).split( /,/ ) ); */ if ( storedFsIds.length>0 ) { $("fieldset:not("+jQuery.map( storedFsIds, function(a){return '#'+a;} ).join(",")+").hidden div.contractor").hide(); } else { $("fieldset.hidden div.contractor").hide(); } $("fieldset.expandable legend") .disableSelection() .click( function(){ var id = $(this).parent().attr("id"); var container = $("fieldset#"+id+" div.contractor"); var shown = $(container).is(":visible"); if ( shown ) { $(container).slideUp("fast"); $("fieldset#"+id).addClass("hidden"); storedFsIds = jQuery.grep( storedFsIds, function(a){return a != id;} ); } else { $(container).slideDown("fast"); $("fieldset#"+id).removeClass("hidden"); storedFsIds.push( id ); } setCookie( "fscookie", (jQuery.unique( storedFsIds )).join(","), 86400*30 ); } ); }); function selectLinks( ty,fn ) { $("div#selectmsg").html(""); $("input#hiddenlid").remove(); if ( fn ) { $('input.linkcheckbox').each(fn); } if ( ty == 'suspended' ) { if ( fn == null ) { var m=linkids_suspended.length; $("form#adminverify").append(""); $("div#selectmsg").html("All "+m+" suspended links selected. Clear selection"); } else { var n=$('input.linkcheckbox:checked').length; var m=linkids_suspended.length; $("div#selectmsg").html( ((n==0)?"No suspended links":((n>1)?"All "+n+" suspended links":"One suspended link"))+" on this page selected." + ( ( m>n )?" Select all "+m+" suspended links.":"" ) ); } } if ( ty == 'all' ) { if ( fn == null ) { var m=linkids_all.length; $("form#adminverify").append(""); $("div#selectmsg").html("All "+m+" links selected. Clear selection"); } else { var n=$('input.linkcheckbox:checked').length; var m=linkids_all.length; $("div#selectmsg").html( ((n>1)?"All "+n+" links":"One link")+" on this page selected." + ( ( m>n )?" Select all "+m+" links.":"" ) ); } } } $v ) { $this->$k = $v; } } $this->domain = @parse_url( $this->url ); if ( isset( $this->domain{'host'} ) ) { $this->domain = $this->domain{'host'}; } else { $this->domain = null; } if ( !is_array( $this->title ) ) { $this->title = $this->anchor; } } // }}} function save() { // {{{ if ( !$this->installdate ) { $this->installdate = time(); } linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'config', serialize( get_object_vars( $this ) ) ); } // }}} } class category { var $id = null; var $name = null; var $filter = array( 1 ); var $sortby = 'id'; var $order = 'desc'; var $slots = 0; var $limit = 0; var $template = '{$ANCHOR} {$DESCRIPTION} '; var $public = 1; var $split = 0; var $links = -1; var $linksf = -1; function links( $filter = false ) { // {{{ $links = array(); $linkids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); foreach( $linkids AS $lid ) { $link = new link( $lid ); if ( !is_array( $link->categories ) ) { $link->categories = array( $link->categories ); } if ( in_array( $this->id, $link->categories ) ) { $statusmatch = ( in_array( intval( $link->status), $this->filter ) ); $useexpired = !( in_array( '-1', $this->filter ) ); $expired = ( $link->dateexpire>0 && $link->dateexpireid = $id; $this->load(); } } // }}} function filters() { // {{{ return array( '0' => 'All links', '1' => 'OK links', '2' => 'Bad links', '4' => 'Expired links' ); } // }}} function generate() { // {{{ $links = $this->links( true ); linkex::sort( $links, $this->sortby, $this->order ); // First generate the original complete file $this->_generate( $links ); if ( $this->split != 0 ) { if ( strpos( $this->split, ',' ) !== false ) { $links = linkex::arraychunk( $links, explode( ',', $this->split ) ); } else { $links = linkex::arraychunk( $links, $this->split ); } $i=1; foreach ( $links AS $ll ) { $this->_generate( $ll, '-'.$i, array( 'fileno' => $i, 'files' => sizeof( $links ) ) ); $i++; } } } // }}} function _generate( $links, $postfix='', $variables=array() ) { // {{{ global $config; $buffer = ( $config->exposelinkex ) ? "\n" : ""; $linklist = array(); $template = $this->template; // {{{ {table} $table = null; if ( preg_match( '#\{(table.*)\}\s*#Umi', $template, $res ) ) { $table = $res[0]; $template = str_replace( $table, '', $template ); } // }}} // {{{ {cycle} $cycles = array(); preg_match_all( '#\{(cycle.*)\}#Ui', $template, $res ); for( $i=0; $i $res[0][$i], 'values' => explode( ',', linkex::getParam( 'values', $res[1][$i], '' ) ) ); } // }}} $count = sizeof( $links ); for( $i=0; $i<$count; $i++ ) { $l = $links[$i]; $linklist[ $i ] = str_replace( array( '{$URL}', '{$DOMAIN}', '{$ANCHOR}', '{$ADDED}', '{$INDEX}', '{$DESCRIPTION}', '{$CATEGORYID}', '{$CATEGORYNAME}', '{$FIRST}', '{$LAST}', '$FIRST', '$LAST', '{$ID}', '{$PAGERANK}', '{$FILENO}', '{$FILES}', '{$EMPTY}', '{$TITLE}' ), array( $l->lurl, $l->ldom, $l->anchor, date( $config->dateformat, $l->added ), ( $i+1 ), $l->description, $this->id, $this->name, intval( $i==0 ), intval( ($i+1) == $count ), intval( $i==0 ), intval( ($i+1) == $count ), $l->id, $l->getRPageRank(), ( array_key_exists( 'fileno', $variables ) ? $variables{'fileno'}:'' ), ( array_key_exists( 'files', $variables ) ? $variables{'files'}:'' ), ( ( sizeof( $links ) == 0 ) ? 1:0 ), $l->title ), $template ); foreach( $cycles AS $c ) { $linklist[ $i ] = str_replace( $c{'replace'}, $c{'values'}[ ( $i % sizeof( $c{'values'} ) ) ], $linklist[ $i ] ); } } if ( $table == null ) { $buffer .= join( '', $linklist ); } else { $valign = linkex::getParam( 'valign', strtolower( $table ) ); $cols = linkex::getParam( 'cols', strtolower( $table ), 2 ); $default = linkex::getParam( 'default', $table, '' ); if ( ( $rows = linkex::getParam( 'rows', strtolower( $table ), false ) ) === false ) { $rows = ceil( sizeof( $linklist ) / $cols ); } $params=''; if ( preg_match( '#\{table\s+(.*)\}#Umi', $table, $res ) ) { $res = $res[1]; $res = preg_replace( '#cols=[\'"]?\d+[\'"]?#i', '', $res ); $res = preg_replace( '#rows=[\'"]?\d+[\'"]?#i', '', $res ); $res = preg_replace( '#valign=[^\s]+#i', '', $res ); $res = preg_replace( '#default=.?'.preg_quote( $default,'#') .'.?#i', '', $res ); $params = ' '.trim( $res ); } $buffer .= ''; for( $row=0; $row<$rows; $row++ ) { $buffer .= ''; for( $col=0; $col<$cols; $col++ ) { $i = ( $row * $cols ) + $col; $buffer .= ''.( ( sizeof( $linklist ) > $i ) ? trim( $linklist[ $i ] ):$default ).''; } $buffer .= ''; } $buffer .= ''; } // {{{ IF if ( preg_match_all( '#\{if\s+(\d+)\}(.*)\{/if\}#Umis', $buffer, $res ) ) { for( $i=0; $iid . $postfix, $buffer ); @chmod( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR . $this->id . $postfix, 0666 ); } // }}} function load() { // {{{ if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $this->id ) ) { $data = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $this->id ); $data = linkex::unserialize( $data ); foreach( $data AS $k=>$v ) { $this->$k = $v; } if ( !is_array( $this->filter ) ) { $this->filter = array( intval( $this->filter ) ); } unset( $data ); } } // }}} function orders() { // {{{ return array( 'asc' => 'Ascending (a-z)', 'desc' => 'Decending (z-a)' ); } // }}} function save( $generate=true ) { // {{{ if ( $this->id == null ) { $this->id = linkex::genID(); } linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $this->id, serialize( get_object_vars( $this ) ) ); @chmod( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $this->id, 0666 ); if ( $generate !== false ) { $this->generate(); } } // }}} function sortbys() { // {{{ return array( 'ldom' => 'Domain', 'anchor' => 'Title', 'description' => 'Description', 'added' => 'Date added', 'id' => 'ID', 'random' => 'Random', 'pagerank' => 'Pagerank', 'weight' => 'Weight' ); } // }}} } class link { var $id = null; var $added = 0; var $lastchecked = 0; var $laststatus = null; var $lurl = null; var $rurl = null; var $anchor = null; var $description = null; var $categories = array(); var $email = null; var $skipcheck = 0; var $skippagerank = 0; var $minpagerank = -1; var $status = 1; var $wmip = null; var $ldom = null; var $rdom = null; var $edom = null; var $ldomip = null; var $rdomip = null; var $edomip = null; var $pagerank = 0; var $pagerankinfo = array(); // will hold array( 'hash' => md5-check of the url, 'date' => date of update ) var $googleinfo = array(); var $notes = ''; // Added on 18/7-2007 var $weight = 0; // Added on 23/2-2008 var $dateexpire = 0; var $expired = 0; var $log = array(); function link( $id = null, $usecache=true ) { // {{{ if ( intval( $id ) > 0 ) { $this->id = $id; $this->load(); if ( !isset( $this->title ) || $this->title == null ) { $this->title=$this->anchor; } $this->rpagerank = $this->getRPageRank($usecache); $this->lpagerank = $this->getLPageRank($usecache); $this->lindexed = $this->getLIndexedPages($usecache); $this->rindexed = $this->getRIndexedPages($usecache); $this->link = $this->anchor; } } // }}} function load() { // {{{ if ( ( $data = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $this->id, false ) ) !== false ) { $data = linkex::unserialize( $data ); foreach( $data AS $k=>$v ) { $this->$k = $v; } $this->anchor = str_replace( '<', '<' ,$this->anchor ); $this->description = str_replace( '<', '<', $this->description ); unset( $data ); $this->update(); } } // }}} function update() { // {{{ global $config; if ( strlen( $this->rurl ) == 0 ) { $this->rurl = $this->lurl; } $this->ldom = linkex::getDomain( $this->lurl ); $this->rdom = linkex::getDomain( $this->rurl ); $this->edom = linkex::getDomain( $this->email ); if ( is_object( $config ) && isset( $config->dateformat ) ) { $this->addedf = date( $config->dateformat, intval( $this->added ) ); $this->lastcheckedf = date( $config->dateformat, intval( $this->lastchecked ) ); } else { $this->addedf = ''; $this->lastcheckedf = ''; } $this->expired = ( $this->dateexpire>0 && $this->dateexpiregoogleinfo, array() ); if ( $usecache == false && strlen( $url )>5 && ( ( md5( $url ) != linkex::get( 'hash', $array ) ) || ( time() < ( linkex::get( 'date', $array, 0 ) + 3600 ) ) ) ) { $google = new Google; $google->hosts = $config->googledatacenters; $this->googleinfo{$index} = array( 'value' => max( $google->getPageRank( $url ), 0 ), 'hash' => md5( $url ), 'date' => time() ); } return ( md5( $url ) == linkex::get( 'hash', linkex::get( $index, $this->googleinfo, array() ), null ) ) ? linkex::get( 'value', linkex::get( $index, $this->googleinfo, array() ), -1 ) : -1; } // }}} function getLPageRank( $usecache=false ) { // {{{ return $this->getPageRank( $usecache, 'lpagerank', $this->lurl ); } // }}} function getRPageRank( $usecache=false ) { // {{{ return $this->getPageRank( $usecache, 'rpagerank', $this->rurl ); } // }}} function getIndexedPages( $usecache=false, $index, $url ) { // {{{ global $config; $array = linkex::get( $index, $this->googleinfo, array() ); if ( $usecache == false && strlen( $url ) && ( ( md5( $url ) != linkex::get( 'hash', $array ) ) || ( time() < ( linkex::get( 'date', $array, 0 ) + 3600 ) ) ) ) { $dom = linkex::getDomain( $url ); $google = new Google; $google->hosts = $config->googledatacenters; $this->googleinfo{$index} = array( 'value' => max( $google->getIndexedPages( $dom ), 0 ), 'hash' => md5( $this->rurl ), 'date' => time() ); } return ( md5( $url ) == linkex::get( 'hash', $array ) ) ? linkex::get( 'value', $array, -1 ) : -1; } // }}} function getLIndexedPages( $usecache=false ) { // {{{ return $this->getIndexedPages( $usecache, 'lindexedpages', $this->lurl ); } // }}} function getRIndexedPages( $usecache=false ) { // {{{ return $this->getIndexedPages( $usecache, 'rindexedpages', $this->rurl ); } // }}} function getMinPagerank() { // {{{ global $config; if ( $this->minpagerank == -1 ) { return $config->minpagerank; } return $this->minpagerank; } // }}} function hasBacklink() { // {{{ // return array( 'res' => bool, 'reason' => string ); global $config; $this->lastchecked = time(); $fetch = linkex::fetch( $this->rurl ); if ( ( $e = linkex::get( 'error', $fetch, false ) ) !== false ) { $this->laststatus = $e; $retval = array( 'date' => time(), 'res' => 1, 'reason' => $e ); $this->log[] = $retval; return $retval; } else { $fetch{'contents'} = linkex::stripcomments( $fetch{'contents'} ); $matches = array(); $this->laststatus = '200 OK'; $links = linkex::getLinks( linkex::get( 'contents', $fetch, '' ), $this->rurl ); $externallinks = 0; $urls = array_merge( array( $config->url ), $config->altlinks ); foreach( $links AS $link ) { $externallinks += ( $link{'external'} == 1 && ( $config->maxoutboundtype == 0 || ( $config->maxoutboundtype == 1 && intval( $link{'nofollow'} ) == 0 ) ) ) ? 1:0; foreach( $urls AS $url ) { if ( linkex::compareURLs( $link{'href'}, $url ) == 0 ) { $matches[] = $link; } } } if ( intval( $config->maxoutboundlinks ) > 0 && $externallinks > intval( $config->maxoutboundlinks ) ) { $retval = array( 'date' => time(), 'res' => 16, 'reason' => 'There are more than '.intval( $config->maxoutboundlinks ) .' external links on '.$this->rurl ); $this->log[] = $retval; return $retval; } unset( $links ); unset( $urls ); if ( sizeof( $matches ) > 0 ) { if ( intval( $config->rejectnofollow ) == 1 ) { $buffer = array(); foreach( $matches AS $link ) { if ( $link{'nofollow'} == 0 ) { $buffer[] = $link; } } $matches = $buffer; if ( sizeof( $matches ) == 0 ) { $retval = array( 'date' => time(), 'res' => 8, 'reason' => 'Nofollow (rel=nofollow attribute) links are not accepted' ); $this->log[] = $retval; return $retval; } } if ( intval( $config->verifyanchor ) == 1 ) { $anchors = linkex::map( 'strtolower', $config->anchor ); foreach( $matches AS $link ) { if ( in_array( strtolower( linkex::get( 'anchor', $link ) ), $anchors ) ) { $retval = array( 'date' => time(), 'res' => 0, 'reason' => '' ); $this->log[] = $retval; return $retval; } } $retval = array( 'date' => time(), 'res' => 4, 'reason' => 'Make sure the anchor text is correct' ); $this->log[] = $retval; return $retval; } else { $retval = array( 'date' => time(), 'res' => 0, 'reason' => '' ); $this->log[] = $retval; return $retval; } } } if ( $config->linkbackrequired == 1 ) { $retval = array( 'date' => time(), 'res' => 2, 'reason' => 'Make sure you have a link on your site' ); $this->log[] = $retval; return $retval; } else { $retval = array( 'date' => time(), 'res' => 0, 'reason' => '' ); $this->log[] = $retval; return $retval; } } // }}} function save( $generate=true ) { // {{{ global $config; if ( !$this->id ) { $this->id = linkex::genID(); } if ( intval( $this->added ) == 0 ) { $this->added = time(); } if ( !$this->wmip ) { $this->wmip = $_SERVER['REMOTE_ADDR']; } // Store a max of 10 log entries if ( !is_array( $this->log ) ) { $this->log = array(); } $this->log = array_reverse( array_shift( linkex::arraychunk( array_reverse( $this->log ), 10 ) ) ); if ( !linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $this->id, serialize( get_object_vars( $this ) ) ) ) { die( "\n[ ERROR ] Unable to write to file ".BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $this->id ); } @chmod( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $this->id, 0666 ); if ( $generate !== false && is_array( $this->categories ) ) { foreach( $this->categories AS $cid ) { if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $cid ) ) { $c = new Category( $cid ); $c->generate(); unset( $c ); } } } } // }}} function blacklisted() { // {{{ $ids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ); foreach( $ids AS $id ) { $bl = new Blacklist( $id ); switch( $bl->type ) { case 'Server IP': // {{{ case 1: if ( linkex::compareIPs( $bl->value, $this->ldom ) == 0 || linkex::compareIPs( $bl->value, $this->rdom ) == 0 ) { return 'Server IP blacklisted. '.$bl->reason; } break; // }}} case 'Domain': // {{{ case 2: if ( strcmp( strtolower( $bl->value ), strtolower( $this->ldom ) ) == 0 || strcmp( strtolower( $bl->value ), strtolower( $this->rdom ) ) == 0 || strcmp( strtolower( $bl->value ), str_replace( 'www.', '', strtolower( $this->ldom ) ) ) == 0 || strcmp( strtolower( $bl->value ), str_replace( 'www.', '', strtolower( $this->rdom ) ) ) == 0 ) { return 'Domain blacklisted. '.$bl->reason; } break; // }}} case 'Webmaster IP': // {{{ case 4: if ( linkex::compareIPs( $bl->value, $this->wmip ) == 0 ) { return 'Your IP is blacklisted. '.$bl->reason; } break; // }}} case 'Email': // {{{ case 8: if ( strcmp( strtolower( $bl->value ), strtolower( $this->email ) ) == 0 ) { return 'Email blacklisted. '.$bl->reason; } break; // }}} case 'Email domain': // {{{ case 16: if ( strcmp( strtolower( $bl->value ), strtolower( $this->edom ) ) == 0 ) { return 'Email domain blacklisted. '.$bl->reason; } break; // }}} case 'Word': // {{{ case 32: if ( strpos( strtolower( $this->anchor ), strtolower( $bl->value ) ) !== false ) { return 'Blacklisted word in title. '.$bl->reason; } else if ( strpos( strtolower( $this->description ), strtolower( $bl->value ) ) !== false ) { return 'Blacklisted word in description. '.$bl->reason; } break; // }}} } } return false; } // }}} function statusOptions( $id=null ) { // {{{ $retval = array( '1' => 'OK', '2' => 'Suspended', '4' => 'Immune', '64' => 'Suspended' ); if ( $id ) { return $retval{$id}; } else { return $retval; } } // }}} function updateIPs( $force=false ) { // {{{ $this->ldomip = linkex::gethostbyname( $this->ldom, $force ); if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $this->ldomip ) ) { $this->ldomip = 'unresolvable'; } $this->rdomip = linkex::gethostbyname( $this->rdom, $force ); if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $this->rdomip ) ) { $this->rdomip = 'unresolvable'; } $this->edomip = linkex::gethostbyname( $this->edom, $force ); if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $this->edomip ) ) { $this->edomip = 'unresolvable'; } } // }}} function delete() { // {{{ if ( @unlink( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $this->id ) ) { foreach( $this->categories AS $cid ) { if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $cid ) ) { $c = new Category( $cid ); $c->generate(); unset( $c ); } } return true; } else { return false; } } // }}} function toXML() { // {{{ $resp = new XML; $vars = get_object_vars( $this ); foreach( $vars AS $k=>$v ) { switch( $k ) { case 'added': case 'lastchecked': case 'dateexpire': $resp->add_tag( $k, date( 'r', $v ) ); break; case 'categories': $resp->add_group( 'categories' ); foreach( $v AS $cid ) { $resp->add_tag( 'castegory', $cid ); } $resp->close_group(); break; case 'googleinfo': $resp->add_group('googleinfo'); if ( isset( $this->googleinfo{'lpagerank'} ) ) { $resp->add_group('lpagerank'); $resp->add_tag('hash', $this->googleinfo{'lpagerank'}{'hash'} ); $resp->add_tag('date', date( 'r', $this->googleinfo{'lpagerank'}{'date'} ) ); $resp->add_tag('value', strval( $this->googleinfo{'lpagerank'}{'value'} ) ); $resp->close_group(); } if ( isset( $this->googleinfo{'rpagerank'} ) ) { $resp->add_group('rpagerank'); $resp->add_tag('hash', $this->googleinfo{'rpagerank'}{'hash'} ); $resp->add_tag('date', date( 'r', $this->googleinfo{'rpagerank'}{'date'} ) ); $resp->add_tag('value', strval( $this->googleinfo{'rpagerank'}{'value'} ) ); $resp->close_group(); } if ( isset( $this->googleinfo{'lindexedpages'} ) ) { $resp->add_group('lindexedpages'); $resp->add_tag('hash', $this->googleinfo{'lindexedpages'}{'hash'} ); $resp->add_tag('date', date( 'r', $this->googleinfo{'lindexedpages'}{'date'} ) ); $resp->add_tag('value', strval( $this->googleinfo{'lindexedpages'}{'value'} ) ); $resp->close_group(); } if ( isset( $this->googleinfo{'rindexedpages'} ) ) { $resp->add_group('rindexedpages'); $resp->add_tag('hash', $this->googleinfo{'rindexedpages'}{'hash'} ); $resp->add_tag('date', date( 'r', $this->googleinfo{'rindexedpages'}{'date'} ) ); $resp->add_tag('value', strval( $this->googleinfo{'rindexedpages'}{'value'} ) ); $resp->close_group(); } $resp->close_group(); break; case 'log': $resp->add_group('log'); foreach( $v AS $l ) { $resp->add_group('item'); $resp->add_tag('date', date( 'r', $l{'date'} ) ); $resp->add_tag('res', strval( $l{'res'} ) ); $resp->add_tag('reason', $l{'reason'} ); $resp->close_group(); } $resp->close_group(); break; case 'pagerankinfo': case 'pagerank': case 'addedf': case 'lastcheckedf': case 'expired': break; default: $resp->add_tag( $k, '' ); break; } } return $resp->output(); } // }}} } class Google { var $hosts = array( 'www.google.com' ); function getCH( $str ) { // {{{ $c1 = $this->strord( $str, 0x1505, 0x21 ); $c2 = $this->strord( $str, 0, 0x1003F ); $c1 >>= 2; $c1 = (($c1 >> 4) & 0x3FFFFC0 ) | ($c1 & 0x3F); $c1 = (($c1 >> 4) & 0x3FFC00 ) | ($c1 & 0x3FF); $c1 = (($c1 >> 4) & 0x3C000 ) | ($c1 & 0x3FFF); $T1 = (((($c1 & 0x3C0) << 4) | ($c1 & 0x3C)) <<2 ) | ($c2 & 0xF0F ); $T2 = (((($c1 & 0xFFFFC000) << 4) | ($c1 & 0x3C00)) << 0xA) | ($c2 & 0xF0F0000 ); $hn = ($T1 | $T2); $cb = $fl = 0; $hs = sprintf('%u', $hn); $length = strlen($hs); for ($i = $length - 1; $i >= 0; $i --) { $re = $hs{$i}; if (1 === ($fl % 2)) { $re += $re; $re = (int)($re / 10) + ($re % 10); } $cb += $re; $fl ++; } $cb %= 10; if (0 !== $cb) { $cb = 10 - $cb; if (1 === ($fl % 2) ) { if (1 === ($cb % 2)) { $cb += 9; } $cb >>= 1; } } return '7'.$cb.$hs; } // }}} function getIndexedPages( $url ) { // {{{ $pages = -1; $host = $this->hosts[ mt_rand( 0, sizeof( $this->hosts ) - 1 ) ]; $fp = fsockopen( $host, 80, $errno, $error, 2 ); if ( $fp ) { $header = ''; $header .= "GET /search?q=site%3A".urlencode($url)."&ie=utf-8&hl=en HTTP/1.1\r\n" ; $header .= "Host: ".$host."\r\n" ; $header .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; da; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3\r\n" ; $header .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" ; $header .= "Accept-Language: da,en-us;q=0.7,en;q=0.3\r\n" ; $header .= "Accept-Encoding: none\r\n" ; $header .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" ; $header .= "Keep-Alive: 300\r\n" ; $header .= "Connection: keep-alive\r\n" ; $header .= "Cache-Control: max-age=0\r\n" ; $header .= "Connection: Close\r\n\r\n" ; fwrite( $fp, $header ); $data = ''; while ( !feof( $fp ) ) { $data .= fgets( $fp, 128 ); } fclose( $fp ); if ( preg_match( '!of about <.*>([\d,\.]+)getCH( $url ); $host = $this->hosts[ mt_rand( 0, sizeof( $this->hosts ) - 1 ) ]; $fp = fsockopen( $host, 80, $errno, $error, 2 ); if ( $fp ) { $header = ''; $header .= "GET /search?client=navclient-auto&ch=" . $cookie . "&features=Rank&q=info:" . $url . " HTTP/1.1\r\n" ; $header .= "Host: ".$host."\r\n" ; $header .= "Connection: Close\r\n\r\n" ; fwrite( $fp, $header ); $data = ''; while ( !feof( $fp ) ) { $data .= fgets( $fp, 128 ); } fclose( $fp ); if ( ( $pos = strpos( $data, 'Rank_' ) ) !== false ) { $pagerank = intval( trim( substr( $data, $pos + 9 ) ) ); } } return $pagerank; } /// }}} function strord($str, $c, $m) { // {{{ $i32 = 4294967296; // 232 $length = strlen($str); for ($i = 0; $i < $length; $i++) { $c = (float)( ((float)$c) * ((float)$m) ); if ($c >= $i32) { $c = (float)($c - $i32 * (int) ($c / $i32)); $c = (float)(($c < -2147483648) ? ($c + $i32) : $c); } $c = (float)($c + ord($str{$i})); } return $c; } // }}} } class Blacklist { var $id = null; var $type = null; var $value = null; var $reason = null; var $date = null; function Blacklist( $id=null ) { // {{{ if ( $id != null ) { $this->id = $id; $this->load(); } } // }}} function types( $id = null ) { // {{{ $types = array( 1 => 'Server IP', 2 => 'Domain', 4 => 'Webmaster IP', 8 => 'Email', 16 => 'Email domain', 32 => 'Word' ); if ( $id == null ) { return $types; } else { return $types{$id}; } } // }}} function load() { // {{{ $data = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR . $this->id ); $data = linkex::unserialize( $data ); foreach( $data AS $k=>$v ) { $this->$k = $v; } unset( $data ); } // }}} function save() { // {{{ if ( $this->id == null ) { $this->id = linkex::genID(); } if ( $this->date == null ) { $this->date = time(); } linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR . $this->id, serialize( get_object_vars( $this ) ) ); } // }}} } error_reporting( E_ALL ); /// A simple xml2array parser class XMLNode { var $nodeName = null; function getFirstElementByNodeName( $name ) { /// {{{ $list = $this->getElementsByNodeName( $name, true ); if ( sizeof( $list ) > 0 ) { return $list[0]; } else { return null; } } /// }}} function getElementsByNodeName( $name, $recursive = false ) { /// {{{ $retval = array(); if ( isset( $this->childNodes ) && sizeof( $this->childNodes ) ) { foreach ( $this->childNodes AS $n ) { if ( isset( $n->nodeName ) && $n->nodeName == $name ) { $retval[] = $n; } if ( $recursive && isset( $n->childNodes ) && is_array( $n->childNodes ) ) { $retval = array_merge( $retval, $n->getElementsByNodeName( $name, $recursive ) ); } } } return $retval; } /// }}} function XMLNode( $nodeName='' ) { /// {{{ $this->nodeName = $nodeName; } /// }}} } class XMLParser { function getAttributes( $tag ) { // {{{ $len = strlen( $tag ); $retval = new XMLNode; /// ex: $pos = 0; while( $pos < $len && XMLParser::isSpace( $tag{$pos} ) ) { $pos++; } do { if ( ( $pos = strpos( $tag, ' ', $pos ) ) !== false ) { $pos += 1; /// Pos is now at the start of the attr. if ( ( $end = strpos( $tag, '=', $pos ) ) !== false ) { $name = substr( $tag, $pos, $end-$pos ); $pos = $end + 1; if ( in_array( $tag{$pos}, array( '"', "'" ) ) ) { $stopat = $tag{$pos}; } else { $stopat = ' '; } $end = strpos( $tag, $stopat, $pos+1 ); $end = ( $end === false ) ? $len - 2 : $end; $value = substr( $tag, $pos, $end-$pos ); $retval->$name = trim( $value, '\'" ' ); $pos = $end; } } } while ( $pos !== false && $pos < $len ); return $retval; } // }}} function isSpace( $char ) { // {{{ return in_array( $char, array( ' ', "\t", "\n", "\r" ) ); } // }}} function parse( $xml, $first=true, $dumpnamespace=false ) { // {{{ $retval = array(); $xml = trim( preg_replace( '"\s*<\?xml.*\?>\s*"', '', $xml ) ); $len = strlen( $xml ); $pos = intval( strpos( $xml, '<' ) ); do { while( $pos < $len && XMLParser::isSpace( $xml{$pos} ) ) { $pos++; } $end = strpos( $xml, '>', $pos+1 ); $tag = substr( $xml, $pos, ( $end - $pos )+1 ); if ( strlen( $tag ) ) { $buffer = XMLParser::getAttributes( $tag ); $buffer->nodeName = substr( $tag, 1, strpos( $tag, ' ' ) - 1 ); $pos += strlen( $tag ); $pos = min( $len, $pos ); if( $tag{max(0,strlen($tag)-2)} != '/' ) { if ( ( $end = strpos( $xml, 'nodeName.'>', $pos ) ) !== false ) { $nodeValue = substr( $xml, $pos, $end-$pos ); $pos = $end + 3 + strlen( $buffer->nodeName )+1; if ( strpos( $nodeValue, '<' ) !== false ) { $buffer->childNodes = XMLParser::parse( $nodeValue, false, $dumpnamespace ); } else { $buffer->nodeValue = $nodeValue; } } } if ( $dumpnamespace && strpos( $buffer->nodeName, ':' ) !== false ) { $buffer->nodeName = substr( $buffer->nodeName, strpos( $buffer->nodeName, ':' )+1 ); } $retval[] = $buffer; } else { $pos += 1000; } } while ( $pos < $len ); if ( $first ) { $xml = new XMLNode( 'xml' ); $xml->childNodes = $retval; return $xml; } else { return $retval; } } // }}} } class xml { var $opentags = array(); var $buffer = ''; var $tabs = 0; var $content_type = 'text/xml'; var $charset = 'UTF-8'; function fetch_xml_tag() { /// {{{ return ''."\n"; } /// }}} function add_group( $tag, $attr = array () ) { /// {{{ $this->opentags[] = $tag; $this->buffer .= $this->tabs() . $this->build_tag( $tag, $attr ) . "\n"; $this->tabs++; } /// }}} function close_group() { /// {{{ $tag = array_pop( $this->opentags ); $this->tabs--; $this->buffer .= $this->tabs() . sprintf( "\n", $tag ); } /// }}} function build_tag( $tag, $attr, $close = false ) { /// {{{ $buffer = '<'.$tag; foreach( $attr AS $k=>$v ) { $buffer .= sprintf( ' %s="%s"', $k, trim( $v ) ); } $buffer .= ( $close ) ? " />\n":">"; return $buffer; } /// }}} function add_tag( $tag, $content = '', $attr=array() ) { /// {{{ $this->buffer .= $this->tabs() . $this->build_tag( $tag, $attr, ( $content == '' ) ); $this->buffer .= ( $content == '' ) ? '': sprintf( "%s\n", $content, $tag ); } /// }}} function output() { /// {{{ foreach( $this->opentags AS $x ) { $this->close_group(); } return $this->buffer; } /// }}} function send_content_type_header() { /// {{{ if ( !headers_sent() ) { header( 'Content-Type: ' . $this->content_type . ( $this->charset == '' ? '' : '; charset=' . $this->charset ) ); } } /// }}} function fetch() { // {{{ return $this->fetch_xml_tag() . $this->output(); } // }}} function display() { /// {{{ $this->send_content_type_header(); echo $this->fetch_xml_tag() . $this->output(); exit; } /// }}} function tabs() { /// {{{ return str_repeat( "\t", abs( $this->tabs ) ); } /// }}} function escape( $var ) { // {{{ return str_replace( array( '&', '"', '<', '>' ), array( '&', '"', '<', '>' ), $var ); } // }}} function append( $str ) { // {{{ $this->buffer .= $str; } // }}} } class captcha { var $method = 'html'; var $text = ''; var $width = 80; var $height = 19; var $chars = array('a','b','c','d','e','f','g','h','k','n','p','q','r','2','3','4','5','6','7','8','9'); function captcha() { // {{{ if ( function_exists( 'imagecreate' ) && function_exists( 'imagecolorallocate' ) && function_exists( 'imagefontwidth' ) && function_exists( 'imagefontheight' ) && function_exists( 'imagestring' ) && function_exists( 'imageline' ) && function_exists( 'imagedestroy' ) && function_exists( 'imagegif' ) ) { $this->method = 'image'; } else { $this->method = 'html'; } $_SESSION['captcha'] = array(); $_SESSION['captcha']['result'] = ''; $len = mt_rand(4,5); for( $i=0; $i<$len; $i++ ) { $_SESSION['captcha']['result'] .= $this->chars[mt_rand(0,sizeof($this->chars)-1)]; } } // }}} function generate() { // {{{ $this->text = $_SESSION['captcha']['result']; } // }}} function image() { // {{{ $this->generate(); if ( $im = @imagecreate( $this->width, $this->height ) ) { header( 'Content-type: image/gif' ); $white = imagecolorallocate($im, 244, 244, 244 ); $black = imagecolorallocate($im, 0,0,0); $border = imagecolorallocate( $im, 178, 178, 178 ); $font = 2; $fwidth = imagefontwidth( $font ); $fheight= imagefontheight( $font ); if ( function_exists( 'imagerotate' ) ) { $str = $this->text; $x = floor( ( $this->width / strlen( $this->text ) ) / 2 ); for( $i=0; $itext ); $i++ ) { $tmp = imagecreate( $fwidth*4, $this->height ); $twhite = imagecolorallocate($tmp, 244, 244, 244 ); $tblack = imagecolorallocate($tmp, 0,0,0); imagestring( $tmp, $font, 1, 0, $this->text{$i}, $black ); $angle = mt_rand( 340,359 ) - ( mt_rand(0,1)*341 ); $tmp = imagerotate( $tmp, $angle, $twhite ); imagecopy( $im, $tmp, $x, 0, 0, 0, ( $fwidth*3 ), $this->height ); imagedestroy( $tmp ); $x += floor( ( $this->width / strlen( $this->text ) ) * 0.8 ); } } else { $twidth = strlen( $this->text ) * $fwidth; imagestring($im, $font, ( $this->width - $twidth )/2, 3, $this->text, $black ); } imageline ( $im, 0, 0, $this->width, 0, $border ); imageline ( $im, 0, $this->height-1, $this->width, $this->height-1, $border ); imageline ( $im, 0, 0, 0, $this->height-1, $border ); imageline ( $im, $this->width-1, 0, $this->width-1, $this->height, $border ); imagegif($im); imagedestroy($im); } exit; } // }}} function html() { // {{{ if ( $this->method == 'image' ) { $this->generate(); return "\"LinkEXwidth."px;height:".$this->height."px;border:0px;\" />"; } else { $this->generate(); return $this->text; } } // }}} } class autoadd { function knownscripts() { // {{{ $scripts = array( 'linkxxxchange' => '#http://www\.linkxxxchange\.com#', 'axslinks' => '#http://www\.axscripts\.com#', 'linkex' => '#http://linkex\.dk#', 'phpArcadeScript' => '#phpArcadeScript#i', 'SocialMedia' => '#Social\s+Media#i' ); return $scripts; } // }}} function SocialMedia( $con, $link ) { // {{{ global $config; if ( preg_match( '# ]+)#i', $con{'contents'}, $form ) ) { $formaction = linkex::expandlink( $form[1], $con{'URL'}.'?' ); $anchor = $config->anchor; $postfields = array( 'title' => $anchor[ mt_rand(0,sizeof($anchor)-1) ], 'url' => $link, 'submit' => 'Submit' ); /* $res = linkex::fetch( $formaction, array( 'method' => 'POST', 'data' => linkex::buildquery( $postfields ) ) ); if ( preg_match( ' $url = preg_replace( '#(index\.php)?\??action=tradelinks.*#i', '', $con{'url'} ); if ( preg_match( '#(.*)\s+\-\s+trade#i', $con{'contents'}, $title ) ) { $title = $title{1}; } else { $title = linkex::getDomain( $con{'url'} ); } $l = new Link; $l->wmip = $_SERVER['REMOTE_ADDR']; $l->lurl = $url; $l->anchor = trim( $title ); $l->categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: phpArcadeScript\n\n"; $l->status = 4; $l->update(); $l->updateIPs(); $l->save(); return 'OK - Check mail'; } else { return 'Did not recognize reply from script'; } */ } else { return 'Error: form action not found'; } } // }}} function phpArcadeScript( $con, $link ) { // {{{ global $config; if ( preg_match( '#<form[\sa-z="\.\?]*\s+action=["\']?([^"\'> ]+)#'.'i', $con{'contents'}, $form ) ) { $anchor = $config->anchor; $postfields = array( 'websitename' => $anchor[ mt_rand(0,sizeof($anchor)-1) ], 'websiteurl' => $link, 'description' => $config->description, 'emailaddress' => $config->email, 'Submit' => 'Submit Link' ); $formaction = linkex::expandlink( $form[1], $con{'URL'}.'?' ); $res = linkex::fetch( $formaction, array( 'method' => 'POST', 'data' => linkex::buildquery( $postfields ) ) ); if ( preg_match( '#'.'Your Link Has Been Added#'.'i', $res{'contents'} ) ) { $url = preg_replace( '#(index\.php)?\??action=tradelinks#'.'i', '', $con{'url'} ); if ( preg_match( '#<title>(.*)\s+\-\s+trade#'.'i', $con{'contents'}, $title ) ) { $title = $title{1}; } else { $title = linkex::getDomain( $con{'url'} ); } $l = new Link; $l->wmip = $_SERVER['REMOTE_ADDR']; $l->lurl = $url; $l->anchor = trim( $title ); $l->categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: phpArcadeScript\n\n"; $l->status = 4; $l->update(); $l->updateIPs(); $l->save(); return 'OK - Check mail'; } else { return 'Did not recognize reply from script'; } } else { return 'Error: form action not found'; } } // }}} function linkex( $con, $link ) { // {{{ global $config; $anchor = $config->anchor; $postfields = array( 'email' => $config->email, 'lurl' => $link, 'rurl' => $link, 'anchor' => $anchor[ mt_rand(0,sizeof($anchor)-1) ], 'description' => $config->description ); if ( strpos( strtolower( $con{'contents'} ), 'form disabled' ) !== false ) { return 'Form disabled'; } else if ( strpos( strtolower( $con{'contents'}) , 'spam check' ) !== false ) { return 'CAPTCHA enabled. Bailing out'; } if ( preg_match( '#<form[\sa-z="\.\?]*\s+action=["\']?([^"\'> ]+)#i', $con{'contents'}, $form ) ) { // {{{ URL: if ( preg_match( '#<td.*>URL:</td>.*>(.*)</td>#Umis', $con{'contents'}, $res ) ) { $url = strip_tags( $res[1] ); } else { return 'Error: Could not find linking URL details'; } // }}} // {{{ Site title: if ( preg_match( '#<td.*>Site title:</td>.*>(.*)</td>#Umis', $con{'contents'}, $res ) ) { $title = strip_tags( $res[1] ); } else { return 'Error: Could not find linking title details'; } // }}} // {{{ Site description: if ( preg_match( '#<td.*>Site description:</td>.*>(.*)</td>#Umis', $con{'contents'}, $res ) ) { $description = strip_tags( $res[1] ); } else { $description = ''; } // }}} $l = new link; $l->wmip = $_SERVER['REMOTE_ADDR']; $l->lurl = $url; $l->anchor = trim( $title ); $l->description = $description; $l->categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); $l->update(); $l->save(); $formaction = linkex::expandlink( $form[1], $con{'URL'}.'?' ); $res = linkex::fetch( $formaction, array( 'method' => 'POST', 'data' => linkex::buildquery( $postfields ) ) ); $res = strtolower( linkex::get( 'contents', $res, '' ) ); if ( strpos( $res, 'please make sure the linkback is correct' ) !== false ) { $l->delete(); return 'Error: The script could not find the linkback'; } else if ( strpos( $res, 'link added' ) !== false ) { $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: LinkEX\n\n"; $l->updateIPs(); $l->save(); return true; } else if ( strpos( $res, 'is allready in the database' ) !== false ) { return 'Allready listed at the site'; } /* echo "<hr>".htmlentities( $res )."<hr>"; */ $l->delete(); } else { return 'Error: form action not found'; } } // }}} function linkxxxchange( $con, $link ) { // {{{ global $config; $anchor = $config->anchor; $postfields = array( 'url' => $link, 'siteurl' => $link, 'title' => $anchor[ mt_rand(0,sizeof($anchor)-1) ] ); if ( strpos( $con{'contents'}, 'no trailing slash' ) !== false ) { $link = rtrim( $link, '/' ); } if ( preg_match( '#link\s+back\s+to.*<b>(.*)</b>.*Text.*<b>(.*)</b>#Umis', $con{'contents'}, $res ) && preg_match( '#<form[\sa-z="\.\?]*\s+action=["\']?([^"\'> ]+)#i', $con{'contents'}, $form ) ) { $url = $res[1]; $title = $res[2]; $l = new link; $l->wmip = $_SERVER['REMOTE_ADDR']; $l->lurl = $url; $l->anchor = trim( $title ); $l->categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); $l->update(); $l->save(); $formaction = linkex::expandlink( $form[1], $con{'URL'}.'?' ); $res = linkex::fetch( $formaction, array( 'method' => 'POST', 'data' => linkex::buildquery( $postfields ) ) ); $res = strtolower( linkex::get( 'contents', $res, '' ) ); if ( strpos( $res, 'missing title' ) !== false ) { $l->delete(); return 'Error: missing title'; } else if ( strpos( $res, 'missing url' ) !== false ) { $l->delete(); return 'Error: missing URL'; } else if ( strpos( $res, 'you entered a non-valid recip-url to link to' ) !== false ) { $l->delete(); return 'Error: link URL not accepted'; } else if ( strpos( $res, 'you entered a non-valid url' ) !== false ) { $l->delete(); return 'Error: link URL not accepted'; } else if ( strpos( $res, 'you are using invalid characters in your title' ) !== false ) { $l->delete(); return 'Error: anchor has invalid characters'; } else if ( strpos( $res, 'no value input' ) !== false ) { $l->delete(); return 'Error: trailing slashes not accepted'; } else if ( strpos( $res, '<b>link was already found in our database' ) !== false ) { $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: Link XXX Change\nAlready listed\n"; $l->updateIPs(); $l->save(); return 'Link allready exists'; } else if ( strpos( $res, '<center><b>cannot write' ) !== false ) { $l->delete(); return 'Error: server error'; } else if ( strpos( $res, '<br><b>thank you' ) !== false ) { $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: Link XXX Change\n\n"; $l->updateIPs(); $l->save(); return true; } else { $l->delete(); return 'Error: unknown response'; } } else { return 'Could not find link details'; } } // }}} function axslinks( $con, $link ) { // {{{ global $config; $anchor = $config->anchor; $postfields = array( 'url' => $link, 'title' => $anchor[ mt_rand(0,sizeof($anchor)-1) ] ); if ( preg_match( '#<textarea.*>\s*(<a.*)\s*</textarea>#mis', $con{'contents'}, $res ) && preg_match( '#<form[\sa-z="\.\?]+\s+action=["\']?([^"\'> ]+)#i', $con{'contents'}, $form ) ) { $reciplink = $res[1]; $url = linkex::getParam( 'href', $reciplink, 'no' ); $title = linkex::getParam( 'title', $reciplink, 'no' ); $l = new link; $l->wmip = $_SERVER['REMOTE_ADDR']; $l->lurl = $url; $l->anchor = trim( $title ); $l->categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); $l->update(); $l->save(); //echo "We'll add a link in our database to '$url' with '$title'<br>"; // The form $formaction = linkex::expandlink( $form[1], $con{'URL'}.'?' ); $res = linkex::fetch( $formaction, array( 'method' => 'POST', 'data' => linkex::buildquery( $postfields ) ) ); if ( preg_match( '#<div id="errorbox">(.*)</div>#', linkex::get( 'contents', $res, '' ), $resp ) ) { switch( $resp[1] ) { case 'Your link was added': $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: AXSLinks\n\n"; $l->updateIPs(); $l->save(); return true; break; case 'Invalid URL': $l->delete(); return 'Error: invalid URL'; break; case 'Recip Link not found': $l->delete(); return 'Error: recip link not found'; break; case 'Your Link was placed in queue for review': $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: AXSLinks\nQueued for review\n"; $l->skipcheck = 1; $l->updateIPs(); $l->save(); return 'Link placed in queue'; break; case 'Your link already exists here. Not added.': $l->notes .= "Autoadded:\nDate:".date( 'Y-m-d H:i:s' )."\nScript: AXSLinks\nAlready listed\n"; $l->updateIPs(); $l->save(); return 'Link allready exists'; break; default: if ( preg_match( '#Error: minimum (\d+)/10 pagerank accepted!#', linkex::get( 'contents', $resp[0], '' ), $pr ) ) { $l->delete(); return 'Min. pagerank error. Requ'.'ired PageRank: '.$pr[1]; } else { // I have no idea what happend! $l->delete(); return 'unknown error: '.$resp[0]; } } } else { // No errorbox found, i'm not even sure it's an axslinks $l->delete(); return 'Could not recognize response test'; } } else { return 'Could not find form inputs'; } } // }}} } // }}} // {{{ Check the environment define( 'INSTALLED', ( linkex::installed() ) ? true:false ); if ( !is_writable( BASEDIR ) ) { $e = 'The directory ('.BASEDIR.') is not writable'; if ( function_exists( 'posix_geteuid' ) && function_exists( 'posix_getpwuid' ) && function_exists( 'getmyuid' ) && function_exists( 'posix_getgrgid' ) ) { $pinfo = posix_getpwuid( posix_geteuid() ); $finfo = posix_getpwuid( getmyuid() ); $e .= '<br />   - the directory is owned by "'.linkex::get( 'name', $finfo ).'" while the webserver process is runned as "'.linkex::get( 'name', $pinfo ).'"'; } $errors[] = $e; } // }}} if ( file_exists( 'storage.db' ) ) { function debug( $str ) { // {{{ echo "<script type=\"text/javascript\">_p('".$str."<br />');</script>"; linkex::flush(); } // }}} if ( is_array( $_POST ) && sizeof ( $_POST ) > 0 && strlen( linkex::get( '_username', $_POST, '' ) ) > 0 && strlen( linkex::get( '_password1', $_POST, '' ) ) > 0 && linkex::get( '_password1', $_POST, '' ) == linkex::get( '_password2', $_POST, false ) ) { echo template::header( array( 'title' => 'Upgrading' ) ); $legend = 'Upgrading'; echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend id=\"legend\">{$legend}</legend> <div><pre id=\"progress\" style=\"font-size:11px;min-height:100px;margin-left:5px;\"> ID Domain Status PageRank BackL.Status<br /> ===============================================================================================================<br /></pre></div> </fieldset> </div> <script type=\"text/javascript\"> /*<![CDATA[*/ function _p(str){ var elem=document.getElementById('progress'); if(elem){ elem.innerHTML +=str; } } function _t(str){ var elem=document.getElementById('legend'); if(elem){ elem.innerHTML=str; } } /*]]>*/ </script> "; echo template::footer(); linkex::flush(); $con = linkex::fileget( 'storage.db' ); if ( strlen( $con ) && ( $oldconf = linkex::unserialize( trim( $con ) ) ) != false ) { $dirs = array( BASEDIR . DIRECTORY_SEPARATOR .'data', BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR ); foreach( $dirs AS $d ) { if ( !is_dir( $d ) && !@mkdir( $d, 0755 ) ) { $errors[] = 'Unable to create directory "'.$d.'"'; break; } } if ( sizeof( $errors ) > 0 ) { // {{{ Dump the error(s) and exit debug( '<span class="error">'.join( '<br />', $errors ).'</span>' ); exit; } // }}} debug( 'Done create new directory tree' ); linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR .'uid', '1000' ); $transtable = array( 'categories' => array(), 'links' => array(), 'filter' => array( 1 => 0, 2 => 1, 3 => 2 ), 'sortby' => array( 'domain' => 'ldom', 'anchor' => 'anchor', 'description' => 'description', 'added' => 'added', 'sortkey' => 'id', 'random' => 'random' ), 'linkstatus' => array( 'OK' => 1, 'BAD' => 2 ), 'blacklist' => array( 'server_ip' => 1, 'domain' => 2, 'webmaster_ip' => 4, 'email' => 8, 'email_domain' => 16 ) ); // {{{ Create the blacklist $list = linkex::get( 'blacklist', $oldconf, array() ); foreach( $list AS $l ) { $b = new Blacklist; $b->type = linkex::get( linkex::get( 'type', $l, 'server_ip' ), $transtable{'blacklist'}, 1 ); $b->value = linkex::get( 'value', $l, 'none' ); $b->reason = linkex::get( 'reason', $l, 'no reason found' ); $b->date = linkex::get( 'date', $l, time() ); $b->save(); unset( $b ); } debug( 'Done converting blacklist' ); // }}} // {{{ Create all the categories $cats = linkex::get( 'outputs', $oldconf, array() ); $catlog = array(); foreach( $cats AS $cat ) { $c = new category; $c->name = linkex::get( 'name', $cat, 'No name found' ); $c->filter = linkex::get( linkex::get( 'filter', $cat, 2 ), $transtable{'filter'}, 2 ); if ( empty( $c->filter ) ) { $c->filter = array( 1 ); } $c->template = linkex::get( 'template', $cat, '' ); $c->limit = linkex::get( 'limit', $cat, 0 ); $c->order = linkex::get( 'order', $cat, 'dasc' ); $c->sortby = linkex::get( linkex::get( 'sortby', $cat, 'id' ), $transtable{'sortby'}, 'id' ); $c->save( false ); $transtable{'categories'}{ linkex::get( 'id', $cat, 0 ) } = $c->id; $catlog[] = array( 'file' => linkex::get( 'file', $cat, 'no filename found' ), 'id' => $c->id ); unset( $c ); } debug( 'Done converting categories' ); // }}} // {{{ Create all the links debug( 'Starting link convertion' ); $links = linkex::get( 'links', $oldconf, array() ); foreach( $links AS $link ) { $l = new link; $l->added = linkex::get( 'added', $link, time() ); $l->lastchecked = linkex::get( 'lastcheck', $link, 0 ); $l->lurl = linkex::get( 'lurl', $link, 'no link url found' ); $l->rurl = linkex::get( 'rurl', $link, 'no recip url found' ); $l->anchor = linkex::get( 'anchor', $link, 'no anchor found' ); $l->description = linkex::get( 'description', $link, '' ); $l->email = linkex::get( 'email', $link, 'no email found' ); $l->skipcheck = linkex::get( 'skipcheck', $link, 0 ); $l->status = linkex::get( linkex::get( 'status', $link, 'OK' ), $transtable{'linkstatus'}, 1 ); $l->wmip = long2ip( linkex::get( 'ip', $link, 0 ) ); // Do the categories $categories = linkex::get( 'outputs', $link, array() ); foreach( $categories AS $c ) { $cid = linkex::get( $c, $transtable{'categories'}, false ); if ( $cid !== false ) { $l->categories[] = $cid; } } $l->update(); $l->updateIPs(); $l->save( false ); debug( $l->ldom.' done' ); $transtable{'links'}{ linkex::get( 'id', $link, 0 ) } = $l->id; unset( $l ); } debug( 'Done converting links' ); // }}} // {{{ Set the config $c = linkex::get( 'config', $oldconf, array() ); $config = new config; $config->password = md5( linkex::get( '_username', $_POST, '' ) .'---'. linkex::get( '_password1', $_POST, '' ) ); $config->installdate = linkex::get( 'installdate', $c, time() ); $config->email = linkex::get( 'email', $c, 'no email found' ); $config->url = linkex::get( 'url', $c, 'no url found' ); $config->anchor = array( linkex::get( 'anchor', $c, 'no anchor found' ) ); $config->description = linkex::get( 'description', $c, '' ); $config->altlinks = linkex::get( 'altlinks', $c, array() ); $config->dateformat = linkex::get( 'datef', $c, 'Y.m.d' ); $config->displaylimit = linkex::get( 'num', $c, 100 ); $config->linkbotuniquedomains = linkex::get( 'uniquedomains', $c, 1 ); $config->remoteenable = linkex::get( 'croncheckallowed', $c, 0 ); $config->remotesummary = linkex::get( 'sendsummary', $c, 0 ); $config->remotepass = linkex::get( 'passphrase', $c, '' ); $config->remotelimitips = linkex::get( 'limitips', $c, 1 ); $config->remoteips = array_unique( array( 'linkex.dk' ) + linkex::get( 'iplist', $c, array() ) ); $config->minpagerank = linkex::get( 'minpagerank', $c, 0 ); $config->publiccategories = linkex::get( 'outputopen', $c, 0 ); $config->disablepublicform = linkex::get( 'disableform', $c, 0 ); $config->disablerecipfield = linkex::get( 'norecipurl', $c, 0 ); $categories = linkex::get( 'outputs', $c, array() ); foreach( $categories AS $cid ) { $config->defaultcategories[] = linkex::get( $cid, $transtable{'categories'}, 0 ); } $config->defaultcategories = array_unique( $config->defaultcategories ); $config->save(); debug( 'Done converting configfile' ); // }}} if ( sizeof( $errors ) > 0 ) { // {{{ Dump the error(s) and exit debug( '<span class="error">'.join( '<br />', $errors ).'</span>' ); exit; } // }}} // {{{ Get the rules if they exists if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'rules.dat' ) && filesize( BASEDIR . DIRECTORY_SEPARATOR . 'rules.dat' ) > 0 ) { linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules', linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'rules.dat' ) ); } // }}} // {{{ Now get rid of all the not needed files $d = dir( BASEDIR ); while (false !== ($entry = $d->read())) { if ( !in_array( $entry, array( '.', '..', 'index.php' ) ) && is_file( BASEDIR . DIRECTORY_SEPARATOR . $entry ) ) { if ( !@rename( BASEDIR . DIRECTORY_SEPARATOR . $entry, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . $entry ) ) { $errors[] = "Unable to move ".$entry." to BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR". $entry; } } } $d->close(); // }}} if ( sizeof( $errors ) > 0 ) { // {{{ Dump the error(s) and exit debug( '<span class="error">'.join( '<br />', $errors ).'</span>' ); exit; } // }}} // linkex::redirect( BASEURI ); // Present a nice "upgrade-done" page $newcats = array(); if ( sizeof( $catlog ) > 0 ) { foreach( $catlog AS $c ) { $cat = new category( $c{'id'} ); $cat->save(); $newcats[] = $c{'file'}.' » '. BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR . $c{'id'}; } } $newcats = join( '<br />', $newcats ); debug( '<br />Your database has been upgraded.<br />' ); debug( 'Please note, that the files generated by LinkEX has been altered,<br />and you need to change all references to them.<br />Below is a list of your categories, along with the file you need to inc'.'lude instead.<br /><br /><a href="?page=admin">Click here to proceed</a>' ); debug( $newcats ); } else { die( 'Error. Could not parse old config' ); } } else { if ( ( $username = linkex::get( '_username', $_POST, false ) ) !== false ) { $errors[] = 'Please specify a username'; } if ( linkex::get( '_password1', $_POST, false ) !== false ) { if ( strlen( linkex::get( '_password1', $_POST, 'linkex' ) ) == 0 ) { $errors[] = 'Please specify a password'; } else if ( linkex::get( '_password1', $_POST, '' ) != linkex::get( '_password2', $_POST, 1 ) ) { $errors[] = 'The two passwords you entered, were not the same. Please try again'; } } echo template::header( array( 'title' => 'Upgrade requirred' ) ); echo "<div style=\"margin:10px 0px;\"> <fieldset> <legend>Upgrading LinkEX</legend> <div class=\"article\"> <p>An older version of LinkEX, with the old backend, has been detected.</p> <p>As of version 20061218 this script is using a different approch to the flatfile database system.<br /> Your current setting, links and categories have to be converted into this new format.</p> <p>Also from this version, the authorization module has been changed, so from now on you need a username and password to login.<br /> To proceed please select your new username and password, and click "OK"</p> <p>Once the script has been converted, you should log in, and make sure every setting is correct.</p> <p><strong>Please note the convertion can take some time. (It could take up to 10 seconds for each link, so please be patient)</strong></p> </div> </fieldset> </div> <div style=\"margin:10px 0px;\"> <fieldset style=\"margin:10px auto;\"> <legend>Set your new login</legend> <form method=\"post\" action=\"".BASEURI."\"> <table class=\"table\"> <tr> <td class=\"key\">Username:</td> <td><input type=\"text\" class=\"text\" name=\"_username\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password:</td> <td><input type=\"password\" class=\"text\" name=\"_password1\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password (again):</td> <td><input type=\"password\" class=\"text\" name=\"_password2\" value=\"\" /></td> </tr> <tr> <td colspan=\"2\"> </td> </tr> <tr> <td class=\"key\"></td> <td><input type=\"submit\" class=\"button\" name=\"ok\" value=\"OK\" /></td> </tr> </table> </form> </fieldset> </div> "; echo template::footer(); } } else if ( INSTALLED ) { // Make sure logs directory is present if ( !is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR ) ) { @mkdir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR ); } // Enable error log @touch( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'error.log' ); @ini_set( 'error_log', BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'error.log' ); @ini_set( 'log_errors', true ); @ini_set('display_errors', 0); // {{{ Make sure .htaccess is present if ( strpos( strtolower( linkex::get( 'SERVER_SOFTWARE', $_SERVER, '' ) ), 'apache' ) !== false ) { if ( !file_exists( BASEDIR . DIRECTORY_SEPARATOR .'data'. DIRECTORY_SEPARATOR . '.htaccess' ) ) { linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR .'data'. DIRECTORY_SEPARATOR . '.htaccess', "Order Deny,Allow Deny from all " ); } if ( !file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR . '.htaccess' ) ) { linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR . '.htaccess', "Order Allow,Deny Allow from all " ); } } // }}} $config = new config; if ( linkex::get( 'SERVER_SOFTWARE', $_SERVER, false ) === false ) { // CLI check error_reporting( E_ALL ); ini_set( 'display_errors', 1 ); if ( intval( $config->commandlineenable ) == 0 ) { die( "LinkEX v.20100226, Free Link Exchange Script by http://linkex.dk Error: Command line access is disabled " ); } @set_time_limit( 7200 ); function output( $str ) { // {{{ global $verbose; if ( $verbose ) { echo $str; flush(); } } // }}} $donecats=$donelinks=false; function verbose( $data ) { // {{{ global $donecats, $donelinks; switch( $data{'action'} ) { case 'link': // {{{ $sp = "% 6s % -20s % -15s % 6s => % -10s % 10s => % -10s\n"; if ( false === $donelinks ) { output( "\n* Verifying backlinks..\n\n" . sprintf( $sp, 'ID', 'Domain', 'IP', 'Old PR', 'New PR', 'Old Status', 'New status' ) . "==========================================================================================\n" ); $donelinks=true; } output( sprintf( $sp, $data{'id'}, linkex::truncate( $data{'rdom'}, 20 ), $data{'rdomip'}, $data{'oldpagerank'}, $data{'pagerank'}, link::statusOptions( $data{'oldstatus'} ), link::statusOptions( $data{'status'} ) ) ); break; // }}} case 'category': // {{{ $sp = "% 6s % -20s % -10s\n"; if ( false === $donecats ) { output( "\n\n* Rebuilding categories..\n\n" . sprintf( $sp, 'ID', 'Name', 'Status' ) . "==========================================================================================\n" ); $donecats = true; } output( sprintf( $sp, $data{'id'}, linkex::truncate( $data{'name'}, 20 ), 'done' ) ); break; // }}} } } // }}} if ( strpos( strtolower( join(' ', $_SERVER['argv'] ) ), '--help' ) !== false ) { $linkexpath = __FILE__; echo "LinkEX v.20100226, Free Link Exchange Script by http://linkex.dk Usage: /path/to/php {$linkexpath} [OPTION]... /path/to/php is usually /usr/local/bin/php or /usr/bin/php if in doubt ask your server administrator The following options are available: --quiet quiet (no output) (this is the default). --verbose be verbose --help this help screen "; exit; } else { $verbose = ( strpos( strtolower( join(' ', $_SERVER['argv'] ) ), 'verbose' ) !== false ); $report = linkex::verifybacklinks( linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ), 'verbose' ); if ( intval( $config->commandlinesummary ) == 1 ) { $report = template::report( $report ); linkex::mail( $config->email, 'Link verification report', $report ); } } } else { define( 'LOGGEDIN', linkex::authorized() ); switch( linkex::get( 'page', $_REQUEST, '' ) ) { case 'xmlcom': case 'xmlrpc': function xmlauthorize( $xml ) { // {{{ global $config; // {{{ Check the IP if ( intval( $config->remotelimitips ) == 1 ) { $ok = false; foreach ( $config->remoteips AS $rip ) { if ( linkex::compareIPs( $_SERVER['REMOTE_ADDR'], $rip ) == 0 ) { $ok = true; break; } } if ( ! $ok ) { $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 403 ); $resp->add_tag( 'error', '403 Forbidden' ); $resp->add_tag( 'description', 'Your IP '.$_SERVER['REMOTE_ADDR'].' is not accepted' ); $resp->close_group(); $resp->display(); exit; } } // }}} // {{{ Check the password if ( strlen( $config->remotepass ) > 0 ) { $password = $xml->getFirstElementByNodeName( 'password' ); if ( $password == null || $password->nodeValue != $config->remotepass ) { $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 401 ); $resp->add_tag( 'error', '401 Unauthorized' ); $resp->add_tag( 'description', 'Invalid password' ); $resp->close_group(); $resp->display(); exit; } } // }}} return true; } // }}} function checkNodes( $xml, $list ) { foreach ( $list AS $n ) { if ( null == $xml->getFirstElementByNodeName( $n ) ) { $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 400 ); $resp->add_tag( 'error', '400 Bad Request' ); $resp->add_tag( 'description', 'Missing element '.$n ); $resp->close_group(); $resp->display(); exit; } } } header( 'Content-type: text/xml' ); header( 'X-Powered-By: LinkEX/20100226' ); // TODO fix allowed methods if ( in_array( linkex::get( 'REQUEST_METHOD', $_SERVER, '' ), array('POST','GET')) ) { // {{{ Get data if ( isset( $HTTP_RAW_POST_DATA ) && strlen( $HTTP_RAW_POST_DATA ) ) { $data = $HTTP_RAW_POST_DATA; } else { $data = str_replace( "\r", '', @implode("\n", @file( 'php://input' ) ) ); } // }}} $xml = XMLParser::parse( $data ); $methodCall = $xml->getFirstElementByNodeName( 'methodCall' ); if ( $methodCall != null ) { $methodName = $methodCall->getFirstElementByNodeName( 'methodName' ); switch( $methodName->nodeValue ) { case 'link.edit': // {{{ case 'link.add': if ( xmlauthorize( $methodCall ) ) { $data = $methodCall->getFirstElementByNodeName( 'link' ); if ( $data == null ) { $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 400 ); $resp->add_tag( 'error', '400 Bad Request' ); $resp->add_tag( 'description', 'No data found' ); $resp->close_group(); $resp->display(); exit; } else { checkNodes( $data, array( 'lurl', 'rurl', 'anchor', 'title', 'description', 'categories', 'email', 'skipcheck', 'skippagerank', 'notes', 'weight' ) ); } } break; // }}} case 'link.list': // {{{ if ( xmlauthorize( $methodCall ) ) { $linkids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', '0' ); $resp->add_group( 'links' ); foreach( $linkids AS $lid ) { $l = new link( $lid ); $resp->add_group( 'link' ); $resp->append( $l->toXML() ); $resp->close_group(); unset( $l ); } $resp->close_group(); $resp->close_group(); $resp->display(); } break; // }}} case 'admin.info': // {{{ if ( xmlauthorize( $methodCall ) ) { $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', '0' ); $resp->add_group( 'LinkEX' ); $resp->add_tag( 'version', 20100226 ); $resp->add_tag( 'formOpen', ( $config->disablepublicform == 1 ) ? '0':'1' ); $resp->add_tag( 'email', htmlentities( $config->email ) ); $resp->add_tag( 'url', $config->url ); $resp->add_tag( 'minpagerank', "".$config->minpagerank ); $resp->add_group( 'titles' ); if ( is_array( $config->anchor ) ) { foreach( $config->anchor AS $a ) { $resp->add_tag( 'title', htmlentities( $a ) ); } } $resp->close_group(); $resp->add_group( 'categories' ); $cats = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ); foreach( $cats AS $cid ) { $c = new Category( $cid ); $ca = array( 'id' => $cid, 'name' => htmlentities( $c->name ) ); $resp->add_tag( 'category', '', $ca ); } $resp->close_group(); $stats=array( 'total'=>0, 'suspended'=>0 ); $links = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); foreach( $links AS $lid ) { $l = new link( $lid ); $stats{'total'}++; if ( $l->status == 2 ) { $stats{'suspended'}++; } } $resp->add_tag( 'links', '', $stats ); $resp->add_tag( 'description', htmlentities( $config->description ) ); $resp->add_tag( 'zend.version', zend_version() ); $resp->add_tag( 'php.version', phpversion() ); $resp->add_tag( 'uname', htmlentities( php_uname( 's' ).' '.php_uname( 'r' ).' '.php_uname( 'm' ) ) ); $resp->close_group(); $resp->close_group(); $resp->display(); } break; // }}} case 'info': // {{{ $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', '0' ); $resp->add_group( 'LinkEX' ); $resp->add_tag( 'version', 20100226 ); $resp->add_tag( 'formOpen', ( $config->disablepublicform == 1 ) ? '0':'1' ); $resp->add_tag( 'email', htmlentities( $config->email ) ); $resp->add_tag( 'url', $config->url ); $resp->add_tag( 'minpagerank', "".$config->minpagerank ); $resp->add_group( 'titles' ); if ( is_array( $config->anchor ) ) { foreach( $config->anchor AS $a ) { $resp->add_tag( 'title', htmlentities( $a ) ); } } $resp->close_group(); $resp->add_group( 'categories' ); $cats = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ); foreach( $cats AS $cid ) { $c = new Category( $cid ); if ( intval( $config->publiccategories ) == 1 && intval( $c->public ) == 1 ) { $ca = array( 'id' => $cid, 'name' => htmlentities( $c->name ) ); $resp->add_tag( 'category', '', $ca ); } } $resp->close_group(); $resp->add_tag( 'description', htmlentities( $config->description ) ); $resp->close_group(); $resp->close_group(); $resp->display(); break; // }}} default: // {{{ $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 501 ); $resp->add_tag( 'error', '501 Not Implemented' ); $resp->add_tag( 'description', 'methodName "'.$methodName->nodeValue.'" not implemented' ); $resp->close_group(); $resp->display(); break; // }}} } } else { // {{{ No method $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 400 ); $resp->add_tag( 'error', '400 Bad Request' ); $resp->add_tag( 'description', 'No method call found' ); $resp->close_group(); $resp->display(); exit; } // }}} } else { // {{{ Not a POST request $resp = new XML; $resp->add_group( 'methodResponse' ); $resp->add_tag( 'errno', 400 ); $resp->add_tag( 'error', '400 Bad Request' ); $resp->add_tag( 'description', 'XML-RPC server accepts POST requests only' ); $resp->close_group(); $resp->display(); exit; } // }}} break; case 'resetpassword': if ( ( $key = linkex::get( 'key', $_GET, false ) ) !== false ) { if ( linkex::get( 'date', $config->resetpassword ) > ( time() - 3600 ) ) { if ( $key == linkex::get( 'key', $config->resetpassword ) ) { $formaction = htmlentities( $_SERVER['REQUEST_URI'] ); echo template::header( array( 'title' => 'Reset forgotten username/password' ) ); if ( array_key_exists( '_username', $_POST ) ) { $_username = linkex::get( '_username', $_POST, '' ); $_password1 = linkex::get( '_password1', $_POST, '' ); $_password2 = linkex::get( '_password2', $_POST, '' ); // {{{ Check the username if ( strlen( trim( $_username ) ) == 0 ) { $errors[] = 'Please enter a username'; } // }}} // {{{ Check the password(s) if ( strlen( trim( $_password1 ) ) == 0 ) { $errors[] = 'Please enter a password'; } else if ( trim( $_password1 ) != trim( $_password2 ) ) { $errors[] = 'The two passwords did not match, please try again.'; } // }}} if ( sizeof( $errors ) == 0 ) { $config->password = md5( $_username .'---'. $_password1 ); $config->save(); echo "<div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Reset username/password</legend> <table class=\"table\"> <tr> <td> Your usename/password has been changed. You can now log in with the new username and password. </td> </tr> </table> </fieldset> </div> "; } else { echo "<div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Reset username/password</legend> <form method=\"post\" action=\"{$formaction}\"> <table class=\"table\"> <tr> <td colspan=\"2\"> You have been authorized to change the password for this LinkEX installation.<br /> Please enter your new username and password in the form below.<br /> </td> </tr> <tr> <td class=\"key\">Username:</td> <td><input type=\"text\" class=\"text\" name=\"_username\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password:</td> <td><input type=\"password\" class=\"text\" name=\"_password1\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password (again):</td> <td><input type=\"password\" class=\"text\" name=\"_password2\" value=\"\" /></td> </tr> <tr> <td class=\"key\"></td> <td><br /><input type=\"submit\" class=\"button\" value=\"OK\" /></td> </tr> </table> </form> </fieldset> </div> "; } } else { echo "<div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Reset username/password</legend> <form method=\"post\" action=\"{$formaction}\"> <table class=\"table\"> <tr> <td colspan=\"2\"> You have been authorized to change the password for this LinkEX installation.<br /> Please enter your new username and password in the form below.<br /> </td> </tr> <tr> <td class=\"key\">Username:</td> <td><input type=\"text\" class=\"text\" name=\"_username\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password:</td> <td><input type=\"password\" class=\"text\" name=\"_password1\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password (again):</td> <td><input type=\"password\" class=\"text\" name=\"_password2\" value=\"\" /></td> </tr> <tr> <td class=\"key\"></td> <td><br /><input type=\"submit\" class=\"button\" value=\"OK\" /></td> </tr> </table> </form> </fieldset> </div> "; } echo template::footer(); exit; } else { $errors[] = 'Key mismatch. Please retry'; } } else { $errors[] = 'This link has expired, please re-request a username/password'; } echo template::header( array( 'title' => 'Reset forgotten username/password' ) ); echo template::footer(); } else if ( sizeof( $_POST ) > 0 ) { if ( linkex::get( 'captcha', $_POST, false ) && linkex::get( 'captcha', $_SESSION, false ) && linkex::get( 'result', $_SESSION['captcha'], false ) && $_POST['captcha'] == $_SESSION['captcha']['result'] ) { $config->resetpassword = array( 'date' => time(), 'key' => md5( mt_rand(0,10000) . time() . microtime() ) ); $config->save(); linkex::mail( $config->email, 'Reset admin password', "This is a message from LinkEX running on {$_SERVER['HTTP_HOST']}. You or someone else has requested a new username/password. To generate a new set, please visit the following address: http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}&key={$config->resetpassword['key']} Thanks " ); echo template::header( array( 'title' => 'Reset forgotten username/password' ) ); echo "<div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Reset username/password</legend> <table class=\"table\"> <tr> <td> An email has been sent to you with further instructions. </td> </tr> </table> </fieldset> </div> "; echo template::footer(); exit; } else { $errors[] = 'Spam check failed. Please retry'; } } echo template::header( array( 'title' => 'Reset forgotten username/password' ) ); $c = new captcha; $captchatag = $c->html(); $captcha = " <tr> <td class=\"key\">Spam check:</td> <td> <table cellpadding=\"0\" cellspacing=\"0\"> <tr> <td style=\"width:100px;\">{$captchatag}</td> <td><input type=\"text\" name=\"captcha\" value=\"\" class=\"text\" style=\"width:50px;\" /></td> </tr> </table> </td> <td class=\"help\"></td> </tr> "; echo "<div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Reset username/password</legend> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <table class=\"table\"> <tr> <td colspan=\"2\"> First you need to fill out the form below. When you submit, you will receive an email with further instructions. </td> </tr> {$captcha} <tr> <td class=\"key\"></td> <td><br /><input type=\"submit\" class=\"button\" value=\"OK\" /></td> </tr> </table> </form> </fieldset> </div> "; echo template::footer(); break; case 'captcha': $c = new captcha; $c->image(); break; case 'xmlclient': header( 'Content-type: text/xml' ); header( 'X-Powered-By: LinkEX/20100226' ); if ( LOGGEDIN ) { switch( linkex::get( 'view', $_REQUEST, '' ) ) { case 'BlackList.list': $file = BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'xml.blacklist.list'; $url = 'http://my.linkex.dk/xml/server.php'; $xml = new xml; $xml->add_group( 'methodCall' ); $xml->add_tag( 'methodName', 'BlackList.list' ); $xml->add_group( 'params' ); $xml->add_tag( 'host', str_replace( 'www.','',$_SERVER['HTTP_HOST'] ) ); $xml->add_group( 'BlackList' ); $ids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ); foreach( $ids AS $id ) { $blacklist = new Blacklist( $id ); if ( $blacklist->public == '1' ) { $xml->add_group( 'entry' ); $xml->add_tag( 'type', xml::escape( str_replace(' ','', strtolower( $blacklist->types( $blacklist->type ) ) ) ) ); $xml->add_tag( 'value', xml::escape( $blacklist->value ) ); $xml->add_tag( 'reason', xml::escape( $blacklist->reason ) ); $xml->close_group(); } } $xml = $xml->output(); $xml = linkex::fetch( $url, array( 'method' => 'POST', 'data' => $xml, 'agent' => 'XML/1.0' ) ); echo linkex::get( 'contents', $xml, '' ); exit; break; case 'changelog': $file = BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'rss.changelog'; $url = 'http://linkex.dk/feeds/changelog.xml?rel=' . 20100226; break; default: $resp = new XML; $resp->add_group( 'ajax' ); $resp->add_tag( 'errno', 503 ); $resp->add_tag( 'error', '503 Service Unavailable' ); $resp->add_tag( 'description', 'Please specify feed' ); $resp->close_group(); $resp->display(); exit; break; } if ( file_exists( $file ) && ( time() - filemtime( $file ) ) < 3600 ) { $con = linkex::fileget( $file ); } else { $con = linkex::fetch( $url, array( 'agent' => 'LinkEX/20100226' ) ); $con = linkex::get( 'contents', $con, '' ); if ( !is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR ) ) { @mkdir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR, 0775 ); } linkex::fileput( $file, $con ); } echo $con; exit; } else { $resp = new XML; $resp->add_group( 'ajax' ); $resp->add_tag( 'errno', 403 ); $resp->add_tag( 'error', '403 Forbidden' ); $resp->add_tag( 'description', 'you must be logged in to do this' ); $resp->close_group(); $resp->display(); } exit; break; case 'rss': header( 'Content-type: text/xml' ); header( 'X-Powered-By: LinkEX/20100226' ); if ( LOGGEDIN ) { switch( linkex::get( 'view', $_REQUEST, '' ) ) { case 'announcements': $file = BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'rss.announcements'; $url = 'http://feeds2.feedburner.com/linkex-script'; break; case 'changelog': $file = BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'rss.changelog'; $url = 'http://linkex.dk/feeds/changelog.xml?rel=' . 20100226; break; default: $resp = new XML; $resp->add_group( 'ajax' ); $resp->add_tag( 'errno', 503 ); $resp->add_tag( 'error', '503 Service Unavailable' ); $resp->add_tag( 'description', 'Please specify feed' ); $resp->close_group(); $resp->display(); exit; break; } if ( file_exists( $file ) && ( time() - filemtime( $file ) ) < 3600 ) { $con = linkex::fileget( $file ); } else { $ref = 'http://'. linkex::get( 'HTTP_HOST', $_SERVER, 'nohost' ) . linkex::get( 'REQUEST_URI', $_SERVER, '/nouri' ); $con = linkex::fetch( $url, array( 'agent' => 'LinkEX/20100226', 'referer' => $ref, 'timeout' => 2 ) ); $con = linkex::get( 'contents', $con, '' ); if ( !is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR ) ) { @mkdir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR, 0775 ); } if ( strlen( $con )>0 ) { linkex::fileput( $file, $con ); } } echo $con; exit; } else { $resp = new XML; $resp->add_group( 'ajax' ); $resp->add_tag( 'errno', 403 ); $resp->add_tag( 'error', '403 Forbidden' ); $resp->add_tag( 'description', 'you must be logged in to do this' ); $resp->close_group(); $resp->display(); } exit; break; case 'admin': if ( LOGGEDIN ) { switch( linkex::get( 'view', $_REQUEST, '' ) ) { case '': // {{{ Search variables.. what a mess $searchshow = 'hidden'; $searchfor = array(); $field = linkex::get( 'sf', $_REQUEST, '' ); $searchfields = linkex::selector( 'sf', array( 'all' => 'all fields', 'email' => 'email', 'recipurl' => 'reciprocal URL', 'linkurl' => 'link URL', 'anchor' => 'site title', 'description' => 'description' ), $field, false, 'select' ); if ( strlen( $field )>0 ) { $searchshow = ''; $searchfor[]='sf='.$field; } $selected = linkex::get( 'c', $_REQUEST, array() ); if ( is_string( $selected ) ) { $selected = linkex::map( 'trim', explode( ',', $selected ) ); } $categories = linkex::selector( 'c', linkex::categories( true ), $selected, true, null, array( 'class' => 'noauto' ) ); if ( sizeof( $selected ) > 0 ) { $searchshow = ''; $searchfor[] = 'c='.join(',',$selected); } $searchq = urldecode( linkex::get( 'q', $_REQUEST, '' ) ); if ( strlen( $searchq )>0 ) { $searchshow = ''; $searchfor[]='q='.$searchq; } $case = linkex::checkbox( linkex::get( 'cs', $_REQUEST, '' ) ); if ( strlen( $case )>0 ) { $searchshow = ''; $searchfor[]='cs=1'; } if ( strlen( $searchshow ) == 0 && sizeof( $_POST ) > 0 ) { linkex::redirect( BASEURI . '?page=admin&'.join( '&', $searchfor ) ); } // }}} $linkids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); // {{{ Summary init.. what a mess $links = array(); $summary = array(); $summary{'pagerank'} = array(); $summary{'pagerank'}{0} = 0; $summary{'pagerank'}{1} = 0; $summary{'pagerank'}{2} = 0; $summary{'pagerank'}{3} = 0; $summary{'pagerank'}{4} = 0; $summary{'pagerank'}{5} = 0; $summary{'pagerank'}{6} = 0; $summary{'pagerank'}{7} = 0; $summary{'pagerank'}{8} = 0; $summary{'pagerank'}{9} = 0; $summary{'pagerank'}{10} = 0; $summary{'links'}{'all'} = 0; $summary{'links'}{1} = 0; $summary{'links'}{2} = 0; $summary{'links'}{4} = 0; $ips = array(); $ips{'ips'} = array(); $ips{'subips'} = array(); // }}} $linkids_suspended = array(); foreach( $linkids AS $lid ) { $l = new link( $lid ); // Apply filter if nessecary // {{{ Category filter if ( ( $c = linkex::get( 'c', $_REQUEST, false ) ) !== false ) { $c = linkex::map( 'trim', explode( ',', $c ) ); if ( sizeof( array_intersect( $c, $l->categories ) ) == 0 ) { continue; } } // }}} // {{{ Search string if ( ( $q = linkex::get( 'q', $_REQUEST, false ) ) !== false && ( $f = linkex::get( 'sf', $_REQUEST ) !== false ) ) { $cs = ( linkex::get( 'cs', $_REQUEST, 0 ) == 0 ); $q = ( $cs ) ? strtolower( $q ) : $q; switch( linkex::get( 'sf', $_REQUEST ) ) { case 'description': // {{{ $a = $l->description; if ( $cs ) { $a = strtolower( $a ); } if ( strpos( $a, $q ) === false ) { continue 2; } break; // }}} case 'anchor': // {{{ $a = $l->anchor; if ( $cs ) { $a = strtolower( $a ); } if ( strpos( $a, $q ) === false ) { continue 2; } break; // }}} case 'linkurl': // {{{ $a = $l->lurl; if ( $cs ) { $a = strtolower( $a ); } if ( strpos( $a, $q ) === false ) { continue 2; } break; // }}} case 'recipurl': // {{{ $a = $l->rurl; if ( $cs ) { $a = strtolower( $a ); } if ( strpos( $a, $q ) === false ) { continue 2; } break; // }}} case 'email': // {{{ $a = $l->email; if ( $cs ) { $a = strtolower( $a ); } if ( strpos( $a, $q ) === false ) { continue 2; } break; // }}} case 'all': // {{{ $a = $l->email; if ( $cs ) { $a = strtolower( $a ); } $b = $l->rurl; if ( $cs ) { $b = strtolower( $b ); } $c = $l->lurl; if ( $cs ) { $c = strtolower( $c ); } $d = $l->anchor; if ( $cs ) { $d = strtolower( $d ); } $e = $l->description; if ( $cs ) { $e = strtolower( $e ); } if ( strpos( $a, $q ) !== false || strpos( $b, $q ) !== false || strpos( $c, $q ) !== false || strpos( $d, $q ) !== false || strpos( $e, $q ) !== false ) {} else { continue 2; } break; // }}} } } // }}} $links[] = $l; $summary{'pagerank'}{ $l->rpagerank }++; $summary{'links'}{'all'}++; $summary{'links'}{ $l->status }++; $ips{'ips'}[] = $l->rdomip; $ips{'subips'}[] = long2ip( ( ip2long( $l->rdomip ) >> 8 << 8 ) ); if( $l->status == 2 ) { $linkids_suspended[] = $lid; } } $summary{'links'}{'ips'} = sizeof( array_unique( $ips{'ips'} ) ); $summary{'links'}{'subips'} = sizeof( array_unique( $ips{'subips'} ) ); $linkids_all = join( ',', $linkids ); $linkids_suspended = join( ',', $linkids_suspended ); unset( $ips ); unset( $linkids ); echo template::header( array( 'title' => 'Overview' ) ); // Sort the $links[] and chunk it up into the size we want $sortkey = linkex::get( 'sortkey', $_REQUEST, $config->sortkey ); $sortorder = linkex::get( 'sortorder', $_REQUEST, $config->sortorder ); linkex::sort( $links, $sortkey, $sortorder ); $links = linkex::arraychunk( $links, $config->displaylimit ); $start = linkex::get( 'start', $_REQUEST, 1 ); $pages = sizeof( $links ); $navlinks = template::navigation( $start, $pages, BASEURI . '?page=admin&sortkey='.$sortkey.'&sortorder='.$sortorder.'&' ); if ( sizeof( $links ) > 0 ) { $links = $links{ ( $start - 1 ) }; } else { $links = array(); } $sorder = array( 'added' => ( $sortkey == 'added' && $sortorder == 'asc' ) ? 'desc':'asc', 'lastchecked' => ( $sortkey == 'lastchecked' && $sortorder == 'asc' ) ? 'desc':'asc', 'rpagerank' => ( $sortkey == 'rpagerank' && $sortorder == 'asc' ) ? 'desc':'asc', 'rindexed' => ( $sortkey == 'rindexed' && $sortorder == 'asc' ) ? 'desc':'asc', 'lpagerank' => ( $sortkey == 'lpagerank' && $sortorder == 'asc' ) ? 'desc':'asc', 'lindexed' => ( $sortkey == 'lindexed' && $sortorder == 'asc' ) ? 'desc':'asc', 'rdom' => ( $sortkey == 'rdom' && $sortorder == 'asc' ) ? 'desc':'asc', 'rdomip' => ( $sortkey == 'rdomip' && $sortorder == 'asc' ) ? 'desc':'asc', 'ldom' => ( $sortkey == 'ldom' && $sortorder == 'asc' ) ? 'desc':'asc', 'ldomip' => ( $sortkey == 'ldomip' && $sortorder == 'asc' ) ? 'desc':'asc', 'anchor' => ( $sortkey == 'anchor' && $sortorder == 'asc' ) ? 'desc':'asc', 'title' => ( $sortkey == 'title' && $sortorder == 'asc' ) ? 'desc':'asc', 'link' => ( $sortkey == 'link' && $sortorder == 'asc' ) ? 'desc':'asc', 'status' => ( $sortkey == 'status' && $sortorder == 'asc' ) ? 'desc':'asc' ); $sclass = array( 'added' => ( ( $sortkey == 'added' ) ? 'sort'.$sortorder:'' ), 'lastchecked' => ( ( $sortkey == 'lastchecked' ) ? 'sort'.$sortorder:'' ), 'rpagerank' => ( ( $sortkey == 'rpagerank' ) ? 'sort'.$sortorder:'' ), 'lpagerank' => ( ( $sortkey == 'lpagerank' ) ? 'sort'.$sortorder:'' ), 'rdom' => ( ( $sortkey == 'rdom' ) ? 'sort'.$sortorder:'' ), 'rdomip' => ( ( $sortkey == 'rdomip' ) ? 'sort'.$sortorder:'' ), 'ldom' => ( ( $sortkey == 'ldom' ) ? 'sort'.$sortorder:'' ), 'ldomip' => ( ( $sortkey == 'ldomip' ) ? 'sort'.$sortorder:'' ), 'lindexed' => ( ( $sortkey == 'lindexed' ) ? 'sort'.$sortorder:'' ), 'rindexed' => ( ( $sortkey == 'rindexed' ) ? 'sort'.$sortorder:'' ), 'anchor' => ( ( $sortkey == 'anchor' ) ? 'sort'.$sortorder:'' ), 'title' => ( ( $sortkey == 'title' ) ? 'sort'.$sortorder:'' ), 'link' => ( ( $sortkey == 'link' ) ? 'sort'.$sortorder:'' ), 'status' => ( ( $sortkey == 'status' ) ? 'sort'.$sortorder:'' ) ); $columns = array(); $template = array_merge( array( 'checkbox', 'options' ), $config->template ); foreach( $template AS $key ) { $columns[] = array( 'key' => $key, 'sorder' => ( $sortkey == $key && $sortorder == 'asc' ) ? 'desc':'asc', 'sclass' => ( $sortkey == $key ) ? 'sort'.$sortorder:'' ); } $columnscount=sizeof($columns); $columnscountleft=sizeof($columns)-6; // {{{ Mass edit options $masseditstatus = linkex::selector( 'masseditsetstatus', array( '0' => 'Leave as it is' ) + link::statusOptions(), '0', false, 'radio' , null, '  '); $masseditskipcheck = linkex::selector( 'masseditskipcheck', array( '0' => 'Leave as it is', '1' => 'Skip selected', '2' => 'Do not skip selected' ), '0', false, 'radio', null, '  ' ); $masseditskippagerank = linkex::selector( 'masseditskippagerank', array( '0' => 'Leave as it is', '1' => 'Ignore selected', '2' => 'Do not ignore selected' ), '0', false, 'radio', null, '  ' ); $masseditcategoryset = linkex::selector( 'masseditcategoryset', array( '0' => 'Leave as it is', '1' => 'Update', '2' => 'Overwrite' ), '0', false, 'radio', null, '  ' ); $masseditcategories = linkex::selector( 'masseditcategories', linkex::categories( true ), null, true, null, array( 'class' => 'noauto' ) ); $masseditminpagerank = linkex::selector( 'masseditminpagerank', array( 'null' => 'Leave as it is', -1=>'Use global min. PageRank™', 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>10 ), null, false, 'select', array( 'style' => 'width:auto;' ) ); // }}} echo "<div style=\"margin:12px;\"> <fieldset class=\"expandable {$searchshow}\" style=\"width:100%;\" id=\"fs_search_filter\"> <legend>Search/filter</legend> <div class=\"contractor\"> <form method=\"post\" action=\"".BASEURI."?page=admin\"> <table style=\"width:90%;margin:0px auto;\"> <tr> <td class=\"key\">Search for:</td> <td><input type=\"text\" class=\"text\" name=\"q\" value=\"{$searchq}\" style=\"width:200px;\" /> in {$searchfields}</td> </tr> <tr> <td class=\"key\"></td> <td><label><input class=\"checkbox noauto\" type=\"checkbox\" name=\"cs\" value=\"1\" {$case} /> case sensitive</label></td> </tr> <tr valign=\"top\"> <td class=\"key\">Categories:</td> <td>{$categories}</td> </tr> <tr valign=\"top\"> <td class=\"key\"></td> <td><input type=\"submit\" name=\"ok\" value=\"OK\" class=\"button\" /></td> </tr> </table> </form> </div> </fieldset> </div> <div style=\"margin:12px;\"> <fieldset class=\"expandable hidden\" style=\"width:100%;\" id=\"fs_links_summary\"> <legend>Links summary</legend> <div class=\"contractor\"> <table style=\"width:90%;margin:0px auto;\"> <tr> <td style=\"width:30%;\" class=\"bold\">Total links:</td> <td style=\"width:20%;\" class=\"bold\">{$summary{'links'}{'all'}}</td> <td style=\"width:20%;\"><div class=\"pagerank pr10\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{10}}</td> </tr> <tr> <td>    Suspended links:</td> <td>{$summary{'links'}{2}}</td> <td style=\"width:20%;\"><div class=\"pagerank pr9\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{9}}</td> </tr> <tr> <td>    Immune links:</td> <td>{$summary{'links'}{4}}</td> <td style=\"width:20%;\"><div class=\"pagerank pr8\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{8}}</td> </tr> <tr> <td>    OK links:</td> <td>{$summary{'links'}{1}}</td> <td style=\"width:20%;\"><div class=\"pagerank pr7\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{7}}</td> </tr> <tr> <td></td> <td></td> <td style=\"width:20%;\"><div class=\"pagerank pr6\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{6}}</td> </tr> <tr> <td>Unique IPs:</td> <td>{$summary{'links'}{'ips'}}</td> <td style=\"width:20%;\"><div class=\"pagerank pr5\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{5}}</td> </tr> <tr> <td>Unique C-Class IPs:</td> <td>{$summary{'links'}{'subips'}}</td> <td style=\"width:20%;\"><div class=\"pagerank pr4\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{4}}</td> </tr> <tr> <td></td> <td></td> <td style=\"width:20%;\"><div class=\"pagerank pr3\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{3}}</td> </tr> <tr> <td></td> <td></td> <td style=\"width:20%;\"><div class=\"pagerank pr2\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{2}}</td> </tr> <tr> <td></td> <td></td> <td style=\"width:20%;\"><div class=\"pagerank pr1\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{1}}</td> </tr> <tr> <td></td> <td></td> <td style=\"width:20%;\"><div class=\"pagerank pr0\"></div></td> <td style=\"width:30%;\">{$summary{'pagerank'}{0}}</td> </tr> </table> </div> </fieldset> </div> <div style=\"margin:12px;\"> <fieldset class=\"expandable hidden\" style=\"width:100%;\" id=\"fs_rss_news\"> <legend id=\"rsslegend\">LinkEX news (updating..)</legend> <div class=\"contractor\"> <div class=\"rssnews\" id=\"rssnews\"> </div> </div> </fieldset> </div> <script type=\"text/javascript\"> /*<![CDATA[*/ \$(document).ready(function(){ var url = location.href.replace( /\?.*/, '' )+'?page=rss&view=announcements'; \$.get( url, function(xml){ var html=''; \$(\"legend#rsslegend\").html(\"LinkEX news (parsing xml..)\"); var items=\$(\"item\", xml); \$(items).each(function(){ var title=\$(this).find(\"title:first\").text(); var link=\$(this).find(\"link:first\").text(); var pubDate=\$(this).find(\"pubDate:first\").text(); var description=\$(this).find(\"description:first\").text(); html +='<div class=\"item\"><div class=\"meta\"><div class=\"title\"><a target=\"_blank\" href=\"'+link+'\">'+ title+'</a></div>Posted on '+pubDate+'</div><div class=\"contents\">'+description+'</div></div>'; }); \$(\"div#rssnews\").html(html); \$(\"legend#rsslegend\").html(\"LinkEX news (\"+items.length+\" items)\"); })}); /*]]>*/ </script> <script type=\"text/javascript\"> /*<![CDATA[*/ var linkids_all = [{$linkids_all}]; var linkids_suspended = [{$linkids_suspended}]; /*]]>*/ </script> <form action=\"".BASEURI."?page=admin&view=verify\" method=\"post\" id=\"adminverify\"> <div style=\"margin:10px;\"> <table class=\"list\" id=\"links\" cellspacing=\"0\"> <thead> <tr class=\"th\" valign=\"bottom\"> "; if ( is_array( $columns ) && sizeof( $columns )>0 ) { foreach ( $columns AS $col ) { echo " ".(($col['key'] == 'checkbox')?("<th style=\"width:20px;\"> </th> "):(($col['key'] == 'options')?("<th style=\"width:50px;\"></th> "):(($col['key'] == 'added')?("<th style=\"width:65px;\"><a class=\"{$sclass['added']}\" href=\"".BASEURI."?page=admin&sortkey=added&sortorder={$sorder['added']}&start={$start}\">Added</a></th> "):(($col['key'] == 'lastchecked')?("<th style=\"width:65px;\"><a class=\"{$sclass['lastchecked']}\" href=\"".BASEURI."?page=admin&sortkey=lastchecked&sortorder={$sorder['lastchecked']}&start={$start}\">Checked</a></th> "):(($col['key'] == 'rpagerank')?("<th style=\"width:75px;\"><abbr title=\"Inbound PageRank™\"><a class=\"{$sclass['rpagerank']}\" href=\"".BASEURI."?page=admin&sortkey=rpagerank&sortorder={$sorder['rpagerank']}&start={$start}\">iPR</a></abbr></th> "):(($col['key'] == 'rdom')?("<th style=\"width:130px;\"><abbr title=\"Inbound domain\"><a class=\"{$sclass['rdom']}\" href=\"".BASEURI."?page=admin&sortkey=rdom&sortorder={$sorder['rdom']}&start={$start}\">iDomain</a></abbr></th> "):(($col['key'] == 'rdomip')?("<th style=\"width:100px;\"><abbr title=\"Inbound domain IP\"><a class=\"{$sclass['rdomip']}\" href=\"".BASEURI."?page=admin&sortkey=rdomip&sortorder={$sorder['rdomip']}&start={$start}\">iIP</a></abbr></th> "):(($col['key'] == 'rindexed')?("<th style=\"width:75px;\"><abbr title=\"Inbound site indexed pages\"><a class=\"{$sclass['rindexed']}\" href=\"".BASEURI."?page=admin&sortkey=rindexed&sortorder={$sorder['rindexed']}&start={$start}\">iIndexed</a></abbr></th> "):(($col['key'] == 'lpagerank')?("<th style=\"width:75px;\"><abbr title=\"Outbound PageRank™\"><a class=\"{$sclass['lpagerank']}\" href=\"".BASEURI."?page=admin&sortkey=lpagerank&sortorder={$sorder['lpagerank']}&start={$start}\">oPR</a></abbr></th> "):(($col['key'] == 'ldom')?("<th style=\"width:130px;\"><abbr title=\"Outbound domain\"><a class=\"{$sclass['ldom']}\" href=\"".BASEURI."?page=admin&sortkey=ldom&sortorder={$sorder['ldom']}&start={$start}\">oDomain</a></abbr></th> "):(($col['key'] == 'ldomip')?("<th style=\"width:100px;\"><abbr title=\"Outbound domain IP\"><a class=\"{$sclass['ldomip']}\" href=\"".BASEURI."?page=admin&sortkey=ldomip&sortorder={$sorder['ldomip']}&start={$start}\">oIP</a></abbr></th> "):(($col['key'] == 'lindexed')?("<th style=\"width:75px;\"><abbr title=\"Outbound site indexed pages\"><a class=\"{$sclass['lindexed']}\" href=\"".BASEURI."?page=admin&sortkey=lindexed&sortorder={$sorder['lindexed']}&start={$start}\">oIndexed</a></abbr></th> "):(($col['key'] == 'anchor')?("<th><abbr title=\"Link anchor\"><a class=\"{$sclass['anchor']}\" href=\"".BASEURI."?page=admin&sortkey=anchor&sortorder={$sorder['anchor']}&start={$start}\">Anchor</a></abbr></th> "):(($col['key'] == 'title')?("<th><abbr title=\"Link title\"><a class=\"{$sclass['title']}\" href=\"".BASEURI."?page=admin&sortkey=title&sortorder={$sorder['title']}&start={$start}\">Title</a></abbr></th> "):(($col['key'] == 'link')?("<th><abbr title=\"Link\"><a class=\"{$sclass['link']}\" href=\"".BASEURI."?page=admin&sortkey=link&sortorder={$sorder['link']}&start={$start}\">Link</a></abbr></th> "):(($col['key'] == 'status')?("<th style=\"width:50px;\"><abbr title=\"Link status\"><a class=\"{$sclass['status']}\" href=\"".BASEURI."?page=admin&sortkey=status&sortorder={$sorder['status']}&start={$start}\">Status</a></abbr></th> "):("")))))))))))))))))." "; } } else { echo ""; } echo " </tr> </thead> <tbody> ".(($pages>1)?(" <tr class=\"navigation\"> <td colspan=\"{$columnscount}\" class=\"center navigation\"> {$navlinks} </td> </tr> "):(""))." "; if ( is_array( $links ) && sizeof( $links )>0 ) { foreach ( $links AS $i=>$link ) { echo " <tr> "; if ( is_array( $columns ) && sizeof( $columns )>0 ) { foreach ( $columns AS $col ) { echo " ".(($col['key'] == 'checkbox')?("<td style=\"width:20px;text-align:center;\"><input tabindex=\"{$i}\" type=\"checkbox\" name=\"lid[]\" value=\"{$link->id}\" class=\"checkbox status{$link->status} linkcheckbox\" /></td> "):(($col['key'] == 'options')?("<td style=\"width:50px;\"> <a href=\"".BASEURI."?page=admin&view=link&action=form&id={$link->id}\">edit</a> <a class=\"delete\" href=\"".BASEURI."?page=admin&view=link&action=delete&id={$link->id}\">del</a></td> "):(($col['key'] == 'added')?("<td>{$link->addedf}</td> "):(($col['key'] == 'lastchecked')?("<td>{$link->lastcheckedf}</td> "):(($col['key'] == 'rpagerank')?("<td> <div class=\"pagerank pr{$link->rpagerank}\"></div> <div class=\"minpagerank minpr". $link->getMinPagerank() ."\"></div> </td> "):(($col['key'] == 'rdom')?("<td>{$link->rdom}</td> "):(($col['key'] == 'rdomip')?("<td>{$link->rdomip}</td> "):(($col['key'] == 'rindexed')?("<td>{$link->rindexed}</td> "):(($col['key'] == 'lpagerank')?("<td> <div class=\"pagerank pr{$link->lpagerank}\"></div> </td> "):(($col['key'] == 'ldom')?("<td>{$link->ldom}</td> "):(($col['key'] == 'ldomip')?("<td>{$link->ldomip}</td> "):(($col['key'] == 'lindexed')?("<td>{$link->lindexed}</td> "):(($col['key'] == 'link')?("<td><a href=\"{$link->lurl}\" target=\"_blank\">{$link->anchor}</a></td> "):(($col['key'] == 'anchor')?("<td>{$link->anchor}</td> "):(($col['key'] == 'title')?("<td>{$link->title}</td> "):(($col['key'] == 'status')?("<td class=\"center\"><div class=\"icon icon{$link->status}\"></div></td> "):("")))))))))))))))))." "; } } else { echo ""; } echo " </tr> "; } } else { echo ""; } echo " ".(($pages>1)?(" <tr class=\"navigation\"> <td colspan=\"{$columnscount}\" class=\"center navigation\"> {$navlinks} </td> </tr> "):(""))." </tbody> <tfoot> <tr valign=\"top\"> <td><div class=\"imageup\"></div></td> <td colspan=\"6\"> <a href=\"#\" onclick=\"this.blur();selectLinks('all',function(){this.checked=true;});return false;\">Select all</a> · <a href=\"#\" onclick=\"this.blur();selectLinks('none',function(){this.checked=false;});return false;\">Select none</a> · <a href=\"#\" onclick=\"this.blur();selectLinks('invert',function(){this.checked=!this.checked;});return false;\">Invert selection</a> · <a href=\"#\" onclick=\"this.blur();selectLinks('suspended',function(){this.checked=$(this).hasClass('status2');});return false;\" >Select suspended</a> <div id=\"selectmsg\"></div> </td> <td colspan=\"{$columnscountleft}\"> <input type=\"submit\" class=\"button\" name=\"verify\" value=\"Verify selected links\" style=\"width:150px;\" /><br /> <input type=\"submit\" class=\"button\" name=\"delete\" value=\"Delete selected links\" style=\"width:150px;color:red;margin-top:5px;\" onclick=\"return confirm( 'Are you sure you would like to delete all the selected links?' );\"/><br /> </td> </tr> </tfoot> </table> </div> <div style=\"margin:12px;\"> <fieldset class=\"expandable {$searchshow}\" style=\"width:100%;\" id=\"fs_mass_edit\"> <legend>Mass edit</legend> <div class=\"contractor\"> <table style=\"width:90%;margin:0px auto;\"> <tr> <td class=\"key\">Set status:</td> <td> {$masseditstatus} </td> </tr> <tr> <td class=\"key\">Skip check:</td> <td> {$masseditskipcheck} </td> </tr> <tr> <td class=\"key\">Ignore PageRank™:</td> <td> {$masseditskippagerank} </td> </tr> <tr> <td class=\"key\">Min. PageRank™:</td> <td> {$masseditminpagerank} </td> </tr> <tr valign=\"top\"> <td class=\"key\">Categories:</td> <td> {$masseditcategoryset}<br /> {$masseditcategories} </td> </tr> <tr valign=\"top\"> <td class=\"key\"></td> <td><input type=\"submit\" name=\"massedit\" value=\"OK\" class=\"button\" /></td> </tr> </table> </div> </fieldset> </div> </form> "; echo template::footer(); break; case 'blacklist': switch( linkex::get( 'action', $_REQUEST, 'overview' ) ) { case 'import': // {{{ echo template::header( array( 'title' => 'Blacklist - import' ) ); if ( ( $xml = linkex::get( 'xml', $_POST, false ) ) !== false ) { // Lets just use regex to parse the input, not sure simplexml is installed on all servers preg_match_all( '#<entry>(.*)</entry>#Umis', $xml, $xml ); if ( sizeof( $xml[1] ) == 0 ) { $errors[] = 'No <entry> elements found'; } else { $ids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ); $current = array(); foreach( $ids AS $id ) { $blacklist = new Blacklist( $id ); $current[] = $blacklist->type.'--'.strtolower( $blacklist->value ); unset( $blacklist ); } $result = array(); foreach( $xml[1] AS $entry ) { if ( preg_match( '#<type>(.*)</type>#Umis', $entry, $type ) && preg_match( '#<value>(.*)</value>#Umis', $entry, $value ) && preg_match( '#<reason>(.*)</reason>#Umis', $entry, $reason ) ) { switch( strtolower( str_replace( ' ', '', $type[1] ) ) ) { case 'serverip': $type = 1; break; case 'domain': $type = 2; break; case 'webmasterip': $type = 4; break; case 'email': $type = 8; break; case 'emaildomain': $type = 16; break; case 'word': $type = 32; break; default: $type = 0; break; } $value = html_entity_decode( $value[1] ); $key = $type .'--'. strtolower( $value ); if ( !in_array( $key, $current ) ) { $b = new Blacklist; $b->type = $type; $b->value = htmlentities( $value ); $b->reason = htmlentities( $reason[1] ); $b->save(); $result[] = htmlentities( $value ) .' added'; } else { $result[] = htmlentities( $value ) .' already listed'; } } else { $result[] = 'Missing type/value/reason in '.htmlentities( $entry ); } } $result = join( "\n", $result ); echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend>XML Import</legend> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <div style=\"margin:10px;\"> <textarea name=\"xml\" style=\"width:800px;height:500px;\" class=\"pre\" disabled=\"disabled\">{$result}</textarea> </div> </form> </fieldset> </div> "; echo template::footer(); exit; } $xml = linkex::get( 'xml', $_POST, '' ); } echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend>XML Import</legend> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <div style=\"margin:10px;\"> <textarea name=\"xml\" style=\"width:800px;height:500px;\" class=\"pre\">{$xml}</textarea><br /> <input class=\"button\" type=\"submit\" name=\"ok\" value=\"OK\" /> </div> </form> </fieldset> </div> "; echo template::footer(); break; // }}} case 'export': // {{{ echo template::header( array( 'title' => 'Blacklist - export' ) ); $ids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ); $xml = new xml; $xml->add_group( 'BlackList' ); foreach( $ids AS $id ) { $xml->add_group( 'entry' ); $blacklist = new Blacklist( $id ); $type = $blacklist->types( $blacklist->type ); $xml->add_tag( 'type', $type ); $xml->add_tag( 'value', htmlentities( xml::escape( $blacklist->value ) ) ); $xml->add_tag( 'reason', htmlentities( xml::escape( $blacklist->reason ) ) ); $xml->close_group(); } $xml = $xml->output(); echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend>XML Export</legend> <div style=\"margin:10px;\"> <textarea name=\"export\" style=\"width:800px;height:500px;\" class=\"pre\">{$xml}</textarea> </div> </fieldset> </div> "; echo template::footer(); break; // }}} case 'delete': // {{{ if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { @unlink( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR . $id ); } linkex::redirect( BASEURI . '?page=admin&view=blacklist' ); break; // }}} case 'form': // {{{ if ( sizeof( $_POST ) > 0 ) { if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { $blacklist = new Blacklist( $id ); } else { $blacklist = new Blacklist; } $blacklist->type = linkex::get( 'type', $_POST, '0' ); $blacklist->value = linkex::get( 'value', $_POST, '' ); $blacklist->reason = linkex::get( 'reason', $_POST, '' ); $blacklist->public = linkex::get( 'public', $_POST, 0 ); $blacklist->save(); linkex::redirect( BASEURI . '?page=admin&view=blacklist&action=form&id='.$blacklist->id ); exit; } if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { $title = 'Edit blacklist entry [id:'.$id.']'; $blacklist = new Blacklist( $id ); } else { $title = 'New Blacklist entry'; $blacklist = new Blacklist; } $type = linkex::selector( 'type', $blacklist->types(), $blacklist->type, false, 'select', array( 'onchange' => 'modified=true;' ) ); $_SERVER['REQUEST_URI'] = htmlentities( $_SERVER['REQUEST_URI'] ); $public = linkex::checkbox( $blacklist->public ); echo template::header( array( 'title' => $title ) ); echo "<div style=\"margin:10px 0px;\"> <fieldset> <legend>{$title}</legend> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <table> <tr> <td class=\"key\">Type:</td> <td>{$type}</td> </tr> <tr> <td class=\"key\">Value:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"value\" value=\"{$blacklist->value}\" style=\"width:300px;\" /></td> </tr> <tr valign=\"top\"> <td class=\"key\">Reason:</td> <td><textarea onchange=\"modified=true;\" class=\"text\" name=\"reason\" style=\"width:300px;font-size:10px;\" cols=\"80\" rows=\"3\">{$blacklist->reason}</textarea></td> </tr> <tr> <td class=\"key\"></td> <td><input class=\"button\" type=\"submit\" name=\"ok\" value=\"OK\" onclick=\"modified=false;\" /></td> </tr> </table> </form> </fieldset> </div> "; echo template::footer(); break; // }}} case 'overview': // {{{ $ids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ); $list = array(); foreach( $ids AS $id ) { $list[] = new Blacklist( $id ); } echo template::header( array( 'title' => 'Blacklist' ) ); echo "<div style=\"margin:10px;\"> <table class=\"list\" id=\"blacklist\" cellspacing=\"0\"> <thead> <tr class=\"th\"> <th></th> <th>Type</th> <th>Value</th> <th>Reason</th> </tr> <tr> <td colspan=\"5\" class=\"center navigation\"> <a href=\"index.php?page=admin&view=blacklist&action=form\">Create new entry</a> <a href=\"index.php?page=admin&view=blacklist&action=import\">Import blacklist</a> <a href=\"index.php?page=admin&view=blacklist&action=export\">Export blacklist</a> </td> </tr> </thead> <tbody> "; if ( is_array( $list ) && sizeof( $list )>0 ) { foreach ( $list AS $blacklist ) { echo " <tr class=\"{$rowclass}\"> <td> <a href=\"".BASEURI."?page=admin&view=blacklist&action=form&id={$blacklist->id}\">edit</a> <a href=\"".BASEURI."?page=admin&view=blacklist&action=delete&id={$blacklist->id}\" onclick=\"return confirm('Are you sure you would like to delete this entry?');\">del</a> </td> <td>{$blacklist->thetype}</td> <td>{$blacklist->value}</td> <td>{$blacklist->reason}</td> </tr> "; } } else { echo " <tr> <td class=\"center\" colspan=\"4\">- no entries found -</td> </tr> "; } echo " </tbody> </table> </div> <script type=\"text/javascript\"></script> "; echo template::footer(); break; // }}} case 'oldoverview': // {{{ $ids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ); echo template::header( array( 'title' => 'Blacklist' ) ); // List all the entries echo "<div style=\"margin:10px;\"> <table class=\"list\" id=\"blacklist\" cellspacing=\"0\"> <thead> <tr class=\"th\"> <th></th> <th>Type</th> <th>Value</th> <th>Reason</th> </tr> <tr> <td colspan=\"5\" class=\"center navigation\"> <a href=\"index.php?page=admin&view=blacklist&action=form\">Create new entry</a> <a href=\"index.php?page=admin&view=blacklist&action=import\">Import blacklist</a> <a href=\"index.php?page=admin&view=blacklist&action=export\">Export blacklist</a> </td> </tr> </thead> <tbody> "; if ( sizeof( $ids ) > 0 ) { $i=0; foreach( $ids AS $id ) { $rowclass=($i++%2)?'even':'odd'; $blacklist = new Blacklist( $id ); $type = $blacklist->types( $blacklist->type ); echo "<tr class=\"{$rowclass}\"> <td> <a href=\"".BASEURI."?page=admin&view=blacklist&action=form&id={$blacklist->id}\">edit</a> <a href=\"".BASEURI."?page=admin&view=blacklist&action=delete&id={$blacklist->id}\" onclick=\"return confirm('Are you sure you would like to delete this entry?');\">del</a> </td> <td>{$type}</td> <td>{$blacklist->value}</td> <td>{$blacklist->reason}</td> </tr> "; } } else { echo "<tr> <td class=\"center\" colspan=\"4\">- no entries found -</td> </tr> "; } echo " </tbody> </table> </div> <script type=\"text/javascript\"></script> "; echo template::footer(); break; // }}} } break; case 'categories': switch( linkex::get( 'action', $_REQUEST, 'overview' ) ) { case 'delete': // {{{ if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { $files = linkex::glob( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR . $id . '(\-\d+)?' ); $files[] = BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $id; foreach( $files AS $f ) { @unlink( $f ); } } linkex::redirect( BASEURI . '?page=admin&view=categories' ); break; // }}} case 'form': // {{{ if ( sizeof( $_POST ) > 0 ) { if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { $category = new Category( $id ); } else { $category = new Category; } $category->name = linkex::get( 'name', $_POST, '' ); $category->filename = linkex::get( 'filename', $_POST, '' ); $category->filter = linkex::get( 'filter', $_POST, $category->filter ); $category->sortby = linkex::get( 'sortby', $_POST, $category->sortby ); $category->order = linkex::get( 'order', $_POST, $category->order ); $category->slots = linkex::get( 'slots', $_POST, $category->slots ); $category->template = linkex::get( 'template', $_POST, $category->template ); $category->public = linkex::get( 'public', $_POST, 0 ); $category->split = linkex::get( 'split', $_POST, 0 ); $category->save(); linkex::redirect( BASEURI . '?page=admin&view=categories&action=form&id='.$category->id ); } if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { $category = new category( $id ); $title = 'Edit Category [id:'.$id.']'; $BASEDIR = BASEDIR; $file = BASEFOLDER . DIRECTORY_SEPARATOR . 'data'. DIRECTORY_SEPARATOR .'output'. DIRECTORY_SEPARATOR . $id; $installcode = "<div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_categories_install_{$id}\"> <legend onclick=\"toggle(this);\">Include code</legend> <div class=\"contractor\"> <table style=\"width:98%;margin:0px auto;\"> <tr> <td colspan=\"3\"><br />Use the following code below to include the links in a PHP script</td> </tr> <tr> <td colspan=\"2\" class=\"pre\"><?php include( "{$file}" ); ?></td> <td class=\"help\"></td> </tr> <tr> <td colspan=\"3\"><br />Use the following code below to include the links using SSI</td> </tr> <tr> <td colspan=\"2\" class=\"pre\"><!--#include file="{$file}" --></td> <td class=\"help\"></td> </tr> </table> </div> </fieldset> </div> "; } else { $installcode = ''; $category = new category; $title = 'New Category'; } $category->template = htmlentities( $category->template ); $category->public = linkex::checkbox( $category->public ); $options = link::statusOptions(); $options['-1'] = 'Expired links'; $filter = linkex::selector( 'filter', $options, $category->filter, true, 'checkbox', array( 'onchange' => 'modified=true;' ) ); $sortby = linkex::selector( 'sortby', $category->sortbys(), $category->sortby, false, 'select', array( 'onchange' => 'modified=true;', 'style' => 'width:150px;' ) ); $order = linkex::selector( 'order', $category->orders(), $category->order, false, 'select', array( 'onchange' => 'modified=true;', 'style' => 'width:150px;' ) ); $_SERVER['REQUEST_URI'] = htmlentities( $_SERVER['REQUEST_URI'] ); $variables = "<div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_category_variables_{$id}\"> <legend onclick=\"toggle(this);\">Template variables</legend> <div class=\"contractor\"> <table style=\"width:98%;margin:0px auto;\"> <tr> <td colspan=\"2\"><br />The following template variables are available:</td> </tr> <tr> <td class=\"pre right\" style=\"width:150px;\">{$URL}</td> <td>Linking url</td> </tr> <tr> <td class=\"pre right\">{$DOMAIN}</td> <td>Linking domain</td> </tr> <tr> <td class=\"pre right\">{$ANCHOR}</td> <td>Site anchor</td> </tr> <tr> <td class=\"pre right\">{$TITLE}</td> <td>Site title</td> </tr> <tr> <td class=\"pre right\">{$DESCRIPTION}</td> <td>Site description</td> </tr> <tr> <td class=\"pre right\">{$ADDED}</td> <td>Date when link was added</td> </tr> <tr> <td class=\"pre right\">{$INDEX}</td> <td>Position of the link in this category. Starting from 1 (one)</td> </tr> <tr> <td class=\"pre right\">{$CATEGORYID}</td> <td>ID of this category</td> </tr> <tr> <td class=\"pre right\">{$CATEGORYNAME}</td> <td>Name of this category</td> </tr> <tr> <td class=\"pre right\">{$FIRST}</td> <td>Evaluates to 1 if the link is the first, else 0</td> </tr> <tr> <td class=\"pre right\">{$LAST}</td> <td>Evaluates to 1 if the link is the last, else 0</td> </tr> <tr> <td class=\"pre right\">{$PAGERANK}</td> <td>The PageRank of the link</td> </tr> <tr> <td class=\"pre right\">{$FILENO}</td> <td>When using the "Links pr. file" this will be replaces with the current file number</td> </tr> <tr> <td class=\"pre right\">{$FILES}</td> <td>When using the "Links pr. file" this will be replaces with the total number of files created</td> </tr> <tr> <td colspan=\"2\"><br /> The following pseudo functions are available: </td> </tr> <tr valign=\"top\"> <td class=\"pre right\">{IF val}...{/IF}</td> <td> To use with {$FIRST} and {$LAST}. Please note, you cannot nest the IF's </td> </tr> <tr valign=\"top\"> <td class=\"pre right\">{CYCLE values=".."}</td> <td> Will cycle through the \"values\"seperated by \",\".<br /><br /> ex. <span class=\"pre\"><a class="{CYCLE values="red,blue"}" href=".."></span><br /> will make every second link have <span class=\"pre\">class="red"</span> and the others <span class=\"pre\">class="blue"</span>. </td> </tr> <tr valign=\"top\"> <td class=\"pre right\">{TABLE}</td> <td> If the very first line is {TABLE} the output will be put into a table.<br /> You can add the parameter <span class=\"pre\">cols="n"</span> to make the table have n columns. The default is 2.<br /> You can add the parameter <span class=\"pre\">rows="n"</span> to limit the table to n rows. If this parameter is left out, the number of rows needed is automaticly calculated so all links will be present.<br /> If you would like empty cells to be filled with use <span class=\"pre\">default=\"..\"</span><br /><br /> ex. <span class=\"pre\">{TABLE cols="3"}<br /><a href="...">...</a></span><br /> <br /> Will create a table with 3 column. <br /><br /> The only \"reserved\" parameters are default, rows, cols and valign. Any other parameters will be inserted into the table. So you can add cellpadding=\"..\" or class=\"..\" or anything. </td> </tr> </table> </div> </fieldset> </div> "; echo template::header( array( 'title' => $title ) ); echo "<div style=\"margin:10px 0px;\"> <fieldset> <legend>{$title}</legend> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <table> <tr> <td class=\"key\">Name:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"name\" value=\"{$category->name}\" /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Link filter:</td> <td>{$filter}</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Order:</td> <td>{$sortby}{$order}</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Public:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"public\" value=\"1\" {$category->public} /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Template:</td> <td><textarea onchange=\"modified=true;\" class=\"text\" name=\"template\" style=\"width:400px;height:200px;font-size:10px;\" cols=\"80\" rows=\"3\">{$category->template}</textarea></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Links pr. file:</td> <td> <input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"split\" value=\"{$category->split}\" style=\"width:80px;\" /> if greater than zero additional files will be created, each having "Links pr. file" links. </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"></td> <td><input class=\"button\" type=\"submit\" name=\"ok\" value=\"OK\" onclick=\"modified=false;\" /></td> <td></td> </tr> </table> </form> </fieldset> </div> {$variables} {$installcode} "; echo template::footer(); break; // }}} case 'overview': // {{{ $catstats = array(); $links = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); foreach( $links AS $l ) { $l = new link( $l ); foreach( $l->categories AS $c ) { $catstats[ $c ] = linkex::get( $c, $catstats, 0 ) + 1; } unset( $l ); } unset( $links ); $categories = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ); $cats = array(); foreach( $categories AS $cid ) { $c = new Category( $cid ); $c->linkscount = linkex::get( $cid, $catstats, 0 ); $cats[] = $c; } $categories = $cats; unset( $cats ); linkex::sort( $categories, 'name', 'asc' ); echo template::header( array( 'title' => 'Categories' ) ); $categories = linkex::arraychunk( $categories, $config->displaylimit ); $start = linkex::get( 'start', $_REQUEST, 1 ); $pages = sizeof( $categories ); $navlinks = template::navigation( $start, $pages, BASEURI . '?page=admin&view=categories&' ); if ( sizeof( $categories ) > 0 ) { $categories = $categories{ ( $start - 1 ) }; } else { $categories = array(); } // List all the categories echo "<div style=\"margin:10px;\"> <table class=\"list\" id=\"categeries\" cellspacing=\"0\"> <thead> <tr class=\"th\"> <th style=\"width:45px;\"></th> <th>ID</th> <th>Name</th> <th>Public</th> <th>Links</th> </tr> <tr> <td colspan=\"5\" class=\"center navigation\"><a href=\"index.php?page=admin&view=categories&action=form\">Create new category</a></td> </tr> </thead> <tbody> "; if ( $pages > 1 ) { echo "<tr class=\"navigation\"> <td colspan=\"9\" class=\"center navigation\"> {$navlinks} </td> </tr> "; } if ( sizeof( $categories ) > 0 ) { $i=0; foreach( $categories AS $category ) { $rowclass=($i++%2)?'even':'odd'; //$category = new category( $cid ); $category->public = linkex::yesno( $category->public ); echo "<tr class=\"{$rowclass}\"> <td> <a href=\"".BASEURI."?page=admin&view=categories&action=form&id={$category->id}\">edit</a> <a href=\"".BASEURI."?page=admin&view=categories&action=delete&id={$category->id}\" onclick=\"return confirm( 'Are you sure you would like to delete this category?' );\">del</a> </td> <td>{$category->id}</td> <td>{$category->name}</td> <td>{$category->public}</td> <td>{$category->linkscount}</td> </tr> "; } } else { echo "<tr> <td class=\"center\" colspan=\"5\">- no categories found -</td> </tr> "; } if ( $pages > 1 ) { echo "<tr class=\"navigation\"> <td colspan=\"9\" class=\"center navigation\"> {$navlinks} </td> </tr> "; } echo " </tbody> </table> </div> "; echo template::footer(); break; // }}} } break; case 'link': switch( linkex::get( 'action', $_REQUEST, 'overview' ) ) { case 'delete': // {{{ if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { $link = new Link( $id ); if ( sizeof( $_POST ) > 0 ) { $elems = linkex::get( 'blacklist', $_POST, array() ); foreach( $elems AS $e ) { $b = new Blacklist; $b->reason = 'Deleted'; switch( $e ) { case 'ldom': $b->type = 2; $b->value = $link->ldom; break; case 'ldomip': $b->type = 1; $b->value = $link->ldomip; break; case 'rdom': $b->type = 2; $b->value = $link->rdom; break; case 'rdomip': $b->type = 1; $b->value = $link->rdomip; break; case 'wmip': $b->type = 4; $b->value = $link->wmip; break; case 'edom': $b->type = 16; $b->value = $link->edom; break; case 'email': $b->type = 8; $b->value = $link->email; break; } if ( strlen( $b->value ) > 0 ) { $b->save(); } unset( $b ); } $link->delete(); linkex::redirect( BASEURI . '?page=admin' ); } else { $_SERVER['REQUEST_URI'] = htmlentities( $_SERVER['REQUEST_URI'] ); echo template::header( array( 'title' => 'Delete link [id:'.$id.']' ) ); echo "<div style=\"margin:10px 0px;\"> <fieldset> <legend>Delete link [id:{$id}]</legend> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <table> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"ldom\" /></td> <td>Blacklist link domain "{$link->ldom}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"ldomip\" /></td> <td>Blacklist link server IP "{$link->ldomip}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"rdom\" /></td> <td>Blacklist recip domain "{$link->rdom}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"rdomip\" /></td> <td>Blacklist recip server IP "{$link->rdomip}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"wmip\" /></td> <td>Blacklist webmaster IP "{$link->wmip}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"edom\" /></td> <td>Blacklist webmaster email domain "{$link->edom}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"><input type=\"checkbox\" class=\"checkbox\" name=\"blacklist[]\" value=\"email\" /></td> <td>Blacklist webmaster email "{$link->email}"</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"></td> <td><input class=\"button\" type=\"submit\" name=\"ok\" value=\"Delete link\" onclick=\"modified=false;\" /></td> <td></td> </tr> </table> </form> </fieldset> </div> "; echo template::footer(); } } else { linkex::redirect( BASEURI . '?page=admin' ); } break; // }}} case 'form': // {{{ if ( ( $id = linkex::get( 'id', $_REQUEST, false ) ) !== false ) { if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $id ) ) { $link = new link( $id ); $link->updateIPs( false ); $pr = $link->getRPageRank(); $link->save( false ); if ( sizeof( $_POST ) > 0 ) { $link->lurl = linkex::get( 'lurl', $_POST, '' ); $link->rurl = linkex::get( 'rurl', $_POST, '' ); $link->weight = intval( linkex::get( 'weight', $_POST, 0 ) ); $link->dateexpire = linkex::get( 'dateexpire', $_POST, '' ); $link->dateexpire = ( strlen( $link->dateexpire ) > 0 ) ? intval( @strtotime( $link->dateexpire ) ) : 0; $link->anchor = trim( linkex::get( 'anchor', $_POST, '' ) ); $link->description = htmlentities( trim( linkex::get( 'description', $_POST, '' ) ) ); $cats = $link->categories; $link->categories = linkex::get( 'categories', $_POST, array() ); if ( !is_array( $link->categories ) ) { $link->categories = array( intval( $link->categories ) ); } $cats = array_unique( array_merge( $cats, $link->categories ) ); $link->email = htmlentities( trim( linkex::get( 'email', $_POST, '' ) ) ); $link->skipcheck = intval( linkex::get( 'skipcheck', $_POST, 0 ) ); $link->skippagerank = intval( linkex::get( 'skippagerank', $_POST, 0 ) ); $link->minpagerank = intval( linkex::get( 'minpagerank', $_POST, -1 ) ); $link->status = linkex::get( 'status', $_POST, '0' ); $link->notes = linkex::get( 'notes', $_POST, '' ); $link->save( false ); foreach( $cats AS $cid ) { if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $cid ) ) { $c = new Category( $cid ); $c->generate(); unset( $c ); } } linkex::redirect( $_SERVER['REQUEST_URI'] ); } $pagerankcheckdatef = date( $config->dateformat, linkex::get( 'date', $link->pagerankinfo, 0 ) ); $_SERVER['REQUEST_URI'] = htmlentities( $_SERVER['REQUEST_URI'] ); $categories = linkex::categories( LOGGEDIN ); $categories = linkex::selector( 'categories', $categories, $link->categories, LOGGEDIN, null, array( 'style' => '' ) ); $status = linkex::selector( 'status', $link->statusOptions(), (string)$link->status, false, 'select' ); $skipcheck = linkex::checkbox( $link->skipcheck ); $skippagerank = linkex::checkbox( $link->skippagerank ); $minpagerank = linkex::selector( 'minpagerank', array( -1=>'Use global min. PageRank™', 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, 10=>10 ), (string)$link->minpagerank, false, 'select', array( 'style' => 'width:auto;' ) ); $link->dateexpire = ( $link->dateexpire > 0 ) ? date( "Y-m-d", $link->dateexpire ) : ""; $laststatus = false; $lastcolor = false; $history = array_reverse( $link->log ); foreach( $history AS $hist ) { $res = ''; $color = 'red'; switch( $hist{'res'} ) { case '0': $res = '200 OK'; $color = 'green'; break; case '1': $res = $hist{'reason'}; break; case '2': $res = 'Missing backlink'; break; case '4': $res = 'Invalid anchor'; break; case '8': $res = 'Nofollow link'; break; case '16': $res = 'Too many external links'; break; case '32': $res = 'Check skipped'; $color = 'yellow'; break; case '64': $res = 'Blacklisted'; break; } $laststatus = ( $laststatus === false ) ? $res : $laststatus; $lastcolor = ( $lastcolor === false ) ? $color : $lastcolor; $h .= '<div>'.date( $config->dateformat, $hist{'date'} ).' (<span style="font-family:monospace;" class="'. $color.'">'.$res."</span>)</div>"; } echo template::header( array( 'title' => 'Edit link [id:'.$id.'] ['.$link->rdom.']' ) ); echo "<form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Linking info</legend> <table class=\"table\"> <tr> <td class=\"key\">Link UID:</td> <td>{$link->id}</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Added on:</td> <td>{$link->addedf}</td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Verified on:</td> <td>{$link->lastcheckedf} (<span style=\"font-family:monospace;\" class=\"{$lastcolor}\">{$laststatus}</span>) (<a href=\"".BASEURI."?page=admin&view=verify&lid={$link->id}\">verify now</a>) (<a href=\"#\" onclick=\"$(this).blur();$('div#linkhistory').slideToggle();return false;\">History</a>) <br /> <div id=\"linkhistory\" style=\"display:none;padding:5px 0px;\"> {$h} </div> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Added by:</td> <td>{$link->email} (<a href=\"http://whois.domaintools.com/{$link->edom}\" target=\"_blank\">whois</a>) {$link->wmip} (<a href=\"http://whois.domaintools.com/{$link->wmip}\" target=\"_blank\">whois</a>)</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Link domain:</td> <td><a href=\"{$link->lurl}\" target=\"_blank\">{$link->ldom}</a> (<a href=\"http://whois.domaintools.com/{$link->ldom}\" target=\"_blank\">whois</a>) {$link->ldomip} (<a href=\"http://whois.domaintools.com/{$link->ldomip}\" target=\"_blank\">whois</a>)</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Reciprocal domain:</td> <td><a href=\"{$link->rurl}\" target=\"_blank\">{$link->rdom}</a> (<a href=\"http://whois.domaintools.com/{$link->rdom}\" target=\"_blank\">whois</a>) {$link->rdomip} (<a href=\"http://whois.domaintools.com/{$link->rdomip}\" target=\"_blank\">whois</a>)</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">PageRank™:</td> <td><div class=\"pagerank pr{$pr}\" style=\"margin-top:3px;\"></div>  Last checked on: {$pagerankcheckdatef}</td> <td class=\"help\"></td> </tr> <tr> <td colspan=\"3\"><br /></td> </tr> <tr> <td class=\"key\">Site anchor:</td> <td><input type=\"text\" class=\"text\" name=\"anchor\" value=\"{$link->anchor}\" /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Site title:</td> <td><input type=\"text\" class=\"text\" name=\"title\" value=\"{$link->title}\" /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Link URL:</td> <td><input type=\"text\" class=\"text\" name=\"lurl\" value=\"{$link->lurl}\" /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Reciprocal link URL:</td> <td><input type=\"text\" class=\"text\" name=\"rurl\" value=\"{$link->rurl}\" /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Email:</td> <td><input type=\"text\" class=\"text\" name=\"email\" value=\"{$link->email}\" /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Site description:</td> <td><textarea cols=\"80\" rows=\"3\" class=\"text\" name=\"description\">{$link->description}</textarea></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Weight:</td> <td><input type=\"text\" class=\"text\" name=\"weight\" value=\"{$link->weight}\" style=\"width:50px;\" /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Categories:</td> <td>{$categories}</td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Status:</td> <td>{$status}</td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Skip check:</td> <td><input type=\"checkbox\" class=\"checkbox\" name=\"skipcheck\" value=\"1\" {$skipcheck} /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Ignore PageRank™:</td> <td><input type=\"checkbox\" class=\"checkbox\" name=\"skippagerank\" value=\"1\" {$skippagerank} /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Min. PageRank™:</td> <td>{$minpagerank}</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\"></td> <td><br /><input type=\"submit\" class=\"button\" value=\"OK\" /></td> <td class=\"help\"></td> </tr> </table> </fieldset> </div> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"linknotes{$link->id}\"> <legend onclick=\"toggle(this);\">Link Notes</legend> <div class=\"contractor\"> <div style=\"padding:5px 10px;\"> <textarea cols=\"80\" rows=\"3\" class=\"text\" name=\"notes\" style=\"width:595px;height:200px;\">{$link->notes}</textarea> </div> </div> </fieldset> </div> </form> "; echo template::footer(); } else { linkex::redirect( BASEURI . '?page=admin' ); } } else { linkex::redirect( BASEURI . '?page=admin' ); } break; // }}} } break; case 'verify': ob_implicit_flush(true); session_write_close(); $lid = linkex::get( 'lid', $_REQUEST, false ); // {{{ Mass delete if ( linkex::get( 'delete', $_POST, false ) !== false ) { if ( is_string( $lid ) ) { $lid = array_unique( linkex::map( 'trim', explode( ',', $lid ) ) ); } else if ( is_int( $lid ) ) { $lid = array( $lid ); } if ( is_array( $lid ) ) { $categories = array(); foreach( $lid AS $id ) { $l = new link( $id ); if ( !is_array( $l->categories ) ) { $l->categories = array( $l->categories ); } $categories = array_merge( $categories, $l->categories ); unset( $l ); @unlink( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR . $id ); } $categories = array_unique( $categories ); foreach( $categories AS $cid ) { $c = new category( $cid ); $c->generate(); unset( $c ); } } linkex::redirect( BASEURI . '?page=admin' ); // }}} // {{{ Check to see if this is a mass edit } elseif ( linkex::get( 'massedit', $_POST, false ) !== false ) { if ( is_string( $lid ) ) { $lid = array_unique( linkex::map( 'trim', explode( ',', $lid ) ) ); } else if ( is_int( $lid ) ) { $lid = array( $lid ); } if ( is_array( $lid ) ) { $updatecategories = array(); foreach( $lid AS $id ) { $l = new Link( $id ); $s = linkex::get( 'masseditsetstatus', $_POST, 0 ); if ( $s>0 ) { $l->status = $s; } $s = linkex::get( 'masseditskipcheck', $_POST, 0 ); if ( $s>0 ) { $l->skipcheck = ( $s==1 ) ? 1:0; } // <<< Added 29/12-2006 $s = linkex::get( 'masseditskippagerank', $_POST, 0 ); if ( $s>0 ) { $l->skippagerank = ( $s==1 ) ? 1:0; } // >>> $s = linkex::get( 'masseditminpagerank', $_POST, 'null' ); if ( $s != 'null' ) { $l->minpagerank = $s; } $s = linkex::get( 'masseditcategoryset', $_POST, 0 ); if ( $s == 1 ) { $updatecategories = array_unique( array_merge( $updatecategories, $l->categories ) ); $l->categories = array_unique( array_merge( $l->categories, linkex::get( 'masseditcategories', $_POST, array() ) ) ); $updatecategories = array_unique( array_merge( $updatecategories, $l->categories ) ); } else if ( $s == 2 ) { $updatecategories = array_unique( array_merge( $updatecategories, $l->categories ) ); $l->categories = linkex::get( 'masseditcategories', $_POST, array() ); $updatecategories = array_unique( array_merge( $updatecategories, $l->categories ) ); } $l->save( false ); unset( $l ); } foreach( $updatecategories AS $cid ) { if ( file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR . $cid ) ) { $c = new Category( $cid ); $c->generate(); unset( $c ); } } } linkex::redirect( BASEURI . '?page=admin' ); } // }}} if ( $lid === false ) { $errors[] = 'You must select at least one link to verify.'; } if ( $lid == null ) { $lid = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); } else if ( is_string( $lid ) ) { $lid = array_unique( linkex::map( 'trim', explode( ',', $lid ) ) ); } else if ( is_int( $lid ) ) { $lid = array( $lid ); } if ( sizeof( $lid ) == 0 ) { $errors[] = 'You must select at least one link to verify..'; } echo template::header( array( 'title' => 'Verifying links' ) ); if ( sizeof( $errors ) == 0 ) { $legend = 'Verifying links...'; echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend id=\"legend\">{$legend}</legend> <div><pre id=\"progress\" style=\"font-size:11px;min-height:100px;margin-left:5px;\"> ID Domain Status PageRank BackL.Status<br /> ===============================================================================================================<br /></pre></div> </fieldset> </div> <script type=\"text/javascript\"> /*<![CDATA[*/ function _p(str){ var elem=document.getElementById('progress'); if(elem){ elem.innerHTML +=str; } } function _t(str){ var elem=document.getElementById('legend'); if(elem){ elem.innerHTML=str; } } /*]]>*/ </script> "; } echo template::footer(); linkex::flush(); $total = sizeof( $lid ); $current = 0; function updateProgress( $data ) { // {{{ global $total, $current; if ( $data{'action'} == 'link' ) { $current++; $title = sprintf( 'Verifying links... (%d%%)', $current/$total*100 ); $progress = sprintf( '% 6s % -30s <span class="%s">% -50s</span> '. '<span class="%s"><strong>% 2s</strong> >=% 2s</span> '. '<span class="%s">% -3s</span> '. '<span class="%s">%s</span><br />', $data{'id'}, linkex::truncate( $data{'rdom'}, 30 ), ( $data{'skipcheck'} == 1 ) ? 'yellow': ( ( strpos( $data{'code'}, '200' ) !== false ) ? 'green':'red' ), ( $data{'skipcheck'} == 1 ) ? 'Skipped' : linkex::truncate( $data{'code'}, 50 ), ( $data{'skippagerank'} == 1 || $data{'skipcheck'} == 1 ) ? 'yellow': ( ( $data{'pagerank'} >= $data{'minpagerank'} ) ?'green':'red' ), $data{'pagerank'}, $data{'minpagerank'}, ( $data{'skipcheck'} == 1 ) ? 'yellow': ( ( linkex::get( 'res', $data{'res'}, -1 ) == 0 ) ? 'green':'red' ), ( $data{'skipcheck'} == 1 ) ? '-': ( ( linkex::get( 'res', $data{'res'}, -1 ) == 0 ) ? 'Yes':'No' ), ( $data{'skipcheck'} == 1 ) ? 'yellow': ( ( $data{'status'} == 1 ) ? 'green':'red' ), ( $data{'skipcheck'} == 1 ) ? 'Skipped' : link::statusOptions( $data{'status'} ) ); echo "<script type=\"text/javascript\"> /*<![CDATA[*/ _p('{$progress}');_t('{$title}'); /*]]>*/ </script> "; linkex::flush(); } } // }}} linkex::verifybacklinks( $lid, 'updateProgress' ); exit; break; case 'settings': $rebuildcategories = false; $checkboxes = array( 'linkbotuniquedomains', 'disablepublicform', 'linkbotignoretrailingslash', 'linkbotdisregardwww', 'linkbackrequired', 'disablerecipfield', 'publiccategories', 'commandlineenable', 'commandlinesummary', 'remoteenable', 'remotesummary', 'remotelimitips', 'showemail', 'usecaptcha', 'verifyanchor', 'indexexchange', 'noquerystring', 'exposelinkex', 'rejectnofollow', 'disableblacklisted', 'usetitle' ); // Save if posted if ( sizeof( $_POST ) > 0 ) { foreach( $checkboxes AS $b ) { $_POST[$b] = linkex::get( $b, $_POST, '0' ); } $config->template = explode( ',', str_replace( ',,', ',', linkex::get( 'template', $_POST, join( ',', $config->template ) ) ) ); $config->htmlcode = htmlentities( stripslashes( $_POST['htmlcode'] ) ); $rebuildcategories = $rebuildcategories || ( $config->exposelinkex != linkex::get( 'exposelinkex', $_POST, 0 ) ); $config->exposelinkex = linkex::get( 'exposelinkex', $_POST, 0 ); $config->maxoutboundlinks = linkex::get( 'maxoutboundlinks', $_POST, 0 ); $crlf = linkex::get( 'emailcrlf', $_POST, '' ); if ( in_array( $crlf, array( '\r\n', '\n\r', '\n' ) ) ) { $config->emailcrlf = $crlf; } $config->rejectnofollow = linkex::get( 'rejectnofollow', $_POST, 0 ); $config->disableblacklisted = linkex::get( 'disableblacklisted', $_POST, 0 ); $config->indexexchange = linkex::get( 'indexexchange', $_POST, 0 ); $config->noquerystring = linkex::get( 'noquerystring', $_POST, 0 ); $config->samedomain = linkex::get( 'samedomain', $_POST, $config->samedomain ); $config->showemail = linkex::get( 'showemail', $_POST, 0 ); $config->usecaptcha = linkex::get( 'usecaptcha', $_POST, 0 ); $config->verifyanchor = intval( linkex::get( 'verifyanchor', $_POST, 0 ) ); $config->remotepass = linkex::get( 'remotepass', $_POST, '' ); $config->remoteips = linkex::map( 'trim', explode( "\n", linkex::get( 'remoteips', $_POST, '' ) ) ); $config->remoteenable = linkex::get( 'remoteenable', $_POST, 0 ); $config->remotesummary = linkex::get( 'remotesummary', $_POST, 0 ); $config->remotelimitips = linkex::get( 'remotelimitips', $_POST, 0 ); $config->commandlineenable = linkex::get( 'commandlineenable', $_POST, 0 ); $config->commandlinesummary = linkex::get( 'commandlinesummary', $_POST, 0 ); $config->googledatacenters = linkex::map( 'trim', explode( "\n", trim( linkex::get( 'googledatacenters', $_POST, '' ) ) ) ); $config->defaultcategories = linkex::get( 'categories', $_POST, array() ); $config->publiccategories = linkex::get( 'publiccategories', $_POST, $config->publiccategories ); $config->email = linkex::get( 'email', $_POST, $config->email ); $config->dateformat = linkex::get( 'dateformat', $_POST, $config->dateformat ); $config->charset = linkex::get( 'charset', $_POST, $config->charset ); $config->displaylimit = max( intval( linkex::get( 'displaylimit', $_POST, $config->displaylimit ) ), 1 ); $config->disablerecipfield = linkex::get( 'disablerecipfield', $_POST, $config->disablerecipfield ); $config->disablepublicform = linkex::get( 'disablepublicform', $_POST, $config->disablepublicform ); $config->sortkey = linkex::get( 'sortkey', $_POST, $config->sortkey ); $config->sortorder = linkex::get( 'sortorder', $_POST, $config->sortorder ); $config->url = linkex::get( 'url', $_POST, $config->url ); $config->anchor = linkex::map( 'trim', explode( "\n", linkex::get( 'anchor', $_POST, join( "\n", $config->anchor ) ) ) ); $config->title = linkex::map( 'trim', explode( "\n", linkex::get( 'title', $_POST, join( "\n", $config->title ) ) ) ); $config->description = linkex::get( 'description', $_POST, $config->description ); $config->altlinks = linkex::map( 'trim', explode( "\n", linkex::get( 'altlinks', $_POST, join( "\n", $config->altlinks ) ) ) ); $config->linkbotagent = linkex::get( 'linkbotagent', $_POST, $config->linkbotagent ); $config->linkbotuniquedomains = linkex::get( 'linkbotuniquedomains', $_POST, $config->linkbotuniquedomains ); $config->linkbotuniqueips = intval( linkex::get( 'linkbotuniqueips', $_POST, 0 ) ); $config->linkbotignoretrailingslash = linkex::get( 'linkbotignoretrailingslash', $_POST, $config->linkbotignoretrailingslash ); $config->linkbotdisregardwww = linkex::get( 'linkbotdisregardwww', $_POST, $config->linkbotdisregardwww ); $config->minpagerank = intval( linkex::get( 'minpagerank', $_POST, 0 ) ); $config->linkbackrequired = linkex::get( 'linkbackrequired', $_POST, $config->linkbackrequired ); // Lengths $config->anchorlength = intval( linkex::get( 'anchorlength', $_POST, 0 ) ); $config->anchorlengthtype = linkex::get( 'anchorlengthtype', $_POST, 'w' ); $config->titlelength = intval( linkex::get( 'titlelength', $_POST, 0 ) ); $config->titlelengthtype = linkex::get( 'titlelengthtype', $_POST, 'w' ); $config->descriptionlength = intval( linkex::get( 'descriptionlength', $_POST, 0 ) ); $config->descriptionlengthtype = linkex::get( 'descriptionlengthtype', $_POST, 'w' ); $config->maxoutboundtype = intval( linkex::get( 'maxoutboundtype', $_POST, 0 ) ); $config->usetitle = linkex::get( 'usetitle', $_POST, 0 ); // Username/password $u = linkex::get( '_username', $_POST, false ); $p1 = linkex::get( '_password1', $_POST, false ); $p2 = linkex::get( '_password2', $_POST, false ); if ( $u && $p1 && $p1 == $p2 ) { $config->password = md5( $u .'---'. $p1 ); if ( linkex::get( 'username', $_COOKIE, false ) ) { setcookie( 'username', $u, time()+60*60*24*30, BASEURI ); setcookie( 'password', $p1, time()+60*60*24*30, BASEURI ); } $_SESSION['username'] = $u; $_SESSION['password'] = $p1; } $config->save(); $rules = linkex::get( 'rules', $_POST, '' ); if ( strlen( trim( $rules ) ) > 0 ) { linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules', $rules ); } else { @unlink( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules' ); } // Should we rebuild the categories? if ( $rebuildcategories ) { $categories = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ); foreach( $categories AS $cid ) { $c = new category( $cid ); $c->generate(); unset( $c ); } } linkex::redirect( $_SERVER['REQUEST_URI'] ); } $_SERVER['REQUEST_URI'] = htmlentities( linkex::get( 'REQUEST_URI', $_SERVER ) ); echo template::header( array( 'title' => 'Settings' ) ); $minpagerank = linkex::selector( 'minpagerank', range( 0,10 ), (string)$config->minpagerank, false, 'select', array( 'style' => 'width:60px;' ) ); $sortkey = linkex::selector( 'sortkey', $templatecolumns, $config->sortkey, false, 'select' ); $sortorder = linkex::selector( 'sortorder', category::orders(), $config->sortorder, false, 'select', array( 'onchange' => 'modified=true;', 'style' => 'width:150px;' ) ); $samedomainselect = linkex::selector( 'samedomain', array( '0' => 'Does not matter', '1' => 'Must be on same domain', '2' => 'Must be on different domains' ), $config->samedomain, false, 'select', array( 'onchange' => 'modified=true;', 'style' => 'width:180px;' ) ); $anchor = join( "\n", $config->anchor ); $title = join( "\n", $config->title ); $altlinks = join( "\n", $config->altlinks ); // Rewrite all checkbox values from [0|1] => [''|checked] foreach( $checkboxes AS $b ) { $config->$b = linkex::checkbox( $config->$b ); } $categories = linkex::selector( 'categories', linkex::categories( true ), $config->defaultcategories, true, 'checkbox', array( 'onchange' => 'modified=true;', 'style'=>'' ) ); $rules = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules', '' ); // The lenths of the input $anchorlengthtype = linkex::selector( 'anchorlengthtype', array( 'w' => 'words', 'c' => 'characters' ), $config->anchorlengthtype, false, 'select', array( 'style' => 'width:100px;' ) ); $titlelengthtype = linkex::selector( 'titlelengthtype', array( 'w' => 'words', 'c' => 'characters' ), $config->titlelengthtype, false, 'select', array( 'style' => 'width:100px;' ) ); $descriptionlengthtype = linkex::selector( 'descriptionlengthtype', array( 'w' => 'words', 'c' => 'characters' ), $config->descriptionlengthtype, false, 'select', array( 'style' => 'width:100px;' ) ); $maxoutboundtypeselect = linkex::selector( 'maxoutboundtype', array( 0 => 'incl. nofollow', 1 => 'excl. nofollow' ), strval( $config->maxoutboundtype ), false, 'select', array( 'style' => 'width:100px;' ) ); $remoteips = join( "\n", $config->remoteips ); $googledatacenters = join( "\n", $config->googledatacenters ); $copyright = htmlentities( "<!-- Output generated by LinkEX (+http://linkex.dk/) -->\n" ); $template = '\''.join('\',\'', $config->template ).'\''; $xx = array(); foreach( $templatecolumns AS $k=>$v ) { $xx[] = $k.':\''.$v.'\''; } $templatecolumns = join(',',$xx); unset($xx); echo "<form method=\"post\" action=\"{$_SERVER{'REQUEST_URI'}}\"> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_admin_settings\"> <legend>Admin settings</legend> <div class=\"contractor\"> <table class=\"table\"> <tr> <td class=\"key\">Username:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"_username\" value=\"{$_SESSION['username']}\" /></td> </tr> <tr> <td class=\"key\">Password:</td> <td><input onchange=\"modified=true;\" type=\"password\" class=\"text\" name=\"_password1\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Password (again):</td> <td><input onchange=\"modified=true;\" type=\"password\" class=\"text\" name=\"_password2\" value=\"\" /></td> </tr> <tr> <td class=\"key\">Email:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"email\" value=\"{$config->email}\" /></td> </tr> <tr> <td class=\"key\">Date format:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"dateformat\" value=\"{$config->dateformat}\" /></td> </tr> <tr> <td class=\"key\">Charset:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"charset\" value=\"{$config->charset}\" /></td> </tr> <tr> <td class=\"key\">Display limit:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"displaylimit\" value=\"{$config->displaylimit}\" style=\"width:40px;\" /></td> </tr> <tr> <td class=\"key\">Email CRLF:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"emailcrlf\" value=\"{$config->emailcrlf}\" style=\"width:40px;\" /></td> </tr> <tr> <td class=\"key\">Default sort key:</td> <td>{$sortkey}</td> </tr> <tr> <td class=\"key\">Default sort order:</td> <td>{$sortorder}</td> </tr> <tr> <td class=\"key\">Disable public form:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"disablepublicform\" value=\"1\" {$config->disablepublicform} /></td> </tr> <tr> <td class=\"key\">Show email:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"showemail\" value=\"1\" {$config->showemail} /></td> </tr> <tr> <td class=\"key\">Use CAPTCHA:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"usecaptcha\" value=\"1\" {$config->usecaptcha} /></td> </tr> <tr valign=\"top\"> <td class=\"key\">Overview template:</td> <td> <table style=\"border:0px;width:100%;\" cellpadding=\"0\" cellspacing=\"0\"> <tr valign=\"top\"> <td style=\"width:50%;\"> <strong>Current Template</strong> <ul id=\"template\" class=\"selector\"> <li id=\"options_checkbox\" class=\"immutable\">Checkbox</li> <li id=\"optins_linktoptions\" class=\"immutable\">Options</li> </ul> </ul> </td> <td style=\"width:50%;\"> <strong>Available options</strong> <ul id=\"templateoptions\" class=\"selector\"></ul> </td> </tr> </table> <em>Drag & drop the items to sort,add and remove options</em> <input type=\"hidden\" name=\"template\" id=\"templateinput\" value=\"\" style=\"width:800px;\" /> <script type=\"text/javascript\"> /*<![CDATA[*/ var options = { {$templatecolumns} }; var currentTemplate = [{$template}]; function createTemplate(){ for(var i=0; i<currentTemplate.length; i++){ if(options[currentTemplate[i]]){ \$(\"<li></li>\").attr(\"id\",\"options_\"+currentTemplate[i]).html(options[currentTemplate[i]]).appendTo(\"#template\"); } } for(var i in options){ if(!currentTemplate.inArray(i)){ \$(\"<li></li>\").attr(\"id\",\"options_\"+i).html(options[i]).appendTo(\"#templateoptions\"); } } \$(\"#templateinput\").val(currentTemplate.join(',')); } \$(document).ready(function(){ createTemplate(); \$(\"#templateoptions,#template\").sortable({ items: 'li:not(.immutable)', connectWith: 'ul.selector', beforeStop: function(event, ui){ \$(\"#templateinput\").val(jQuery.map(\$(\"#template\").sortable('toArray'), function(a){ return a.replace(/^options_/, ''); }).join(',')); } }).trigger('change'); \$(\"#templateoptions,#template\").disableSelection(); }); /*]]>*/ </script> </td> </tr> </table> </div> </fieldset> </div> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_category_settings\"> <legend>Category settings</legend> <div class=\"contractor\"> <table class=\"table\"> <tr> <td class=\"key\">Public categories:</td> <td> <input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"publiccategories\" value=\"1\" {$config->publiccategories} /> </td> </tr> <tr valign=\"top\"> <td class=\"key\">Default categories:</td> <td>{$categories}</td> </tr> <tr valign=\"top\"> <td class=\"key\">Expose LinkEX:</td> <td> <input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"exposelinkex\" value=\"1\" {$config->exposelinkex} /> <em>Show {$copyright} in top of category outout</em> </td> </table> </div> </fieldset> </div> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_linking_settings\"> <legend>Linking settings</legend> <div class=\"contractor\"> <table class=\"table\"> <tr> <td class=\"key\">Website URL:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"url\" value=\"{$config->url}\" /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Website anchor:<br />(one pr. line)</td> <td><textarea cols=\"80\" rows=\"3\" onchange=\"modified=true;\" class=\"text\" name=\"anchor\">{$anchor}</textarea></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Website title:<br />(one pr. line)</td> <td><textarea cols=\"80\" rows=\"3\" onchange=\"modified=true;\" class=\"text\" name=\"title\">{$title}</textarea></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Description:</td> <td><textarea cols=\"80\" rows=\"3\" onchange=\"modified=true;\" class=\"text\" name=\"description\">{$config->description}</textarea></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Alternative backlinks:<br />(one pr. line)</td> <td><textarea cols=\"80\" rows=\"3\" onchange=\"modified=true;\" class=\"text\" name=\"altlinks\">{$altlinks}</textarea></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Rules:</td> <td><textarea cols=\"80\" rows=\"3\" onchange=\"modified=true;\" class=\"text\" name=\"rules\">{$rules}</textarea></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">HMTL code:</td> <td> <textarea cols=\"80\" rows=\"3\" onchange=\"modified=true;\" class=\"text\" name=\"htmlcode\">{$config->htmlcode}</textarea> <div> {$URL} - Website URL<br /> {$ANCHOR} - A random selected anchor<br /> {$TITLE} - A random selected title<br /> {$DESCRIPTION} - Description </div> </td> <td class=\"help\"></td> </tr> </table> </div> </fieldset> </div> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_link_verification_settings\"> <legend>Link verification settings</legend> <div class=\"contractor\"> <table class=\"table\"> <tr> <td class=\"key\">Use title AND anchor:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"usetitle\" value=\"1\" {$config->usetitle} /></td> <td></td> </tr> <tr> <td class=\"key\">Site anchor length:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"anchorlength\" value=\"{$config->anchorlength}\" style=\"width:50px;\"/> {$anchorlengthtype} (0:unlimited)</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Site title length:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"titlelength\" value=\"{$config->titlelength}\" style=\"width:50px;\"/> {$titlelengthtype} (0:unlimited)</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Site descri. length:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"descriptionlength\" value=\"{$config->descriptionlength}\" style=\"width:50px;\"/> {$descriptionlengthtype} (0:unlimited)</td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Linkback required:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"linkbackrequired\" value=\"1\" {$config->linkbackrequired} /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Reject nofollow links:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"rejectnofollow\" value=\"1\" {$config->rejectnofollow} /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Disable recip. field:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"disablerecipfield\" id=\"disablerecipfield\" value=\"1\" {$config->disablerecipfield} /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Same domain:</td> <td>{$samedomainselect} <em>domain of url and reciprocal url</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Min. PageRank™:</td> <td>{$minpagerank}</td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Google Datacenter(s)<br />(one pr. line)<br />(use IP or domain)</td> <td><textarea cols=\"80\" rows=\"5\" onchange=\"modified=true;\" class=\"text\" name=\"googledatacenters\">{$googledatacenters}</textarea></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Linkbot User-Agent:<br />(one pr. line)</td> <td><textarea cols=\"80\" rows=\"5\" onchange=\"modified=true;\" class=\"text\" name=\"linkbotagent\">{$config->linkbotagent}</textarea></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Unique domains:</td> <td> <input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"linkbotuniquedomains\" value=\"1\" {$config->linkbotuniquedomains} /> <em>Only allow one link pr. domain</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Links/IP:</td> <td> <input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"linkbotuniqueips\" value=\"{$config->linkbotuniqueips}\" style=\"width:50px;\"/> <em>Max. number of links from an IP. (0:unlimited)</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Ignore trailing slash:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"linkbotignoretrailingslash\" value=\"1\" {$config->linkbotignoretrailingslash} /> <em>domain.com and domain.com/ is the same with this enabled</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Disregard www:</td> <td> <input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"linkbotdisregardwww\" value=\"1\" {$config->linkbotdisregardwww} /> <em>www.domain.com and domain.com is the same with this enabled</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Validate anchor:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"verifyanchor\" value=\"1\" {$config->verifyanchor} /> <em>The text between > and </a> must be an exact match</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Index exchange only:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"indexexchange\" value=\"1\" {$config->indexexchange} /> <em>Only root link exchanges</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Disallow querystring:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"noquerystring\" value=\"1\" {$config->noquerystring} /> <em>Reject URLs having ?</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Max. outbound links:</td> <td> <input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"maxoutboundlinks\" value=\"{$config->maxoutboundlinks}\" style=\"width:30px;\"/> {$maxoutboundtypeselect} <em>Max. number of external links on reciprocal URL. (0:unlimited)</em> </td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Disable blacklisted:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"disableblacklisted\" value=\"1\" {$config->disableblacklisted} /> <em>Disable links found in the blacklist</em> </td> <td class=\"help\"></td> </tr> </table> </div> </fieldset> </div> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_command_line_settings\"> <legend>Command line settings</legend> <div class=\"contractor\"> <table class=\"table\"> <tr> <td class=\"key\">Enable:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"commandlineenable\" value=\"1\" {$config->commandlineenable} /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Send summary:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"commandlinesummary\" value=\"1\" {$config->commandlinesummary} /></td> <td class=\"help\"></td> </tr> </table> </div> </fieldset> </div> <div style=\"margin:10px auto;\"> <fieldset class=\"expandable hidden\" id=\"fs_remote_access_settings\"> <legend>Remote access settings</legend> <div class=\"contractor\"> <table class=\"table\"> <tr> <td class=\"key\">Enable:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"remoteenable\" value=\"1\" {$config->remoteenable} /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Send email summary:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"remotesummary\" value=\"1\" {$config->remotesummary} /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Remote passphrase:</td> <td><input onchange=\"modified=true;\" type=\"text\" class=\"text\" name=\"remotepass\" value=\"{$config->remotepass}\" /></td> <td class=\"help\"></td> </tr> <tr> <td class=\"key\">Limit IPs:</td> <td><input onchange=\"modified=true;\" class=\"checkbox\" type=\"checkbox\" name=\"remotelimitips\" value=\"1\" {$config->remotelimitips} /></td> <td class=\"help\"></td> </tr> <tr valign=\"top\"> <td class=\"key\">Accepted IPs<br />(one pr. line)</td> <td><textarea cols=\"80\" rows=\"5\" onchange=\"modified=true;\" class=\"text\" name=\"remoteips\">{$remoteips}</textarea></td> <td class=\"help\"></td> </tr> </table> </div> </fieldset> </div> <div class=\"center\" style=\"padding-bottom:10px;\"><input class=\"button save\" type=\"submit\" name=\"ok\" value=\"Save\" onclick=\"modified=false;\" /></div> </form> "; echo template::footer(); break; case 'tools': switch( linkex::get( 'action', $_REQUEST, 'overview' ) ) { case 'autoadd': // {{{ ob_implicit_flush(true); session_write_close(); echo template::header( array( 'title' => 'Tools' ) ); $_POST['url'] = linkex::get( 'url', $_POST, $config->url ); $_POST['data'] = linkex::get( 'data', $_POST, '' ); if ( strlen( trim( $_POST['data'] ) ) > 0 ) { $legend = 'Adding links'; echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend id=\"legend\">{$legend}</legend> <div><pre id=\"progress\" style=\"font-size:11px;min-height:100px;margin-left:5px;\"> ID Domain Status PageRank BackL.Status<br /> ===============================================================================================================<br /></pre></div> </fieldset> </div> <script type=\"text/javascript\"> /*<![CDATA[*/ function _p(str){ var elem=document.getElementById('progress'); if(elem){ elem.innerHTML +=str; } } function _t(str){ var elem=document.getElementById('legend'); if(elem){ elem.innerHTML=str; } } /*]]>*/ </script> "; echo template::footer(); linkex::flush(); $links = array_map( 'trim', explode( "\n", trim( $_POST['data'] ) ) ); foreach ( $links AS $link ) { $dom = linkex::getDomain( str_replace( 'www.', '', strtolower( $link ) ) ); template::progress( sprintf( "%-15s", substr( $dom, 0, 14 ) ) ); $con = linkex::fetch( $link ); if ( preg_match( '#^HTTP/\d+\.\d+\s+200#', linkex::get( 'headers', $con, '' ) ) ) { $f=0; foreach( autoadd::knownscripts() AS $script=>$regex ) { if ( preg_match( $regex, $con{'contents'} ) ) { template::progress( sprintf( '[ %-13s ]', $script ) ); $f=1; $res = autoadd::$script( $con, $_POST['url'] ); if ( $res === true ) { template::progress( ' [ OK ]' ); } else { template::progress( ' [ '.$res.' ]' ); } break; } } if ( $f==0 ) { template::progress( '[ Link Script not recognized ]' ); } } else { template::progress( sprintf( ' [ ERROR: Invalid response %-20s ]', linkex::get( 'headers', $con ) ) ); } template::progress( '<br>' ); } exit; } else { $cat = $config->defaultcategories; $categories = linkex::categories( LOGGEDIN ); $cats = array(); foreach( $categories AS $cid=>$name ) { $cats[] = new Category( $cid ); } $categories = $cats; unset( $cats ); linkex::sort( $categories, 'name', 'asc' ); $cats = array(); foreach( $categories AS $c ) { $cats{ $c->id } = $c->name; } $categories = $cats; unset( $cats ); $categories = linkex::selector( 'categories', $categories, linkex::get( 'categories', $_POST, $cat ), LOGGEDIN, null, array( 'style' => '' ) ); $formaction = htmlentities( $_SERVER['REQUEST_URI'] ); echo "<div style=\"margin:10px auto;\"> <fieldset style=\"margin:10px auto;\"> <legend>Linking Details</legend> <form method=\"post\" action=\"{$formaction}\"> <table class=\"table\"> <tr> <td class=\"key\">URL:</td> <td><input type=\"text\" class=\"text\" name=\"url\" value=\"{$_POST['url']}\" /></td> </tr> <tr valign=\"top\"> <td class=\"key\">Categories:</td> <td>{$categories}</td> </tr> <tr valign=\"top\"> <td class=\"key\">Link Sites:<br /> (One URL pr. line)<br /> (URL to trade form)</td> <td><textarea cols=\"80\" rows=\"3\" style=\"height:150px;\" class=\"text\" name=\"data\">{$_POST['data']}</textarea></td> </tr> <tr> <td class=\"key\"></td> <td><br /><input type=\"submit\" class=\"button\" value=\"OK\" /></td> </tr> </table> </form> </fieldset> </div> "; } echo template::footer(); break; // }}} case 'email': // {{{ $linkids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); $list = array(); $email2id = array(); foreach( $linkids AS $lid ) { $l = new link( $lid ); if ( strlen( $l->email ) > 0 ) { if ( linkex::get( $l->email, $list, false ) === false ) { $list[ $l->email ] = array( $l->ldom ); $email2id[ $l->email ] = array( $l->id ); } else { $list[ $l->email ][] = $l->ldom; $email2id[ $l->email ][] = $l->id; } } } if ( linkex::get( 'subject', $_POST, false ) !== false && linkex::get( 'sendto', $_POST, false ) !== false ) { echo template::header( array( 'title' => 'Tools » Send email' ) ); $subject = linkex::get( 'subject', $_POST, '' ); $body = linkex::get( 'body', $_POST, '' ); $sendto = linkex::get( 'sendto', $_POST, array() ); $ids = array(); foreach( $sendto AS $to ) { $ids = $ids + linkex::get( $to, $email2id, array() ); } foreach( $ids AS $id ) { $l = new link( $id ); linkex::mail( $l->email, $subject, $body ); } echo "Done sending mails.."; echo template::footer(); } else { $emails = array(); foreach( $list AS $e=>$l ) { $emails[ $e ] = sprintf( '%s (%s)', $e, join(', ',$l ) ); } $selected = linkex::get( 'sendto', $_REQUEST, array() ); if ( is_string( $selected ) ) { $selected = explode( ',', $selected ); } $emails = linkex::selector( 'sendto', $emails, $selected, true, 'select', array( 'style'=>'width:400px;' ) ); $_SERVER['REQUEST_URI'] = htmlentities( $_SERVER['REQUEST_URI'] ); echo template::header( array( 'title' => 'Tools » Send email' ) ); echo "<div style=\"margin:10px;\"> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <table> <tr valign=\"top\"> <td class=\"key\">To:</td> <td>{$emails}</td> </tr> <tr valign=\"top\"> <td class=\"key\">Subject:</td> <td><input class=\"text\" type=\"text\" name=\"subject\" style=\"width:400px;\" value=\"\" /></td> </tr> <tr valign=\"top\"> <td class=\"key\">Message:</td> <td><textarea class=\"text\" name=\"body\" style=\"height:150px;width:400px;\" id=\"body\"></textarea></td> </tr> <tr> <td></td> <td> <input class=\"button\" type=\"submit\" name=\"submit\" value=\"Send\" /> </td> </tr> </table> </form> </div> "; echo template::footer(); } break; // }}} case 'import': // {{{ echo template::header( array( 'title' => 'Tools » Import' ) ); if ( linkex::get( 'seperator', $_POST, false ) && linkex::get( 'input', $_POST, false ) ) { if ( linkex::get( 'unique', $_POST, false ) !== false ) { $doms = array(); // We need to make sure the domains are unique, so we make a list of all out domains $linkids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); foreach ( $linkids AS $lid ) { $l = new link( $lid ); $doms[] = $l->ldom; unset( $l ); } } $seperator = preg_quote( linkex::get( 'seperator', $_POST, '' ), '#' ); $fields = explode( ',', linkex::get( 'fields', $_POST, '' ) ); $field_count = sizeof( $fields ); $categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); $verify = linkex::get( 'verify', $_POST, 0 ); $lines = explode( "\n", str_replace( "\r", '', linkex::get( 'input', $_POST, '' ) ) ); $legend = 'Adding new links...'; echo " <div style=\"margin:10px 0px;\"> <fieldset> <legend id=\"legend\">{$legend}</legend> <div><pre id=\"progress\" style=\"font-size:11px;min-height:100px;margin-left:5px;\"> ID Domain Status PageRank BackL.Status<br /> ===============================================================================================================<br /></pre></div> </fieldset> </div> <script type=\"text/javascript\"> /*<![CDATA[*/ function _p(str){ var elem=document.getElementById('progress'); if(elem){ elem.innerHTML +=str; } } function _t(str){ var elem=document.getElementById('legend'); if(elem){ elem.innerHTML=str; } } /*]]>*/ </script> "; echo template::footer(); flush(); $progress = ''; $title = ''; foreach( $lines AS $line ) { $list = preg_split( "#".$seperator."#", trim( $line ) ); if ( sizeof( $list ) == sizeof( $fields ) ) { $l = new link; for( $i=0; $i<sizeof( $fields ); $i++ ) { switch( $fields[$i] ) { case 'email': $l->email = $list[$i]; break; case 'rurl': $l->rurl = $list[$i]; break; case 'lurl': $l->lurl = $list[$i]; break; case 'anchor': $l->anchor = $list[$i]; break; case 'description': $l->description = $list[$i]; break; case 'randlurl': $l->lurl = $list[$i]; $l->rurl = $list[$i]; break; } } $l->update(); if ( ( $verify==1 && ( $res = $l->hasBacklink() ) && linkex::get( 'res', $res, 0 ) != 0 ) ) { $p = sprintf( 'Skipping line due to missing backlink<br />  (%s)', trim( $line ) ); } elseif ( linkex::get( 'unique', $_POST, false ) !== false && sizeof( $doms ) > 0 && in_array( $l->ldom, $doms ) ) { $p = sprintf( 'Skipping line since there allready exists a link to %s', $l->ldom ); } else { $l->categories = $categories; $l->save(); $p = sprintf( 'Added link' ); } } else { $p = sprintf( 'Skipping line due to mismatch in field count<br />  (%s)', trim( $line ) ); } printf( '<script type="text/javascript">_p("%s<br />");</script>', $p ); flush(); } } else { $_SERVER['REQUEST_URI'] = htmlentities( $_SERVER['REQUEST_URI'] ); $categories = linkex::categories( true ); $categories = linkex::selector( 'categories', $categories ); echo "<div style=\"margin:10px;\"> <form method=\"post\" action=\"{$_SERVER['REQUEST_URI']}\"> <input type=\"hidden\" name=\"fields\" id=\"fields\" value=\"\" /> <table> <tr> <td class=\"key\">Input seperator:</td> <td> <input type=\"text\" class=\"text\" name=\"seperator\" style=\"width:50px;\" id=\"seperator\" /> (tip: use <em>\t</em> for tab, or <em>\s+</em> for one or more space characters) </td> </tr> <tr valign=\"top\"> <td class=\"key\">Input fields:</td> <td> <table style=\"width:auto;\"> <tr> <td style=\"width:180px;\"> <select name=\"listA\" size=\"10\" id=\"listA\" style=\"width:180px;\"> <option value=\"email\">Email</option> <option value=\"rurl\">Recip URL</option> <option value=\"lurl\">Linking URL</option> <option value=\"anchor\">Site title</option> <option value=\"description\">Description</option> <option value=\"randlurl\">Recip AND linking URL</option> </select> </td> <td style=\"text-align:center;width:100px;\"> <a href=\"#\" style=\"border:1px solid #ccc;padding:5px;padding-top:2px;\" id=\"moveBA\">«</a> <a href=\"#\" style=\"border:1px solid #ccc;padding:5px;padding-top:2px;\" id=\"moveAB\">»</a></td> <td style=\"width:180px;\"> <select name=\"listB\" size=\"10\" id=\"listB\" style=\"width:180px;\"></select> </td> </tr> </table> </td> </tr> <tr> <td class=\"key\">Input example:</td> <td><div id=\"example\" style=\"font-family:monospace;\"></div></td> </tr> <tr valign=\"top\"> <td class=\"key\">Categories:</td> <td>{$categories}</td> </tr> <tr valign=\"top\"> <td class=\"key\">Verify linkback:</td> <td><input type=\"checkbox\" class=\"checkbox\" name=\"verify\" value=\"1\" /> (only links with a valid backlink will be imported)</td> </tr> <tr valign=\"top\"> <td class=\"key\">Unique domains:</td> <td><input type=\"checkbox\" class=\"checkbox\" name=\"unique\" value=\"1\" /> (Do not import links when there allready exists links to same domain)</td> </tr> <tr valign=\"top\"> <td class=\"key\">Input:</td> <td><textarea name=\"input\" class=\"text\" style=\"width:450px;height:200px;\"></textarea></td> </tr> <tr> <td></td> <td><input type=\"submit\" value=\"OK\" class=\"button\" /></td> </tr> </table> </form> </div> <script type=\"text/javascript\"> /*<![CDATA[*/ function update(){ var keys=new Array(); var text=new Array(); \$(\"select#listB\").each(function(){ var o=this.options; for(var i=0; i<o.length; i++){ keys.push(o[i].value); text.push(\"[\"+o[i].text+\"]\"); } }); \$(\"#fields\").val(keys.join(\",\")); \$(\"#example\").html(text.join(\$(\"input#seperator\").val())); } \$(document).ready(function(){ \$(\"select#listA\").dblclick(function(){ \$(this).find(\"option:selected\").remove().appendTo(\"select#listB\"); update(); }); \$(\"select#listB\").dblclick(function(){ \$(this).find(\"option:selected\").remove().appendTo(\"select#listA\"); update(); }); \$(\"input#seperator\").keyup(function(){update()}).blur(function(){update()}); \$(\"a#moveAB\").click(function(){ \$(\"select#listA\").trigger(\"dblclick\")}); \$(\"a#moveBA\").click(function(){ \$(\"select#listB\").trigger(\"dblclick\")}); }); /*]]>*/ </script> "; echo template::footer(); } break; // }}} case 'overview': // {{{ echo template::header( array( 'title' => 'Tools' ) ); echo "<div style=\"margin:10px;\"> <table> <tr> <td class=\"key\"><a href=\"".BASEURI."?page=admin&view=tools&action=import\">Mass add</a></td> <td>Batch import links into LinkEX</td> </tr> <tr> <td class=\"key\"><a href=\"".BASEURI."?page=admin&view=tools&action=email\">Send email</a></td> <td>Send an email to one or more webmasters</td> </tr> <tr valign=\"top\"> <td class=\"key\"><a href=\"".BASEURI."?page=admin&view=tools&action=autoadd\">Autoadd</a></td> <td>Automatically add your site to other link exchange scripts.<br />(BETA. Let me know how it works for you)</td> </tr> <tr valign=\"top\"> <td class=\"key\"><a href=\"".BASEURI."?page=admin&view=tools&action=pageranktest\">Pagerank Test</a></td> <td>Having problems with PageRank? Use this tool to debug the communication with Google.</td> </tr> </table> </div> "; echo template::footer(); break; // }}} case 'pageranktest': // {{{ echo <<<END <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>LinkEX » Test Pagerank algorithm
    END;
    
    	$pr = new PageRank;
    	$url = 'http://linkex.dk';
    	echo "Testing pagerank for: $url\n";
    	echo "Calculation Google Cookie (expecting 773196802182)\n";
    	$cookie = $pr->getCH( $url );
    	echo "  $cookie - ";
    	if ( $cookie == "773196802182" ) {
    		echo "passed\n";
    
    		$host = $pr->hosts[ mt_rand( 0, sizeof( $pr->hosts ) - 1 ) ];
    		$ip = linkex::gethostbyname( $host, true );
    		echo "Requesting info from Google (using $host - $ip)\n";
    		$fp = fsockopen( $ip, 80, $errno, $error, 2 );
    		if ( $fp ) {
    			$header = '';
    			$header .= "GET /search?client=navclient-auto&ch=" . $cookie .  "&features=Rank&q=info:" . $url . " HTTP/1.1\r\n" ;
    			$header .= "Host: ".$host."\r\n" ;
    			$header .= "Connection: Close\r\n\r\n" ;
    			fwrite( $fp, $header );
    			$data = '';
    			while ( !feof( $fp ) ) {
    				$data .= fgets( $fp, 128 );
    			}
    			fclose( $fp );
    			if ( preg_match( '#(HTTP/\d+\.\d+\s+(\d{3}))#Umis', $data, $res ) ) {
    				if ( $res[2] == '200' ) {
    					echo "  ".$res[1]."\n";
    					if ( ( $pos = strpos( $data, 'Rank_' ) ) !== false ) {
    						$pagerank = intval( trim( substr( $data, $pos + 9 ) ) );
    						echo "  PageRank for $url - $pagerank\n";
    						echo "  Test ended successfully\n";
    					} else {
    						echo "  Did not find Rank_ in body of document\n";
    						echo "\n".htmlentities( $data );
    					}
    				} else {
    					echo "\n".htmlentities( $data );
    				}
    			} else {
    				$data = explode( "\n", str_replace( "\r", '', $data ) );
    				echo "  Get invalid response from $host - ".$data[0]."\n";
    			}
    		} else {
    			echo "  unable to create socket to $host - $error\n";
    		}
    	} else {
    		echo "failed\n";
    	}
    	echo <<
    	
    
    END;
    	break; // }}}
    }
    
    					break;
    				case 'upgrade':
    
    function debug( $str ) { // {{{
    	echo "";
    	linkex::flush();
    } // }}}
    
    echo template::header( array( 'title' => 'Upgrading  LinkEX' ) );
    $legend = 'Upgrading LinkEX';
    echo "				
    {$legend}
        ID  Domain                         Status                                              PageRank BackL.Status
    ===============================================================================================================
    "; echo template::footer(); linkex::flush(); if ( ( $fp = @fopen( 'index.php', 'a' ) ) === false ) { // Unable to write to index.php debug( 'Cannot open index.php for writing. Please check the permissions.' ); exit; } fclose ( $fp ); debug( 'Cheking file permissions.. done' ); if ( @copy( __FILE__, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'index.'.date( 'Ymd' ).'.php' ) === false ) { debug( 'Unable to backup LinkEX script' ); exit; } debug( 'Backing up current version.. done' ); if ( linkex::get( 'beta', $_REQUEST, 0 ) == 1 ) { $md5 = linkex::fetch( 'http://linkex.dk/releases/current.beta.md5' ); } else { $md5 = linkex::fetch( 'http://linkex.dk/releases/current.md5' ); } if ( ( $error = linkex::get( 'error', $md5, false ) ) !== false ) { debug( 'Error while fetching version checkum ('.$md5['error'].')' ); exit; } else if ( strlen( trim( linkex::get( 'contents', $md5, '' ) ) ) != 32 ) { debug( 'Invalid response while fetching version checksum.' ); exit; } $checksum = trim( linkex::get( 'contents', $md5, '' ) ); debug( 'Fetching new version checksum.. ['.$checksum.']' ); if ( linkex::get( 'beta', $_REQUEST, 0 ) == 1 ) { $script = linkex::fetch( 'http://linkex.dk/releases/current.beta.tar' ); } else { $script = linkex::fetch( 'http://linkex.dk/releases/current.tar' ); } if ( ( $error = linkex::get( 'error', $md5, false ) ) !== false ) { debug( 'Error while fetching new script ['.$md5['error'].']' ); exit; } $script = linkex::get( 'contents', $script, '' ); debug( 'Fetching new version data file.. done ['.round(strlen($script)/1024,1).'kb]' ); if ( strcmp( strtolower( md5( $script ) ), strtolower( $checksum ) ) != 0 ) { debug( 'Verifying script checksum.. Error! Checksum mismatch ['.md5( $script).']' ); exit; } debug( 'Verifying script checksum.. done' ); linkex::fileput( __FILE__, $script ); debug( 'Installing new version.. done' ); debug( '
    Upgrade complete.' ); break; default: linkex::redirect( BASEURI, 404 ); } } else { echo template::header( array( 'title' => 'Please login', 'metarobots' => 'noindex,follow' ) ); echo "
    Please login
    Username:
    Password:
    I have forgotten my username/password
    "; echo template::footer(); } break; case 'check': @set_time_limit( 0 ); // Remote check function checkoutput( $code, $str ) { // {{{ die( "{$code}:{$str} " ); } // }}} // {{{ Is this thing enabled? if ( intval( $config->remoteenable ) == 0 ) { checkoutput( 1, 'Remote access is not enabled' ); } // }}} // {{{ IP check if ( intval( $config->remotelimitips ) == 1 ) { $ips = $config->remoteips; $found = false; $remote = linkex::get( 'REMOTE_ADDR', $_SERVER, '' ); foreach( $ips AS $ip ) { if ( linkex::compareIPs( $ip, $remote ) == 0 ) { $found = true; break; } } if ( $found !== true ) { checkoutput( 2, 'Your IP ('.$remote.') is not in the accepted IP list' ); } } // }}} // {{{ Passphrase check if ( ( $pass = $config->remotepass ) && strlen( $pass ) > 0 ) { if ( linkex::get( 'passphrase', $_GET, false ) != $pass ) { checkoutput( 3, 'Invalid or missing passphrase' ); } } // }}} $report = linkex::verifybacklinks( linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ) ); if ( $config->remotesummary == 1 ) { $report = template::report( $report ); linkex::mail( $config->email, 'Link verification report', $report ); } checkoutput( 0, 'OK' ); break; case 'about': echo template::header( array( 'title' => 'About', 'metarobots' => 'noindex,follow' ) ); echo template::about(); echo template::footer(); break; case 'logout': $path = dirname( linkex::get( 'SCRIPT_NAME', $_SERVER, '/' ) ); setcookie( '_authcookie', '', time() - 3600, $path ); unset( $_SESSION['_authcookie'] ); linkex::redirect( BASEURI, 301 ); case '': // Add link if ( !LOGGEDIN && intval( $config->disablepublicform ) == 1 ) { echo template::header( array( 'title' => 'Add link', 'metadescription' => 'Exchange hardlinks with '.$config->domain ) ); echo "
    Form disabled
    Please contact the webmaster to setup a link trade.
    "; echo template::footer(); } else { if ( sizeof( $_POST ) > 0 ) { if ( ( intval( $config->usecaptcha ) == 0 ) || ( LOGGEDIN ) || ( intval( $config->usecaptcha ) == 1 && linkex::get( 'captcha', $_POST, false ) && linkex::get( 'captcha', $_SESSION, false ) && linkex::get( 'result', $_SESSION['captcha'], false ) && $_POST['captcha'] == $_SESSION['captcha']['result'] ) ) { $link = new link; $link->wmip = $_SERVER['REMOTE_ADDR']; $link->lurl = htmlentities( linkex::get( 'lurl', $_POST, '' ) ); if ( $config->disablerecipfield == 1 && !LOGGEDIN && $config->samedomain != 2 ) { $link->rurl = $link->lurl; } else { $link->rurl = htmlentities( linkex::get( 'rurl', $_POST, '' ) ); } // Damn stupid noobish exploit $link->anchor = htmlentities( trim( linkex::get( 'anchor', $_POST, '' ) ) ); if ( $config->usetitle == 1 ) { $link->title = htmlentities( trim( linkex::get( 'title', $_POST, '' ) ) ); } else { $link->title = $link->anchor; } $link->description = htmlentities( trim( linkex::get( 'description', $_POST, '' ) ) ); $link->categories = linkex::get( 'categories', $_POST, $config->defaultcategories ); if ( !is_array( $link->categories ) ) { $link->categories = array( $link->categories ); } $link->categories = linkex::map( 'intval', $link->categories ); $link->email = htmlentities( trim( linkex::get( 'email', $_POST, '' ) ) ); // Start link validation // {{{ Check the title if ( $config->usetitle == 1 && strlen( $link->title ) == 0 ) { $errors[] = 'Please fill out the title'; } // }}} // {{{ Check the anchor if ( strlen( $link->anchor ) == 0 ) { if ( $config->usetitle == 1 ) { $errors[] = 'Please fill out the anchor text'; } else { $errors[] = 'Please fill out the title text'; } } // }}} // {{{ Check the lurl if ( strlen( $link->lurl ) == 0 ) { $errors[] = 'Please fill out the URL'; } else if ( !preg_match( '/^https?:\/\/(.*\.)*[a-z0-9]([a-z0-9-]*[a-z0-9])?\.[a-z]+(.*)?/i', $link->lurl ) ) { $errors[] = 'The URL "'.$link->lurl.'" in invalid'; } // }}} // {{{ Check the email if ( strlen( $link->email ) == 0 ) { $errors[] = 'Please enter an email address'; } else if ( !preg_match( '/\S+@[a-z0-9]([a-z0-9-]*[a-z0-9])?\.[a-z]+(.*)?/i', $link->email ) ) { $errors[] = 'The email "'.$link->email.'" is invalid'; } // }}} // {{{ Check the rurl if ( intval( $config->disablerecipfield ) == 0 ) { if ( strlen( $link->rurl ) == 0 ) { $errors[] = 'Please fill out the reprocial URL'; } else if ( !preg_match( '/^https?:\/\/(.*\.)*[a-z0-9]([a-z0-9-]*[a-z0-9])?\.[a-z]+(.*)?/i', $link->rurl ) ) { $errors[] = 'The reprocial URL "'.$link->rurl.'" in invalid'; } } // }}} // {{{ Check the categories if ( $config->publiccategories == 1 ) { if ( sizeof( $link->categories ) == 0 ) { $errors[] = 'Please select a category'; } } // }}} $link->update(); $link->updateIPs(); // {{{ indexexchange if ( $config->indexexchange == 1 ) { $elems = @parse_url( $link->lurl ); if ( linkex::get( 'path', $elems, '/' ) != '/' ) { $errors[] = 'Only index exchanges allowed'; } if ( $link->lurl != $link->rurl ) { $elems = @parse_url( $link->rurl ); if ( linkex::get( 'path', $elems, '/' ) != '/' ) { $errors[] = 'Only index exchanges allowed'; } } } // }}} // {{{ noquerystring if ( $config->noquerystring == 1 ) { if ( strpos( $link->lurl, '?' ) !== false ) { $errors[] = 'No querystrings allowed'; } if ( $link->rurl != $link->lurl && strpos( $link->rurl, '?' ) !== false ) { $errors[] = 'No querystrings allowed'; } } // }}} // {{{ Same domain? switch( intval( $config->samedomain ) ) { case 1: if ( linkex::compareURLs( $link->ldom, $link->rdom ) != 0 ) { $errors[] = 'The submitted URLs must be on the same domain'; } break; case 2: if ( intval( $config->disablerecipfield ) == 0 && linkex::compareURLs( $link->ldom, $link->rdom ) == 0 ) { $errors[] = 'The submitted URLs must be on different domains'; } break; } // }}} // {{{ Check the length's if ( sizeof( $errors ) == 0 && (( LOGGEDIN && linkex::get( 'skiplengths', $_POST, 0 ) == 0 ) || !LOGGEDIN ) ) { // First the anchor if ( $config->anchorlength > 0 ) { if ( $config->anchorlengthtype == 'w' ) { // Max words if ( sizeof( preg_split( '#\s+#', $link->anchor ) ) > $config->anchorlength ) { $errors[] = sprintf( 'Your site anchor text is too long' ); } } else { // Max len if ( strlen( $link->anchor ) > $config->anchorlength ) { $errors[] = sprintf( 'Your site anchor text is too long' ); } } } // Then the title if ( $config->usetitle == 1 && $config->titlelength > 0 ) { if ( $config->titlelengthtype == 'w' ) { // Max words if ( sizeof( preg_split( '#\s+#', $link->title ) ) > $config->titlelength ) { $errors[] = sprintf( 'Your site title is too long' ); } } else { // Max len if ( strlen( $link->title ) > $config->titlelength ) { $errors[] = sprintf( 'Your site title is too long' ); } } } // Then the description if ( $config->descriptionlength > 0 ) { if ( $config->descriptionlengthtype == 'w' ) { // Max words if ( sizeof( preg_split( '#\s+#', $link->description ) ) > $config->descriptionlength ) { $errors[] = sprintf( 'Your site description is too long' ); } } else { // Max len if ( strlen( $link->description ) > $config->descriptionlength ) { $errors[] = sprintf( 'Your site description is too long' ); } } } } // }}} // {{{ Check for dublicate domains/ips if ( ( LOGGEDIN && linkex::get( 'skipdupes', $_POST, 0 ) == 0 ) || !LOGGEDIN ) { $linkids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ); $ipcount = 0; foreach ( $linkids AS $lid ) { $l = new link( $lid ); $ipcount += ( linkex::compareIPs( $l->rdomip, $link->rdomip ) == 0 ) ? 1:0; if ( $config->linkbotuniquedomains == 1 ) { if ( linkex::compareURLs( $link->ldom, $l->ldom ) == 0 ) { $errors[] = 'We allready have a link to "'.$l->ldom.'"'; break; } else if ( linkex::compareURLs( $link->rdom, $l->rdom ) == 0 ) { $errors[] = 'We allready have a link from "'.$l->rdom.'"'; break; } } else { if ( linkex::compareURLs( $link->lurl, $l->lurl ) == 0 ) { $errors[] = 'We allready have a link to "'.$l->lurl.'"'; break; } else if ( linkex::compareURLs( $link->rurl, $l->rurl ) == 0 ) { $errors[] = 'We allready have a link from "'.$l->rdom.'"'; break; } } unset( $l ); } if ( intval( $config->linkbotuniqueips )>0 && $ipcount >= intval( $config->linkbotuniqueips ) ) { $errors[] = 'We allready have '.intval($ipcount).' links from "'.$link->rdomip.'"'; } } // }}} // {{{ Check the blacklist if ( ( LOGGEDIN && linkex::get( 'skipblacklist', $_POST, 0 ) == 0 ) || !LOGGEDIN ) { if ( sizeof( $errors ) == 0 && linkex::get( 'skipblacklist', $_POST, 0 ) == 0 && ( $reason = $link->blacklisted() ) !== false ) { $errors[] = $reason; } } // }}} // {{{ Make sure a backlink is present $link->lastchecked = time(); if ( sizeof( $errors ) == 0 && ( ( LOGGEDIN && linkex::get( 'skipbacklinkcheck', $_POST, 0 ) == 0 ) || !LOGGEDIN ) && ( ( $config->linkbackrequired == 1 ) || ( intval( $config->maxoutboundlinks ) > 0 ) ) && ( $e=$link->hasBacklink() ) && linkex::get( 'res', $e, 0 ) != 0 ) { switch( linkex::get( 'res', $e, 0 ) ) { case '1': $errors[] = 'Unable to verify backlink. '.linkex::get( 'reason', $e, '' ); break; case '2': $errors[] = 'None of the links found on "'.$link->rurl.'" could be accepted. ' . linkex::get( 'reason', $e, '' ); break; case '4': $errors[] = 'The anchor text of the backlink did not match the req'.'uired anchor text.'; break; case '8': $errors[] = 'None of the links found on "'.$link->rurl.'" could be accepted. ' . linkex::get( 'reason', $e, '' ); break; case '16': $errors[] = linkex::get( 'reason', $e, '' ); break; default: $errors[] = 'Iternal error'; break; } } $link->skipcheck = ( LOGGEDIN && linkex::get( 'skipbacklinkcheck', $_POST, 0 ) == 1 ) ? 1:0; // }}} // {{{ Check the min PageRank // The pagerank must be checked if: // ( config->minpagerank > 0 && !LOGGEDIN ) || ( LOGGEDIN && linkex::get( 'skippagerank', $_POST, 0 ) == 0 ) if ( sizeof( $errors ) == 0 && $config->minpagerank > 0 && !( LOGGEDIN && linkex::get( 'skippagerank', $_POST, 0 ) != 0 ) ) { if ( $link->getRPageRank( false ) < $config->minpagerank ) { $errors[] = 'We require a min. PR'.$pr.', your site has a PR'.$link->getRPageRank( false ).''; } } // }}} if ( sizeof( $errors ) == 0 ) { $link->save(); $link = new link( $link->id ); if ( !LOGGEDIN && strlen( $config->email ) > 4 ) { $_SERVER['HTTP_HOST'] = str_replace( 'www.', '', strtolower( linkex::get( 'HTTP_HOST', $_SERVER, 'unknown' ) ) ); $host = $_SERVER['HTTP_HOST']; linkex::mail( $config->email, 'LinkEX: new link @ '.linkex::get( 'HTTP_HOST', $_SERVER, 'unknown' ), "This is a message from {$host}. A new link was just added: By: {$link->wmip} Email: {$link->email} Outbound link: {$link->lurl} IP: {$link->ldomip} PageRank: {$link->lpagerank} Indexed pages: {$link->lindexed} Anchor text: {$link->anchor} Title text: {$link->title} Inbound link: {$link->rurl} IP: {$link->rdomip} PageRank: {$link->rpagerank} Indexed pages: {$link->rindexed} " ); } echo template::header( array( 'title' => 'Link added' ) ); echo "
    Rules

    Thank you for adding your link to our database.
    Please make sure you allways keep a link to our site, otherwise your link will be disabled from our site.

    Like the looks of this script? Get yours for free, head over to LinkEX and check out this free script.

    "; echo template::footer(); exit; } } else { // Captcha failed $errors[] = 'Spam check failed. Please retry'; } } echo template::header( array( 'title' => 'Add link', 'metadescription' => 'Exchange hardlinks with '.$config->domain.'. Instant linkexchange' ) ); $rules = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules', "We are constantly looking for new perm link exchanges to improve link popularity and page rank.
    Please remember that this is not about traffic, it's about the link.
    Play fair! " ); $anchor = $config->anchor; $anchor = $anchor[ mt_rand( 0, sizeof( $anchor )-1 ) ]; $title = $config->title; $title = $title[ mt_rand( 0, sizeof( $title )-1 ) ]; $htmlcode = str_replace( array( '{$URL}', '{$ANCHOR}', '{$DESCRIPTION}', '{$TITLE}' ), array( htmlentities( $config->url ), htmlentities( $anchor ), htmlentities( $config->description ), htmlentities( $title ) ), $config->htmlcode ); if ( intval( $config->publiccategories ) == 1 || LOGGEDIN ) { $categories = linkex::categories( LOGGEDIN ); $cats = array(); foreach( $categories AS $cid=>$name ) { $cats[] = new Category( $cid ); } $categories = $cats; unset( $cats ); linkex::sort( $categories, 'name', 'asc' ); $cats = array(); foreach( $categories AS $c ) { $cats{ $c->id } = $c->name; } $categories = $cats; unset( $cats ); $categories = linkex::selector( 'categories', $categories, linkex::get( 'categories', $_POST, $categories ), LOGGEDIN, null, array( 'style' => 'width:auto;max-width:300px;' ) ); } if ( intval( $config->usecaptcha ) == 1 && !LOGGEDIN ) { $c = new captcha; $captcha = $c->html(); } if ( LOGGEDIN ) { $skipbacklinkcheck = linkex::checkbox( linkex::get( 'skipbacklinkcheck', $_POST, 0 ) ); $skippagerank = linkex::checkbox( linkex::get( 'skippagerank', $_POST, 0 ) ); $skipblacklist = linkex::checkbox( linkex::get( 'skipblacklist', $_POST, 0 ) ); $skiplengths = linkex::checkbox( linkex::get( 'skiplengths', $_POST, 0 ) ); $skipdupes = linkex::checkbox( linkex::get( 'skipdupes', $_POST, 0 ) ); } $_POST['email'] = htmlentities( linkex::get( 'email', $_POST, ( (LOGGEDIN)?$config->email:'') ) ); $_POST['lurl'] = htmlentities( linkex::get( 'lurl', $_POST, '' ) ); $_POST['rurl'] = htmlentities( linkex::get( 'rurl', $_POST, '' ) ); $_POST['title'] = htmlentities( linkex::get( 'title', $_POST, '' ) ); $_POST['anchor'] = htmlentities( linkex::get( 'anchor', $_POST, '' ) ); $_POST['description'] = htmlentities( linkex::get( 'description', $_POST, '' ) ); echo "
    Rules ".(($config->maxoutboundlinks>0)?(" "):(""))."
    {$rules}
    Linkback: ".(($config->linkbackrequired == 1)?("Required"):("Not required"))."
    Min. PageRank™:
    minpagerank}\">
    Max. links: {$config->maxoutboundlinks} external links on reciprocal link URL
    Our linking details ".(($config->showemail == 1)?(" "):(""))."
    Email: {$config->email}
    URL: {$config->url}
    Site title: {$title}
    Site description: {$config->description}
    HTML code:
    {$htmlcode}
    Your linking details
    ".(($config->usetitle==1)?(" "):(" "))." ".(($config->disablerecipfield == 0 || $config->samedomain == 2)?(" "):(""))." ".(($config->usecaptcha && !LOGGEDIN)?(" "):(""))." ".(($config->publiccategories || LOGGEDIN)?(" "):(""))." ".((LOGGEDIN)?(" "):(""))."
    Site anchor: ".(($config->anchorlength>0 && $config->anchorlengthtype == 'w')?(" max {$config->anchorlength} words"):(""))." ".(($config->anchorlength>0 && $config->anchorlengthtype == 'c')?(" max {$config->anchorlength} characters"):(""))."
    Site title: ".(($config->titlelength>0 && $config->titlelengthtype == 'w')?(" max {$config->titlelength} words"):(""))." ".(($config->titlelength>0 && $config->titlelengthtype == 'c')?(" max {$config->titlelength} characters"):(""))."
    Site title: ".(($config->titlelength>0 && $config->titlelengthtype == 'w')?(" max {$config->titlelength} words"):(""))." ".(($config->titlelength>0 && $config->titlelengthtype == 'c')?(" max {$config->titlelength} characters"):(""))."
    Your URL:
    Reciprocal link URL: ".(($config->samedomain == 1)?("Must be on the same domain as above"):(""))." ".(($config->samedomain == 2)?("Must be on a different domain as above "):(""))."
    Your email:
    Site description: ".(($config->descriptionlength>0 && $config->descriptionlengthtype == 'w')?(" max {$config->descriptionlength} words"):(""))." ".(($config->descriptionlength>0 && $config->descriptionlengthtype == 'c')?(" max {$config->descriptionlength} characters"):(""))."
    Spam check:
    {$captcha}
    Category: {$categories}

    Since you are logged in, you have additional options:

    "; echo template::footer(); } break; default: linkex::redirect( BASEURI, 404 ); } } } else { $_username = linkex::get( '_username', $_POST, '' ); $_password1 = linkex::get( '_password1', $_POST, '' ); $_password2 = linkex::get( '_password2', $_POST, '' ); $_email = linkex::get( '_email', $_POST, '' ); $_url = linkex::get( '_url', $_POST, 'http://'.linkex::get( 'HTTP_HOST', $_SERVER, '' ) ); $_anchor = linkex::get( '_anchor', $_POST, '' ); if ( linkex::get( 'ok', $_POST, false ) !== false ) { // Form is posted // {{{ Check if we have a username if ( strlen( trim( $_username ) ) == 0 ) { $errors[] = 'Please enter a username'; } // }}} // {{{ Check the password(s) if ( strlen( trim( $_password1 ) ) == 0 ) { $errors[] = 'Please enter a password'; } else if ( trim( $_password1 ) != trim( $_password2 ) ) { $errors[] = 'The two passwords did not match, please try again.'; } // }}} // {{{ Check the email if ( strlen( trim( $_email ) ) == 0 ) { $errors[] = 'Please enter an email address'; } else if ( !preg_match( '/\S+@[a-z0-9]([a-z0-9-]*[a-z0-9])?\.[a-z]+(.*)?/i', $_email ) ) { $errors[] = 'The email "'.$_email.'" is invalid'; } // }}} // {{{ Check the URL if ( strlen( trim( $_url ) ) == 0 ) { $errors[] = 'Please fill out the URL of your website'; } else if ( !preg_match( '/^https?:\/\/(.*\.)*[a-z0-9]([a-z0-9-]*[a-z0-9])?\.[a-z]+(.*)?/i', $_url ) ) { $errors[] = 'The URL "'.$_url.'" in invalid /^https?:\/\/(.*\.)*[a-z0-9]([a-z0-9-]*[a-z0-9])?\.[a-z]+(.*)?/i'; } // }}} // {{{ Check the anchor if ( strlen( trim( $_anchor ) ) == 0 ) { $errors[] = 'Please fill out the title of your website'; } // }}} if ( sizeof( $errors ) == 0 ) { $dirs = array( BASEDIR . DIRECTORY_SEPARATOR .'data', BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR, BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR ); foreach( $dirs AS $d ) { if ( !is_dir( $d ) && @mkdir( $d, 0777 ) === false ) { $errors[] = 'Unable to create directory "'.$d.'"'; break; } @chmod( $d, 0777 ); } $config = new config; $config->password = md5( $_username .'---'. $_password1 ); $config->email = $_email; $config->url = $_url; $config->anchor = array( $_anchor ); $config->defaultcategories = array( '1001' ); if ( sizeof( $errors ) == 0 ) { $config->save(); linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR .'data'. DIRECTORY_SEPARATOR .'config'. DIRECTORY_SEPARATOR .'uid', '1000' ); $cat = new category; $cat->name = 'Default'; $cat->save(); unset( $cat ); echo template::header( array( 'title' => 'Installation complete' ) ); echo "
    All done
    You LinkEX is now ready to use, log in here, and check out the opportunities with this script.
    "; echo template::footer(); exit; } } } echo template::header( array( 'title' => 'Installation' ) ); echo "
    Welcome to LinkEX
    Thank you for choosing LinkEX. Hopefully LinkEX will help you build a strong network of links, and lessen the workload for you at the same time.

    In order to start using LinkEX, you need to fill out the form below.
    "; echo "
    Settings
    Username:
    Password:
    Password (again):
    Email:
     
    Website URL:
    Website Title:
    "; echo template::footer(); } ?>