From 513fe7eeb094738b6cd5de72e1124bb3281d628c Mon Sep 17 00:00:00 2001 From: diosmosis <benaka.moorthi@gmail.com> Date: Mon, 25 Mar 2013 10:01:39 +0000 Subject: [PATCH] Fixes #3734, added 'external backlinks' and 'referrer domains' stats to SEO widget via Majestic SEO API. --- lang/en.php | 2 + plugins/SEO/API.php | 18 +++++- plugins/SEO/MajesticClient.php | 95 +++++++++++++++++++++++++++++ plugins/SEO/RankChecker.php | 34 +++++++++++ plugins/SEO/images/majesticseo.png | Bin 0 -> 674 bytes plugins/SEO/templates/index.tpl | 2 +- 6 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 plugins/SEO/MajesticClient.php create mode 100644 plugins/SEO/images/majesticseo.png diff --git a/lang/en.php b/lang/en.php index 36f52c3c7a..72f52b122f 100644 --- a/lang/en.php +++ b/lang/en.php @@ -1285,6 +1285,8 @@ And thank you for using Piwik!', 'SEO_Bing_IndexedPages' => 'Bing indexed pages', 'SEO_Dmoz' => 'DMOZ entries', 'SEO_SEORankingsFor' => 'SEO Rankings for %s', + 'SEO_ExternalBacklinks' => 'External Backlinks', + 'SEO_ReferrerDomains' => 'Referrer Domains', 'SitesManager_PluginDescription' => 'Websites Management in Piwik: Add a new Website, Edit an existing one, Show the JavaScript code to include on your pages. All the actions are also available through the API.', 'SitesManager_Sites' => 'Websites', 'SitesManager_TrackingTags' => 'Tracking code for %s', diff --git a/plugins/SEO/API.php b/plugins/SEO/API.php index 0cec1ad523..0df9c3b1da 100644 --- a/plugins/SEO/API.php +++ b/plugins/SEO/API.php @@ -36,9 +36,9 @@ class Piwik_SEO_API } /** - * Get rank + * Returns SEO statistics for a URL. * - * @param string $url URL to request Ranks for + * @param string $url URL to request SEO stats for * @return Piwik_DataTable */ public function getRank( $url ) @@ -46,6 +46,8 @@ class Piwik_SEO_API Piwik::checkUserHasSomeViewAccess(); $rank = new Piwik_SEO_RankChecker($url); + $linkToMajestic = Piwik_SEO_MajesticClient::getLinkForUrl($url); + $data = array( 'Google PageRank' => array( 'rank' => $rank->getPageRank(), @@ -72,6 +74,18 @@ class Piwik_SEO_API 'logo' => 'plugins/SEO/images/whois.png', 'id' => 'domain-age', ), + Piwik_Translate('SEO_ExternalBacklinks') => array( + 'rank' => $rank->getExternalBacklinkCount(), + 'logo' => 'plugins/SEO/images/majesticseo.png', + 'logo_link' => $linkToMajestic, + 'id' => 'external-backlinks', + ), + Piwik_Translate('SEO_ReferrerDomains') => array( + 'rank' => $rank->getReferrerDomainCount(), + 'logo' => 'plugins/SEO/images/majesticseo.png', + 'logo_link' => $linkToMajestic, + 'id' => 'referrer-domains', + ), ); // Add DMOZ only if > 0 entries found diff --git a/plugins/SEO/MajesticClient.php b/plugins/SEO/MajesticClient.php new file mode 100644 index 0000000000..61ab4d2d29 --- /dev/null +++ b/plugins/SEO/MajesticClient.php @@ -0,0 +1,95 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + * @category Piwik_Plugins + * @package Piwik_SEO + */ + +/** + * Client for Majestic SEO's HTTP API. + * + * Hides the HTTP request sending logic. + */ +class Piwik_SEO_MajesticClient +{ + const API_BASE = 'http://simpleapi.majesticseo.com/sapi/'; + const API_KEY = 'ETHPYY'; // please only use this key within Piwik + + /** + * Returns a URL that can be used to view all SEO data for a particular website. + * + * @param string $targetSiteUrl The URL of the website for whom SEO stats should be + * accessible for. + * @return string + */ + public static function getLinkForUrl( $targetSiteUrl ) + { + $domain = @parse_url($targetSiteUrl, PHP_URL_HOST); + return "http://www.majesticseo.com/reports/site-explorer/summary/$domain?IndexDataSource=F"; + } + + /** + * Returns backlink statistics including the count of backlinks and count of + * referrer domains (domains with backlinks). + * + * This method issues an HTTP request and waits for it to return. + * + * @param string $siteDomain The domain of the website to get stats for. + * @param int $timeout The number of seconds to wait before aborting + * the HTTP request. + * @return array An array containing the backlink count and referrer + * domain count: + * array( + * 'backlink_count' => X, + * 'referrer_domains_count' => Y + * ) + * If either stat is false, either the API returned an + * error, or the IP was blocked for this request. + */ + public function getBacklinkStats( $siteDomain, $timeout = 300 ) + { + $apiUrl = $this->getApiUrl($method = 'GetBacklinkStats', $args = array( + 'items' => '1', + 'item0' => $siteDomain + )); + $apiResponse = Piwik_Http::sendHttpRequest($apiUrl, $timeout); + + $result = array( + 'backlink_count' => false, + 'referrer_domains_count' => false + ); + + $apiResponse = Piwik_Common::json_decode($apiResponse, $assoc = true); + if (!empty($apiResponse) + && !empty($apiResponse['Data'])) + { + $siteSeoStats = reset($apiResponse['Data']); + + if (isset($siteSeoStats['ExtBackLinks']) + && $siteSeoStats['ExtBackLinks'] !== -1) + { + $result['backlink_count'] = $siteSeoStats['ExtBackLinks']; + } + + if (isset($siteSeoStats['RefDomains']) + && $siteSeoStats['RefDomains'] !== -1) + { + $result['referrer_domains_count'] = $siteSeoStats['RefDomains']; + } + } + + return $result; + } + + private function getApiUrl( $method, $args = array() ) + { + $args['sak'] = self::API_KEY; + + $queryString = http_build_query($args); + return self::API_BASE.$method.'?'.$queryString; + } +} diff --git a/plugins/SEO/RankChecker.php b/plugins/SEO/RankChecker.php index c5a43b2261..da9fa0cf60 100644 --- a/plugins/SEO/RankChecker.php +++ b/plugins/SEO/RankChecker.php @@ -21,6 +21,7 @@ class Piwik_SEO_RankChecker { private $url; + private $majesticInfo = null; public function __construct($url) { @@ -170,6 +171,28 @@ class Piwik_SEO_RankChecker } return false; } + + /** + * Returns the number backlinks that link to the current site. + * + * @return int + */ + public function getExternalBacklinkCount() + { + $majesticInfo = $this->getMajesticInfo(); + return $majesticInfo['backlink_count']; + } + + /** + * Returns the number of referrer domains that link to the current site. + * + * @return int + */ + public function getReferrerDomainCount() + { + $majesticInfo = $this->getMajesticInfo(); + return $majesticInfo['referrer_domains_count']; + } /** * Returns the domain age archive.org lists for the current url @@ -332,4 +355,15 @@ class Piwik_SEO_RankChecker return '7'.$CheckByte.$HashStr; } + + private function getMajesticInfo() + { + if ($this->majesticInfo === null) + { + $client = new Piwik_SEO_MajesticClient(); + $this->majesticInfo = $client->getBacklinkStats($this->url); + } + + return $this->majesticInfo; + } } diff --git a/plugins/SEO/images/majesticseo.png b/plugins/SEO/images/majesticseo.png new file mode 100644 index 0000000000000000000000000000000000000000..a42875c250f7081411bb823bc4fc904b99e3735d GIT binary patch literal 674 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z`&N| z?e4<x9|RZdT|SwCfq}EYBeIx*fm;}a85w5Hkzin8U@!6Xb!ETHEXk^Es(04Ll!1Xs z$<xI##Nu@AWb15EM~SxiJKx;AySY6>FU!xMbNY-2a}}B*x|dF6+`8o>d&G^*=l&nm zBRIm!#F~UQbo5Raxo6;hG{#58a`xoAw!5v94Ogoup5$g`{#?udzGlz-4cDT~PD^c& zoMJeGMPPxHg0g_AK$7>)wB0%4U8yJbIqqX{a?U*>dzZVSnqf_2k?bbRj^!tp-&f*q zU-4Lcp`s(3!dEfzTakJPmIah8ux6iYKH=Yj&o7jJMKmA#YjwhkgY#ZM>37ErlT_(0 zQH^PHo_-Nd(cSd?^Ng_eyw%Qy+HU=48#)ilGq2~orx@^C(ClZDXPROq``vhk85Zep zzh%EEVrwX0IRDt;&mFUh_8p!aFux^1Ch>Z@&T4%Rx&2H2Z1DQHvv;QdP0u0|C;u-G ze7`;P_jN4c?7gtSWYcx^%B@G@jMnnq{n_&1mcflnj)8jvq>t`5@~C)zWFEto1s@;i z{5s=c+RV}WuDyWi6YC-AglWc`mftUb)BkSXqOzX~SI#%qv!w6~NjAwf+%jOuGP!lN zL8{MTg;of&0<((K&W=+T{(dgsrM)1=CwA_d@Qu@EPts7~XpJmkxXHtjCwFw+(<S~< zH!P0p<owCMBbNGf#XW&T_5LOAP5xa~^ANxJ;1|cs><qu)lYBdTlRf_S&N=dM+n* zQsVDAt*l+}`#_XN_?@y-98HBBY6qlQUWPM7?@-nH?{ITnP;fb~gogQnoE?n+m`@9| bJkt-5JI*@ICRvGrfq}u()z4*}Q$iB}ER`Pa literal 0 HcmV?d00001 diff --git a/plugins/SEO/templates/index.tpl b/plugins/SEO/templates/index.tpl index 6abe3cce97..9d7c31602b 100644 --- a/plugins/SEO/templates/index.tpl +++ b/plugins/SEO/templates/index.tpl @@ -23,7 +23,7 @@ <table cellspacing='2' style='margin:auto;line-height:1.5em;padding-top:10px'> {foreach from=$ranks item=rank} <tr> - <td><img style='vertical-align:middle;margin-right:6px;' src='{$rank.logo}' border='0' alt="{$rank.label}"> {$rank.label} + <td>{if !empty($rank.logo_link)}<a href="{$rank.logo_link}" target="_blank">{/if}<img style='vertical-align:middle;margin-right:6px;' src='{$rank.logo}' border='0' alt="{$rank.label}">{if !empty($rank.logo_link)}</a>{/if} {$rank.label} </td><td> <div style='margin-left:15px'> {if isset($rank.rank)}{$rank.rank}{else}-{/if} -- GitLab