From 31f8b9a74af8448ce4c4206c27d0ac7d69ec18e6 Mon Sep 17 00:00:00 2001 From: Stephan Schmitz Date: Sun, 19 Jan 2014 20:09:36 +0100 Subject: [PATCH 01/40] Fix #62: Fix Google+ +1 share count --- SEOstats/Services/Social.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SEOstats/Services/Social.php b/SEOstats/Services/Social.php index aa381183..2d511f3b 100644 --- a/SEOstats/Services/Social.php +++ b/SEOstats/Services/Social.php @@ -8,7 +8,7 @@ * @author Stephan Schmitz * @copyright Copyright (c) 2010 - present Stephan Schmitz * @license http://eyecatchup.mit-license.org/ MIT License - * @updated 2013/12/16 + * @updated 2014/01/19 */ use SEOstats\SEOstats as SEOstats; @@ -36,9 +36,9 @@ public static function getGooglePlusShares($url = false) $url = parent::getUrl($url); $dataUrl = sprintf(Config\Services::GOOGLE_PLUSONE_URL, urlencode($url)); $html = parent::_getPage($dataUrl); - @preg_match_all('#c: (.*?)\.0#si', $html, $matches); + @preg_match_all('/window\.__SSR\s\=\s\{c:\s(\d+?)\./', $html, $match, PREG_SET_ORDER); - return isset($matches[1][0]) ? intval($matches[1][0]) : parent::noDataDefaultValue(); + return (1 === sizeof($match) && 2 === sizeof($match[0])) ? intval($match[0][1]) : parent::noDataDefaultValue(); } /** From d6f8dc189f12801bdc2b5fc9aa58a4f342c76681 Mon Sep 17 00:00:00 2001 From: Stephan Schmitz Date: Sun, 19 Jan 2014 20:20:52 +0100 Subject: [PATCH 02/40] Hello 2014 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d86ce18..a91c7580 100644 --- a/README.md +++ b/README.md @@ -453,6 +453,6 @@ More detailed examples can be found in the `./example` directory. ## License -(c) 2010 - 2013, Stephan Schmitz eyecatchup@gmail.com +(c) 2010 - 2014, Stephan Schmitz eyecatchup@gmail.com License: MIT, http://eyecatchup.mit-license.org URL: https://github.com/eyecatchup/SEOstats From c4d96f8bb40645f21e465bdf79bada711b9c6bb4 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 11:35:34 +0100 Subject: [PATCH 03/40] remove tailing spaces --- SEOstats/Services/3rdparty/GTB_PageRank.php | 122 ++++++++++---------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/SEOstats/Services/3rdparty/GTB_PageRank.php b/SEOstats/Services/3rdparty/GTB_PageRank.php index 7ce901ee..fac57446 100644 --- a/SEOstats/Services/3rdparty/GTB_PageRank.php +++ b/SEOstats/Services/3rdparty/GTB_PageRank.php @@ -15,16 +15,16 @@ interface tbr { // 2 toolbar server hostnames, as found in the toolbar source code. const SERVER_HOSTS = '["toolbarqueries.google.","alt1.toolbarqueries.google."]'; - + //138 toolbar server top level domains, as found in the toolbar source code. const SERVER_TLDS = '["com","ae","com.af","com.ag","com.ai","am","com.ar","as","at","com.au","az","ba","com.bd","be","bg","com.bh","bi","com.bo","com.br","bs","co.bw","com.bz","ca","cd","cg","ch","ci","co.ck","cl","com.co","co.cr","com.cu","cz","de","dj","dk","dm","com.do","com.ec","ee","com.eg","es","com.et","fi","com.fj","fm","fr","co.uk","gg","com.gi","gl","gm","gr","com.gt","com.hk","hn","hr","ht","hu","co.id","ie","co.il","co.im","co.in","is","it","co.je","com.jm","jo","co.jp","co.ke","kg","co.kr","kz","li","lk","co.ls","lt","lu","lv","com.ly","co.ma","mn","ms","com.mt","mu","mw","com.mx","com.my","com.na","com.nf","com.ni","nl","no","com.np","co.nz","com.om","com.pa","com.pe","com.ph","com.pk","pl","pn","com.pr","pt","com.py","com.qa","ro","ru","rw","com.sa","sc","se","com.sg","sh","si","sk","sm","sn","com.sv","co.th","com.tj","tm","to","com.tr","tt","com.tw","com.ua","co.ug","com.uy","co.uz","com.vc","co.ve","vg","co.vi","com.vn","co.za","co.zm"]'; // Service request path as found in the toolbar source code. const SERVER_PATH = "/tbr"; - + // Request query string as found in the toolbar source code. const QUERY_STRING = "?features=Rank&client=navclient-auto&ch=%s&q=info:%s"; - + // Google's client-specific suggestion of a prefered top level domain (as found in tb source code). const SUGGEST_TLD_URL = "https://www.google.com/searchdomaincheck?format=domain&sourceid=navclient-ff"; } @@ -37,14 +37,14 @@ class GTB_PageRank implements tbr, pref { // objects vars public $QUERY_URL, $URL_HASHES, $PREFERED_TLD, $GTB_SUGESSTED_TLD, $GTB_QUERY_STRINGS; - private $GTB_SERVER; + private $GTB_SERVER; /** __construct - Initialize a new object of the class 'GTB_PageRank'. * @access public */ public function __construct($a=NULL) { - if(NULL===$a) { - GTB_Exception::noUrl(); + if(NULL===$a) { + GTB_Exception::noUrl(); } $this->GTB_SERVER = array( // setup the toolbar server vars "host" => GTB_HELPER::_json_decode(tbr::SERVER_HOSTS), @@ -54,8 +54,8 @@ public function __construct($a=NULL) { if (!in_array(self::getPref('tld'), self::getTbrTlds() )) { GTB_Exception::invalidPref('PREFERED_TLD'); } else { - $this->PREFERED_TLD = pref::PREFERED_TLD; - $this->GTB_SUGESSTED_TLD = self::getTbrTldSuggestion(); + $this->PREFERED_TLD = pref::PREFERED_TLD; + $this->GTB_SUGESSTED_TLD = self::getTbrTldSuggestion(); } $init = self::setQueryURL($a); // setup the query url if (TRUE !== $init) { @@ -67,7 +67,7 @@ public function getPageRank() { $host = $this->GTB_SERVER['host'][0]; $tld = (strlen($this->GTB_SUGESSTED_TLD) > 0) ? $this->GTB_SUGESSTED_TLD : $this->PREFERED_TLD; $path = $this->GTB_SERVER['path']; - $tbUrl = 'http://' . $host . $tld . $path; + $tbUrl = 'http://' . $host . $tld . $path; $qStrings = self::getQueryStrings(); if(isset($qStrings[0])) { $PR = self::getToolbarPageRank($tbUrl . $qStrings[0]); @@ -90,17 +90,17 @@ public function getPageRank() { return $PR; } else { return 'Failed to generate a valid hash for PR check.'; - } + } } - } + } } - } + } } } } else { return 'Failed to generate a valid hash for PR check.'; } - } + } public function getToolbarPageRank($toolbarUrl) { $ret = GTB_Request::_get($toolbarUrl); $pagerank = trim(substr($ret, 9)); @@ -109,52 +109,52 @@ public function getToolbarPageRank($toolbarUrl) { /** getQueryURL - Get the object query url. * @access public - */ + */ public function getQueryURL() { return $this->QUERY_URL; } /** getHash - Get a single hash key value string from object's 'URL_HASHES' array. * @access public - */ + */ public function getHash($k) { $array = $this->URL_HASHES; return $array[$k]; - } + } /** getHash - Get the object's 'URL_HASHES' array. * @access public * @return Array returns array of hash-key-pairs for the object url. - */ + */ public function getHashes() { return $this->URL_HASHES; } - + /** getQueryStrings - Get an array of formatted request query strings. * @access public - */ + */ public function getQueryStrings() { return $this->GTB_QUERY_STRINGS; - } + } /** getQueryUrls - Get the object's 'URL_HASHES' array. * @access public * @return Array returns array of all possible url combinations. - */ + */ public function getQueryUrls($limit=NULL) { $a = self::getQueryUrl(); $b = self::getHashes(); $QueryUrls = array(); - $limit = (NULL!==$limit && is_numeric($limit)) ? (int)$limit : 0; + $limit = (NULL!==$limit && is_numeric($limit)) ? (int)$limit : 0; $c = 0; //Foreach hash key value... - foreach ( $b as $k => $v ) { + foreach ( $b as $k => $v ) { //...that is a string with length > 0... if ( is_string($v) AND strlen($v) > 0 ) { - //...format a query string. + //...format a query string. $rs = sprintf(tbr::QUERY_STRING, $v, $a); //Then, foreach available toolbar hostname... foreach ( $this->GTB_SERVER['host'] as $host ) { - //...append any available top level domain... + //...append any available top level domain... foreach ($this->GTB_SERVER['tld'] as $tld) { $tbUri = 'http://'. $host . $tld . tbr::SERVER_PATH . $rs; if ( $c < $limit || $limit == 0 ) { @@ -164,35 +164,35 @@ public function getQueryUrls($limit=NULL) { } } } - } + } return (sizeof($QueryUrls)>0) ? $QueryUrls : FALSE; } /** getTbrServer - Get the Google Toolbar server vars array. * @access public * @return Array Array contains keys: 'host', 'tld', 'path'. - */ + */ public function getTbrServer() { - return $this->GTB_SERVER; - } + return $this->GTB_SERVER; + } /** getTbrHosts - Get all available host names. * @access public * @return Array Array containing all available Toolbar server host names. - */ + */ public function getTbrHosts() { - return $this->GTB_SERVER['host']; + return $this->GTB_SERVER['host']; } /** getTbrTlds - Get all available top level domains. * @access public * @return Array Array containing all available Toolbar server top level domains. - */ + */ public function getTbrTlds() { - return $this->GTB_SERVER['tld']; + return $this->GTB_SERVER['tld']; } /** getTbrTldSuggestion - Get Google's suggestion which top level domain to use. * @access public * @return Array Array containing all available Toolbar server top level domains. - */ + */ public function getTbrTldSuggestion() { $tmp = explode(".google.", GTB_Request::_get(tbr::SUGGEST_TLD_URL)); return isset($tmp[1]) ? trim($tmp[1]) : 'com'; @@ -200,17 +200,17 @@ public function getTbrTldSuggestion() { /** getTbrPath - Get the Google Toolbar Pagerank request path. * @access public * @return String - */ + */ public function getTbrPath() { - return $this->GTB_SERVER['path']; + return $this->GTB_SERVER['path']; } - + public function getPref($k) { if ($k == 'tld') { return pref::PREFERED_TLD; } } - + public function GPR_awesomeHash() { $a = self::getQueryURL(); if (NULL!==$a) { @@ -235,7 +235,7 @@ public function GPR_ieHash() { return GTB_ieHash::ieHash($a); } else { GTB_Exception::noUrl(); } } - + // setQueryURL setter function for the url key. // @return Boolean returns true if input string validated as url, else false. private function setQueryURL($a) { @@ -252,16 +252,16 @@ private function setQueryStrings($a,$b) { $qs = array(); foreach ($b as $k => $v) { //Foreach hash key value... if(is_string($v) && strlen($v) > 0) { - //...format a query string. + //...format a query string. $qs[] = sprintf(tbr::QUERY_STRING, $v, urlencode($a)); } - } + } if (sizeof($qs) > 0) { $this->GTB_QUERY_STRINGS = $qs; - return TRUE; + return TRUE; } return FALSE; - } + } }//eoc /** GTB_awesomeHash Hash a variable-length key into a 32-bit value. @@ -500,10 +500,10 @@ public static function _fmod($x, $y) { $i = floor( $x / $y ); return (int)( $x - $i * $y ); } - + // array_rand_val - Returns $n random values from array $a. public static function array_rand_val($a, $n=1) { - shuffle($a); + shuffle($a); $b = array(); for ($i=0; $i<$n; $i++) { $b[] = $a[$i]; } @@ -512,7 +512,7 @@ public static function array_rand_val($a, $n=1) { // array_rand_val_assoc - Returns $n random values from assoc array $a. public static function array_rand_val_assoc($a, $n=1) { $k = array_keys($a); - shuffle($k); + shuffle($k); $b = array(); for ($i=0; $i<$n; $i++) { $b[$k[$i]] = $a[$k[$i]]; } @@ -520,15 +520,15 @@ public static function array_rand_val_assoc($a, $n=1) { } // use regex to match values from string, if native json_decode is not available. - public static function _json_decode($a) { + public static function _json_decode($a) { if (TRUE !== function_exists('json_decode')) { $m = array(); preg_match_all('#"(.*?)"#si', $a, $m); return (isset($m[1]) && sizeof($m[1])>0) ? $m[1] : FALSE; } else { - return json_decode($a); - } - } + return json_decode($a); + } + } }//eoc /** GTB_Request Connection helper methods. * @package GTB_PageRank @@ -538,7 +538,7 @@ class GTB_Request extends GTB_PageRank { public static function _get($url) { if (!function_exists('curl_init')) { - return self::GetWithoutCurl($url); } + return self::GetWithoutCurl($url); } else { return self::GetWithCurl($url); } } @@ -565,7 +565,7 @@ private static function GetWithCurl($url) { * @package GTB_PageRank * @author Stephan Schmitz */ -class GTB_Exception extends Exception +class GTB_Exception extends Exception { // exitNoUrl - throws an exception and exits, when trying to create a new object on no input. static function noUrl() { @@ -582,23 +582,23 @@ static function tryAgain() { /* DOCUMENTATION AND TEST PROGRAM - Run './GTB_PageRank.php?man' to view the content below! */ -function print_ln() { +function print_ln() { print "--------------------------------------------------------------------------------------------------------\n"; } -function print_cbb($a="") { - if($a!="") { print_n("\nBelow, see the output of `var_dump( $a );` :"); } +function print_cbb($a="") { + if($a!="") { print_n("\nBelow, see the output of `var_dump( $a );` :"); } print "------------------------------------------------------------------------------------- CODEBLOCK BEGIN --\n"; } -function print_cbe() { +function print_cbe() { print "--------------------------------------------------------------------------------------- CODEBLOCK END --\n"; } -function print_n($a="") { +function print_n($a="") { print "$a\n"; } -function print_h($a) { +function print_h($a) { print_n(""); print_n($a); print_ln(); } if ( TRUE !== DISABLE_MAN AND isset($_GET['man']) ) : try { //init a test object $url = (isset($_GET['url']) && !empty($_GET['url'])) ? $_GET['url'] : 'http://www.nahklick.de'; $_url = new GTB_PageRank($url); - //send docs + //send docs if ( !headers_sent() ): header("Content-Type: text/plain;"); else : @@ -635,7 +635,7 @@ function print_h($a) { print_n(" [\"ie\"] => string(n) \"7xxxxxxxxxx\"} # 11-12 chars, first is 7"); print_n(" [\"PREFERED_TLD\"] => string(n) # The Toolbar top level domain *you* prefer."); print_n(" [\"GTB_SUGESSTED_TLD\"] => string(n) # The Toolbar top level domain Google suggests to you."); - print_n(" [\"GTB_QUERY_STRINGS\"] => string(n) # Array of possible path combination, based on different hashes (max. Arraysize: 4)."); + print_n(" [\"GTB_QUERY_STRINGS\"] => string(n) # Array of possible path combination, based on different hashes (max. Arraysize: 4)."); print_n(" [\"GTB_SERVER\"] => array(3) { # Array containing the Toolbar server adress parts."); print_n(" [\"host\"] => array(2) # Array containing valid toolbar host names."); print_n(" [\"tld\"] => array(138) # Array containing valid toolbar top level domains."); @@ -656,7 +656,7 @@ function print_h($a) { print_n("Output:"); print_n("\t".$_url->GPR_ieHash()."\n\t".$_url->GPR_jenkinsHash()."\n\t".$_url->GPR_jenkinsHash2()."\n\t".$_url->GPR_awesomeHash() ); print_cbe(); # END code block - print_n(); + print_n(); print_n("The same could be achieved using the `getHash(key)` method providing one of the key names"); print_n("'awesome', 'jenkins', 'jenkins2', or 'ie'."); print_cbb("\$_url->getHash('awesome')");# BEGIN code block From a32298fb74669fd4e035ec444b2f8c71bd7302b9 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 11:44:30 +0100 Subject: [PATCH 04/40] refactor nested logic to little shorter... --- SEOstats/Services/3rdparty/GTB_PageRank.php | 39 ++++++--------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/SEOstats/Services/3rdparty/GTB_PageRank.php b/SEOstats/Services/3rdparty/GTB_PageRank.php index fac57446..1af7d41f 100644 --- a/SEOstats/Services/3rdparty/GTB_PageRank.php +++ b/SEOstats/Services/3rdparty/GTB_PageRank.php @@ -69,37 +69,18 @@ public function getPageRank() { $path = $this->GTB_SERVER['path']; $tbUrl = 'http://' . $host . $tld . $path; $qStrings = self::getQueryStrings(); - if(isset($qStrings[0])) { - $PR = self::getToolbarPageRank($tbUrl . $qStrings[0]); - if ($PR !== FALSE) { - return $PR; - } else { - if (isset($qStrings[1])) { - $PR = self::getToolbarPageRank($tbUrl . $qStrings[1]); - if ($PR !== FALSE) { - return $PR; - } else { - if (isset($qStrings[2])) { - $PR = self::getToolbarPageRank($tbUrl . $qStrings[2]); - if ($PR !== FALSE) { - return $PR; - } else { - if (isset($qStrings[3])) { - $PR = self::getToolbarPageRank($tbUrl . $qStrings[3]); - if ($PR !== FALSE) { - return $PR; - } else { - return 'Failed to generate a valid hash for PR check.'; - } - } - } - } - } - } + + for ( $i=0; $i < 3; $i++ ) { + if( !isset($qStrings[$i])) { + break; } - } else { - return 'Failed to generate a valid hash for PR check.'; + $PR = self::getToolbarPageRank($tbUrl . $prString); + if ($PR === FALSE) { + continue; + } + return $PR; } + return 'Failed to generate a valid hash for PR check.'; } public function getToolbarPageRank($toolbarUrl) { $ret = GTB_Request::_get($toolbarUrl); From 9a11f3f76ff3a21468420ae02f1fa4714fb8576d Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 11:58:00 +0100 Subject: [PATCH 05/40] easier if structure --- SEOstats/Services/Google.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/SEOstats/Services/Google.php b/SEOstats/Services/Google.php index 95598e6f..e287bb0f 100644 --- a/SEOstats/Services/Google.php +++ b/SEOstats/Services/Google.php @@ -145,19 +145,17 @@ public static function getSerps($query, $maxResults=100, $domain=false) if (!preg_match('#^https?://www.google.com/(?:intl/.+/)?webmasters#', $match[1])) { $c++; $resCnt = ($start * 10) + $c; - if (FALSE !== $domain) { - if (preg_match("#^{$domain}#i", $match[1])) { - $result[] = array( - 'position' => $resCnt, - 'url' => $match[1], - 'headline' => trim(strip_tags($match[2])) - ); - } - } else { + if (FALSE === $domain) { $result[$resCnt] = array( 'url' => $match[1], 'headline' => trim(strip_tags($match[2])) ); + } elseif (preg_match("#^{$domain}#i", $match[1])) { + $result[] = array( + 'position' => $resCnt, + 'url' => $match[1], + 'headline' => trim(strip_tags($match[2])) + ); } } } From 4992d8110edb463d20cd3c73843b0f7e4e8cda36 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 11:59:41 +0100 Subject: [PATCH 06/40] use continue to remove unneeded nest --- SEOstats/Services/Google.php | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/SEOstats/Services/Google.php b/SEOstats/Services/Google.php index e287bb0f..9fbe74a8 100644 --- a/SEOstats/Services/Google.php +++ b/SEOstats/Services/Google.php @@ -141,23 +141,25 @@ public static function getSerps($query, $maxResults=100, $domain=false) if (!empty($matches[1])) { $c = 0; foreach ($matches[1] as $link) { - if (preg_match('#]*href=[\'"]?([^\'" ]+)[\'"]?[^>]*>(.*?)#', $link, $match)) { - if (!preg_match('#^https?://www.google.com/(?:intl/.+/)?webmasters#', $match[1])) { - $c++; - $resCnt = ($start * 10) + $c; - if (FALSE === $domain) { - $result[$resCnt] = array( - 'url' => $match[1], - 'headline' => trim(strip_tags($match[2])) - ); - } elseif (preg_match("#^{$domain}#i", $match[1])) { - $result[] = array( - 'position' => $resCnt, - 'url' => $match[1], - 'headline' => trim(strip_tags($match[2])) - ); - } - } + if ( !preg_match('#]*href=[\'"]?([^\'" ]+)[\'"]?[^>]*>(.*?)#', $link, $match) || + preg_match('#^https?://www.google.com/(?:intl/.+/)?webmasters#', $match[1])) + { + continue; + } + + $c++; + $resCnt = ($start * 10) + $c; + if (FALSE === $domain) { + $result[$resCnt] = array( + 'url' => $match[1], + 'headline' => trim(strip_tags($match[2])) + ); + } elseif (preg_match("#^{$domain}#i", $match[1])) { + $result[] = array( + 'position' => $resCnt, + 'url' => $match[1], + 'headline' => trim(strip_tags($match[2])) + ); } } if ( preg_match('#id="?pnnext"?#', $curledSerp) ) { From 43521a470fe6c0f1600ded53328743706896ed9f Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 12:00:53 +0100 Subject: [PATCH 07/40] comment end of loops --- SEOstats/Services/Google.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/SEOstats/Services/Google.php b/SEOstats/Services/Google.php index 9fbe74a8..975cfa74 100644 --- a/SEOstats/Services/Google.php +++ b/SEOstats/Services/Google.php @@ -161,7 +161,9 @@ public static function getSerps($query, $maxResults=100, $domain=false) 'headline' => trim(strip_tags($match[2])) ); } - } + } // foreach ($matches[1] as $link) + + if ( preg_match('#id="?pnnext"?#', $curledSerp) ) { // Found 'Next'-link on currect page $pages += 1; @@ -179,7 +181,7 @@ public static function getSerps($query, $maxResults=100, $domain=false) if ($start == $maxResults) { $pages -= 1; } - } + } // for ($start=0; $start<$pages; $start++) return $result; } From f49252901375ab78b78535e2e4ac91b3b308bc4d Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 12:02:25 +0100 Subject: [PATCH 08/40] move small else up to first line --- SEOstats/Services/Google.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SEOstats/Services/Google.php b/SEOstats/Services/Google.php index 975cfa74..172dcd27 100644 --- a/SEOstats/Services/Google.php +++ b/SEOstats/Services/Google.php @@ -138,7 +138,10 @@ public static function getSerps($query, $maxResults=100, $domain=false) else { $matches = array(); preg_match_all('#

(.*?)

#', $curledSerp, $matches); - if (!empty($matches[1])) { + if (empty($matches[1])) { + // No [@id="rso"]/li/h3 on currect page + $pages -= 1; + } else { $c = 0; foreach ($matches[1] as $link) { if ( !preg_match('#]*href=[\'"]?([^\'" ]+)[\'"]?[^>]*>(.*?)#', $link, $match) || @@ -173,9 +176,6 @@ public static function getSerps($query, $maxResults=100, $domain=false) // No 'Next'-link on currect page $pages -= 1; } - } else { - // No [@id="rso"]/li/h3 on currect page - $pages -= 1; } } if ($start == $maxResults) { From 7de1e3fd87672c4e3bf8b673c27e62f14efdb540 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 12:06:07 +0100 Subject: [PATCH 09/40] remove unneeded else nest after a possible exit() --- SEOstats/Services/Google.php | 81 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/SEOstats/Services/Google.php b/SEOstats/Services/Google.php index 172dcd27..cfe9cc78 100644 --- a/SEOstats/Services/Google.php +++ b/SEOstats/Services/Google.php @@ -135,49 +135,50 @@ public static function getSerps($query, $maxResults=100, $domain=false) print('Please read: https://support.google.com/websearch/answer/86640'); exit(); } - else { - $matches = array(); - preg_match_all('#

