|
|
|
|
|
|
| |
| <?
/*
* L I N K S M A N A G E R
* Author: Sarah King
* http://sarahk.pcpropertymanager.com
* March 2005
*
* Description: This script is designed to review the links on a page and identify
* if the links are already held in the tables of a links directory
* If not, then the link is presented in a submission form which can be customised
* for the users own directory system.
*
* The CURL option is fully debugged, was not able to fully test the fsockopen version
*
* Setup: The class has 4 variables used for connecting to the database.
* These need to be changed.
*
* $query needs to be updated with the actual query used to check for a links existence
*
* $form works for my old version of the wsnlinks directory. You need to change this
* so that it works for the directory system you use
*
* $useCurl should be true if curl is available. fsockopen functions haven't been fully tested
* $user_agent should be set to your site name
*
* getScratchPad is for static information you need to copy and paste from time to time
*
*/
class LinkManager
{
// user variables
var $dbhost = 'localhost';
var $dbuser = '';
var $dbname = 'test';
var $dbpass = '';
var $allowSubDomains = true; // treat subdomains as separate sites
var $myDomains = array('pcpropertymanager.com',
'https://secure.maxnet.co.nz/pcpm/',
'propertyinvestor.info'
); // I don't want to detect links on my domain
// the database query I use to see if the link exists and to get the category name where I'd find it.
// need to return something called 'name' so that it can be fed back out
var $query = "select cat.name
from `wsnlinks_links` link, `wsnlinks_categories` cat
where link.catid = cat.id
and link.url like '%{DOMAIN}%' ";
// the default form works on my directory system, you need to change this to the form needed on your system
var $form = "<form action='/wsnlinks/suggest.php?action=addlink&filled=1'
method='post' target='_blank'>
<table>
<tr><th>Category:</th><td><input type='text' name='catid' value='' size='5'><td></tr>
<tr><th>Title:</th><td><input type='text' name='title' size=40 value='{TITLE}'><td></tr>
<tr><th>URL:</th><td><input type='text' name='url' size='40' value='{URL}'><a href='{URL}' target='_blank'>Go</a><td></tr>
<tr><th>Description:</th><td><textarea cols='40' rows='4' NAME='description'></textarea><td></tr>
<tr><th>Reciprocal Link URL:</th><td><input type=text name='recipurl' size='40' value='http://'><td></tr>
<tr><th>Your E-mail:</th><td><input type=text name=email size=40><td></tr>
<tr><th>REW Username:</th><td><input type=text name='rewusername' size='20'></td></tr>
<tr><td> </td><td><input type=submit value='Submit Link'></td></tr>
</table>
</form>";
//curl option is fully debugged
var $useCurl = true; //set to false to use fsockopen
var $ch; //curl handler if we need it
//curl lets us be good citizens and declare our user agent
var $user_agent='http://www.pcpropertymanager.com/wsnlinks/ Property Investment Directory ';
//any words which mean a local page shouldn't be checked for a redirect
var $stopWords = array('archive', 'clicks', 'content', 'download', 'Your_Account', 'profile', 'private');
var $debug = false;
// internal variables
var $html;
var $links;
var $domain;
var $errors = array();
/**
* @return string
* @desc Fill this up with the info you need frequently when filling in link requests
*/
function getScratchPad()
{
$output = "<a href='http://www.pcpropertymanager.com/wsnlinks/' target='_blank'>Property Investment Directory</a><br /><br />
<b>Our Link Information</b><br>
PC Property Manager<br>
http://www.pcpropertymanager.com<br>
Rental Property Management Software saves you time, money and keeps you organized.<br>
More than a great bookkeeping system, designed for property management issues leaving you in control and stress free. Helps with tax returns and tracking rents.
<br><br>
<p><b>Test Pages</b></p>
<ul>
<li><a href='linkmanager.php?url=http%3A%2F%2Fwww.propertytalk.co.nz%2Flink-38.html'>PropertyTalk International Links</a></li>
<li><a href='linkmanager.php?url=http%3A%2F%2Fwww.pcpropertymanager.com%2Fwsn1_1display.html'>Other Property Directories</a></li>
<li><a href='linkmanager.php?url=" . urlencode('http://www.pcpropertymanager.com/wsn30_1display.html') . "'>Colorado Property</a></li>
</ul>";
return $output;
}//getScratchPad
///////////////////////////////////
// No changes to the class should be made below here
///////////////////////////////////
/**
* @return string
* @param array $item
* @desc Controls the presentation of the link form and allows it to be hidden
*/
function getLinkForm($item, $cnter)
{
$form = $this->form;
$form = str_replace('{URL}', $item['url'], $form);
$form = str_replace('{TITLE}', $item['title'], $form);
$output = "<div class='new'>
<table width='100%'><tr><td>{$item['title']}</td><td><p class='shoh'><a href='#new{$cnter}' onClick=\"shoh('new{$cnter}');\">+/-</a></tr></table>
<div id='new{$cnter}'>\n{$form}</div>\n</div>\n";
return $output;
}//getLinkForm
/**
* @return LinkManager
* @desc Constructor, just sets up the page
* if no url is passed check to see if the form has been submitted
*/
function LinkManager($url='')
{
global $_SERVER;
if (empty($url)) $url = $this->getGetVar('url');
$this->domain = $this->extractDomain($url);
echo $this->getHeader($url);
if (!empty($url))
{
if ($this->useCurl) $this->initialiseCurl();
$this->processPage($url, 0);
}
else
{
echo "<p>Enter a page to check</p>
<form name='formURL' action='linkmanager.php' method='get'>
<input type='text' name='url' size='35'> <input type='submit' name='cmdSave' value='Process'>
</form>";
}
echo $this->getFooter();
if ($this->useCurl) $this->closeCurl();
}//LinkManager
/**
* @return string
* @param string $url
* @desc Returns the main part of the domain for comparison in the database
*/
function extractDomain($url)
{
$bits = parse_url($url);
$domain = $bits['host'];
if ($this->allowSubDomains == false)
{
$bits = explode('.', $domain);
krsort($bits);
$ok = true;
$parts = 0;
$domain = $dot = '';
foreach($bits as $v)
{
if ($parts < 2) $domain = $v . $dot . $domain;
elseif ($ok)
{
if ($v != 'www') $domain = $v . '.' . $domain;
$ok = false;
}
$parts++;
$dot = '.';
}
}
return $domain;
}//extractDomain
/**
* @return array
* @param string $data
* @desc returns an array of extracted links
*/
function extractLinks()
{
$data = $this->html;
unset($location);
$links = array();
$pos = 0;
$i = 0;
while (!(($pos = strpos($data,"<",$pos)) === false))
{
$pos++;
$curLink = array();
$endpos = strpos($data,">",$pos);
$tag = substr($data,$pos,$endpos-$pos);
$tag = trim($tag);
if (isset($location)) { // look for a </A>
if (!strcasecmp(strtok($tag," "),"/A"))
{
$link = substr($data, $linkpos, $pos-1-$linkpos);
$curLink['title'] = strip_tags($link);
$curLink['url'] = $location;
$curLink['status'] = 0;
$links[] = $curLink;
unset($location);
}
$pos = $endpos+1;
}
else
{ // look for a <A ...>
if (!strcasecmp(strtok($tag,' '),'A'))
{
$regs[] = array();
preg_match('/href\s*=\s*([\'"]?)([^\'">\s]+)\1/i', $tag, $regs);
if ($regs[2])
{ // Only use it if it seems to be reasonable
$location = $regs[2];
}
$pos = $endpos+1;
$linkpos = $pos;
} else $pos = $endpos+1;
}
$i++;
}
$this->links = $links;
} //extract_links
/**
* @return void
* @param string $url
* @desc Retrieves the html for the page in question
*/
function getPage($url)
{
$output = $this->getHTTPContent($url, 'GET');
$output = implode(' ', $output);
$output = ereg_replace("\n|\r", ' ', $output);
$this->html = $output;
}//getPage
/**
* @return string
* @desc Works through the links and displays according to status
*/
function showPossibleLinks()
{
$output = '';
for ($i = 0; $i < 3; $i++)
{
if ($i == 1) $output .= "<h2>Already Listed</h2><ul>\n";
if ($i == 2) $output .= "<h2>Potential Listings</h2>\n";
if ($i == 0 && $this->debug) $output .= "<h2>Rejected</h2><ul>\n";
foreach ($this->links as $k => $varray)
{
$label = $varray['title'];
if (empty($label)) $label = $varray['url'];
if ($varray['status'] == 1 && $i == 1)
{
$output .= "<li><A HREF='{$varray['url']}' target='_blank'>{$label}</A> - {$varray['category']}</li>\n";
}
elseif ($varray['status'] == 2 && $i == 2)
{
$output .= $this->getLinkForm($varray, $k);
}
elseif ($this->debug) $output .= "<li><A HREF='{$varray['url']}' target='_blank'>{$label}</A></li>\n";
}
if ($i == 1) $output .= "</ul>\n";
if ($i == 0 && $this->debug) $output .= "</ul>\n";
}
return $output;
}//showPossibleLinks
function checkLinks()
{
$this->dbConnect();
foreach ($this->links as $k => $varray)
{
// see if we have a redirect
if ( stristr($varray['url'], $this->domain))
{
$varray['url'] = $this->detectExternalLink($varray['url']);
$this->links[$k]['url'] = $varray['url'];
}
elseif ( substr($varray['url'],0,4) != 'http')
{
$varray['url'] = $this->detectExternalLink($this->domain . '/'. $varray['url']);
$this->links[$k]['url'] = $varray['url'];
}
// now check the link against the database
if ($this->validDomain($varray['url']))
{
$domain = $this->extractDomain( $varray['url']);
$sql = str_replace('{DOMAIN}', $domain, $this->query);
$result = mysql_query($sql) or die(mysql_error() . "\n<br>\n" . $sql);
if ($row = mysql_fetch_array($result))
{
$this->links[$k]['status'] = 1;
$this->links[$k]['category'] = $row['name'];
}
else $this->links[$k]['status'] = 2;
}
}
}//checkLinks
/**
* @return boolean
* @param string $url
* @desc Checks to see if this is a domain we want to think about linking to
*/
function validDomain($url)
{
if (empty($url)) return false;
if (substr($url,0,4) != 'http') return false;
if (stristr($url, $this->domain)) return false;
foreach($this->myDomains as $d)
{
if (stristr($url, $d)) return false;
}
return true;
}//validDomain
function detectExternalLink($url)
{
$newUrl = '';
if ($this->checkNoStopWords($url))
{
$header = $this->getHTTPContent($url);
foreach($header as $lines)
{
if (substr($lines, 0, 9) == 'Location:') $newUrl = trim( substr( $lines, 10));
}
}
return $newUrl;
}//detectExternalLink
/**
* @return boolean
* @param string $url
* @desc Check to see if the url has any stopwords
*/
function checkNoStopWords($url)
{
foreach($this->stopWords as $needle)
{
if (stristr($url, $needle)) return false;
}
return true;
}//checkNoStopWords
/**
* @return array
* @param string $url
* @param string $method
* @desc Returns the requested information in an array
*/
function getHTTPContent($url, $method = 'HEAD')
{
$output = array();
$info = parse_url($url);
if (!isset($info['host'])) $info['host'] = $this->domain;
$host = $info['host'];
if (!isset($info['port'])) $info['port'] = 80;
if (!isset($info['path'])) $info['path'] = '/';
$path = $info['path'];
if ($info['query']) {
$path .= '?' . $info['query'];
}
if (!stristr($path, $host)) $path = $host. $path;
if ($this->useCurl)
{
curl_setopt ($this->ch, CURLOPT_URL, $path);
$output[] = curl_exec ($this->ch);
if ($method == 'HEAD')
{
$header = curl_getinfo($this->ch);
$output[] = 'Location: ' . $header['url'];
}
if (curl_errno($this->ch))
$this->errors[] = "Curl Error: " . curl_error($this->ch) . " ==> {$path}<br>\n";
}
else
{
// open connection
$fp = fsockopen( $info['host'], $info['port'], $errno, $errstr, 60);
if ($fp)
{
// send request
fwrite ($fp, "{$method} {$path} HTTP/1.0\r\nHost: {$host}\r\n\r\n");
while (!feof($fp))
{
$output[] = fgets($fp, 1028);
}
}
else $this->errors[] = "FSock Error: {$errstr} ({$errno})<br />\n";
fclose($fp);
}
return $output;
}//openHTTPConnection
/**
* @return void
* @param string $url
* @desc Controlling script for processing a page
*/
function processPage($url)
{
$this->getPage($url);
$this->extractLinks();
$this->checkLinks();
echo $this->showPossibleLinks();
}//processPage
/**
* @return string
* @desc Returns the basic page setup
*/
function getHeader($url)
{
$title = ($this->domain)?$this->domain:'Links Manager';
$output = "<html>
<head>
<title>Link Manager</title>
<style>
body{
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 12px;
color: #400040;
margin: 0px;
}
td, th {
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 12px;
color: #400040;
vertical-align: top;
}
a {color: #1F4000;}
input, textarea {color: navy;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 12px;
}
td { text-align: left; }
th { text-align: right; }
.new {border: 1px navy solid; margin-bottom: 5px;}
.shoh {text-align: right; font-weight: bold; padding-right: 5px; margin: 0px;}
.shoh a { text-decoration: none }
.heading {padding: 10px;}
.heading td { text-align: right; }
.heading th { text-align: left; }
</style>
<script type='text/javascript' language='Javascript'>
//show OR hide function depends on if element is shown or hidden
function shoh(id)
{
var newval = 'none';
if (document.getElementById)
{ // DOM3 = IE5, NS6
if ( document.getElementById(id).style.display == 'none') newval = 'block';
document.getElementById(id).style.display = newval;
}
else
{
if (document.layers)
{
if ( document.id.display == 'none') newval = 'block';
document.id.display = newval;
}
else
{
if ( document.all.id.style.visibility == 'none') newval = 'block';
document.all.id.style.display = newval;
}
}
}//shoh
</script>
</head>
<body>
<table width='100%' class='heading'>
<tr><td>Domain</td><th>{$title}</th><td rowspan='3' align='right'><a href='linkmanager.php'>Start Again</a></td></tr>
<tr><td>URL</td><th>{$url}</th></tr>
<tr><td>Date</td><th>".date('d/m/Y H:i')."</th></tr>
</table>
<table border='0' cellpadding='10' cellspacing='0'>
<tr><td>";
return $output;
}//getHeader
/**
* @return string
* @desc Finishes off the html for the footer
*/
function getFooter()
{
if (count($this->errors) > 0)
{
$output .= "<ul>\n";
foreach ($this->errors as $val) $output .= "<li>{$val}</li>\n";
$output .= "</ul>\n";
}
$output = "</td>
<td><h3>Scratchpad</h3>\n". $this->getScratchPad() . "</td>
</tr></table>
<div style='background: navy; text-align: center; padding: 5px;'><a style='color: white' href='http://www.pcpropertymanager.com/wsnlinks/'>Property Investment Directory</a></div>
</body>\n</html>";
return $output;
}//getFooter
/**
* @return void
* @desc Create the curl option and store in this object
*/
function initialiseCurl()
{
$ch = curl_init();
curl_setopt ($ch, CURLOPT_USERAGENT, $this->user_agent);
curl_setopt ($ch, CURLOPT_REFERER, 'http://www.pcpropertymanager.com/wsnlinks/');
curl_setopt ($ch, CURLOPT_HEADER, 1);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_FAILONERROR, 1);
$this->ch = $ch;
}//initialiseCurl
/**
* @return void
* @desc Close the curl connection
*/
function closeCurl()
{
curl_close($this->ch);
}//closeCurl
/**
* @return void
* @desc Simple database connection function
*/
function dbConnect()
{
mysql_connect($this->dbhost, $this->dbuser, $this->dbpass)
OR die( 'DB Connect: ' . mysql_error());
mysql_select_db($this->dbname)
OR die( 'DB Select: ' . mysql_error());
}//dbConnect
/**
* @return string
* @param string $name
* @param string $default
* @desc Returns a GET variable
*/
function getGetVar($name, $default='')
{
global $_GET;
if (isset($_GET[$name])) $output = $_GET[$name];
else $output = $default;
return $output;
}//getGetVar
}//class UTIL_linkmanager
$lm = new LinkManager();
?> | | |
|
| MySQL Handler Categories : PHP, Databases, MySQL, Classes and Objects, PHP Classes | | | Powerful php/mysql Pagination for up to 6 URL Params Categories : PHP, PHP Classes, Databases, MySQL, Navigation | | | PostGreSQL and MySQL 2 in 1 db Manager Categories : PHP, PHP Classes, Databases, PostgreSQL, MySQL | | | Password reminder Categories : PHP, PHP Classes, Databases, MySQL, Mail | | | MySQL Class to ease Database connectivity Categories : MySQL, PHP Classes, Databases, PHP | | | usercounter class Categories : PHP, PHP Classes, Databases, MySQL, Environment Variables | | | Simple Mini Poll class library (SimPoll) Categories : PHP, PHP Classes, Databases, MySQL, Complete Programs | | | Simple database class Categories : PHP, PHP Classes, MySQL, Databases | | | Simple usersOnline class - keep track of how many users are online on your site Categories : PHP, PHP Classes, Databases, MySQL | | | Online Automatic Class Generator for MySQL Tables Categories : PHP, PHP Classes, Classes and Objects, Databases, MySQL | | | Specify your connection settings and create a link to a MySQL database. Categories : PHP, PHP Classes, Databases, MySQL, Beginner Guides | | | Setting up InnoDB on MySQL and using Transactions Begin, Commit, Rollback in PHP. Categories : PHP Classes, Databases, PHP, MySQL, InnoDB | | | Ajax PHP Tree (Left and Right) with MySQL Categories : PHP, Databases, MySQL, AJAX, PHP Classes | | | YellowPages Content Grabber (PHP5 +) Categories : |
| |