(.*?)

#', $curledSerp, $matches); - if (empty($matches[1])) { - // No [@id="rso"]/li/h3 on currect page - $pages -= 1; - } else { - $c = 0; - foreach ($matches[1] as $link) { - if ( !preg_match('#]*href=[\'"]?([^\'" ]+)[\'"]?[^>]*>(.*?)#', $link, $match) || - preg_match('#^https?://www.google.com/(?:intl/.+/)?webmasters#', $match[1])) - { - continue; - } - - $c++; - $resCnt = ($start * 10) + $c; - if (FALSE === $domain) { - $result[$resCnt] = array( - 'url' => $match[1], - 'headline' => trim(strip_tags($match[2])) - ); - } elseif (preg_match("#^{$domain}#i", $match[1])) { - $result[] = array( - 'position' => $resCnt, - 'url' => $match[1], - 'headline' => trim(strip_tags($match[2])) - ); - } - } // foreach ($matches[1] as $link) - - - if ( preg_match('#id="?pnnext"?#', $curledSerp) ) { - // Found 'Next'-link on currect page - $pages += 1; - $delay += 200000; - usleep($delay); - } else { - // No 'Next'-link on currect page - $pages -= 1; + + + $matches = array(); + preg_match_all('#

(.*?)

#', $curledSerp, $matches); + if (empty($matches[1])) { + // No [@id="rso"]/li/h3 on currect page + $pages -= 1; + } else { + $c = 0; + foreach ($matches[1] as $link) { + if ( !preg_match('#]*href=[\'"]?([^\'" ]+)[\'"]?[^>]*>(.*?)#', $link, $match) || + preg_match('#^https?://www.google.com/(?:intl/.+/)?webmasters#', $match[1])) + { + continue; + } + + $c++; + $resCnt = ($start * 10) + $c; + if (FALSE === $domain) { + $result[$resCnt] = array( + 'url' => $match[1], + 'headline' => trim(strip_tags($match[2])) + ); + } elseif (preg_match("#^{$domain}#i", $match[1])) { + $result[] = array( + 'position' => $resCnt, + 'url' => $match[1], + 'headline' => trim(strip_tags($match[2])) + ); } + } // foreach ($matches[1] as $link) + + + if ( preg_match('#id="?pnnext"?#', $curledSerp) ) { + // Found 'Next'-link on currect page + $pages += 1; + $delay += 200000; + usleep($delay); + } else { + // No 'Next'-link on currect page + $pages -= 1; } } + if ($start == $maxResults) { $pages -= 1; } From 8652d427411934f8a2ae20d450c4b2be80de00c7 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 13:59:55 +0100 Subject: [PATCH 10/40] early return for autoload --- SEOstats/Common/AutoLoader.php | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/SEOstats/Common/AutoLoader.php b/SEOstats/Common/AutoLoader.php index 6a278a28..dbaf2445 100644 --- a/SEOstats/Common/AutoLoader.php +++ b/SEOstats/Common/AutoLoader.php @@ -45,18 +45,21 @@ public function load($class) { $class = ltrim($class, '\\'); - if (strpos($class, $this->namespace) === 0) { - $nsparts = explode('\\', $class); - $class = array_pop($nsparts); - $nsparts[] = ''; - $path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts); - $path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; + if (strpos($class, $this->namespace) !== 0) { + return false; + } + + $nsparts = explode('\\', $class); + $class = array_pop($nsparts); + $nsparts[] = ''; + $path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts); + $path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; - if (file_exists($path)) { - require $path; - return true; - } + if (file_exists($path)) { + require $path; + return true; } + return false; } From c3c9bde2f26c4d7aff9d4829ec64d940dc047148 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 14:01:11 +0100 Subject: [PATCH 11/40] use "is_readable" vs "file_exists" --- SEOstats/Common/AutoLoader.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SEOstats/Common/AutoLoader.php b/SEOstats/Common/AutoLoader.php index dbaf2445..fa1b8a0d 100644 --- a/SEOstats/Common/AutoLoader.php +++ b/SEOstats/Common/AutoLoader.php @@ -55,12 +55,12 @@ public function load($class) $path = $this->path . implode(DIRECTORY_SEPARATOR, $nsparts); $path .= str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; - if (file_exists($path)) { - require $path; - return true; + if (!is_readable($path)) { + return false; } - return false; + require $path; + return true; } /** From 2085e1763c207edcacc427911a62513214125df9 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 14 Feb 2014 14:02:46 +0100 Subject: [PATCH 12/40] use class exists to control that the class was loaded --- SEOstats/Common/AutoLoader.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/SEOstats/Common/AutoLoader.php b/SEOstats/Common/AutoLoader.php index fa1b8a0d..a20eb828 100644 --- a/SEOstats/Common/AutoLoader.php +++ b/SEOstats/Common/AutoLoader.php @@ -41,9 +41,9 @@ public function __construct($namespace, $path) * * @return boolean If the loading was successful */ - public function load($class) + public function load($className) { - $class = ltrim($class, '\\'); + $class = ltrim($className, '\\'); if (strpos($class, $this->namespace) !== 0) { return false; @@ -60,7 +60,8 @@ public function load($class) } require $path; - return true; + + return class_exists($className,false); } /** From 2046455ad52cb4261a2843ac085a84bcc82b6316 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 8 May 2014 22:52:08 +0200 Subject: [PATCH 13/40] fix travis config --- .travis.yml | 17 ++++- composer.json | 74 +++++++++++-------- tests/SEOstatsTest/SEOstatsTest.php | 109 ++++++++++++++++++++++++++++ tests/bootstrap.php | 6 ++ tests/phpunit.xml | 37 ++++++++++ 5 files changed, 213 insertions(+), 30 deletions(-) create mode 100644 tests/SEOstatsTest/SEOstatsTest.php create mode 100644 tests/bootstrap.php create mode 100644 tests/phpunit.xml diff --git a/.travis.yml b/.travis.yml index ce972cb7..03303769 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,22 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - hhvm before_script: - wget http://getcomposer.org/composer.phar - - php composer.phar install --dev \ No newline at end of file + - php composer.phar install --dev + +script: + - phpunit --configuration ./tests/phpunit.xml + - ./vendor/bin/phpcs -n --standard=PSR2 ./SEOstats/ ./tests/ + +notifications: + email: false + +matrix: + fast_finish: true + allow_failures: + - php: 5.6 + - php: hhvm diff --git a/composer.json b/composer.json index da57e17e..01641e43 100644 --- a/composer.json +++ b/composer.json @@ -1,31 +1,47 @@ { - "name": "seostats/seostats", - "type": "library", - "description": "SEOstats is a powerful open source PHP library to request a bunch of SEO relevant metrics for any website.", - "keywords": ["SEO","Pagerank","Backlinks","Google","Mozscape","SEOmoz","Sistrix","Open Site Explorer","SEMRush","Alexa"], - "homepage": "http://github.com/eyecatchup/SEOstats", - "version": "2.5.2", - "license": "MIT", - "authors": [ - { - "name": "Stephan Schmitz", - "email": "eyecatchup@gmail.com", - "homepage": "https://github.com/eyecatchup", - "role": "Creator, Developer, Maintainer" - }, - { - "name": "SEOstats Community", - "homepage": "https://github.com/eyecatchup/seostats/contributors", - "role": "Contributor, Developer" - } - ], - "require": { - "php": ">=5.3", - "ext-curl": "*", - "ext-json": "*" + "name" : "seostats/seostats", + "type" : "library", + "description" : "SEOstats is a powerful open source PHP library to request a bunch of SEO relevant metrics for any website.", + "keywords" : [ + "SEO", + "Pagerank", + "Backlinks", + "Google", + "Mozscape", + "SEOmoz", + "Sistrix", + "Open Site Explorer", + "SEMRush", + "Alexa" + ], + "homepage" : "http://github.com/eyecatchup/SEOstats", + "version" : "2.5.2", + "license" : "MIT", + "authors" : [{ + "name" : "Stephan Schmitz", + "email" : "eyecatchup@gmail.com", + "homepage" : "https://github.com/eyecatchup", + "role" : "Creator, Developer, Maintainer" + }, { + "name" : "SEOstats Community", + "homepage" : "https://github.com/eyecatchup/seostats/contributors", + "role" : "Contributor, Developer" + } + ], + "require" : { + "php" : ">=5.3", + "ext-curl" : "*", + "ext-json" : "*" + }, + "require-dev" : { + "squizlabs/php_codesniffer" : "~1" }, - "autoload": { - "psr-0": { "SEOstats\\": "" }, - "classmap": ["SEOstats/Services/3rdparty"] - } -} + "autoload" : { + "psr-0" : { + "SEOstats\\" : "" + }, + "classmap" : [ + "SEOstats/Services/3rdparty" + ] + } +} \ No newline at end of file diff --git a/tests/SEOstatsTest/SEOstatsTest.php b/tests/SEOstatsTest/SEOstatsTest.php new file mode 100644 index 00000000..10a665fa --- /dev/null +++ b/tests/SEOstatsTest/SEOstatsTest.php @@ -0,0 +1,109 @@ +SUT = new SEOstats(); + } + + public function testAlexa() + { + $this->markTestIncomplete(); + } + + public function testGoogle() + { + $this->markTestIncomplete(); + } + + public function testMozscape() + { + $this->markTestIncomplete(); + } + + public function testOpenSiteExplorer() + { + $this->markTestIncomplete(); + } + + public function testSEMRush() + { + $this->markTestIncomplete(); + } + + public function testSistrix() + { + $this->markTestIncomplete(); + } + + public function testSocial() + { + $this->markTestIncomplete(); + } + + public function testGetLastLoadedHtml() + { + $this->markTestIncomplete(); + } + + public function testGetLastLoadedUrl() + { + $this->markTestIncomplete(); + } + + public function testGetUrl() + { + $this->markTestIncomplete(); + } + + public function testSetUrl() + { + $this->markTestIncomplete(); + } + + public function testGetHost() + { + $this->markTestIncomplete(); + } + + public function testGetDomain() + { + $this->markTestIncomplete(); + } + + public function testGetDOMDocument() + { + $this->markTestIncomplete(); + } + + public function testGetDOMXPath() + { + $this->markTestIncomplete(); + } + + public function testGetPage() + { + $this->markTestIncomplete(); + } + + public function testSetHtml() + { + $this->markTestIncomplete(); + } + + public function testNoDataDefaultValue() + { + $this->markTestIncomplete(); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 00000000..344a1a5a --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,6 @@ +add('SEOstatsTest', __DIR__ . '/SEOstatsTest'); diff --git a/tests/phpunit.xml b/tests/phpunit.xml new file mode 100644 index 00000000..0fc217e0 --- /dev/null +++ b/tests/phpunit.xml @@ -0,0 +1,37 @@ + + + + + + + ./SEOstatsTest + + + + + + performance + + + + + + ../SEOstats + + + + + + + + From e05f995aaad93507aef3c0e36d5ce75f252ff3b4 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Fri, 9 May 2014 14:21:11 +0200 Subject: [PATCH 14/40] add Alexa blank test --- tests/SEOstatsTest/Services/AlexaTest.php | 79 +++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tests/SEOstatsTest/Services/AlexaTest.php diff --git a/tests/SEOstatsTest/Services/AlexaTest.php b/tests/SEOstatsTest/Services/AlexaTest.php new file mode 100644 index 00000000..d2eee87b --- /dev/null +++ b/tests/SEOstatsTest/Services/AlexaTest.php @@ -0,0 +1,79 @@ +SUT = new Alexa(); + } + + public function testGetDailyRank() + { + $this->markTestIncomplete(); + } + + public function testGetWeeklyRank() + { + $this->markTestIncomplete(); + } + + public function testGetMonthlyRank() + { + $this->markTestIncomplete(); + } + + public function testGetGlobalRank() + { + $this->markTestIncomplete(); + } + + public function testSetRankingKeys() + { + $this->markTestIncomplete(); + } + + public function testGetCountryRank() + { + $this->markTestIncomplete(); + } + + public function testGetBacklinkCount() + { + $this->markTestIncomplete(); + } + + public function testGetPageLoadTime() + { + $this->markTestIncomplete(); + } + + public function testGetTrafficGraph() + { + $this->markTestIncomplete(); + } + + public function test_GetXPath() + { + $this->markTestIncomplete(); + } + + public function test_GetAlexaPage() + { + $this->markTestIncomplete(); + } + + public function testRetInt() + { + $this->markTestIncomplete(); + } +} From d890e805c2eaedf4e13360a140c6f910a1e2b40c Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 25 Jun 2014 16:07:55 +0200 Subject: [PATCH 15/40] fix tests on travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 03303769..45f127af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_script: - php composer.phar install --dev script: - - phpunit --configuration ./tests/phpunit.xml + - ./vendor/bin/phpunit ./tests/ - ./vendor/bin/phpcs -n --standard=PSR2 ./SEOstats/ ./tests/ notifications: From 9da1fe42d3c9c4cde4f4f8e48fff820650ff3ed1 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 25 Jun 2014 16:16:42 +0200 Subject: [PATCH 16/40] fix tests --- .travis.yml | 2 +- composer.json | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45f127af..672c8791 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ before_script: script: - ./vendor/bin/phpunit ./tests/ - - ./vendor/bin/phpcs -n --standard=PSR2 ./SEOstats/ ./tests/ +# - ./vendor/bin/phpcs -n --standard=PSR2 ./SEOstats/ ./tests/ notifications: email: false diff --git a/composer.json b/composer.json index 01641e43..44162ede 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ "ext-json" : "*" }, "require-dev" : { - "squizlabs/php_codesniffer" : "~1" + "squizlabs/php_codesniffer" : "~1", + "phpunit/phpunit" : ">=3.7,<4" }, "autoload" : { "psr-0" : { @@ -44,4 +45,4 @@ "SEOstats/Services/3rdparty" ] } -} \ No newline at end of file +} From 3e8e841c2599833feccd27b965b99e99a4d0f369 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 25 Jun 2014 22:00:01 +0200 Subject: [PATCH 17/40] Finish Alexa tests & fix test codecoverge and send to scrutinizer --- .scrutinizer.yml | 6 + .travis.yml | 6 +- SEOstats/Services/Alexa.php | 10 +- composer.json | 3 +- tests/SEOstatsTest/Services/AlexaTest.php | 334 +- .../alexa-siteinfo-2013-getDailyRank-1.html | 67 + .../alexa-siteinfo-2013-getDailyRank-2.html | 40 + .../alexa-siteinfo-2013-getMonthlyRank-1.html | 48 + .../alexa-siteinfo-2013-getMonthlyRank-2.html | 40 + .../alexa-siteinfo-2013-getWeeklyRank-1.html | 57 + .../alexa-siteinfo-2013-getWeeklyRank-2.html | 40 + .../alexa-siteinfo-2013-setRankingKeys-2.html | 40 + .../alexa-siteinfo-2013-setRankingKeys-3.html | 48 + .../alexa-siteinfo-2013-setRankingKeys-4.html | 57 + .../alexa-siteinfo-2013-setRankingKeys-5.html | 67 + .../Services/_assert/alexa-siteinfo-2013.html | 2437 ++++++ .../Services/_assert/alexa-siteinfo-2014.html | 6718 +++++++++++++++++ tests/bootstrap.php | 2 + tests/phpunit.xml | 1 + 19 files changed, 9987 insertions(+), 34 deletions(-) create mode 100644 .scrutinizer.yml create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-1.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-2.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-1.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-2.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-1.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-2.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-2.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-3.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-4.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-5.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013.html create mode 100644 tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2014.html diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 00000000..39c28269 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,6 @@ +imports: + - php + +tools: + external_code_coverage: + timeout: 2100 diff --git a/.travis.yml b/.travis.yml index 672c8791..c7870549 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,9 +11,13 @@ before_script: - php composer.phar install --dev script: - - ./vendor/bin/phpunit ./tests/ + - cd ./tests/ + - ../vendor/bin/phpunit # - ./vendor/bin/phpcs -n --standard=PSR2 ./SEOstats/ ./tests/ +after_script: + - ../vendor/bin/ocular code-coverage:upload --format=php-clover ../build/logs/clover.xml + notifications: email: false diff --git a/SEOstats/Services/Alexa.php b/SEOstats/Services/Alexa.php index 8aef8a2f..49b7c4c8 100644 --- a/SEOstats/Services/Alexa.php +++ b/SEOstats/Services/Alexa.php @@ -237,13 +237,13 @@ public static function getTrafficGraph($type = 1, $url = false, $w = 660, $h = 3 /** * @return DOMXPath */ - private static function _getXPath($url) { + protected static function _getXPath($url) { $url = parent::getUrl($url); if (parent::getLastLoadedUrl() == $url && self::$_xpath) { return self::$_xpath; } - $html = self::_getAlexaPage($url); + $html = static::_getAlexaPage($url); $doc = parent::_getDOMDocument($html); $xpath = parent::_getDOMXPath($doc); @@ -252,15 +252,15 @@ private static function _getXPath($url) { return $xpath; } - private static function _getAlexaPage($url) + protected static function _getAlexaPage($url) { $domain = Helper\Url::parseHost($url); $dataUrl = sprintf(Config\Services::ALEXA_SITEINFO_URL, $domain); - $html = parent::_getPage($dataUrl); + $html = static::_getPage($dataUrl); return $html; } - private static function retInt($str) + protected static function retInt($str) { $strim = trim(str_replace(',', '', $str)); $intStr = 0 < strlen($strim) ? $strim : '0'; diff --git a/composer.json b/composer.json index 44162ede..ef13abdb 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,8 @@ }, "require-dev" : { "squizlabs/php_codesniffer" : "~1", - "phpunit/phpunit" : ">=3.7,<4" + "phpunit/phpunit" : ">=3.7,<4", + "scrutinizer/ocular" : "~1" }, "autoload" : { "psr-0" : { diff --git a/tests/SEOstatsTest/Services/AlexaTest.php b/tests/SEOstatsTest/Services/AlexaTest.php index d2eee87b..bb8b2e39 100644 --- a/tests/SEOstatsTest/Services/AlexaTest.php +++ b/tests/SEOstatsTest/Services/AlexaTest.php @@ -1,79 +1,359 @@ SUT = new Alexa(); + $this->reflection = array(); + + $this->url = 'http://github.com'; + $this->SUT = new \SEOstats\Services\Alexa(); + $this->SUT->setUrl($this->url); + } - public function testGetDailyRank() + /** + * + * @dataProvider providerTestSiteinfoMethodWithDiffrentVersion + */ + public function testSiteinfoMethodWithDiffrentVersion ($method, $version, $type) { - $this->markTestIncomplete(); + $this->mockAlexa($method); + $this->mockGetAlexaPage ($version); + $SUT = $this->mockedSUT; + $result = call_user_func(get_class($SUT) . '::' . $method, $this->url); + + $noDataDefault = $this->helperMakeAccessable($SUT, 'noDataDefaultValue', array()); + + if ($type){ + if (is_array($type)) { + foreach ($type as $arrayKey=>$arrayValueType) { + $this->assertArrayHasKey($arrayKey, $result); + $this->assertInternalType($arrayValueType, $result[$arrayKey]); + } + } elseif (is_string($type)) { + $this->assertInternalType($type, $result); + } + $this->assertNotEquals($noDataDefault, $result); + } + elseif (null === $type) { + $this->assertEquals($noDataDefault, $result); + } else { + $this->markTestSkipped(sprintf('methode %s returns an invalid result check source data version', $method)); + } } - public function testGetWeeklyRank() + /** + * + * @dataProvider providerTestGetTrafficGraph + */ + public function testGetTrafficGraph($url, $paramsArray, $assertResult) { - $this->markTestIncomplete(); + if ($assertResult instanceof \Exception) { + $this->setExpectedException(get_class($assertResult), $assertResult->getMessage()); + } + $result = call_user_func_array(array($this->SUT, 'getTrafficGraph'), $paramsArray); + + if (! $assertResult instanceof \Exception) { + $this->assertInternalType('string', $result); + $this->assertEquals($assertResult, $result); + } } - public function testGetMonthlyRank() + public function testGetXPath() { - $this->markTestIncomplete(); + $urlList = array( + $this->url, + 'http://www.google.de' + ); + + $reflectionMethod = $this->helperMakeAccessable($this->SUT,'_getXPath'); + $reflectionProperty = $this->helperMakeAccessable($this->SUT,'_lastLoadedUrl'); + + $result1 = $result2 = null; + + $SUT = $this->SUT; + + foreach ($urlList as $url) { + // first call + $result1 = $reflectionMethod->invoke($this->SUT, $url); + $this->assertInternalType('object', $result1); + $this->assertInstanceOf('DOMXPath', $result1); + $this->assertNotSame($result1, $result2); + + + $reflectionProperty->setValue($this->SUT, $url); + + + // secound call + $result2 = $reflectionMethod->invoke($this->SUT, $url); + $this->assertInternalType('object', $result2); + $this->assertInstanceOf('DOMXPath', $result2); + $this->assertSame($result1, $result2); + } } - public function testGetGlobalRank() + public function testGetAlexaPage() { - $this->markTestIncomplete(); + $this->mockAlexa('_getAlexaPage'); + $this->mockGetPage(); + $reflectionMethod = $this->helperMakeAccessable($this->mockedSUT,'_getAlexaPage'); + + $result = $reflectionMethod->invoke($this->mockedSUT, $this->url); + $this->assertInternalType('string', $result); + + $this->assertRegExp('#markTestIncomplete(); + $reflectionMethod = $this->helperMakeAccessable($this->SUT,'retInt'); + + $result = $reflectionMethod->invoke($this->SUT, $string); + $this->assertInternalType('integer', $result); + $this->assertSame($assert, $result); } - public function testGetCountryRank() + public function providerTestRetInt() { - $this->markTestIncomplete(); + return array( + array('1234',1234), + array('12,34',1234), + array(' 1234 ',1234), + array(' 1,2,3,4 ',1234), + array('',0), + array(' , , , , ',0), + array(' ',0), + array(',,,,,',0), + ); } - public function testGetBacklinkCount() + public function providerTestGetTrafficGraph() { - $this->markTestIncomplete(); + // $type = 1, $url = false, $w = 660, $h = 330, $period = 1, $html = true + $result = array(); + $result[]= array( + 'http://github.com', + array(1, false, 660, 330, 1, true), + sprintf( + 'Alexa Statistics Graph for %s', + sprintf(\SEOstats\Config\Services::ALEXA_GRAPH_URL, 't', 660, 330, 1, 'github.com'), + 660, 330, 'github.com' + ) + ); + + $paramsArray = array(); + $paramsArray[] = array( + 'width'=>660, + 'height'=>330, + 'periode'=>1, + 'typeIndex'=>1, + 'typeChar'=>'t', + 'url'=>'http://github.com', + 'domain'=>'github.com', + ); + + $paramsArray[] = array_merge($paramsArray[0], array('url'=>'http://github.com','domain'=>'github.com')); + $paramsArray[] = array_merge($paramsArray[0], array('width'=>880,'height'=>440)); + $paramsArray[] = array_merge($paramsArray[0], array('periode'=>2)); + + + $typeArray = array(0=>'',1=>'t',2=>'p',3=>'u',4=>'s',5=>'b',6=>'q',1337=>''); + + foreach ($typeArray as $typeIndex=>$typeChar) { + $paramsArray[] = array_merge($paramsArray[0], array('typeIndex'=>$typeIndex,'typeChar'=>$typeChar)); + } + + foreach ($paramsArray as $params) { + + $assertResult = $params['typeChar'] !== '' + ? sprintf(\SEOstats\Config\Services::ALEXA_GRAPH_URL, $params['typeChar'], $params['width'], $params['height'], $params['periode'], $params['domain']) + : new \Exception("Undefined variable: gtype"); + + $result[]= array( + $params['url'], + array($params['typeIndex'], $params['url'], $params['width'], $params['height'], $params['periode'], false), + $assertResult + ); + } + + return $result; } - public function testGetPageLoadTime() + public function providerTestSiteinfoMethodWithDiffrentVersion() { - $this->markTestIncomplete(); + $result = array(); + $methodList = array( + 'getPageLoadTime'=>'string', + 'getBacklinkCount'=>'integer', + 'getCountryRank'=>array('rank'=>'integer','country'=>'string'), + 'getGlobalRank'=>'integer', + 'getQuarterRank'=>'integer', + + 'getMonthlyRank'=>array('integer', null), + 'getMonthRank'=>'integer', + + 'getWeeklyRank'=>array('integer', null), + 'getWeekRank'=>'integer', + + 'getDailyRank'=>array('integer', null), + ); + + $versionList = array( + array('2013',true), + array('2014',null), + array('2014',false) # new version currently not supported + ); + + foreach ($versionList as $version) { + foreach ($methodList as $methodName=>$methodeAssertResultType) { + $versionArray = $this->getStandardVersions($version[0], $methodName); + $iVersion = 0; + foreach($versionArray as $versionSub) { + $assertResult = $methodeAssertResultType; + + if (is_array($methodeAssertResultType) && array_key_exists(0, $methodeAssertResultType)) { + if ($version[0] == $versionSub) { + $assertResult = $methodeAssertResultType[0]; + } else { + $versionIndex = explode('-',$versionSub); + $assertResult = $methodeAssertResultType[ $versionIndex[2] - 1]; + } + } + + $result[]= array( + $methodName, + $versionSub, + $version[1] ? $assertResult : $version[1] + ); + } + } + } + + return $result; } - public function testGetTrafficGraph() + protected function mockAlexa($method, $vars=array()) { - $this->markTestIncomplete(); + + $methods = array(); + switch ($method) { + case '_getXPath': + $methods = array('_getAlexaPage','_getPage'); + break; + case '_getAlexaPage': + $methods = array('_getPage'); + break; + default: + $methods = array('_getAlexaPage','_getPage'); + break; + } + + $this->mockedSUT = $this->getMock('\SEOstats\Services\Alexa', $methods); + $this->mockedSUT->setUrl(array_key_exists('url',$vars) ? $vars['url'] : $this->url); } - public function test_GetXPath() + protected function mockGetPage() { - $this->markTestIncomplete(); + $standardFile = sprintf('%s/_assert/alexa-siteinfo-%s.html', __DIR__, 2013); + + $this->mockedSUT->staticExpects($this->any()) + ->method('_getPage') + ->will($this->returnValue(file_get_contents($standardFile))); } - public function test_GetAlexaPage() + protected function mockGetAlexaPage ($version, $calledTest = null) { - $this->markTestIncomplete(); + $standardFile = sprintf('%s/_assert/alexa-siteinfo-%s.html', __DIR__, $version); + $this->mockedSUT->staticExpects($this->any()) + ->method('_getAlexaPage') + ->will($this->returnValue(file_get_contents($standardFile))); } - public function testRetInt() + protected function getStandardVersions ($version, $methode) { - $this->markTestIncomplete(); + $filePattern = 'alexa-siteinfo-%s-%s-%s.html'; + + $methodeFile = __DIR__ . '/_assert/' . sprintf($filePattern, $version, $methode, 1); + + + $result= array($version); + if (! file_exists($methodeFile)) { + return array($version); + } + + $fileList = new \DirectoryIterator(__DIR__ . '/_assert/'); + $regexp = '#' . sprintf($filePattern, $version, $methode, '\d+') . '$#'; + $filtertList = new \RegexIterator($fileList, $regexp); + + $regexp = '#alexa-siteinfo-([^.]+).html$#'; + foreach ($filtertList as $file) { + preg_match($regexp, $file, $matches); + $result[] = $matches[1]; + } + return $result; + } + + protected function helperMakeAccessable ($object, $propertyOrMethod, $value = null) + { + $objectClass = get_class($object); + if (!isset($this->reflection[$objectClass])) { + $this->reflection[$objectClass] = new ReflectionClass($object); + } + $reflection = $this->reflection[$objectClass]; + $isMethod = $reflection->hasMethod($propertyOrMethod); + + if ($isMethod) { + $reflectionSub = $reflection->getMethod($propertyOrMethod); + } else { + $reflectionSub = $reflection->getProperty($propertyOrMethod); + } + + $reflectionSub->setAccessible(true); + + if (!is_null($value)) { + if ($isMethod) { + return $reflectionSub->invokeArgs($object, $value); + } else { + $reflectionSub->setValue($object, $value); + } + } + + return $reflectionSub; } } diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-1.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-1.html new file mode 100644 index 00000000..03f9e578 --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-1.html @@ -0,0 +1,67 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
Yesterday1 +0
7 day1 +0
1 month1 +-1 Change in Traffic Rank over the trailing 1 month period (A negative change means the site is getting more popular)
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-2.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-2.html new file mode 100644 index 00000000..32ef387f --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-2.html @@ -0,0 +1,40 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-1.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-1.html new file mode 100644 index 00000000..c68deb87 --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-1.html @@ -0,0 +1,48 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
1 month1 +-1 Change in Traffic Rank over the trailing 1 month period (A negative change means the site is getting more popular)
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-2.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-2.html new file mode 100644 index 00000000..32ef387f --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-2.html @@ -0,0 +1,40 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-1.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-1.html new file mode 100644 index 00000000..3b211bff --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-1.html @@ -0,0 +1,57 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
7 day1 +0
1 month1 +-1 Change in Traffic Rank over the trailing 1 month period (A negative change means the site is getting more popular)
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-2.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-2.html new file mode 100644 index 00000000..32ef387f --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-2.html @@ -0,0 +1,40 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-2.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-2.html new file mode 100644 index 00000000..32ef387f --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-2.html @@ -0,0 +1,40 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-3.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-3.html new file mode 100644 index 00000000..c68deb87 --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-3.html @@ -0,0 +1,48 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
1 month1 +-1 Change in Traffic Rank over the trailing 1 month period (A negative change means the site is getting more popular)
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-4.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-4.html new file mode 100644 index 00000000..3b211bff --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-4.html @@ -0,0 +1,57 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
7 day1 +0
1 month1 +-1 Change in Traffic Rank over the trailing 1 month period (A negative change means the site is getting more popular)
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-5.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-5.html new file mode 100644 index 00000000..03f9e578 --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-5.html @@ -0,0 +1,67 @@ + + + + + +Google.com Site Info + + + + +
+
+

Traffic rank for google.com:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Traffic RankChange
Yesterday1 +0
7 day1 +0
1 month1 +-1 Change in Traffic Rank over the trailing 1 month period (A negative change means the site is getting more popular)
3 month2 ++1 Change in Traffic Rank over the trailing 3 month period (A positive change means the site is getting less popular)
+
+
+ + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013.html new file mode 100644 index 00000000..f8a293f7 --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013.html @@ -0,0 +1,2437 @@ + + + + + + + + + + + + + +Google.com Site Info + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+ + + +
+

google.com

+Google +
+
+ + +
+Add to Comparison +
+ + +  + + +
+ +
+

Sign up to access comparisons feature.

+
+

Easily compare sites on traffic, engagement, reputation and demographics metrics and see who is winning.


+

Features

+
    +
  • - Compare up to 10 sites.
  • +
  • - Create unlimited lists
  • +
  • - Global Rank comparisons
  • +
  • - Traffic, engagement, reputation
      and demographics comparisons.
      (PRO only) +
+

+

Sign up for a FREE account and start comparing sites.

+Create an account +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Customize your site listing with your logo, plus add links back to your +site and much more! Enhanced Site Listings are just one of the features +you get with an Alexa PRO subscription. Learn +more about Enhanced Site Listings. +
+
+ +

I want an Alexa PRO subscription.

+ +
+ +
+

I have an Alexa PRO subscription.

+ +Sign In + +
+
+
+
+ +
+
+
+
+ +

How popular is google.com?

+

+
+ + +
+

+Alexa Traffic Ranks
+The global and country traffic ranks show how popular a site is relative to other sites. +

+ +

+Unique Visitors and Pageviews
+The number of people who visit this site and the number of pages they view. +Site owners who install the Alexa Certify Code on their website can choose +to display their Certified Metrics, such as Monthly Unique Visitors and +Pageviews, if they wish. Coming soon, estimated metrics will be displayed +for many sites if Certified Metrics are not available. +

+ +
+
+
+
+
+
+ +
+

+Alexa Traffic Ranks +

+

How is this site ranked relative to other sites?

+
+
+ +
+
+ +
+ + +

Global Rank + + + +Alexa Traffic Rank
An estimate of +this site's popularity.

The rank is calculated using a combination of average daily visitors to +this site and pageviews on this site over the past 3 months. The site with the highest combination +of visitors and pageviews is ranked #1.

Updated Daily
+ +
+

+
+Global rank icon2 +1 +
+ +
    +
  • -1%
  • +
+
+
+
+
+
+ + +

Rank in United States + + + +Traffic Rank in Country
An estimate of this site's popularity in a specific country.

+The rank by country is calculated using a combination of average daily visitors +to this site and pageviews on this site from users from that country over the +past month. The site with the highest combination of visitors and pageviews +is ranked #1 in that country.

Updated Daily
+ +
+

+
+United States Flag1 +  +
+ +
    +
  • %
  • +
+
+
+
+
+
+
+
+
+ +Did you know? You can get the most accurate rank possible by certifying your site's metrics. +Find out how. + +
+
+
+
+
+
+
+ +

How engaged are visitors to google.com?

+

+
+ + +
+

+How engaged are visitors to this site?
+Engagement metrics help you understand how interested a site's visitors are with the site's content. The metrics are updated daily based on the trailing 3 months. +

+

+Bounce Rate (%)
+Percentage of visits to the site that consist of a single pageview. +

+

+Daily Pageviews per Visitor
+Estimated daily unique pageviews per visitor on the site. +

+

+Daily Time on Site
+Estimated daily time on site (mm:ss) per visitor to the site. +

+
+
+
+
+
+
+ + + +

Bounce Rate

+
+18.00% +7.00% +
+ +
    +
  • 7%
  • +
+
+
+
+
+ + + +

Daily Pageviews per Visitor

+
+16.89 +5.23% +
+ +
    +
  • 5.23%
  • +
+
+
+
+
+ + + +

Daily Time on Site

+
+14:53 +4.00% +
+ +
    +
  • -4%
  • +
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +

Who visits google.com?

+

+
+ + +
+

+Audience Demographics
+The audience demographics data comes from voluntary demographics information submitted by people in our global traffic panel. The data is for the past 12 months, updated monthly. +Learn more +

+

The demographics data consists of:

+

+

+

+

+Audience Geography
+The audience geography data describes where visitors to this site over the past month are located, and how the site is ranked in popular countries. If a country is not listed, it is because Alexa does not have enough data for this site to rank/measure the site's popularity among that country's online population. These metrics are updated monthly. +

+
+
+
+
+
+
+

+Audience Demographics +

+

How similar is this site's audience to the general internet population?

+
+
+
+ +
+
+Gender +
+
+ +Male + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among Males is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+ +Female + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among Females is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+
+ +
+
+Education +
+
+ +No College + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people who did not go to college is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+ +Some College + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people some college education is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+ +Graduate School + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people who went to graduate school is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+ +College + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people who went to college is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+
+ +
+
+Browsing Location +
+
+ +Home + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people browsing from home is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+ +School + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, people browsing from school are under-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+ +Work + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people browsing from work is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+
+
+
+Subscribe to Alexa Pro to view all demographics including age, income, ethnicity and children. +View More +
+
+ + +  + + +
+ +
+

Subscribe to view all demographics

+
+

Gain access to:

+
    +
  • - Age, income, children, ethnicity
      in additon to gender, education and browsing location.
  • +
  • - Comparisons of website demographics
  • +
+
+
+

Subscribe to Alexa Pro Insight Plan to
view all demographics.

+Subscribe +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+
+
+

+Audience Geography +

+

Where are this site's visitors located?

+
+
+ +
+

Visitors by Country

+
+

You need Flash 8 to view the map.

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CountryPercent of VisitorsRank in Country
United States Flag  United States 30.2% 1
India Flag  India 8.9% 1
Brazil Flag  Brazil 3.4% 3
Russia Flag  Russia 3.3% 4
United Kingdom Flag  United Kingdom 2.8% 2
Japan Flag  Japan 2.6% 5
Iran Flag  Iran 2.4% 1
Germany Flag  Germany 2.4% 4
Indonesia Flag  Indonesia 2.4% 1
France Flag  France 2.2% 2
+
+
+
+
+
+ + +
+
+
+
+ +

What sites link to google.com?

+

+
+ + +
+

The "Sites Linking In" count shows the number of sites that Alexa found that link to this site. +For more information please see this explanation of +how Alexa determines the number of sites linking in.

+

The complete list of sites linking to this site is available to Alexa Pro subscribers.

+
+
+
+
+
+
+
+
Total Sites Linking In
+4,272,563 +
+ + + + + + + + + + + + + + + + + + + + +
SiteGlobal RankPage
1. amazon.com 6 amazon.com/-/e/B001JS4V8E
2. twitter.com 11 blog.de.twitter.com/2010/04/wir-wachse...
3. linkedin.com 14 apply.linkedin.com/documents/libraries...
4. google.co.in 13 bks0.books.google.co.in
5. google.fr 35 adwords.google.fr/support/aw/bin/searc...
+
+Subscribe to Alexa Pro to view all 4,272,563 sites linking in. +View More +
+
+ + +  + + +
+ +
+

Subscribe to view all sites linking in

+
+

With any Alexa Pro plan you can:

+
    +
  • - Get the full list of sites linking in for any site
  • +
  • - Benchmark your link-building efforts
  • +
  • - See who is linking to your competitors
  • +
+
+

Subscribe to Alexa Pro to
view all sites linking in

+Subscribe +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ +

+Where do visitors go on google.com? +

+

+
+ + +
+

The table shows the top subdomains for this site ordered by the percentage of visitors +that visited the subdomain over a month. Note that the percentages can add up to more than +100% because a visitor can visit multiple subdomains during the month.

+

Updated Monthly.

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SubdomainPercent of Visitors
google.com 72.24%
mail.google.com 48.66%
accounts.google.com 34.25%
docs.google.com 12.65%
plus.google.com 10.59%
drive.google.com 6.65%
translate.google.com 6.23%
maps.google.com 5.57%
support.google.com 5.30%
adwords.google.com 3.49%
play.google.com 2.98%
news.google.com 2.27%
developers.google.com 1.06%
sites.google.com 1.05%
productforums.google.com 1.01%
code.google.com 0.96%
url.google.com 0.76%
feedburner.google.com 0.76%
groups.google.com 0.71%
ejabat.google.com 0.49%
admin.google.com 0.37%
picasaweb.google.com 0.35%
encrypted.google.com 0.18%
prod.google.com 0.02%
+
+
+
+
+
+
+
+ +

How fast does google.com load?

+

+
+ + +
+

The reported load time for a website is the median time it takes to load +pages from that site in a real users' web browsers.

+

Alexa takes the median of all the page load times we observe for a site +and then compares that to the same figure for all other sites. For example, +a site in the 98th percentile (Very Fast) has a median load time faster than +98% of all measured sites, while a site in the 2nd percentile (Very Slow) +loads more quickly than only 2% of all sites and is slower than 97% of all sites.

+

The load time of an individual page is how long it takes for the DOM - +the structure of the page - to be loaded. This time doesn't include the time +to load all images and stylesheets, for example.

+

The load time metric is updated monthly.

+
+
+
+
+

Average (1.439 Seconds), 52% of sites are slower.

+
+
+
+
+
+
+
+ +

Where can I find more info about google.com?

+

+
+ + +
+

+Site Description
+A short description of the site. +

+

+Contact
+How to contact the owner of the site. +

+
+
+
+
+
+
+ +

Site Description

+

Enables users to search the world's information, including webpages, images, and videos. Offers unique features and search technology.

+ +
+ +

Contact

+
unlisted
dns-admin [at] google.com

+
+
+ +
+
+
+
+
+
+
+ +

How can I get deeper insight?

+

By subscribing to Alexa Pro you can gain deeper insight on your traffic and search engine optimizations.

+
+ + +
+

Alexa Pro subscriptions for site owners give you metrics, +tools and analysis to increase your web traffic and succeed online. +We give you accurate traffic metrics, automated site scans, lists of sites linking in, +SEO recommendations, and much more.

+
+
+
+
+
+
    +
  • +

    SEO Score

    +

    Alexa will audit your site regularly and give you reports with actionable recommendations.

    +
  • +
  • +

    Accurate Metrics

    +

    Get Alexa Traffic Rank and other key performance metrics, certified for accuracy by Alexa.

    +
  • +
  • +

    Uptime Monitor

    +

    Know what percent of the time your site is up, and more importantly when it was down.

    +
  • +
+ +
+
+
+ + + +
+
+ +
+ +
+

Try Alexa PRO Basic: One Month Free

+ +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2014.html b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2014.html new file mode 100644 index 00000000..18f7e842 --- /dev/null +++ b/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2014.html @@ -0,0 +1,6718 @@ + + + + + + + + + + + +github.com Site Overview + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+
+
+

Competitive Intelligence

+
+
+
+ +
+
+ +
+
+

Site Overview

+
+
+
+ + + +
+
+ +

+ +
+
+ +Is this your site? +Certify your site's metrics. + +
+
+
+
+
+
+ +
+ + + +
+
+
+
+

Certified Site Metrics are metrics that are directly-measured from the website +instead of estimated. The website owner has installed an Alexa Certify Code on +the pages of their site and chosen to show the metrics publicly. +

+
For the website owner Certified Metrics provide:
+
    +
  • A more accurate Alexa Rank
  • +
  • A private metrics Dashboard for On-Site Analytics
  • +
  • The ability to publish unique visitor and pageview counts if desired
  • +
+

Certified Metrics are available with all Alexa Pro plans.

+ +
+
+

Not all websites implement our on-site analytics and publish the results. +For these sites, we show estimated metrics based on traffic patterns across the web as a whole. +We identify these patterns by looking at the activity of millions of web users throughout the world, +and using data normalization to correct for any biases.

+

The more traffic a site gets, the more data we have to calculate estimated metrics. +Estimates are more reliable the closer a site is to being ranked #1. Global traffic ranks of 100,000+ +are subject to large fluctuations and should be considered rough estimates.

+

If a site has Certified Metrics instead of estimated, that means its owner has installed code allowing us to directly measure their traffic. +These metrics have a greater level of accuracy, no matter what the ranking.

+

Learn more about Alexa's Data

+
+ +

How popular is github.com?

+
+
+ +
+

+Alexa Traffic Ranks +

+

How is this site ranked relative to other sites?

+
+
+ +
+
+ +
+ + +

Global Rank + + + +Alexa Traffic Rank
An estimate of +this site's popularity.

The rank is calculated using a combination of average daily visitors to +this site and pageviews on this site over the past 3 months. The site with the highest combination +of visitors and pageviews is ranked #1.

Updated Daily
+ +
+

+
+Global rank icon178 +6 +
+ +
    +
  • -6%
  • +
+
+
+
+
+
+ + +

Rank in United States + + + +Traffic Rank in Country
An estimate of this site's popularity in a specific country.

+The rank by country is calculated using a combination of average daily visitors +to this site and pageviews on this site from users from that country over the +past month. The site with the highest combination of visitors and pageviews +is ranked #1 in that country.

Updated Daily
+ +
+

+
+United States Flag197 +  +
+ +
    +
  • %
  • +
+
+
+
+
+ +
+
+
+ +
+
+

+Alexa Traffic Ranks
+The global and country traffic ranks show how popular a site is relative to other sites. +

+ +

+Unique Visitors and Pageviews
+The number of people who visit this site and the number of pages they view. +Site owners who install the Alexa Certify Code on their website can choose +to display their Certified Metrics, such as Monthly Unique Visitors and +Pageviews, if they wish. Coming soon, estimated metrics will be displayed +for many sites if Certified Metrics are not available. +

+ +
+

How engaged are visitors to github.com?

+
+ + + +

Bounce Rate

+
+42.60% +3.00% +
+ +
    +
  • -3%
  • +
+
+
+
+
+ + + +

Daily Pageviews per Visitor

+
+5.96 +8.60% +
+ +
    +
  • 8.6%
  • +
+
+
+
+
+ + + +

Daily Time on Site

+
+5:39 +7.00% +
+ +
    +
  • 7%
  • +
+
+
+
+
+
+
+
+
+

+How engaged are visitors to this site?
+Engagement metrics help you understand how interested a site's visitors are with the site's content. The metrics are updated daily based on the trailing 3 months. +

+

+Bounce Rate (%)
+Percentage of visits to the site that consist of a single pageview. +

+

+Daily Pageviews per Visitor
+Estimated daily unique pageviews per visitor on the site. +

+

+Daily Time on Site
+Estimated daily time on site (mm:ss) per visitor to the site. +

+
+ +

Who visits github.com?

+
+
+

+Audience Demographics +

+

How similar is this site's audience to the general internet population?

+
+
+
+ +
+
+Gender +
+
+ +Male + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, Males are over-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+ +Female + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, Females are under-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+
+ +
+
+Education +
+
+ +No College + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, people who did not go to college are over-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+ +Some College + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, people with some college education are over-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+ +Graduate School + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people who went to graduate school is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+ +College + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, people who went to college are under-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+
+ +
+
+Browsing Location +
+
+ +Home + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, people browsing from home are under-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+ +School + + +
+ + +  + + + + +  + + + + + + + +Relative to the general internet population, people browsing from school are greatly over-represented at this site.

Confidence: high
+ +
+
+
+
+
+
+ +Work + + +
+ + +  + + + + +  + + + + + + + +The audience for this site among people browsing from work is similar to the general internet population.

Confidence: high
+ +
+
+
+
+
+
+
+
+
+ +Upgrade to the Alexa Pro Insight Plan to view all demographics including age, income, ethnicity and children. + +Upgrade to View +
+
+ + +  + + +
+ +
+

Upgrade to view all demographics

+
+

Gain access to:

+
    +
  • - Age, income, children, ethnicity
      in additon to gender, education and browsing location.
  • +
  • - Comparisons of website demographics.
  • +
+
+
+

Upgrade to the Alexa Pro Insight Plan to
view all demographics.

+Upgrade +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+
+
+

+Audience Demographics
+The audience demographics data comes from voluntary demographics information submitted by people in our global traffic panel. The data is for the past 12 months, updated monthly. +Learn more +

+

The demographics data consists of:

+

+

+

+

+Audience Geography
+The audience geography data describes where visitors to this site over the past month are located, and how the site is ranked in popular countries. If a country is not listed, it is because Alexa does not have enough data for this site to rank/measure the site's popularity among that country's online population. These metrics are updated monthly. +

+
+
+
+

+Audience Geography +

+

Where are this site's visitors located?

+
+
+ +

Visitors by Country

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CountryPercent of VisitorsRank in Country
United States Flag  United States 21.3% 197
India Flag  India 12.4% 132
China Flag  China 4.6% 369
Brazil Flag  Brazil 3.6% 185
Japan Flag  Japan 3.5% 324
France Flag  France 3.4% 210
Russia Flag  Russia 3.4% 320
United Kingdom Flag  United Kingdom 2.9% 231
Germany Flag  Germany 2.7% 338
Spain Flag  Spain 2.5% 214
+
+
+
+ +

Where do github.com's visitors come from?

+ +
+

+Search Traffic +

+

What percentage of visits to this site come from a search engine?

+
+ + + +

Search Visits

+
+17.90% +5.00% +
+ +
    +
  • -5%
  • +
+
+
+
+
+ +
+

+Top Keywords from Search Engines +

+

Which search keywords send traffic to this site?

+
+ + + + + + + + + + + + + + + + + + + +
KeywordPercent of Search Traffic
  1.  github 2.57%
  2.  bootstrap 0.98%
  3.  cgminer 0.63%
  4.  laravel 0.51%
  5.  font awesome 0.42%
+
+ +Upgrade to the Alexa Pro Advanced Plan to view all keyword data. + +Upgrade to View +
+
+ + +  + + +
+ +
+

Upgrade to view all keyword data

+

Get more insight into your competitors' keyword strategy.

+
+

Gain access to:

+
    +
  • - Top organic keywords.
  • +
  • - Top paid keywords.
  • +
  • - Keyword competition.
  • +
  • - Keyword opportunities.
  • +
+
+
+

Upgrade to the Alexa Pro Advanced Plan to
view all keyword data.

+Upgrade +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+
+

+Search Traffic
+The percentage of traffic, both free and paid, that come to this site from a search engine over the past 3 months, updated daily. The change number shows the difference versus the previous 3 month period. +

+

+Top Keywords from Search Engines
+The table shows the top keywords that sent traffic to this site from major search engines over the past 6 months. The list is updated monthly. +

+

+Upstream Sites
+Upstream sites are sites that people visited just before they visited this site. Note that this list is not the same as referrals from upstream sites. There is not necessarily a link between the upstream site and this site. +

+
+
+
+ +
+

+Upstream Sites +

+

Which sites did people visit immediately before this site?

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SitePercent of Unique Visits
  1.  google.com 12.5%
  2.  stackoverflow.com 4.8%
  3.  github.io 2.9%
  4.  facebook.com 2.3%
  5.  google.co.in 1.9%
  6.  youtube.com 1.1%
  7.  githubusercontent.com 1.0%
  8.  twitter.com 0.9%
  9.  google.com.tr 0.8%
10.  google.com.vn 0.8%
+ +
+
+
+ +

Where do github.com's visitors go next?

+
+
+ +Upgrade to the Alexa Pro Insight Plan to view downstream sites. + +Upgrade to View +
+
+ + +  + + +
+ +
+

Upgrade to view downstream sites

+
+

Gain access to:

+
    +
  • - The top 10 sites visitors went to next.
  • +
+
+
+

Upgrade to the Alexa Pro Insight Plan to
view downstream sites.

+Upgrade +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+

+Downstream sites are sites that people visit immediately after visiting this site. Note this does not necessarily mean that people are directed to the downstream site by this site

+
+

What sites link to github.com?

+ +
+
Total Sites Linking In
+83,625 +
+
+

+
+ + + + + + + + + + + + + + + + + + + +
SitePage
1. youtube.com youtube.com/channel/UCZnwOxM6jQSfsftjm...
2. baidu.com anquan.baidu.com/bbs/thread-86532-1-1....
3. pconline.com.cn pcedu.pconline.com.cn/323/3234394.html
4. yahoo.com answers.yahoo.com/question/index?qid=2...
5. taobao.com taobao.com/go/chn/snsdkjs/guide.php?sp...
+
+ +Upgrade to the Alexa Pro Basic Plan to view all 83,625 sites linking in. + +Upgrade to View +
+
+ + +  + + +
+ +
+

Upgrade to view all 83,625 sites linking in

+

Subscribe to view all sites linking in

+
+

Gain access to:

+
    +
  • - Get the full list of sites linking in for any site.
  • +
  • - Benchmark your link-building efforts.
  • +
  • - See who is linking to your competitors.
  • +
+
+
+

Upgrade to the Alexa Pro Basic Plan to
view all 83,625 sites linking in.

+Upgrade +
+
+ +
+

Already have a subscription?

+

Login with your Alexa Account

+
+
+
+ + +
+
+ + + + + + +
+
+
+
+ + + + + +Forgot your password? + + +
+
+
+
+
+
+
+
+
+
+

The "Sites Linking In" count shows the number of sites that Alexa found that link to this site. +For more information please see this explanation of +how Alexa determines the number of sites linking in.

+

The complete list of sites linking to this site is available to Alexa Pro subscribers.

+
+

What sites are related to github.com?

+
+ +

Where do visitors go on github.com?

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SubdomainPercent of Visitors
github.com 95.35%
gist.github.com 9.14%
help.github.com 2.72%
windows.github.com 1.85%
enterprise.github.com 0.62%
mac.github.com 0.44%
developer.github.com 0.44%
status.github.com 0.29%
training.github.com 0.28%
shop.github.com 0.26%
octicons.github.com 0.24%
+
+
+

The table shows the top subdomains for this site ordered by the percentage of visitors +that visited the subdomain over a month. Note that the percentages can add up to more than +100% because a visitor can visit multiple subdomains during the month.

+

Updated Monthly.

+
+

How fast does github.com load?

Fast (1.176 Seconds), 68% of sites are slower.

+
+
+

The reported load time for a website is the median time it takes to load +pages from that site in a real users' web browsers.

+

Alexa takes the median of all the page load times we observe for a site +and then compares that to the same figure for all other sites. For example, +a site in the 98th percentile (Very Fast) has a median load time faster than +98% of all measured sites, while a site in the 2nd percentile (Very Slow) +loads more quickly than only 2% of all sites and is slower than 97% of all sites.

+

The load time of an individual page is how long it takes for the DOM - +the structure of the page - to be loaded. This time doesn't include the time +to load all images and stylesheets, for example.

+

The load time metric is updated monthly.

+
+

Where can I find more info about github.com?

+
+ + + +
+

GitHub

+
+
+

+
+ +

+Site Description +

+

GitHub is the best place to share code with friends, co-workers, classmates, and complete strangers. Over four million people use GitHub to build amazing things together.

+ +
+ +

+Contact +

+
GitHub
88 Colin P Kelly Jr St
San Francisco, CA 94107
USA
support [at] github.com

+
+
+ +
+

To edit your site's public information you need to verify ownership of your site.

+ +
+
+

Customize your site overview page with your logo, plus add links back to your site +and much more! An Enhanced Site Overview is just one of the features you get with +an Alexa PRO subscription.

+ +
+
+
+

+Site Description
+A short description of the site. +

+

+Contact
+How to contact the owner of the site. +

+
+ +
+
+ + + +
+
+
+
+
+
+

To edit your site's public information you need to sign in and verify ownership of your site.

+
+
+
+
+
+ + + + + + + + + + + + + + + diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 344a1a5a..295c0fb9 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -4,3 +4,5 @@ $loader = require __DIR__.'/../vendor/autoload.php'; $loader->add('SEOstatsTest', __DIR__ . '/SEOstatsTest'); + +error_reporting(E_ALL); diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 0fc217e0..be3b07f4 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -10,6 +10,7 @@ processIsolation="false" stopOnFailure="false" syntaxCheck="false" + verbose="true" > From f8f5048507d5d10b21f43996289cbc722e0ff564 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Sun, 29 Jun 2014 01:49:06 +0200 Subject: [PATCH 18/40] add a AbstractTestCase and move assertFiles to test-root --- .../SEOstatsTest/AbstractSEOstatsTestCase.php | 101 ++++++++++++++++++ tests/SEOstatsTest/Services/AlexaTest.php | 98 ++--------------- tests/SEOstatsTest/Services/MozscapeTest.php | 26 +++++ .../alexa-siteinfo-2013-getDailyRank-1.html | 0 .../alexa-siteinfo-2013-getDailyRank-2.html | 0 .../alexa-siteinfo-2013-getMonthlyRank-1.html | 0 .../alexa-siteinfo-2013-getMonthlyRank-2.html | 0 .../alexa-siteinfo-2013-getWeeklyRank-1.html | 0 .../alexa-siteinfo-2013-getWeeklyRank-2.html | 0 .../alexa-siteinfo-2013-setRankingKeys-2.html | 0 .../alexa-siteinfo-2013-setRankingKeys-3.html | 0 .../alexa-siteinfo-2013-setRankingKeys-4.html | 0 .../alexa-siteinfo-2013-setRankingKeys-5.html | 0 .../Service}/alexa-siteinfo-2013.html | 0 .../Service}/alexa-siteinfo-2014.html | 0 tests/bootstrap.php | 3 +- 16 files changed, 136 insertions(+), 92 deletions(-) create mode 100644 tests/SEOstatsTest/AbstractSEOstatsTestCase.php create mode 100644 tests/SEOstatsTest/Services/MozscapeTest.php rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-getDailyRank-1.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-getDailyRank-2.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-getMonthlyRank-1.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-getMonthlyRank-2.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-getWeeklyRank-1.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-getWeeklyRank-2.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-setRankingKeys-2.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-setRankingKeys-3.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-setRankingKeys-4.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013-setRankingKeys-5.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2013.html (100%) rename tests/SEOstatsTest/{Services/_assert => _assert/Service}/alexa-siteinfo-2014.html (100%) diff --git a/tests/SEOstatsTest/AbstractSEOstatsTestCase.php b/tests/SEOstatsTest/AbstractSEOstatsTestCase.php new file mode 100644 index 00000000..e1057e84 --- /dev/null +++ b/tests/SEOstatsTest/AbstractSEOstatsTestCase.php @@ -0,0 +1,101 @@ +assertDirectory = __DIR__ . '/_assert/'; + } + + + protected function getStandardVersions ($version, $methode) + { + $filePattern = $this->standardVersionSubFile; + + $methodeFile = $this->assertDirectory . sprintf($filePattern, $version, $methode, 1); + + + $result= array($version); + if (! file_exists($methodeFile)) { + return array($version); + } + + $fileList = new \DirectoryIterator($this->assertDirectory); + $regexp = sprintf('#' . $filePattern . '$#', $version, $methode, '\d+'); + $filtertList = new \RegexIterator($fileList, $regexp); + + $regexp = sprintf('#' . $this->standardVersionFile . '#','([^.]+)'); + foreach ($filtertList as $file) { + preg_match($regexp, $file, $matches); + $result[] = $matches[1]; + } + return $result; + } + + protected function helperMakeAccessable ($object, $propertyOrMethod, $value = null) + { + $objectClass = get_class($object); + if (!isset($this->reflection[$objectClass])) { + $this->reflection[$objectClass] = new ReflectionClass($object); + } + $reflection = $this->reflection[$objectClass]; + $isMethod = $reflection->hasMethod($propertyOrMethod); + + if ($isMethod) { + $reflectionSub = $reflection->getMethod($propertyOrMethod); + } else { + $reflectionSub = $reflection->getProperty($propertyOrMethod); + } + + $reflectionSub->setAccessible(true); + + if (!is_null($value)) { + if ($isMethod) { + return $reflectionSub->invokeArgs($object, $value); + } else { + $reflectionSub->setValue($object, $value); + } + } + + return $reflectionSub; + } + + protected function mockGetPage() + { + $standardFile = sprintf('%s/_assert/' . $this->standardVersionFile, __DIR__, 2013); + + $this->mockedSUT->staticExpects($this->any()) + ->method('_getPage') + ->will($this->returnValue(file_get_contents($standardFile))); + } +} diff --git a/tests/SEOstatsTest/Services/AlexaTest.php b/tests/SEOstatsTest/Services/AlexaTest.php index bb8b2e39..c71ef286 100644 --- a/tests/SEOstatsTest/Services/AlexaTest.php +++ b/tests/SEOstatsTest/Services/AlexaTest.php @@ -2,46 +2,23 @@ namespace SEOstatsTest\Services; +use SEOstatsTest\AbstractSEOstatsTestCase; use SEOstats\Services\Alexa; -use ReflectionClass; -class AlexaTest extends \PHPUnit_Framework_TestCase +class AlexaTest extends AbstractSEOstatsTestCase { - /** - * - * @var Alexa - */ - protected $SUT; - - - /** - * - * @var Alexa - */ - protected $mockedSUT; - - - /** - * - * @var string - */ - protected $url; - - - /** - * - * @var string - */ - protected $reflection = array(); + protected $standardVersionFile = "alexa-siteinfo-%s.html"; + protected $standardVersionSubFile = "alexa-siteinfo-%s-%s-%s.html"; public function setUp() { + parent::setup(); + $this->reflection = array(); $this->url = 'http://github.com'; $this->SUT = new \SEOstats\Services\Alexa(); $this->SUT->setUrl($this->url); - } /** @@ -288,72 +265,11 @@ protected function mockAlexa($method, $vars=array()) $this->mockedSUT->setUrl(array_key_exists('url',$vars) ? $vars['url'] : $this->url); } - protected function mockGetPage() - { - $standardFile = sprintf('%s/_assert/alexa-siteinfo-%s.html', __DIR__, 2013); - - $this->mockedSUT->staticExpects($this->any()) - ->method('_getPage') - ->will($this->returnValue(file_get_contents($standardFile))); - } - protected function mockGetAlexaPage ($version, $calledTest = null) { - $standardFile = sprintf('%s/_assert/alexa-siteinfo-%s.html', __DIR__, $version); + $standardFile = sprintf($this->assertDirectory . $this->standardVersionFile, $version); $this->mockedSUT->staticExpects($this->any()) ->method('_getAlexaPage') ->will($this->returnValue(file_get_contents($standardFile))); } - - protected function getStandardVersions ($version, $methode) - { - $filePattern = 'alexa-siteinfo-%s-%s-%s.html'; - - $methodeFile = __DIR__ . '/_assert/' . sprintf($filePattern, $version, $methode, 1); - - - $result= array($version); - if (! file_exists($methodeFile)) { - return array($version); - } - - $fileList = new \DirectoryIterator(__DIR__ . '/_assert/'); - $regexp = '#' . sprintf($filePattern, $version, $methode, '\d+') . '$#'; - $filtertList = new \RegexIterator($fileList, $regexp); - - $regexp = '#alexa-siteinfo-([^.]+).html$#'; - foreach ($filtertList as $file) { - preg_match($regexp, $file, $matches); - $result[] = $matches[1]; - } - return $result; - } - - protected function helperMakeAccessable ($object, $propertyOrMethod, $value = null) - { - $objectClass = get_class($object); - if (!isset($this->reflection[$objectClass])) { - $this->reflection[$objectClass] = new ReflectionClass($object); - } - $reflection = $this->reflection[$objectClass]; - $isMethod = $reflection->hasMethod($propertyOrMethod); - - if ($isMethod) { - $reflectionSub = $reflection->getMethod($propertyOrMethod); - } else { - $reflectionSub = $reflection->getProperty($propertyOrMethod); - } - - $reflectionSub->setAccessible(true); - - if (!is_null($value)) { - if ($isMethod) { - return $reflectionSub->invokeArgs($object, $value); - } else { - $reflectionSub->setValue($object, $value); - } - } - - return $reflectionSub; - } } diff --git a/tests/SEOstatsTest/Services/MozscapeTest.php b/tests/SEOstatsTest/Services/MozscapeTest.php new file mode 100644 index 00000000..fd099295 --- /dev/null +++ b/tests/SEOstatsTest/Services/MozscapeTest.php @@ -0,0 +1,26 @@ +reflection = array(); + + $this->url = 'http://github.com'; + $this->SUT = new \SEOstats\Services\Mozscape(); + $this->SUT->setUrl($this->url); + + } + + public function testFoo() + { + + } +} diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-1.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getDailyRank-1.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-1.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getDailyRank-1.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-2.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getDailyRank-2.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getDailyRank-2.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getDailyRank-2.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-1.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getMonthlyRank-1.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-1.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getMonthlyRank-1.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-2.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getMonthlyRank-2.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getMonthlyRank-2.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getMonthlyRank-2.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-1.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getWeeklyRank-1.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-1.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getWeeklyRank-1.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-2.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getWeeklyRank-2.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-getWeeklyRank-2.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-getWeeklyRank-2.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-2.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-2.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-2.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-2.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-3.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-3.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-3.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-3.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-4.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-4.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-4.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-4.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-5.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-5.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013-setRankingKeys-5.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013-setRankingKeys-5.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2013.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2013.html diff --git a/tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2014.html b/tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2014.html similarity index 100% rename from tests/SEOstatsTest/Services/_assert/alexa-siteinfo-2014.html rename to tests/SEOstatsTest/_assert/Service/alexa-siteinfo-2014.html diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 295c0fb9..6c4c71aa 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -3,6 +3,7 @@ /* @var $loader \Composer\Autoload\ClassLoader */ $loader = require __DIR__.'/../vendor/autoload.php'; -$loader->add('SEOstatsTest', __DIR__ . '/SEOstatsTest'); +$classMap1 = \Composer\Autoload\ClassMapGenerator::createMap(__DIR__); +$loader->addClassMap($classMap1); error_reporting(E_ALL); From 37f287c1c2843fdbf80c20626e8017477e14a042 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 16 Jul 2014 15:47:18 +0200 Subject: [PATCH 19/40] make static function testable/mockable --- SEOstats/Services/3rdparty/GTB_PageRank.php | 2 +- SEOstats/Services/Google.php | 12 ++++++------ SEOstats/Services/Mozscape.php | 19 ++++++++++++------- SEOstats/Services/OpenSiteExplorer.php | 2 +- SEOstats/Services/Sistrix.php | 2 +- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/SEOstats/Services/3rdparty/GTB_PageRank.php b/SEOstats/Services/3rdparty/GTB_PageRank.php index 1af7d41f..7f71fae1 100644 --- a/SEOstats/Services/3rdparty/GTB_PageRank.php +++ b/SEOstats/Services/3rdparty/GTB_PageRank.php @@ -74,7 +74,7 @@ public function getPageRank() { if( !isset($qStrings[$i])) { break; } - $PR = self::getToolbarPageRank($tbUrl . $prString); + $PR = self::getToolbarPageRank($tbUrl . $qStrings[$i]); if ($PR === FALSE) { continue; } diff --git a/SEOstats/Services/Google.php b/SEOstats/Services/Google.php index cfe9cc78..8912d799 100644 --- a/SEOstats/Services/Google.php +++ b/SEOstats/Services/Google.php @@ -77,7 +77,7 @@ public static function getSearchResultsTotal($url = false) $url = parent::getUrl($url); $url = sprintf(Config\Services::GOOGLE_APISEARCH_URL, 1, $url); - $ret = parent::_getPage($url); + $ret = static::_getPage($url); $obj = Helper\Json::decode($ret); return !isset($obj->responseData->cursor->estimatedResultCount) @@ -97,7 +97,7 @@ public static function getPagespeedAnalysis($url = false) $url = sprintf(Config\Services::GOOGLE_PAGESPEED_URL, $url, Config\ApiKeys::GOOGLE_SIMPLE_API_ACCESS_KEY); - $ret = parent::_getPage($url); + $ret = static::_getPage($url); return Helper\Json::decode($ret); } @@ -107,7 +107,7 @@ public static function getPagespeedScore($url = false) $url = parent::getUrl($url); $ret = self::getPagespeedAnalysis($url); - return !$ret->score ? parent::noDataDefaultValue() : + return !isset($ret->score) || !$ret->score ? parent::noDataDefaultValue() : intval($ret->score); } @@ -129,7 +129,7 @@ public static function getSerps($query, $maxResults=100, $domain=false) $ref = 0 == $start ? 'ncr' : sprintf('search?q=%s&hl=en&prmd=imvns&start=%s0&sa=N', $q, $start); $nextSerp = 0 == $start ? sprintf('search?q=%s&filter=0', $q) : sprintf('search?q=%s&filter=0&start=%s0', $q, $start); - $curledSerp = utf8_decode( self::gCurl($nextSerp, $ref) ); + $curledSerp = utf8_decode( static::gCurl($nextSerp, $ref) ); if (preg_match("#answer[=|/]86640#i", $curledSerp)) { print('Please read: https://support.google.com/websearch/answer/86640'); @@ -186,13 +186,13 @@ public static function getSerps($query, $maxResults=100, $domain=false) return $result; } - private static function gCurl($path, $ref, $useCookie = Config\DefaultSettings::ALLOW_GOOGLE_COOKIES) + protected static function gCurl($path, $ref, $useCookie = Config\DefaultSettings::ALLOW_GOOGLE_COOKIES) { $url = sprintf('https://www.google.%s/', Config\DefaultSettings::GOOGLE_TLD); $referer = $ref == '' ? $url : $ref; $url .= $path; - $ua = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.83 Safari/535.11"; + $ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"; if (isset($_SERVER["HTTP_USER_AGENT"]) && 0 < strlen($_SERVER["HTTP_USER_AGENT"])) { $ua = $_SERVER["HTTP_USER_AGENT"]; } diff --git a/SEOstats/Services/Mozscape.php b/SEOstats/Services/Mozscape.php index b51815fc..9a7d4dc5 100644 --- a/SEOstats/Services/Mozscape.php +++ b/SEOstats/Services/Mozscape.php @@ -22,7 +22,7 @@ class Mozscape extends SEOstats // of the URL to rank well in search engine results. public static function getPageAuthority($url = false) { - $data = self::getCols('34359738368', $url); + $data = static::getCols('34359738368', $url); return (parent::noDataDefaultValue() == $data) ? $data : $data['upa']; } @@ -31,7 +31,7 @@ public static function getPageAuthority($url = false) // of the domain of the URL to rank well in search engine results. public static function getDomainAuthority($url = false) { - $data = self::getCols('68719476736', Helper\Url::parseHost($url)); + $data = static::getCols('68719476736', Helper\Url::parseHost($url)); return (parent::noDataDefaultValue() == $data) ? $data : $data['pda']; } @@ -40,7 +40,7 @@ public static function getDomainAuthority($url = false) // http://apiwiki.moz.com/glossary#equity public static function getEquityLinkCount($url = false) { - $data = self::getCols('2048', $url); + $data = static::getCols('2048', $url); return (parent::noDataDefaultValue() == $data) ? $data : $data['uid']; } @@ -48,7 +48,7 @@ public static function getEquityLinkCount($url = false) // The number of links (equity or nonequity or not, internal or external) to the URL. public static function getLinkCount($url = false) { - $data = self::getCols('2048', $url); + $data = static::getCols('2048', $url); return (parent::noDataDefaultValue() == $data) ? $data : $data['uid']; } @@ -56,7 +56,7 @@ public static function getLinkCount($url = false) // The normalized 10-point MozRank score of the URL. public static function getMozRank($url = false) { - $data = self::getCols('16384', $url); + $data = static::getCols('16384', $url); return (parent::noDataDefaultValue() == $data) ? $data : $data['umrp']; } @@ -64,7 +64,7 @@ public static function getMozRank($url = false) // The raw MozRank score of the URL. public static function getMozRankRaw($url = false) { - $data = self::getCols('16384', $url); + $data = static::getCols('16384', $url); return (parent::noDataDefaultValue() == $data) ? $data : number_format($data['umrr'], 16); } @@ -95,7 +95,7 @@ public static function getCols($cols, $url = false) urlencode(self::_getUrlSafeSignature($expires)) ); - $ret = parent::_getPage($apiEndpoint); + $ret = static::_getPage($apiEndpoint); return (!$ret || empty($ret) || '{}' == (string)$ret) ? parent::noDataDefaultValue() @@ -118,6 +118,11 @@ private static function _hmacsha1($data, $key) return hash_hmac('sha1', $data, $key, true); } + return self::_hmacsha1Rebuild($data, $key); + } + + private static function _hmacsha1Rebuild($data, $key) + { $blocksize = 64; $hashfunc = 'sha1'; diff --git a/SEOstats/Services/OpenSiteExplorer.php b/SEOstats/Services/OpenSiteExplorer.php index 811ca6cc..64738768 100644 --- a/SEOstats/Services/OpenSiteExplorer.php +++ b/SEOstats/Services/OpenSiteExplorer.php @@ -21,7 +21,7 @@ public static function getPageMetrics($url = false) $url = parent::getUrl($url); $dataUrl = sprintf(Config\Services::OPENSITEEXPLORER_URL, 'links', '1', urlencode($url)); - $html = parent::_getPage($dataUrl); + $html = static::_getPage($dataUrl); $doc = parent::_getDOMDocument($html); $xpath = parent::_getDOMXPath(@$doc); diff --git a/SEOstats/Services/Sistrix.php b/SEOstats/Services/Sistrix.php index 43d0bcf7..21e156da 100644 --- a/SEOstats/Services/Sistrix.php +++ b/SEOstats/Services/Sistrix.php @@ -31,7 +31,7 @@ public static function getVisibilityIndex($url = false) $domain = Helper\Url::parseHost($url); $dataUrl = sprintf(Config\Services::SISTRIX_VI_URL, urlencode($domain)); - $html = parent::_getPage($dataUrl); + $html = static::_getPage($dataUrl); @preg_match_all('#

(.*?)<\/h3>#si', $html, $matches); return isset($matches[1][0]) ? $matches[1][0] : parent::noDataDefaultValue(); From f979fe66511d3f42ed2d33b96796d78e0e1c0d94 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 16 Jul 2014 15:47:33 +0200 Subject: [PATCH 20/40] fix autoload problem --- SEOstats/Services/SemRush.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SEOstats/Services/SemRush.php b/SEOstats/Services/SemRush.php index 4ba87927..f4659cb5 100644 --- a/SEOstats/Services/SemRush.php +++ b/SEOstats/Services/SemRush.php @@ -16,7 +16,7 @@ use SEOstats\Config as Config; use SEOstats\Helper as Helper; -class SEMRush extends SEOstats +class SemRush extends SEOstats { public static function getDBs() { From aa07643e63485ba67972af0db190dae14475f9ec Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 16 Jul 2014 15:49:29 +0200 Subject: [PATCH 21/40] add tests for many services --- .../SEOstatsTest/AbstractSEOstatsTestCase.php | 45 +- tests/SEOstatsTest/Helper/HttpRequestTest.php | 79 + tests/SEOstatsTest/Helper/JsonTest.php | 59 + tests/SEOstatsTest/Helper/UrlTest.php | 75 + tests/SEOstatsTest/SEOstatsTest.php | 101 +- .../Services/AbstractServiceTestCase.php | 17 + tests/SEOstatsTest/Services/AlexaTest.php | 6 +- .../Google/AbstractGoogleTestCase.php | 34 + .../Services/Google/GoogleApiTest.php | 61 + .../Services/Google/GooglePagespeedTest.php | 50 + .../Services/Google/GoogleSearchTest.php | 156 ++ tests/SEOstatsTest/Services/MozscapeTest.php | 148 +- .../Services/OpenSiteExplorerTest.php | 65 + tests/SEOstatsTest/Services/SistrixTest.php | 64 + .../Service/AbstractServiceTestCase.php | 17 + .../_assert/Service/google-api-2014.json | 1 + .../_assert/Service/google-api-failed.json | 1 + .../Service/google-pagespeed-2014.json | 98 + .../Service/google-pagespeed-failed.json | 1 + .../Service/google-search-2014-page-1.html | 245 +++ .../Service/google-search-2014-page-2.html | 245 +++ .../_assert/Service/google-search-failed.html | 0 .../_assert/Service/ose-siteinfo-2014.html | 1616 +++++++++++++++++ .../_assert/Service/ose-siteinfo-failed.html | 0 .../_assert/Service/sistrix-2013.html | 11 + .../_assert/Service/sistrix-failed.html | 0 tests/SEOstatsTest/_assert/buffer.txt | 0 tests/SEOstatsTest/_assert/no_access.txt | 1088 +++++++++++ tests/bootstrap.php | 11 + tests/phpunit.xml | 9 +- 30 files changed, 4238 insertions(+), 65 deletions(-) create mode 100644 tests/SEOstatsTest/Helper/HttpRequestTest.php create mode 100644 tests/SEOstatsTest/Helper/JsonTest.php create mode 100644 tests/SEOstatsTest/Helper/UrlTest.php create mode 100644 tests/SEOstatsTest/Services/AbstractServiceTestCase.php create mode 100644 tests/SEOstatsTest/Services/Google/AbstractGoogleTestCase.php create mode 100644 tests/SEOstatsTest/Services/Google/GoogleApiTest.php create mode 100644 tests/SEOstatsTest/Services/Google/GooglePagespeedTest.php create mode 100644 tests/SEOstatsTest/Services/Google/GoogleSearchTest.php create mode 100644 tests/SEOstatsTest/Services/OpenSiteExplorerTest.php create mode 100644 tests/SEOstatsTest/Services/SistrixTest.php create mode 100644 tests/SEOstatsTest/_assert/Service/AbstractServiceTestCase.php create mode 100644 tests/SEOstatsTest/_assert/Service/google-api-2014.json create mode 100644 tests/SEOstatsTest/_assert/Service/google-api-failed.json create mode 100644 tests/SEOstatsTest/_assert/Service/google-pagespeed-2014.json create mode 100644 tests/SEOstatsTest/_assert/Service/google-pagespeed-failed.json create mode 100644 tests/SEOstatsTest/_assert/Service/google-search-2014-page-1.html create mode 100644 tests/SEOstatsTest/_assert/Service/google-search-2014-page-2.html create mode 100644 tests/SEOstatsTest/_assert/Service/google-search-failed.html create mode 100644 tests/SEOstatsTest/_assert/Service/ose-siteinfo-2014.html create mode 100644 tests/SEOstatsTest/_assert/Service/ose-siteinfo-failed.html create mode 100644 tests/SEOstatsTest/_assert/Service/sistrix-2013.html create mode 100644 tests/SEOstatsTest/_assert/Service/sistrix-failed.html create mode 100644 tests/SEOstatsTest/_assert/buffer.txt create mode 100644 tests/SEOstatsTest/_assert/no_access.txt diff --git a/tests/SEOstatsTest/AbstractSEOstatsTestCase.php b/tests/SEOstatsTest/AbstractSEOstatsTestCase.php index e1057e84..444b30cd 100644 --- a/tests/SEOstatsTest/AbstractSEOstatsTestCase.php +++ b/tests/SEOstatsTest/AbstractSEOstatsTestCase.php @@ -33,25 +33,34 @@ abstract class AbstractSEOstatsTestCase extends \PHPUnit_Framework_TestCase public function setup() { parent::setup(); + } + + public function __construct($name = null, array $data = array(), $dataName = '') + { + parent::__construct($name, $data, $dataName); $this->assertDirectory = __DIR__ . '/_assert/'; } + public function getAssertDirectory ($file = null) + { + return $this->assertDirectory . $file?:''; + } + protected function getStandardVersions ($version, $methode) { $filePattern = $this->standardVersionSubFile; - - $methodeFile = $this->assertDirectory . sprintf($filePattern, $version, $methode, 1); - + $methodeFile = sprintf($this->getAssertDirectory($filePattern), $version, $methode, 1); $result= array($version); if (! file_exists($methodeFile)) { return array($version); } - $fileList = new \DirectoryIterator($this->assertDirectory); + $fileList = new \DirectoryIterator($this->getAssertDirectory()); $regexp = sprintf('#' . $filePattern . '$#', $version, $methode, '\d+'); + $filtertList = new \RegexIterator($fileList, $regexp); $regexp = sprintf('#' . $this->standardVersionFile . '#','([^.]+)'); @@ -64,13 +73,19 @@ protected function getStandardVersions ($version, $methode) protected function helperMakeAccessable ($object, $propertyOrMethod, $value = null) { - $objectClass = get_class($object); + if ( is_string($object) ) { + $objectClass = $object; + $object = null; + } else { + $objectClass = get_class($object); + } + if (!isset($this->reflection[$objectClass])) { - $this->reflection[$objectClass] = new ReflectionClass($object); + $this->reflection[$objectClass] = new ReflectionClass($objectClass); } $reflection = $this->reflection[$objectClass]; $isMethod = $reflection->hasMethod($propertyOrMethod); - + if ($isMethod) { $reflectionSub = $reflection->getMethod($propertyOrMethod); } else { @@ -90,9 +105,21 @@ protected function helperMakeAccessable ($object, $propertyOrMethod, $value = nu return $reflectionSub; } - protected function mockGetPage() + protected function mockGetPage($arg = null) { - $standardFile = sprintf('%s/_assert/' . $this->standardVersionFile, __DIR__, 2013); + if (is_callable($arg)) { + $this->mockedSUT->staticExpects($this->any()) + ->method('_getPage') + ->will($this->returnCallback($arg)); + + return; + } + + if (! is_string($arg)) { + $arg = 2013; + } + + $standardFile = sprintf($this->getAssertDirectory() . $this->standardVersionFile, $arg); $this->mockedSUT->staticExpects($this->any()) ->method('_getPage') diff --git a/tests/SEOstatsTest/Helper/HttpRequestTest.php b/tests/SEOstatsTest/Helper/HttpRequestTest.php new file mode 100644 index 00000000..05460fd3 --- /dev/null +++ b/tests/SEOstatsTest/Helper/HttpRequestTest.php @@ -0,0 +1,79 @@ +assertSame(200, $statusCode); + } + + /** + * + * @dataProvider providerTestGetFile + */ + public function testGetFile($url, $filePath, $assertStatusCode) + { + + unlink($filePath); + $this->assertFalse(file_exists($filePath)); + $SUT = new HttpRequest(); + $statusCode = $SUT->getFile($url, $filePath); + + $this->assertTrue(file_exists($filePath)); + $this->assertSame($assertStatusCode, $statusCode); + } + + /** + * + * @dataProvider providerTestSendRequest + * @group live + */ + public function testSendRequest($url, $postData, $postJson, $assertResponse) + { + $statusCode = HttpRequest::sendRequest($url, $postData, $postJson); + + if ($assertResponse) { + $this->assertInternalType('string', $statusCode); + } else { + $this->assertFalse($statusCode); + } + } + + public function providerTestSendRequest() + { + $url = 'http://www.example.com'; + $postData = array('fieldA'=>'foo','fieldB'=>'bar'); + + return array( + array($url, $postData, false, true), + array($url, $postData, true, true), + array($url, false, false, true), + array('www.' . hash('sha512','this-domain-is-not-realy-exsist') . '.com/README.md', + $postData, false, false), + array('www.' . hash('sha512','this-domain-is-not-realy-exsist') . '.com/README.md', + $postData, true, false) + ); + } + + public function providerTestGetFile() + { + $file_buffer = $this->getAssertDirectory() . 'buffer.txt'; + $url = 'https://github.com/eyecatchup/SEOstats/blob/master'; + return array( + array($url . '/README.md', $file_buffer, true), + array('www.' . hash('sha512','this-domain-is-not-realy-exsist') . '.com/README.md', $file_buffer, true) + ); + } +} diff --git a/tests/SEOstatsTest/Helper/JsonTest.php b/tests/SEOstatsTest/Helper/JsonTest.php new file mode 100644 index 00000000..ca4c8fc5 --- /dev/null +++ b/tests/SEOstatsTest/Helper/JsonTest.php @@ -0,0 +1,59 @@ +assertEquals($assert, $result); + } + + /** + * + * @dataProvider providerTestEncode + */ + public function testEncode($var, $assert) + { + $result = Json::encode($var); + + $this->assertEquals($assert, $result); + } + + public function providerTestDecode() + { + $jsonValid = '{"foo":"bar","baz":["foo","bar"]}'; + $arrayValid = array( + 'foo'=>'bar', + 'baz'=>array('foo','bar') + ); + + return array( + array($jsonValid, true, $arrayValid), + array($jsonValid, false, (object) $arrayValid), + ); + } + + public function providerTestEncode() + { + $jsonValid = '{"foo":"bar","baz":["foo","bar"]}'; + $arrayValid = array( + 'foo'=>'bar', + 'baz'=>array('foo','bar') + ); + + return array( + array($arrayValid, $jsonValid), + array(utf8_decode("json-with-uml-äöü"), false), + ); + } +} diff --git a/tests/SEOstatsTest/Helper/UrlTest.php b/tests/SEOstatsTest/Helper/UrlTest.php new file mode 100644 index 00000000..1167bd6f --- /dev/null +++ b/tests/SEOstatsTest/Helper/UrlTest.php @@ -0,0 +1,75 @@ +assertSame($assertResult, $result); + } + + /** + * + * @dataProvider providerTestParseHost + */ + public function testParseHost($url, $assertHost) + { + $host = Url::parseHost($url); + + $this->assertEquals($assertHost, $host); + } + + public function providerTestParseHost() + { + return array( + array('github.com','github.com'), + array('http://github.com','github.com'), + array('https://github.com','github.com'), + + array('www.github.com','www.github.com'), + array('http://www.github.com','www.github.com'), + array('https://www.github.com','www.github.com'), + + array('', false), + array('/index.php?foo=bar', false), + ); + } + + public function providerTestIsRfc() + { + return array( + array('http://github.com',true), + array('https://github.com',true), + array('https://github.com/file',true), + array('https://github.com/file#anchor',true), + array('https://github.com/#anchor',true), + array('https://github.com/file?query=value',true), + array('https://github.com/?query=value',true), + + array('http://www.github.com',true), + array('https://www.github.com',true), + array('https://www.github.com',true), + array('https://www.github.com/file',true), + array('https://www.github.com/file#anchor',true), + array('https://www.github.com/#anchor',true), + array('https://www.github.com/file?query=value',true), + array('https://www.github.com/?query=value',true), + + array('github.com',false), + array('www.github.com',false), + array('', false), + array('.', false), + array('/index.php?foo=bar', false), + ); + } +} diff --git a/tests/SEOstatsTest/SEOstatsTest.php b/tests/SEOstatsTest/SEOstatsTest.php index 10a665fa..b402741d 100644 --- a/tests/SEOstatsTest/SEOstatsTest.php +++ b/tests/SEOstatsTest/SEOstatsTest.php @@ -4,7 +4,7 @@ use SEOstats\SEOstats; -class SEOstatsTest extends \PHPUnit_Framework_TestCase +class SEOstatsTest extends AbstractSEOstatsTestCase { /** * @@ -17,89 +17,98 @@ public function setUp() $this->SUT = new SEOstats(); } - public function testAlexa() + /** + * @dataProvider providerTestServiceMethods + */ + public function testServiceMethods($method, $assertInstance) { - $this->markTestIncomplete(); - } + $object = $this->SUT->{$method}(); - public function testGoogle() - { - $this->markTestIncomplete(); + $this->assertInstanceOf($assertInstance, $object); } - public function testMozscape() + public function providerTestServiceMethods() { - $this->markTestIncomplete(); + return array( + array('Alexa', 'SEOstats\Services\Alexa'), + array('Google', 'SEOstats\Services\Google'), + array('Mozscape', 'SEOstats\Services\Mozscape'), + array('OpenSiteExplorer', 'SEOstats\Services\OpenSiteExplorer'), + array('SEMRush', 'SEOstats\Services\SEMRush'), + array('Sistrix', 'SEOstats\Services\Sistrix'), + array('Social', 'SEOstats\Services\Social'), + ); } - public function testOpenSiteExplorer() + public function testSetAndGetUrl() { - $this->markTestIncomplete(); - } + $url = 'http://github.com'; - public function testSEMRush() - { - $this->markTestIncomplete(); - } + $result = $this->SUT->getUrl($url); + $this->assertSame($url, $result); - public function testSistrix() - { - $this->markTestIncomplete(); + $this->SUT->setUrl($url); + $this->assertSame($url, $this->SUT->getUrl()); } - public function testSocial() + public function testSetUrlInvalid() { - $this->markTestIncomplete(); - } + $this->setExpectedException('SEOstats\Common\SEOstatsException' ,'Invalid URL!'); - public function testGetLastLoadedHtml() - { - $this->markTestIncomplete(); - } - - public function testGetLastLoadedUrl() - { - $this->markTestIncomplete(); - } - - public function testGetUrl() - { - $this->markTestIncomplete(); - } - - public function testSetUrl() - { - $this->markTestIncomplete(); + $this->SUT->setUrl("github.com"); } public function testGetHost() { - $this->markTestIncomplete(); + $host = $this->SUT->getHost('http://github.com/path/file.txt'); + $this->assertEquals('github.com', $host); } public function testGetDomain() { - $this->markTestIncomplete(); + $domain = $this->SUT->getDomain('http://github.com/path/file.txt'); + $this->assertEquals('http://github.com', $domain); } public function testGetDOMDocument() { - $this->markTestIncomplete(); + $html = 'test'; + + $result = $this->helperMakeAccessable($this->SUT, '_getDOMDocument', array($html)); + $this->assertInstanceOf('DOMDocument', $result); } public function testGetDOMXPath() { - $this->markTestIncomplete(); + $doc = new \DOMDocument('test'); + + $result = $this->helperMakeAccessable($this->SUT, '_getDOMXPath', array($doc)); + $this->assertInstanceOf('DOMXPath', $result); } + /** + * + * @group live + */ public function testGetPage() { - $this->markTestIncomplete(); + $url = 'http://github.com/test'; + $result = $this->helperMakeAccessable($this->SUT, '_getPage', array($url)); + + $this->assertInternalType('string', $result); + $this->assertEquals($url, $this->SUT->getLastLoadedUrl()); } public function testSetHtml() { - $this->markTestIncomplete(); + $html = ''; + $this->helperMakeAccessable($this->SUT, '_lastHtml', false); + + $this->assertFalse($this->SUT->getLastLoadedHtml()); + + $result = $this->helperMakeAccessable($this->SUT, '_setHtml', array($html)); + + $this->assertSame($html, $this->SUT->getLastLoadedHtml()); } public function testNoDataDefaultValue() diff --git a/tests/SEOstatsTest/Services/AbstractServiceTestCase.php b/tests/SEOstatsTest/Services/AbstractServiceTestCase.php new file mode 100644 index 00000000..7ddb410c --- /dev/null +++ b/tests/SEOstatsTest/Services/AbstractServiceTestCase.php @@ -0,0 +1,17 @@ +assertDirectory .= 'Service/'; + } +} diff --git a/tests/SEOstatsTest/Services/AlexaTest.php b/tests/SEOstatsTest/Services/AlexaTest.php index c71ef286..32b71f6e 100644 --- a/tests/SEOstatsTest/Services/AlexaTest.php +++ b/tests/SEOstatsTest/Services/AlexaTest.php @@ -2,10 +2,9 @@ namespace SEOstatsTest\Services; -use SEOstatsTest\AbstractSEOstatsTestCase; use SEOstats\Services\Alexa; -class AlexaTest extends AbstractSEOstatsTestCase +class AlexaTest extends AbstractServiceTestCase { protected $standardVersionFile = "alexa-siteinfo-%s.html"; protected $standardVersionSubFile = "alexa-siteinfo-%s-%s-%s.html"; @@ -219,6 +218,7 @@ public function providerTestSiteinfoMethodWithDiffrentVersion() foreach ($versionList as $version) { foreach ($methodList as $methodName=>$methodeAssertResultType) { + $versionArray = $this->getStandardVersions($version[0], $methodName); $iVersion = 0; foreach($versionArray as $versionSub) { @@ -267,7 +267,7 @@ protected function mockAlexa($method, $vars=array()) protected function mockGetAlexaPage ($version, $calledTest = null) { - $standardFile = sprintf($this->assertDirectory . $this->standardVersionFile, $version); + $standardFile = sprintf($this->getAssertDirectory() . $this->standardVersionFile, $version); $this->mockedSUT->staticExpects($this->any()) ->method('_getAlexaPage') ->will($this->returnValue(file_get_contents($standardFile))); diff --git a/tests/SEOstatsTest/Services/Google/AbstractGoogleTestCase.php b/tests/SEOstatsTest/Services/Google/AbstractGoogleTestCase.php new file mode 100644 index 00000000..574d78f2 --- /dev/null +++ b/tests/SEOstatsTest/Services/Google/AbstractGoogleTestCase.php @@ -0,0 +1,34 @@ +mockedSUT = $this->getMock('\SEOstats\Services\Google', $methods); + $this->mockedSUT->setUrl(array_key_exists('url',$vars) ? $vars['url'] : $this->url); + } + public function setup() + { + parent::setup(); + $this->reflection = array(); + + $this->url = 'http://github.com'; + $this->SUT = new \SEOstats\Services\Google(); + $this->SUT->setUrl($this->url); + } +} diff --git a/tests/SEOstatsTest/Services/Google/GoogleApiTest.php b/tests/SEOstatsTest/Services/Google/GoogleApiTest.php new file mode 100644 index 00000000..9267033a --- /dev/null +++ b/tests/SEOstatsTest/Services/Google/GoogleApiTest.php @@ -0,0 +1,61 @@ +reflection = array(); + + $this->url = 'http://github.com'; + } + + /** + * @dataProvider providerTestSimpleMethodeTest + * @todo value controll + * @group google + * @group google-api + */ + public function testSimpleMethodeTest($method, $version, $assertValue) + { + $this->mockSUT(); + $this->mockGetPage ($version); + + $result = call_user_func(get_class($this->mockedSUT) . '::' . $method, $this->url); + + $this->assertEquals($assertValue, $result); + } + + + public function providerTestSimpleMethodeTest() + { + $failedValue = $this->helperMakeAccessable('SEOstats\Services\Google', 'noDataDefaultValue', array()); + + $version = array( + array('2014', 7200000), + array('failed', $failedValue) + ); + + $methods = array( + 'getSiteindexTotal', + 'getBacklinksTotal', + 'getSearchResultsTotal' + ); + + $result= array(); + foreach ( $methods as $m) { + foreach ($version as $v) { + + } + $result[] = array_merge(array($m), $v); + } + + return $result; + } +} diff --git a/tests/SEOstatsTest/Services/Google/GooglePagespeedTest.php b/tests/SEOstatsTest/Services/Google/GooglePagespeedTest.php new file mode 100644 index 00000000..5bea1b44 --- /dev/null +++ b/tests/SEOstatsTest/Services/Google/GooglePagespeedTest.php @@ -0,0 +1,50 @@ +reflection = array(); + + $this->url = 'http://github.com'; + } + + /** + * @dataProvider providerTestSimpleMethodeTest + * @todo value controll + * @group google + * @group google-pagespeed + */ + public function testSimpleMethodeTest($method, $version, $assertValue) + { + $this->mockSUT(); + $this->mockGetPage ($version); + + $result = call_user_func(get_class($this->mockedSUT) . '::' . $method, $this->url); + + $this->assertEquals($assertValue, $result); + } + + + public function providerTestSimpleMethodeTest() + { + $failedValue = $this->helperMakeAccessable('SEOstats\Services\Google', 'noDataDefaultValue', array()); + $pagespeedValue = json_decode(file_get_contents($this->getAssertDirectory('google-pagespeed-2014.json'))); + + $result[] = array('getPagespeedAnalysis', '2014', $pagespeedValue); + $result[] = array('getPagespeedAnalysis', 'failed', (object) array()); + + $result[] = array('getPagespeedScore', '2014', 90); + $result[] = array('getPagespeedScore', 'failed', $failedValue); + + + return $result; + } +} diff --git a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php new file mode 100644 index 00000000..ae4696b5 --- /dev/null +++ b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php @@ -0,0 +1,156 @@ +SUT->getPageRank(); + + $this->assertInternalType('string', $result); + $this->assertGreaterThanOrEqual(0, $result); + } + + /** + * @dataProvider providerTestGoogleCurl + * @group google + * @group google-search + * @group live + */ + public function testGoogleCurl($args, $status) + { + $result = $this->helperMakeAccessable($this->SUT, 'gCurl', $args); + + if ($status) { + $this->assertInternalType('string', $result); + $this->assertTrue(strlen($result) >= 1); + + } else { + $this->assertFalse($result); + } + } + + /** + * @dataProvider providerTestGetSerps + * @todo value controll + * @group google + * @group google-search + */ + public function testGetSerps($args, $version, $assertResultCount) + { + $this->mockSUT('getSerps'); + $this->mockGCurl ($version); + + $result = $this->helperMakeAccessable($this->mockedSUT, 'getSerps', $args); + + $this->assertEquals($assertResultCount, count($result)); + } + + + public function providerTestGoogleCurl() + { + $query = rawurlencode('github.com'); + + $result = array(); + + // @todo implement cookie support in tests + $result[] = array(array(# $path, $ref, $useCookie + sprintf('search?q=%s&filter=0', $query), + 'ncr', + false + ), + true); + $result[] = array(array(# $path, $ref, $useCookie + sprintf('search?q=%s&filter=0', $query), + '', + false + ), + true); + + return $result; + } + + + public function providerTestGetSerps() + { + // query, $maxResults=100, $domain=false + $query = 'github.com'; + + $args = array( $query, 10, false ); + $result[] = array($args, '2014', 15); // github.com result gives more than 10 results on first page + $result[] = array($args, 'failed', 0); + + // @TODO fix domain filter regexp + // $args = array( $query, 10, 'github.com' ); + // $result[] = array($args, '2014', 0); + // $result[] = array($args, 'failed', 0); + + + + // @TODO add support for 4, 15 , 25 maxResult to + // $args = array( $query, 15, false ); + // $result[] = array($args, '2014', 15); + // $result[] = array($args, 'failed', 0); + + // @TODO fix domain filter regexp + // $args = array( $query, 15, 'github.com' ); + // $result[] = array($args, '2014', 15); + // $result[] = array($args, 'failed', 0); + + + + + // @TODO fix domain filter regexp + // $args = array( $query, 10, 'github.com' ); + // $result[] = array($args, '2014', 0); + // $result[] = array($args, 'failed', 0); + + $args = array( $query, 20, false ); + $result[] = array($args, '2014', 25); + $result[] = array($args, 'failed', 0); + + // @TODO fix domain filter regexp + // $args = array( $query, 20, 'github.com' ); + // $result[] = array($args, '2014', 20); + // $result[] = array($args, 'failed', 0); + + + return $result; + } + + public function setUp () + { + parent::setUp(); + $this->called = 1; + } + + protected function mockGCurl ($version) + { + $standardFile = $this->getAssertDirectory() . $this->standardVersionFile; + + $this->mockedSUT->staticExpects($this->any()) + ->method('gCurl') + ->will($this->returnCallback(function() use ($standardFile, $version) { + $file = sprintf($standardFile, $version . '-page-' . $this->called); + + if (!file_exists($file)) { + $file = sprintf($standardFile, $version); + } + $this->called++; + + return file_get_contents($file); + })); + } +} diff --git a/tests/SEOstatsTest/Services/MozscapeTest.php b/tests/SEOstatsTest/Services/MozscapeTest.php index fd099295..70a53e83 100644 --- a/tests/SEOstatsTest/Services/MozscapeTest.php +++ b/tests/SEOstatsTest/Services/MozscapeTest.php @@ -2,11 +2,9 @@ namespace SEOstatsTest\Services; -use SEOstatsTest\AbstractSEOstatsTestCase; use SEOstats\Services\Mozscape; -use ReflectionClass; -class MozscapeTest extends AbstractSEOstatsTestCase +class MozscapeTest extends AbstractServiceTestCase { public function setUp() @@ -16,11 +14,151 @@ public function setUp() $this->url = 'http://github.com'; $this->SUT = new \SEOstats\Services\Mozscape(); $this->SUT->setUrl($this->url); + } + + public function providerTestGetMethodeMethods() + { + $SUT = '\SEOstats\Services\Mozscape'; + + $validValue = array('foo'=>'bar'); + $inValidValue = $this->helperMakeAccessable($SUT, 'noDataDefaultValue', array()); + + $result = array(); + $float = array( + 100.12345678901234567890, + 100.1234567890123456 + ); + + $result[]= array('getMozRankRaw', '16384', array('umrr'=>$float[0]), $float[1]); + $result[]= array('getMozRankRaw', '16384', $inValidValue, $inValidValue); + + $result[]= array('getMozRank', '16384', array('umrp'=>'foo'), 'foo'); + $result[]= array('getMozRank', '16384', $inValidValue, $inValidValue); + + + $result[]= array('getLinkCount', '2048', array('uid'=>'foo'), 'foo'); + $result[]= array('getLinkCount', '2048', $inValidValue, $inValidValue); + + $result[]= array('getEquityLinkCount', '2048', array('uid'=>'foo'), 'foo'); + $result[]= array('getEquityLinkCount', '2048', $inValidValue, $inValidValue); + + + $result[]= array('getDomainAuthority', '68719476736', array('pda'=>'foo'), 'foo'); + $result[]= array('getDomainAuthority', '68719476736', $inValidValue, $inValidValue); + + + $result[]= array('getPageAuthority', '34359738368', array('upa'=>'foo'), 'foo'); + $result[]= array('getPageAuthority', '34359738368', $inValidValue, $inValidValue); +#*/ + + return $result; + } + + /** + * @dataProvider providerTestGetMethodeMethods + */ + public function testGetMethodeMethods($methode, $metricCode, $callbackReturn, $assertResult) + { + $this->mockSUT(); + $this->mockGetCols(array($metricCode, null), $callbackReturn); + + $result = call_user_func(array($this->mockedSUT,$methode), null); + $this->assertEquals($assertResult, $result); + } + + /** + * @dataProvider providerTestGetCols + */ + public function testGetCols($callbackReturn, $assertResult) + { + $this->mockSUT('getCols'); + $this->mockGetPage(function($url) use($callbackReturn) { + $parse = parse_url($url); + parse_str($parse['query'], $query); + + $assertSignature = $this->helperMakeAccessable( + $this->SUT, + '_getUrlSafeSignature', + array($query['Expires'], basename($parse['path'])) + ); + + $this->assertEquals($assertSignature, $query['Signature']); + + return $callbackReturn; + }); + $result = $this->mockedSUT->getCols(1337); + $this->assertEquals($assertResult, $result); } - public function testFoo() + public function testGetUrlSafeSignature() { - + $expires = 1405036732; + + $sig = $this->helperMakeAccessable($this->SUT,'_getUrlSafeSignature', array($expires)); + + $this->assertEquals('BH4/rZyS0Hv8/3UMU6MnOMGD5Ow=', $sig); + } + + public function testHmacSha1() + { + $data = hash('sha512','foo'); + $key = md5('bar'); + + $assert = hash_hmac('sha1', $data, $key, true); + $value1 = $this->helperMakeAccessable($this->SUT,'_hmacsha1', array($data, $key)); + $value2 = $this->helperMakeAccessable($this->SUT,'_hmacsha1Rebuild', array($data, $key)); + + $this->assertEquals($assert, $value1); + $this->assertEquals($assert, $value2); + $this->assertEquals($value1, $value2); + } + + public function providerTestGetCols() + { + $SUT = '\SEOstats\Services\Mozscape'; + + $validValue = array('foo'=>'bar'); + $inValidValue = $this->helperMakeAccessable($SUT, 'noDataDefaultValue', array()); + + return array( + array('', $inValidValue), + array('{}', $inValidValue), + array(false, $inValidValue), + array('invalid json', null), + array(json_encode($validValue), $validValue), + ); + } + + protected function mockSUT($method=null, $vars=array()) + { + + $methods = array(); + switch ($method) { + case 'getCols': + $methods = array('_getPage'); + break; + default: + $methods = array('getCols'); + break; + } + + $this->mockedSUT = $this->getMock('\SEOstats\Services\Mozscape', $methods); + $this->mockedSUT->setUrl(array_key_exists('url',$vars) ? $vars['url'] : $this->url); + } + + + + protected function mockGetCols ($assertParams, $returnValue) + { + $this->mockedSUT->staticExpects($this->any()) + ->method('getCols') + ->will($this->returnCallback(function ($cols, $url = null) use($assertParams, $returnValue) { + + $this->assertEquals($assertParams[0], $cols); + $this->assertEquals($assertParams[1], $url); + + return $returnValue; + })); } } diff --git a/tests/SEOstatsTest/Services/OpenSiteExplorerTest.php b/tests/SEOstatsTest/Services/OpenSiteExplorerTest.php new file mode 100644 index 00000000..1e3a9ed7 --- /dev/null +++ b/tests/SEOstatsTest/Services/OpenSiteExplorerTest.php @@ -0,0 +1,65 @@ +reflection = array(); + + $this->url = 'http://github.com'; + } + + /** + * @dataProvider providerTestGetPageMetrics + * @todo value controll + */ + public function testGetPageMetrics($version, $status) + { + $this->mockSUT(); + $this->mockGetPage ($version); + + $result = call_user_func(get_class($this->mockedSUT) . '::getPageMetrics', $this->url); + + if ($status) { + $assertPropertyArray = array('domainAuthority','pageAuthority','justDiscovered', + 'justDiscovered', 'linkingRootDomains', 'totalLinks'); + + $assertSubPropertyArray = array('result','unit','descr'); + + foreach ($assertPropertyArray as $assertProperty ) { + $this->assertTrue( isset($result->{$assertProperty}) ); + + foreach ($assertSubPropertyArray as $assertSubProperty ) { + $this->assertTrue( isset($result->{$assertProperty}->{$assertSubProperty}) ); + } + } + + } else { + $this->assertEquals($this->helperMakeAccessable($this->mockedSUT, 'noDataDefaultValue', array()), $result); + } + } + + + public function providerTestGetPageMetrics() + { + return array( + array('2014', true), + array('failed', false) + ); + } + + protected function mockSUT($method=null, $vars=array()) + { + $methods = array('_getPage'); + + $this->mockedSUT = $this->getMock('\SEOstats\Services\OpenSiteExplorer', $methods); + $this->mockedSUT->setUrl(array_key_exists('url',$vars) ? $vars['url'] : $this->url); + } +} diff --git a/tests/SEOstatsTest/Services/SistrixTest.php b/tests/SEOstatsTest/Services/SistrixTest.php new file mode 100644 index 00000000..8a9bb011 --- /dev/null +++ b/tests/SEOstatsTest/Services/SistrixTest.php @@ -0,0 +1,64 @@ +reflection = array(); + + $this->url = 'http://github.com'; + } + + /** + * @dataProvider providerTestGetVisibilityIndex + * @todo value controll + */ + public function testGetVisibilityIndex($version, $status) + { + $this->mockSUT(); + $this->mockGetPage ($version); + + $result = call_user_func(get_class($this->mockedSUT) . '::getVisibilityIndex', $this->url); + + if ($status) { + $assertValue ='h3 foo1'; + + } else { + $assertValue = $this->helperMakeAccessable($this->mockedSUT, 'noDataDefaultValue', array()); + } + + $this->assertEquals($assertValue, $result); + } + + + public function providerTestGetPageMetrics() + { + return array( + array('2014', true), + array('failed', false) + ); + } + + public function providerTestGetVisibilityIndex() + { + return array( + array('2013', true), + array('failed', false) + ); + } + + protected function mockSUT($method=null, $vars=array()) + { + $methods = array('_getPage'); + + $this->mockedSUT = $this->getMock('\SEOstats\Services\Sistrix', $methods); + $this->mockedSUT->setUrl(array_key_exists('url',$vars) ? $vars['url'] : $this->url); + } +} diff --git a/tests/SEOstatsTest/_assert/Service/AbstractServiceTestCase.php b/tests/SEOstatsTest/_assert/Service/AbstractServiceTestCase.php new file mode 100644 index 00000000..7ddb410c --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/AbstractServiceTestCase.php @@ -0,0 +1,17 @@ +assertDirectory .= 'Service/'; + } +} diff --git a/tests/SEOstatsTest/_assert/Service/google-api-2014.json b/tests/SEOstatsTest/_assert/Service/google-api-2014.json new file mode 100644 index 00000000..823c9a12 --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/google-api-2014.json @@ -0,0 +1 @@ +{"responseData": {"results":[{"GsearchResultClass":"GwebSearch","unescapedUrl":"https://github.com/","url":"https://github.com/","visibleUrl":"github.com","cacheUrl":"http://www.google.com/search?q\u003dcache:SZgkdCZ5k2sJ:github.com","title":"\u003cb\u003eGitHub\u003c/b\u003e · Build software better, together.","titleNoFormatting":"GitHub · Build software better, together.","content":"Online project hosting using Git. Includes source-code browser, in-line editing, \nwikis, and ticketing. Free for public open-source code. Commercial closed source\n ..."}],"cursor":{"resultCount":"7.200.000","pages":[{"start":"0","label":1},{"start":"1","label":2},{"start":"2","label":3},{"start":"3","label":4},{"start":"4","label":5},{"start":"5","label":6},{"start":"6","label":7},{"start":"7","label":8}],"estimatedResultCount":"7200000","currentPageIndex":0,"moreResultsUrl":"http://www.google.com/search?oe\u003dutf8\u0026ie\u003dutf8\u0026source\u003duds\u0026start\u003d0\u0026hl\u003dde\u0026q\u003dgithub.com","searchResultTime":"0,24"}}, "responseDetails": null, "responseStatus": 200} diff --git a/tests/SEOstatsTest/_assert/Service/google-api-failed.json b/tests/SEOstatsTest/_assert/Service/google-api-failed.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/google-api-failed.json @@ -0,0 +1 @@ +{} diff --git a/tests/SEOstatsTest/_assert/Service/google-pagespeed-2014.json b/tests/SEOstatsTest/_assert/Service/google-pagespeed-2014.json new file mode 100644 index 00000000..4db51e59 --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/google-pagespeed-2014.json @@ -0,0 +1,98 @@ +{ + "kind": "pagespeedonline#result", + "id": "/speed/pagespeed", + "responseCode": 200, + "title": "PageSpeed Home", + "score": 90, + "pageStats": { + "numberResources": 22, + "numberHosts": 7, + "totalRequestBytes": "2761", + "numberStaticResources": 16, + "htmlResponseBytes": "91981", + "cssResponseBytes": "37728", + "imageResponseBytes": "13909", + "javascriptResponseBytes": "247214", + "otherResponseBytes": "8804", + "numberJsResources": 6, + "numberCssResources": 2 + }, + "formattedResults": { + "locale": "en_US", + "ruleResults": { + "AvoidBadRequests": { + "localizedRuleName": "Avoid bad requests", + "ruleImpact": 0.0 + }, + "MinifyJavaScript": { + "localizedRuleName": "Minify JavaScript", + "ruleImpact": 0.1417, + "urlBlocks": [ + { + "header": { + "format": "Minifying the following JavaScript resources could reduce their size by $1 ($2% reduction).", + "args": [ + { + "type": "BYTES", + "value": "1.3KiB" + }, + { + "type": "INT_LITERAL", + "value": "0" + } + ] + }, + "urls": [ + { + "result": { + "format": "Minifying $1 could save $2 ($3% reduction).", + "args": [ + { + "type": "URL", + "value": "http://code.google.com/js/codesite_tail.pack.04102009.js" + }, + { + "type": "BYTES", + "value": "717B" + }, + { + "type": "INT_LITERAL", + "value": "1" + } + ] + } + }, + { + "result": { + "format": "Minifying $1 could save $2 ($3% reduction).", + "args": [ + { + "type": "URL", + "value": "http://www.gmodules.com/ig/proxy?url\u003dhttp%3A%2F%2Fjqueryjs.googlecode.com%2Ffiles%2Fjquery-1.2.6.min.js" + }, + { + "type": "BYTES", + "value": "258B" + }, + { + "type": "INT_LITERAL", + "value": "0" + } + ] + } + } + ] + } + ] + }, + "SpriteImages": { + "localizedRuleName": "Combine images into CSS sprites", + "ruleImpact": 0.0 + } + } + }, + "version": { + "major": 1, + "minor": 11 + } +} diff --git a/tests/SEOstatsTest/_assert/Service/google-pagespeed-failed.json b/tests/SEOstatsTest/_assert/Service/google-pagespeed-failed.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/google-pagespeed-failed.json @@ -0,0 +1 @@ +{} diff --git a/tests/SEOstatsTest/_assert/Service/google-search-2014-page-1.html b/tests/SEOstatsTest/_assert/Service/google-search-2014-page-1.html new file mode 100644 index 00000000..11aadf3c --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/google-search-2014-page-1.html @@ -0,0 +1,245 @@ + +github.com - Google-Suche
Wenn Sie ein Bildschirmleseprogramm verwenden, klicken Sie hier zum Deaktivieren von Google Instant.
Ungefähr 141.000.000 Ergebnisse (0,19 Sekunden) 
diff --git a/tests/SEOstatsTest/_assert/Service/google-search-2014-page-2.html b/tests/SEOstatsTest/_assert/Service/google-search-2014-page-2.html new file mode 100644 index 00000000..11aadf3c --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/google-search-2014-page-2.html @@ -0,0 +1,245 @@ + +github.com - Google-Suche
Wenn Sie ein Bildschirmleseprogramm verwenden, klicken Sie hier zum Deaktivieren von Google Instant.
Ungefähr 141.000.000 Ergebnisse (0,19 Sekunden) 
diff --git a/tests/SEOstatsTest/_assert/Service/google-search-failed.html b/tests/SEOstatsTest/_assert/Service/google-search-failed.html new file mode 100644 index 00000000..e69de29b diff --git a/tests/SEOstatsTest/_assert/Service/ose-siteinfo-2014.html b/tests/SEOstatsTest/_assert/Service/ose-siteinfo-2014.html new file mode 100644 index 00000000..0744d917 --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/ose-siteinfo-2014.html @@ -0,0 +1,1616 @@ + + + + + Open Site Explorer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + +
+ +Open Site Explorer - Link Popularity Checker + Backlink Analysis Tool + +
+
+ + + +
+
+
+
+
+
New. You can now filter your Top Pages by HTTP Status code. Give it a try!
+
+ + +
+ + + +
+
+ Show + + + links + +
Link Types:
  • Link equity: Juice-passing links, including followed links and 301 (permanent) redirects.
  • No link equity: Links that do not pass link juice.
  • Only follow: Links that have not been defined as nofollow links.
  • Only rel=nofollow: Links with the rel=nofollow attribute.
  • Only 301: 301 (permanent) redirect links that pass link juice.
+ from + + pages + +
Link Sources:
  • Internal Pages Only: Links from pages on the domain
  • External Pages Only: Links from pages from external sites
+ + to + + +
Link Targets:
  • Subdomain: Links to pages that live on the subdomain.
  • Root Domain: Links to pages on the root domain *.domain.com. This includes pages on subdomains (ex. blog.seomoz.org or www.seomoz.org). Selecting Root Domain will expand your search beyond the initial page you entered.
+ + + and + + + + +
+
+ + +
+ Request CSV +
+ We can email you a CSV containing the info shown below, but you must + log in or register for an account. +
+
+ + + 1 - 50 inbound links from 9,018 domains + +
Although we do not currently display a count of total links for this filter set, you can still view all the links by paginating or downloading a CSV (up to 25 links per domain).
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Title and URL of Linking Page + Link Anchor Text +
The visible, clickable text in a hyperlink.
+
+ Page Authority +
Predicts this page's ranking potential in the search engines based on an algorithmic combination of all link metrics.
+
+ Domain Authority +
Predicts this domain's ranking potential in the search engines based on an algorithmic combination of all link metrics.
+
+
+ + Ruby on Rails + + +
(img alt)
GitHub
9290
+
+ (nofollow) + + Nginx Community + + +
GitHub8892
+
+ + Julie Ann Horvath Describes Sexism And Intimidation Behind Her GitHub Exit | TechCrunch + + +
http://github.com8696
+
+ (nofollow) + + Wiki Engines + + +
http://github.com8290
+
+ (nofollow) + + Free Social Media Icon Set | Elegant Themes Blog + + +
http://github.com/8294
+
+

As a Moz Pro subscriber you get:

+ +
    +
  • Unlimited Open Site Explorer reports
  • +
  • Valuable metrics for up to 10,000 links
  • +
  • Other SEO and inbound marketing tools
  • +
+
+
+
+ + After Editorially: The Search For Alternative Collaborative Online Writing Tools | Smashing Magazine + + +
+
+ + [No Data] + + +
+
+ (nofollow) + + [No Data] + + +
+
+ + HIV Testing Sites & Care Services Locator + + +
+
+ + [No Data] + + +
+
+ + Robin Good's Latest News + + +
+
+ + Zend PHP Webinars - Zend.com + + +
+
+ + Top Sites: The 500 Most Important Websites on the Internet - Moz + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + TCPDUMP/LIBPCAP public repository + + +
+
+ + [No Data] + + +
+
+ + The Silicon Valley iOS Developers' Meetup (Palo Alto, CA) - Meetup + + +
+
+ + [No Data] + + +
+
+ + Apache Maven Changes Plugin - Introduction + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + Report: Social network demographics in 2012 + + +
+
+ + [No Data] + + +
+
+ + David Heinemeier Hansson (DHH) + + +
+
+ + [No Data] + + +
+
+ + Google Cloud Platform Blog + + +
+
+ + GitHub For Beginners: Don't Get Scared, Get Started – ReadWrite + + +
+
+ + Techmeme Leaderboard + + +
+
+ + [No Data] + + +
+
+ + GitHub�Ȥ� - �ϤƤʥ������ + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + Introducing: Project Open Data | The White House + + +
+
+ + HIV Testing Sites & Care Services Locator + + +
+
+ + 7 Version Control Systems Reviewed | Smashing Magazine + + +
+
+ + Inside GitHub's Super-Lean Management Strategy--And How It Drives Innovation ⚙ Co.Labs ⚙ code + community + + +
+
+ + Julie Horvath “Satisfied” With GitHub Transparency | TechCrunch + + +
+
+ + 37signals Podcast + + +
+
+ (nofollow) + + [No Data] + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + Open Source Hardware Association + + +
+
+ + Thank you all - Free Web Analytics Software + + +
+
+ + What Exactly Is GitHub Anyway? | TechCrunch + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ + [No Data] + + +
+
+ +
+ +
+ + +
+ + + +
+
+ +

+ Get more insight with Moz Pro +

+

+ Run unlimited reports and analyze your traffic and link metrics over time. +

+ Take a free 30-day trial of Moz Pro +
+ +
+ +

+ Moz Local New +

+

+ Correct, consistent business listings across the web—for all your + locations—at the click of a button. +

+ Learn More +
+
+ + + +
+
+ + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + diff --git a/tests/SEOstatsTest/_assert/Service/ose-siteinfo-failed.html b/tests/SEOstatsTest/_assert/Service/ose-siteinfo-failed.html new file mode 100644 index 00000000..e69de29b diff --git a/tests/SEOstatsTest/_assert/Service/sistrix-2013.html b/tests/SEOstatsTest/_assert/Service/sistrix-2013.html new file mode 100644 index 00000000..a57561a3 --- /dev/null +++ b/tests/SEOstatsTest/_assert/Service/sistrix-2013.html @@ -0,0 +1,11 @@ + + +
+

h2 foo bar

+

foobar

+

h3 foo1

+

h3 foo2

+

h3 foo3

+
+ + diff --git a/tests/SEOstatsTest/_assert/Service/sistrix-failed.html b/tests/SEOstatsTest/_assert/Service/sistrix-failed.html new file mode 100644 index 00000000..e69de29b diff --git a/tests/SEOstatsTest/_assert/buffer.txt b/tests/SEOstatsTest/_assert/buffer.txt new file mode 100644 index 00000000..e69de29b diff --git a/tests/SEOstatsTest/_assert/no_access.txt b/tests/SEOstatsTest/_assert/no_access.txt new file mode 100644 index 00000000..42f4d8cc --- /dev/null +++ b/tests/SEOstatsTest/_assert/no_access.txt @@ -0,0 +1,1088 @@ + + + + + + + + + + + + + SEOstats/README.md at master · eyecatchup/SEOstats · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ + + + + + + +
+
+ + + + + + + +
+ + +
+ +
+ + + +
+ + + +
+ + This repository + + + +
+ + + + + + + + +
+
+ +
+
+ + + +
+
+
+ +
+
+
+ + + + +

+ public + + /SEOstats + + + + + +

+
+
+ +
+
+
+ + + + +
+ + + + +
+

HTTPS clone URL

+
+ + + + +
+
+ + + +
+

Subversion checkout URL

+
+ + + + +
+
+ + +

You can clone with + HTTPS + or Subversion. + + + +

+ + + + + + Download ZIP + +
+
+ +
+ + + + + + + + + +
+ + +
+ + + branch: + master + + + +
+ +
+ + + + +
+ + +
+ + +
+ Stephan Schmitz + + + + +
+

2 contributors

+ Stephan Schmitz + Francis Besset + + +
+ +
+ +
+
+
+
+ + file + + 459 lines (346 sloc) + + 15.726 kb +
+ +
+ +
+

Flattr SEOstats

+ +

+SEOstats: SEO metrics library for PHP

+ +

SEOstats is a powerful open source PHP library to request a bunch of SEO relevant metrics such as detailed backlink analyses, keyword and traffic statistics, website trends, page authority, the Google Pagerank, the Alexa Trafficrank and much more.

+ +

SEOstats offers over 50 different methods and gathers data from Alexa, Google, Mozscape (by Moz - f.k.a. Seomoz), SEMRush, Open-Site-Explorer, Sistrix, Facebook, Twitter & many more.

+ +

+Dependencies

+ +

SEOstats requires PHP version 5.3 or greater and the PHP5-CURL and PHP5-JSON extensions.

+ +

+Installation

+ +

The recommended way to install SEOstats is through composer. +To install SEOstats, just create the following composer.json file

+ +
{
+    "require": {
+        "seostats/seostats": "dev-master"
+    }
+}
+
+ +

and run the php composer.phar install (Windows: composer install) command in path of the composer.json.

+ +

+Step-by-step example:

+ +

If you haven't installed composer yet, here's the easiest way to do so:

+ +
# Download the composer installer and execute it with PHP:
+user@host:~/> curl -sS https://getcomposer.org/installer | php
+
+# Copy composer.phar to where your local executables live:
+user@host:~/> mv /path/given/by/composer-installer/composer.phar /usr/local/bin/composer.phar
+
+# Alternatively: For ease of use, you can add an alias to your bash profile:
+# (Note, you need to re-login your terminal for the change to take effect.)
+user@host:~/> echo 'alias composer="php /usr/local/bin/composer.phar"' >> ~/.profile
+
+ +

If you have installed composer, follow these steps to install SEOstats:

+ +
# Create a new directory and cd into it:
+user@host:~/> mkdir /path/to/seostats && cd /path/to/seostats
+
+# Create the composer.json for SEOstats:
+user@host:/path/to/seostats> echo '{"require":{"seostats/seostats":"dev-master"}}' > composer.json
+
+# Run the install command:
+user@host:/path/to/seostats> composer install
+Loading composer repositories with package information
+Installing dependencies (including require-dev)
+  - Installing seostats/seostats (dev-master 4c192e4)
+    Cloning 4c192e43256c95741cf85d23ea2a0d59a77b7a9a
+
+Writing lock file
+Generating autoload files
+
+# You're done. For a quick start, you can now 
+# copy the example files to the install directory:
+user@host:/path/to/seostats> cp ./vendor/seostats/seostats/example/*.php  ./
+
+# Your SEOstats install directory should look like this now:
+user@host:/path/to/seostats> ls -1
+composer.json
+composer.lock
+get-alexa-graphs.php
+get-alexa-metrics.php
+get-google-pagerank.php
+get-google-pagespeed-analysis.php
+get-google-serps.php
+get-opensiteexplorer-metrics.php
+get-semrush-graphs.php
+get-semrush-metrics.php
+get-sistrix-visibilityindex.php
+get-social-metrics.php
+vendor
+
+ +

+Use SEOstats without composer

+ +

If composer is no option for you, you can still just download the SEOstats.zip file of the current master branch (version 2.5.2) and extract it. However, currently there is an issues with autoloading and you need to follow the instructions in the comments in the example files in order to use SEOstats (or download zip for the development version of SEOstats (2.5.3) here).

+ +

+Usage

+ +

+TOC

+ +

+Configuration

+ +

There're two configuration files to note:

+ +
    +
  1. `./SEOstats/Config/ApiKeys.php`
    Client API Keys (currently required for Mozscape and Google's Pagespeed Service only). +
  2. +
  3. `./SEOstats/Config/DefaultSettings.php`
    Some default settings for querying data (mainly locale related stuff). +
  4. +

+Brief Example of Use

+ +

To use the SEOstats methods, you must include one of the Autoloader classes first (For composer installs: ./vendor/autoload.php; for zip download: ./SEOstats/bootstrap.php).

+ +

Now, you can create a new SEOstats instance an bind any URL to the instance for further use with any child class.

+ +
<?php
+// Depending on how you installed SEOstats
+#require_once __DIR__ . DIRECTORY_SEPARATOR . 'SEOstats' . DIRECTORY_SEPARATOR . 'bootstrap.php';
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
+
+use \SEOstats\Services as SEOstats;
+
+try {
+  $url = 'http://www.google.com/';
+
+  // Create a new SEOstats instance.
+  $seostats = new \SEOstats\SEOstats;
+
+  // Bind the URL to the current SEOstats instance.
+  if ($seostats->setUrl($url)) {
+
+    echo SEOstats\Alexa::getGlobalRank();
+    echo SEOstats\Google::getPageRank();
+  }
+}
+catch (SEOstatsException $e) {
+  die($e->getMessage());
+}
+
+ +

Alternatively, you can call all methods statically passing the URL to the methods directly.

+ +
<?php
+// Depending on how you installed SEOstats
+#require_once __DIR__ . DIRECTORY_SEPARATOR . 'SEOstats' . DIRECTORY_SEPARATOR . 'bootstrap.php';
+require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
+
+try {
+  $url = 'http://www.google.com/';
+
+  // Get the Google Toolbar Pagerank for the given URL.
+  echo \SEOstats\Services\Google::getPageRank($url);
+}
+catch (SEOstatsException $e) {
+  die($e->getMessage());
+}
+
+ +

More detailed examples can be found in the ./example directory.

+ +

+SEOstats Alexa Methods

+ +

+Alexa Traffic Metrics

+ +
<?php
+  // Returns the global Alexa Traffic Rank (last 3 months).
+  print Alexa::getGlobalRank();
+
+  // Returns the global Traffic Rank for the last month.
+  print Alexa::getMonthlyRank();
+
+  // Returns the global Traffic Rank for the last week.
+  print Alexa::getWeeklyRank();
+
+  // Returns the global Traffic Rank for yesterday.
+  print Alexa::getDailyRank();
+
+  // Returns the country-specific Alexa Traffic Rank.
+  print_r( Alexa::getCountryRank() );
+
+  // Returns Alexa's backlink count for the given domain.
+  print Alexa::getBacklinkCount();
+
+  // Returns Alexa's page load time info for the given domain.
+  print Alexa::getPageLoadTime();
+
+ +

+Alexa Traffic Graphs

+ +
<?php
+  // Returns HTML code for the 'daily traffic trend'-graph.
+  print Alexa::getTrafficGraph(1);
+
+  // Returns HTML code for the 'daily pageviews (percent)'-graph.
+  print Alexa::getTrafficGraph(2);
+
+  // Returns HTML code for the 'daily pageviews per user'-graph.
+  print Alexa::getTrafficGraph(3);
+
+  // Returns HTML code for the 'time on site (in minutes)'-graph.
+  print Alexa::getTrafficGraph(4);
+
+  // Returns HTML code for the 'bounce rate (percent)'-graph.
+  print Alexa::getTrafficGraph(5);
+
+  // Returns HTML code for the 'search visits'-graph, using specific graph dimensions of 320*240 px.
+  print Alexa::getTrafficGraph(6, 0, 320, 240);
+
+ +

+SEOstats Google Methods

+ +

+Google Toolbar PageRank

+ +
<?php
+  //  Returns the Google PageRank for the given URL.
+  print Google::getPageRank();
+
+ +

+Google Pagespeed Service

+ +
<?php
+  // Returns the Google Pagespeed analysis' metrics for the given URL.
+  print_r( Google::getPagespeedAnalysis() );
+
+  // Returns the Google Pagespeed analysis' total score.
+  print Google::getPagespeedScore();
+
+ +

+Google Websearch Index

+ +
<?php
+  // Returns the total amount of results for a Google site-search for the object URL.
+  print Google::getSiteindexTotal();
+
+  // Returns the total amount of results for a Google link-search for the object URL.
+  print Google::getBacklinksTotal();
+
+  // Returns the total amount of results for a Google search for 'keyword'.
+  print Google::getSearchResultsTotal('keyword');
+
+ +

+Google SERP Details

+ +
<?php
+  // Returns an array of URLs and titles for the first 100 results for a Google web search for 'keyword'.
+  print_r ( Google::getSerps('keyword') );
+
+  // Returns an array of URLs and titles for the first 200 results for a Google site-search for $url.
+  print_r ( Google::getSerps("site:$url", 200) );
+
+  // Returns an array of URLs, titles and position in SERPS for occurrences of $url
+  // within the first 1000 results for a Google web search for 'keyword'.
+  print_r ( Google::getSerps('keyword', 1000, $url) );
+
+ +

+SEOstats Mozscape Methods

+ +
<?php
+  // The normalized 10-point MozRank score of the URL. 
+  print Mozscape::getMozRank();
+
+  // The raw MozRank score of the URL.
+  print Mozscape::getMozRankRaw();
+
+  // The number of links (equity or nonequity or not, internal or external) to the URL.
+  print Mozscape::getLinkCount();
+
+  // The number of external equity links to the URL (http://apiwiki.moz.com/glossary#equity).
+  print Mozscape::getEquityLinkCount();
+
+  // A normalized 100-point score representing the likelihood
+  // of the URL to rank well in search engine results.  
+  print Mozscape::getPageAuthority();
+
+  // A normalized 100-point score representing the likelihood
+  // of the root domain of the URL to rank well in search engine results.
+  print Mozscape::getDomainAuthority();
+
+ +

+SEOstats Open Site Explorer (by MOZ) Methods

+ +
<?php
+  // Returns several metrics from Open Site Explorer (by MOZ)
+  $ose = OpenSiteExplorer::getPageMetrics();
+
+  // MOZ Domain-Authority Rank - Predicts this domain's ranking potential in the search engines 
+  // based on an algorithmic combination of all link metrics.
+  print "Domain-Authority:         " .
+        $ose->domainAuthority->result . ' (' .      // Int - e.g 42
+        $ose->domainAuthority->unit   . ') - ' .    // String - "/100"
+        $ose->domainAuthority->descr  . PHP_EOL;    // String - Result value description
+
+  // MOZ Page-Authority Rank - Predicts this page's ranking potential in the search engines 
+  // based on an algorithmic combination of all link metrics.
+  print "Page-Authority:           " .
+        $ose->pageAuthority->result . ' (' .        // Int - e.g 48
+        $ose->pageAuthority->unit   . ') - ' .      // String - "/100"
+        $ose->pageAuthority->descr  . PHP_EOL;      // String - Result value description
+
+  // Just-Discovered Inbound Links - Number of links to this page found over the past %n days, 
+  // indexed within an hour of being shared on Twitter.
+  print "Just-Discovered Links:    " .
+        $ose->justDiscovered->result . ' (' .       // Int - e.g 140
+        $ose->justDiscovered->unit   . ') - ' .     // String - e.g "32 days"
+        $ose->justDiscovered->descr  . PHP_EOL;     // String - Result value description
+
+  // Root-Domain Inbound Links - Number of unique root domains (e.g., *.example.com) 
+  // containing at least one linking page to this URL.
+  print "Linking Root Domains:     " .
+        $ose->linkingRootDomains->result . ' (' .   // Int - e.g 210
+        $ose->linkingRootDomains->unit   . ') - ' . // String - "Root Domains"
+        $ose->linkingRootDomains->descr  . PHP_EOL; // String - Result value description
+
+  // Total Links - All links to this page including internal, external, followed, and nofollowed.
+  print "Total Links:              " .
+        $ose->totalLinks->result . ' (' .           // Int - e.g 31571
+        $ose->totalLinks->unit   . ') - ' .         // String - "Total Links"
+        $ose->totalLinks->descr  . PHP_EOL;         // String - Result value description
+
+ +

+SEOstats SEMRush Methods

+ +

+SEMRush Domain Reports

+ +
<?php
+  // Returns an array containing the SEMRush main report (includes DomainRank, Traffic- & Ads-Data)
+  print_r ( SEMRush::getDomainRank() );
+
+  // Returns an array containing the domain rank history.
+  print_r ( SEMRush::getDomainRankHistory() );
+
+  // Returns an array containing data for competeing (auto-detected) websites.
+  print_r ( SEMRush::getCompetitors() );
+
+  // Returns an array containing data about organic search engine traffic, using explicitly SEMRush's german database.
+  print_r ( SEMRush::getOrganicKeywords(0, 'de') );
+
+ +

+SEMRush Graphs

+ +
<?php
+  // Returns HTML code for the 'search engine traffic'-graph.
+  print SEMRush::getDomainGraph(1);
+
+  // Returns HTML code for the 'search engine traffic price'-graph.
+  print SEMRush::getDomainGraph(2);
+
+  // Returns HTML code for the 'number of adwords ads'-graph, using explicitly SEMRush's german database.
+  print SEMRush::getDomainGraph(3, 0, 'de');
+
+  // Returns HTML code for the 'adwords traffic'-graph, using explicitly SEMRush's german database and
+  // specific graph dimensions of 320*240 px.
+  print SEMRush::getDomainGraph(4, 0, 'de', 320, 240);
+
+  // Returns HTML code for the 'adwords traffic price '-graph, using explicitly SEMRush's german database,
+  // specific graph dimensions of 320*240 px and specific graph colors (black lines and red dots for data points).
+  print SEMRush::getDomainGraph(5, 0, 'de', 320, 240, '000000', 'ff0000');
+
+ +

+SEOstats Sistrix Methods

+ +

+Sistrix Visibility Index

+ +
<?php
+  // Returns the Sistrix visibility index
+  // @link http://www.sistrix.com/blog/870-sistrix-visibilityindex.html
+  print Sistrix::getVisibilityIndex();
+
+ +

+SEOstats Social Media Methods

+ +

+Google+ PlusOnes

+ +
<?php
+  // Returns integer PlusOne count
+  print Social::getGooglePlusShares();
+
+ +

+Facebook Interactions

+ +
<?php
+  // Returns an array of total counts for overall Facebook interactions count, shares, likes, comments and clicks.
+  print_r ( Social::getFacebookShares() );
+
+ +

+Twitter Mentions

+ +
<?php
+  // Returns integer tweet count for URL mentions
+  print Social::getTwitterShares();
+
+ +

+Other Shares

+ +
<?php
+  // Returns the total count of URL shares via Delicious
+  print Social::getDeliciousShares();
+
+  // Returns array of top ten delicious tags for a URL
+  print_r ( Social::getDeliciousTopTags() );
+
+  // Returns the total count of URL shares via Digg
+  print Social::getDiggShares();
+
+  // Returns the total count of URL shares via LinkedIn
+  print Social::getLinkedInShares();
+
+  // Returns shares, comments, clicks and reach for the given URL via Xing
+  print_r( Social::getXingShares() );
+
+  // Returns the total count of URL shares via Pinterest
+  print Social::getPinterestShares();
+
+  // Returns the total count of URL shares via StumbleUpon
+  print Social::getStumbleUponShares();
+
+  // Returns the total count of URL shares via VKontakte
+  print Social::getVKontakteShares();
+
+ +

+License

+ +

(c) 2010 - 2014, Stephan Schmitz eyecatchup@gmail.com
+License: MIT, http://eyecatchup.mit-license.org
+URL: https://github.com/eyecatchup/SEOstats

+
+ +
+
+ + + + +
+ +
+ +
+
+ + +
+ +
+ +
+ + +
+
+
+ +
+
+ +
+ + + +
+ + + Something went wrong with that request. Please try again. +
+ + + + + + + + + + diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 6c4c71aa..4c6d3af4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -7,3 +7,14 @@ $loader->addClassMap($classMap1); error_reporting(E_ALL); + +$configApiFilePath = dirname(__DIR__) . '/SEOstats/Config/ApiKeys.php'; + +$configApi = file_get_contents($configApiFilePath); + +$configApi = preg_replace("#(\s+const MOZSCAPE_ACCESS_ID\s+=) \'\';#", "\$1 'MOZSCAPE_ACCESS_ID';", $configApi); +$configApi = preg_replace("#(\s+const MOZSCAPE_SECRET_KEY\s+=) \'\';#", "\$1 'MOZSCAPE_SECRET_KEY';", $configApi); +$configApi = preg_replace("#(\s+const GOOGLE_SIMPLE_API_ACCESS_KEY\s+=) \'\';#", "\$1 'GOOGLE_SIMPLE_API_ACCESS_KEY';", $configApi); + + +file_put_contents($configApiFilePath, $configApi); diff --git a/tests/phpunit.xml b/tests/phpunit.xml index be3b07f4..953fcfdd 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -10,7 +10,7 @@ processIsolation="false" stopOnFailure="false" syntaxCheck="false" - verbose="true" + verbose="false" > @@ -28,9 +28,14 @@ ../SEOstats + + ../SEOstats/Services/3rdparty + + + - + From a48be9581ba458be99d960f0def8c4411c1a1093 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 16 Jul 2014 15:57:02 +0200 Subject: [PATCH 22/40] add composer to dev requirements --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index ef13abdb..16ab562a 100644 --- a/composer.json +++ b/composer.json @@ -35,6 +35,7 @@ }, "require-dev" : { "squizlabs/php_codesniffer" : "~1", + "composer/composer" : "dev", "phpunit/phpunit" : ">=3.7,<4", "scrutinizer/ocular" : "~1" }, From c974edece964981cfd50292db06a521a59ad9f62 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 16 Jul 2014 16:03:29 +0200 Subject: [PATCH 23/40] fix typo --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 16ab562a..c89c0d78 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ }, "require-dev" : { "squizlabs/php_codesniffer" : "~1", - "composer/composer" : "dev", + "composer/composer": "1.0.*@dev", "phpunit/phpunit" : ">=3.7,<4", "scrutinizer/ocular" : "~1" }, From c9674f19665d4b726d2cade7780078f1d2b39b5d Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Wed, 16 Jul 2014 16:14:16 +0200 Subject: [PATCH 24/40] make alexa test better --- tests/SEOstatsTest/Services/AlexaTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/SEOstatsTest/Services/AlexaTest.php b/tests/SEOstatsTest/Services/AlexaTest.php index 32b71f6e..5d28e04f 100644 --- a/tests/SEOstatsTest/Services/AlexaTest.php +++ b/tests/SEOstatsTest/Services/AlexaTest.php @@ -33,7 +33,8 @@ public function testSiteinfoMethodWithDiffrentVersion ($method, $version, $type) $noDataDefault = $this->helperMakeAccessable($SUT, 'noDataDefaultValue', array()); - if ($type){ + // for the case that this version can be invalid + if ($type || $noDataDefault != $result) { if (is_array($type)) { foreach ($type as $arrayKey=>$arrayValueType) { $this->assertArrayHasKey($arrayKey, $result); @@ -212,7 +213,6 @@ public function providerTestSiteinfoMethodWithDiffrentVersion() $versionList = array( array('2013',true), - array('2014',null), array('2014',false) # new version currently not supported ); From 5dc678fc5eabe81d2c76a21b318c9e1f83b2f829 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 09:22:59 +0200 Subject: [PATCH 25/40] add parse methods for alexa --- SEOstats/Services/Alexa.php | 73 +++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/SEOstats/Services/Alexa.php b/SEOstats/Services/Alexa.php index 49b7c4c8..04d51e62 100644 --- a/SEOstats/Services/Alexa.php +++ b/SEOstats/Services/Alexa.php @@ -266,4 +266,77 @@ protected static function retInt($str) $intStr = 0 < strlen($strim) ? $strim : '0'; return intval($intStr); } + + /** + * + * @return mixed nodeValue + */ + protected static function parseDomByXpaths($xpathDom, $xpathQueryList) { + + foreach ( $xpathQueryList as $query ) { + $nodes = @$xpathDom->query($query); + + if ( $nodes->length != 0 ) { + return $nodes; + } + } + + return null; + } + + /** + * + * @return mixed nodeValue + */ + protected static function parseDomByXpathsGetValue($xpathDom, $xpathQueryList) + { + $nodes = static::parseDomByXpaths($xpathDom, $xpathQueryList); + + return ($nodes) ? $nodes->item(0)->nodeValue : null; + } + + /** + * + * @return mixed nodeValue + */ + protected static function parseDomByXpathsToInteger($xpathDom, $xpathQueryList) + { + $nodeValue = static::parseDomByXpathsGetValue($xpathDom, $xpathQueryList); + + if ($nodeValue === null) { + return parent::noDataDefaultValue(); + } + return self::retInt( $nodeValue ); + } + + /** + * + * @return mixed nodeValue + */ + protected static function parseDomByXpathsWithoutTags($xpathDom, $xpathQueryList) + { + + $nodeValue = static::parseDomByXpathsGetValue($xpathDom, $xpathQueryList); + + if ($nodeValue === null) { + return parent::noDataDefaultValue(); + } + + return strip_tags($nodeValue); + } + + /** + * + * @return mixed nodeValue + */ + protected static function parseDomByXpathsToIntegerWithoutTags($xpathDom, $xpathQueryList) + { + $nodeValue = static::parseDomByXpathsGetValue($xpathDom, $xpathQueryList); + + if ($nodeValue === null) { + return parent::noDataDefaultValue(); + } + + return self::retInt(strip_tags($nodeValue)); + } } From 45aa51c05c0e49cd2770a9c8f7caac8ac9ddb312 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 09:47:11 +0200 Subject: [PATCH 26/40] fix alexa methods and add test groups for alexa fixed methods: - getPageLoadTime - getBacklinkCount - getCountryRank - getGlobalRank --- SEOstats/Services/Alexa.php | 40 ++++++++++++++++------- tests/SEOstatsTest/Services/AlexaTest.php | 10 ++++++ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/SEOstats/Services/Alexa.php b/SEOstats/Services/Alexa.php index 04d51e62..6a5c7def 100644 --- a/SEOstats/Services/Alexa.php +++ b/SEOstats/Services/Alexa.php @@ -117,12 +117,15 @@ public static function getGlobalRank($url = false) return parent::noDataDefaultValue(); } */ - + $xpath = self::_getXPath($url); - $nodes = @$xpath->query("//*[@id='traffic-rank-content']/div/span[2]/div[1]/span/span/div/strong/a"); - return !$nodes->item(0) ? parent::noDataDefaultValue() : - self::retInt( strip_tags($nodes->item(0)->nodeValue) ); + $xpathQueryList = array( + "//*[@id='traffic-rank-content']/div/span[2]/div[1]/span/span/div/strong", + "//*[@id='traffic-rank-content']/div/span[2]/div[1]/span/span/div/strong/a" + ); + + return static::parseDomByXpathsToIntegerWithoutTags($xpath, $xpathQueryList); } /** @@ -171,8 +174,15 @@ public static function setRankingKeys($url = false) public static function getCountryRank($url = false) { $xpath = self::_getXPath($url); - $node1 = @$xpath->query("//*[@id='traffic-rank-content']/div/span[2]/div[2]/span/span/h4/strong/a"); - $node2 = @$xpath->query("//*[@id='traffic-rank-content']/div/span[2]/div[2]/span/span/div/strong/a"); + $node1 = self::parseDomByXpaths($xpath, array( + "//*[@id='traffic-rank-content']/div/span[2]/div[2]/span/span/h4/a", + "//*[@id='traffic-rank-content']/div/span[2]/div[2]/span/span/h4/strong/a", + )); + + $node2 = self::parseDomByXpaths($xpath, array( + "//*[@id='traffic-rank-content']/div/span[2]/div[2]/span/span/div/strong/a", + "//*[@id='traffic-rank-content']/div/span[2]/div[2]/span/span/div/strong", + )); if ($node2->item(0)) { $rank = self::retInt(strip_tags($node2->item(0)->nodeValue)); @@ -190,19 +200,25 @@ public static function getCountryRank($url = false) public static function getBacklinkCount($url = false) { $xpath = self::_getXPath($url); - $nodes = @$xpath->query("//*[@id='linksin_div']/section/div/div[1]/span"); - return !$nodes->item(0) ? parent::noDataDefaultValue() : - self::retInt($nodes->item(0)->nodeValue); + $queryList = array( + "//section[@class='row-fluid panel-wrapper '][6]/section/div/span/div/span", + "//*[@id='linksin_div']/section/div/div[1]/span" + ); + + return static::parseDomByXpathsToInteger($xpath, $queryList); } public static function getPageLoadTime($url = false) { $xpath = self::_getXPath($url); - $nodes = @$xpath->query( "//*[@id='section-load']/div/section/p" ); - return !$nodes->item(0) ? parent::noDataDefaultValue() : - strip_tags($nodes->item(0)->nodeValue); + $queryList = array( + "//section[@class='row-fluid panel-wrapper '][9]/section/p", + "//*[@id='section-load']/div/section/p" + ); + + return static::parseDomByXpathsWithoutTags($xpath, $queryList); } /** diff --git a/tests/SEOstatsTest/Services/AlexaTest.php b/tests/SEOstatsTest/Services/AlexaTest.php index 5d28e04f..22c65815 100644 --- a/tests/SEOstatsTest/Services/AlexaTest.php +++ b/tests/SEOstatsTest/Services/AlexaTest.php @@ -23,6 +23,7 @@ public function setUp() /** * * @dataProvider providerTestSiteinfoMethodWithDiffrentVersion + * @group alexa */ public function testSiteinfoMethodWithDiffrentVersion ($method, $version, $type) { @@ -55,6 +56,7 @@ public function testSiteinfoMethodWithDiffrentVersion ($method, $version, $type) /** * * @dataProvider providerTestGetTrafficGraph + * @group alexa */ public function testGetTrafficGraph($url, $paramsArray, $assertResult) { @@ -69,6 +71,9 @@ public function testGetTrafficGraph($url, $paramsArray, $assertResult) } } + /** + * @group alexa + */ public function testGetXPath() { $urlList = array( @@ -102,6 +107,9 @@ public function testGetXPath() } } + /** + * @group alexa + */ public function testGetAlexaPage() { $this->mockAlexa('_getAlexaPage'); @@ -116,6 +124,7 @@ public function testGetAlexaPage() /** * @dataProvider providerTestRetInt + * @group alexa */ public function testRetInt($string, $assert) { @@ -194,6 +203,7 @@ public function providerTestGetTrafficGraph() public function providerTestSiteinfoMethodWithDiffrentVersion() { + // @TODO to get the new alexa rank daily/weekly/monthly we need a svg analyse for the site comparisons< $result = array(); $methodList = array( 'getPageLoadTime'=>'string', From 474b8e7f90599b457485ad8889144e4c08d58b13 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 09:55:21 +0200 Subject: [PATCH 27/40] fix php5.3 test error --- tests/SEOstatsTest/Services/Google/GoogleSearchTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php index ae4696b5..b0f1d593 100644 --- a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php +++ b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php @@ -139,10 +139,11 @@ public function setUp () protected function mockGCurl ($version) { $standardFile = $this->getAssertDirectory() . $this->standardVersionFile; + $that = $this; $this->mockedSUT->staticExpects($this->any()) ->method('gCurl') - ->will($this->returnCallback(function() use ($standardFile, $version) { + ->will($this->returnCallback(function() use ($standardFile, $version, $that) { $file = sprintf($standardFile, $version . '-page-' . $this->called); if (!file_exists($file)) { From 4f38d206c6dac4c59f183540fca58fc9aeb16a95 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 09:58:10 +0200 Subject: [PATCH 28/40] fix typo --- tests/SEOstatsTest/Helper/JsonTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SEOstatsTest/Helper/JsonTest.php b/tests/SEOstatsTest/Helper/JsonTest.php index ca4c8fc5..ae5b9167 100644 --- a/tests/SEOstatsTest/Helper/JsonTest.php +++ b/tests/SEOstatsTest/Helper/JsonTest.php @@ -53,7 +53,7 @@ public function providerTestEncode() return array( array($arrayValid, $jsonValid), - array(utf8_decode("json-with-uml-äöü"), false), + array(utf8_decode("json-with-uml-äöü"), null), ); } } From e7f324e2e043800bb7239a90cf0d4e2fe6b9eb37 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 09:59:37 +0200 Subject: [PATCH 29/40] fix php5.3 error --- tests/SEOstatsTest/Services/Google/GoogleSearchTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php index b0f1d593..9760c186 100644 --- a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php +++ b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php @@ -144,12 +144,12 @@ protected function mockGCurl ($version) $this->mockedSUT->staticExpects($this->any()) ->method('gCurl') ->will($this->returnCallback(function() use ($standardFile, $version, $that) { - $file = sprintf($standardFile, $version . '-page-' . $this->called); + $file = sprintf($standardFile, $version . '-page-' . $that->called); if (!file_exists($file)) { $file = sprintf($standardFile, $version); } - $this->called++; + $that->called++; return file_get_contents($file); })); From 3ba547ab8e6c0ce086e89edeffece4b57ada641f Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 10:01:43 +0200 Subject: [PATCH 30/40] fix access error in test --- tests/SEOstatsTest/Services/Google/GoogleSearchTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php index 9760c186..0792789c 100644 --- a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php +++ b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php @@ -8,7 +8,7 @@ class GoogleSearchTest extends AbstractGoogleTestCase { protected $standardVersionFile = "google-search-%s.html"; protected $standardVersionSubFile = "google-search-%s-%s-%s.html"; - protected $called = 0; + public $called = 0; /** * @group google From 4de6b8c2eb9ddadfd04fc70f603a78ea47890393 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 10:17:01 +0200 Subject: [PATCH 31/40] fix tests for php version 5.3, 5.4 --- tests/SEOstatsTest/AbstractSEOstatsTestCase.php | 12 +++++------- tests/SEOstatsTest/Helper/JsonTest.php | 3 ++- tests/SEOstatsTest/SEOstatsTest.php | 2 +- .../Services/Google/GoogleSearchTest.php | 2 +- tests/SEOstatsTest/Services/MozscapeTest.php | 16 +++++++++------- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tests/SEOstatsTest/AbstractSEOstatsTestCase.php b/tests/SEOstatsTest/AbstractSEOstatsTestCase.php index 444b30cd..73f394f7 100644 --- a/tests/SEOstatsTest/AbstractSEOstatsTestCase.php +++ b/tests/SEOstatsTest/AbstractSEOstatsTestCase.php @@ -12,9 +12,7 @@ abstract class AbstractSEOstatsTestCase extends \PHPUnit_Framework_TestCase protected $assertDirectory; - protected $SUT; - - protected $mockedSUT; + public $mockedSUT; /** @@ -48,7 +46,7 @@ public function getAssertDirectory ($file = null) } - protected function getStandardVersions ($version, $methode) + public function getStandardVersions ($version, $methode) { $filePattern = $this->standardVersionSubFile; $methodeFile = sprintf($this->getAssertDirectory($filePattern), $version, $methode, 1); @@ -71,7 +69,7 @@ protected function getStandardVersions ($version, $methode) return $result; } - protected function helperMakeAccessable ($object, $propertyOrMethod, $value = null) + public function helperMakeAccessable ($object, $propertyOrMethod, $value = null) { if ( is_string($object) ) { $objectClass = $object; @@ -85,7 +83,7 @@ protected function helperMakeAccessable ($object, $propertyOrMethod, $value = nu } $reflection = $this->reflection[$objectClass]; $isMethod = $reflection->hasMethod($propertyOrMethod); - + if ($isMethod) { $reflectionSub = $reflection->getMethod($propertyOrMethod); } else { @@ -105,7 +103,7 @@ protected function helperMakeAccessable ($object, $propertyOrMethod, $value = nu return $reflectionSub; } - protected function mockGetPage($arg = null) + public function mockGetPage($arg = null) { if (is_callable($arg)) { $this->mockedSUT->staticExpects($this->any()) diff --git a/tests/SEOstatsTest/Helper/JsonTest.php b/tests/SEOstatsTest/Helper/JsonTest.php index ae5b9167..16ee421d 100644 --- a/tests/SEOstatsTest/Helper/JsonTest.php +++ b/tests/SEOstatsTest/Helper/JsonTest.php @@ -53,7 +53,8 @@ public function providerTestEncode() return array( array($arrayValid, $jsonValid), - array(utf8_decode("json-with-uml-äöü"), null), + array(utf8_decode("json-with-uml-äöü"), + version_compare(PHP_VERSION, '5.5', '<') ? 'null' : false), ); } } diff --git a/tests/SEOstatsTest/SEOstatsTest.php b/tests/SEOstatsTest/SEOstatsTest.php index b402741d..b4098120 100644 --- a/tests/SEOstatsTest/SEOstatsTest.php +++ b/tests/SEOstatsTest/SEOstatsTest.php @@ -10,7 +10,7 @@ class SEOstatsTest extends AbstractSEOstatsTestCase * * @var SEOstats */ - protected $SUT; + public $SUT; public function setUp() { diff --git a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php index 0792789c..d63b720f 100644 --- a/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php +++ b/tests/SEOstatsTest/Services/Google/GoogleSearchTest.php @@ -52,7 +52,7 @@ public function testGetSerps($args, $version, $assertResultCount) { $this->mockSUT('getSerps'); $this->mockGCurl ($version); - + $result = $this->helperMakeAccessable($this->mockedSUT, 'getSerps', $args); $this->assertEquals($assertResultCount, count($result)); diff --git a/tests/SEOstatsTest/Services/MozscapeTest.php b/tests/SEOstatsTest/Services/MozscapeTest.php index 70a53e83..c4b2f788 100644 --- a/tests/SEOstatsTest/Services/MozscapeTest.php +++ b/tests/SEOstatsTest/Services/MozscapeTest.php @@ -72,17 +72,18 @@ public function testGetMethodeMethods($methode, $metricCode, $callbackReturn, $a public function testGetCols($callbackReturn, $assertResult) { $this->mockSUT('getCols'); - $this->mockGetPage(function($url) use($callbackReturn) { + $that = $this; + $this->mockGetPage(function($url) use($callbackReturn, $that) { $parse = parse_url($url); parse_str($parse['query'], $query); - $assertSignature = $this->helperMakeAccessable( - $this->SUT, + $assertSignature = $that->helperMakeAccessable( + $that->SUT, '_getUrlSafeSignature', array($query['Expires'], basename($parse['path'])) ); - $this->assertEquals($assertSignature, $query['Signature']); + $that->assertEquals($assertSignature, $query['Signature']); return $callbackReturn; }); @@ -151,12 +152,13 @@ protected function mockSUT($method=null, $vars=array()) protected function mockGetCols ($assertParams, $returnValue) { + $that = $this; $this->mockedSUT->staticExpects($this->any()) ->method('getCols') - ->will($this->returnCallback(function ($cols, $url = null) use($assertParams, $returnValue) { + ->will($this->returnCallback(function ($cols, $url = null) use($assertParams, $returnValue, $that) { - $this->assertEquals($assertParams[0], $cols); - $this->assertEquals($assertParams[1], $url); + $that->assertEquals($assertParams[0], $cols); + $that->assertEquals($assertParams[1], $url); return $returnValue; })); From 200ccfe7ac24ac0f296f7c85f6b90604ad7817e9 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 10:32:00 +0200 Subject: [PATCH 32/40] fix HHVM tests --- tests/SEOstatsTest/Helper/JsonTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/SEOstatsTest/Helper/JsonTest.php b/tests/SEOstatsTest/Helper/JsonTest.php index 16ee421d..d602a41c 100644 --- a/tests/SEOstatsTest/Helper/JsonTest.php +++ b/tests/SEOstatsTest/Helper/JsonTest.php @@ -54,7 +54,13 @@ public function providerTestEncode() return array( array($arrayValid, $jsonValid), array(utf8_decode("json-with-uml-äöü"), - version_compare(PHP_VERSION, '5.5', '<') ? 'null' : false), + $this->helperJsonGivesFalseOrNull() ? false : 'null' + ), ); } + + public function helperJsonGivesFalseOrNull () + { + return defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.5', '>'); + } } From b8720374abb3e0b90c9511dfe8b936e805ad3117 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 10:40:52 +0200 Subject: [PATCH 33/40] fix typo --- tests/SEOstatsTest/Helper/JsonTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/SEOstatsTest/Helper/JsonTest.php b/tests/SEOstatsTest/Helper/JsonTest.php index d602a41c..679c57b9 100644 --- a/tests/SEOstatsTest/Helper/JsonTest.php +++ b/tests/SEOstatsTest/Helper/JsonTest.php @@ -54,13 +54,13 @@ public function providerTestEncode() return array( array($arrayValid, $jsonValid), array(utf8_decode("json-with-uml-äöü"), - $this->helperJsonGivesFalseOrNull() ? false : 'null' + $this->helperJsonGivesFalseOrNull() ? 'null' : false ), ); } public function helperJsonGivesFalseOrNull () { - return defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.5', '>'); + return defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.5', '<'); } } From 72000f634200899ac19dc97ebdb81153e0707cf1 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 10:55:43 +0200 Subject: [PATCH 34/40] add excluded path to scrutinizer ci --- .scrutinizer.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 39c28269..d2a0ad91 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -4,3 +4,11 @@ imports: tools: external_code_coverage: timeout: 2100 + +filter: + excluded_paths: + - SEOstats/Services/3rdparty/* + - vendor/* + - tests/* + - app/* + - bin/* From 351eb9543d84916244e3e76c452548c999fafe0b Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 17 Jul 2014 11:29:15 +0200 Subject: [PATCH 35/40] add test case for social and SemRush --- tests/SEOstatsTest/Services/SemRushTest.php | 73 +++++++++++++++++++ tests/SEOstatsTest/Services/SocialTest.php | 78 +++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 tests/SEOstatsTest/Services/SemRushTest.php create mode 100644 tests/SEOstatsTest/Services/SocialTest.php diff --git a/tests/SEOstatsTest/Services/SemRushTest.php b/tests/SEOstatsTest/Services/SemRushTest.php new file mode 100644 index 00000000..c1b32ffb --- /dev/null +++ b/tests/SEOstatsTest/Services/SemRushTest.php @@ -0,0 +1,73 @@ +reflection = array(); + + $this->url = 'http://github.com'; + } + + public function testGetDBs() + { + $this->markTestIncomplete(); + } + + public function testGetParams() + { + $this->markTestIncomplete(); + } + + public function testGetDomainRank() + { + $this->markTestIncomplete(); + } + + public function testGetDomainRankHistory() + { + $this->markTestIncomplete(); + } + + public function testGetOrganicKeywords() + { + $this->markTestIncomplete(); + } + + public function testGetCompetitors() + { + $this->markTestIncomplete(); + } + + public function testGetDomainGraph() + { + $this->markTestIncomplete(); + } + + public function testGetApiData() + { + $this->markTestIncomplete(); + } + + public function testGetBackendUrl() + { + $this->markTestIncomplete(); + } + + public function testGetWidgetUrl() + { + $this->markTestIncomplete(); + } + + public function testExc() + { + $this->markTestIncomplete(); + } +} diff --git a/tests/SEOstatsTest/Services/SocialTest.php b/tests/SEOstatsTest/Services/SocialTest.php new file mode 100644 index 00000000..c8f1691b --- /dev/null +++ b/tests/SEOstatsTest/Services/SocialTest.php @@ -0,0 +1,78 @@ +reflection = array(); + + $this->url = 'http://github.com'; + } + + public function testGetGoogleShares() + { + $this->markTestIncomplete(); + } + + public function testGetGooglePlusShares() + { + $this->markTestIncomplete(); + } + + public function testGetFacebookShares() + { + $this->markTestIncomplete(); + } + + public function testGetTwitterShares() + { + $this->markTestIncomplete(); + } + + public function testGetDeliciousShares() + { + $this->markTestIncomplete(); + } + + public function testGetDeliciousTopTags() + { + $this->markTestIncomplete(); + } + + public function testGetDiggShares() + { + $this->markTestIncomplete(); + } + + public function testGetLinkedInShares() + { + $this->markTestIncomplete(); + } + + public function testGetPinterestShares() + { + $this->markTestIncomplete(); + } + + public function testGetStumbleUponShares() + { + $this->markTestIncomplete(); + } + + public function testGetVKontakteShares() + { + $this->markTestIncomplete(); + } + + public function testGetXingShares() + { + $this->markTestIncomplete(); + } +} From 4b50ca79ef3f3c5161e1e47993689461b35ad6cb Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 24 Jul 2014 10:47:02 +0200 Subject: [PATCH 36/40] update version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c89c0d78..dbb6ced0 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "Alexa" ], "homepage" : "http://github.com/eyecatchup/SEOstats", - "version" : "2.5.2", + "version" : "2.5.3-beta2", "license" : "MIT", "authors" : [{ "name" : "Stephan Schmitz", From 4e1bec709d171a2f215d4e8cbe909d4ca9ec3c0e Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 24 Jul 2014 10:47:32 +0200 Subject: [PATCH 37/40] update composer keywords [ci skip] --- composer.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/composer.json b/composer.json index dbb6ced0..4150760a 100644 --- a/composer.json +++ b/composer.json @@ -4,6 +4,8 @@ "description" : "SEOstats is a powerful open source PHP library to request a bunch of SEO relevant metrics for any website.", "keywords" : [ "SEO", + "SEOStats", + "SEO-Stats", "Pagerank", "Backlinks", "Google", From 3f92d1ef2c9cdbc7d680df3ebf8975f3abb37364 Mon Sep 17 00:00:00 2001 From: Clemens Sahs Date: Thu, 24 Jul 2014 16:03:18 +0200 Subject: [PATCH 38/40] remove version from composer, add branch-alias to master [ci skip] --- composer.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 4150760a..d9cfb953 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "Alexa" ], "homepage" : "http://github.com/eyecatchup/SEOstats", - "version" : "2.5.3-beta2", "license" : "MIT", "authors" : [{ "name" : "Stephan Schmitz", @@ -48,5 +47,10 @@ "classmap" : [ "SEOstats/Services/3rdparty" ] - } + }, + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + } } From 4cbab6c085977233f5e4584da2a54e06bed53e0e Mon Sep 17 00:00:00 2001 From: Thomas Lutz Date: Fri, 25 Jul 2014 12:56:50 +0200 Subject: [PATCH 39/40] Fixed SEMRush to SemRush calls in Readme --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1d86ce18..c8418d6d 100644 --- a/README.md +++ b/README.md @@ -348,16 +348,16 @@ More detailed examples can be found in the `./example` directory. ```php From f6a16f9c19b5dff32a7642815a6194adb6b72934 Mon Sep 17 00:00:00 2001 From: Thomas Lutz Date: Sat, 26 Jul 2014 12:54:42 +0200 Subject: [PATCH 40/40] Fixed SEMRush examples --- example/get-semrush-graphs.php | 16 ++++++++-------- example/get-semrush-metrics.php | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/example/get-semrush-graphs.php b/example/get-semrush-graphs.php index 9e0e72b9..f4e812a9 100644 --- a/example/get-semrush-graphs.php +++ b/example/get-semrush-graphs.php @@ -6,7 +6,7 @@ * @author Stephan Schmitz * @copyright Copyright (c) 2010 - present Stephan Schmitz * @license http://eyecatchup.mit-license.org/ MIT License - * @updated 2013/12/17 + * @updated 2014/07/26 */ // NOTE: The given path to the autoload.php assumes that you installed SEOstats via composer @@ -24,10 +24,10 @@ #require_once realpath(__DIR__ . '/SEOstats/bootstrap.php'); require_once realpath(__DIR__ . '/vendor/autoload.php'); -use \SEOstats\Services\SEMRush as SEMrush; +use \SEOstats\Services\SemRush; try { - $url = 'http://www.nahklick.de/'; + $url = 'http://www.google.de/'; // Create a new SEOstats instance. $seostats = new \SEOstats\SEOstats; @@ -38,25 +38,25 @@ /** * Print HTML code for the 'search engine traffic'-graph. */ - echo SEMrush::getDomainGraph(1); + echo SemRush::getDomainGraph(1); /** * Print HTML code for the 'search engine traffic price'-graph. */ - echo SEMrush::getDomainGraph(2); + echo SemRush::getDomainGraph(2); /** * Print HTML code for the 'number of adwords ads'-graph, * using explicitly SEMRush's data for google.de (german index). */ - echo SEMrush::getDomainGraph(3, false, 'de'); + echo SemRush::getDomainGraph(3, false, 'de'); /** * Print HTML code for the 'adwords traffic'-graph, using * explicitly SEMRush's data for google.de (german index) * and specific graph dimensions of 320*240 px. */ - echo SEMrush::getDomainGraph(4, false, 'de', 320, 240); + echo SemRush::getDomainGraph(4, false, 'de', 320, 240); /** * Print HTML code for the 'adwords traffic price'-graph, @@ -64,7 +64,7 @@ * specific graph dimensions of 320*240 px and specific * graph colors (black lines and red dots for data points). */ - echo SEMrush::getDomainGraph(5, false, 'de', 320, 240, '000000', 'ff0000'); + echo SemRush::getDomainGraph(5, false, 'de', 320, 240, '000000', 'ff0000'); } } catch (\Exception $e) { diff --git a/example/get-semrush-metrics.php b/example/get-semrush-metrics.php index 562dc46d..3b7c822e 100644 --- a/example/get-semrush-metrics.php +++ b/example/get-semrush-metrics.php @@ -6,7 +6,7 @@ * @author Stephan Schmitz * @copyright Copyright (c) 2010 - present Stephan Schmitz * @license http://eyecatchup.mit-license.org/ MIT License - * @updated 2013/12/17 + * @updated 2014/07/26 */ // NOTE: The given path to the autoload.php assumes that you installed SEOstats via composer @@ -24,10 +24,10 @@ #require_once realpath(__DIR__ . '/SEOstats/bootstrap.php'); require_once realpath(__DIR__ . '/vendor/autoload.php'); -use \SEOstats\Services\SEMRush as SEMrush; +use \SEOstats\Services\SemRush; try { - $url = 'http://www.nahklick.de/'; + $url = 'http://www.google.de/'; // Create a new SEOstats instance. $seostats = new \SEOstats\SEOstats; @@ -38,18 +38,18 @@ /** * Get the current SEMrush DomainRank metrics for the given URL. */ - print_r(SEMrush::getDomainRank()); + print_r(SemRush::getDomainRank()); /** * Get historical SEMrush DomainRank metrics for the given URL. */ - //print_r(SEMrush::getDomainRankHistory()); + //print_r(SemRush::getDomainRankHistory()); /** * Get competing domains for the given URL * and their basic SEMrush DomainRank metrics. */ - //print_r(SEMrush::getCompetitors()); + //print_r(SemRush::getCompetitors()); /** * Get organic search engine traffic data for the given URL. @@ -60,13 +60,13 @@ * Get organic search engine traffic metrics for the given URL, * using explicitly SEMrush's data for google.de (german index). */ - //print_r(SEMrush::getOrganicKeywords(false, 'de')); + //print_r(SemRush::getOrganicKeywords(false, 'de')); /** * Get an array containing explainations for the * result keys of the DomainRank metric methods. */ - //print_r(SEMrush::getParams()); + //print_r(SemRush::getParams()); } } catch (\Exception $e) {