├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── assets ├── entrecore.png └── opsbears.png ├── build.xml ├── composer.json ├── data └── ca-bundle.crt ├── phpunit.xml ├── src ├── GTMetrixBrowser.php ├── GTMetrixClient.php ├── GTMetrixConfigurationException.php ├── GTMetrixException.php ├── GTMetrixLocation.php └── GTMetrixTest.php └── tests ├── AbstractGTMetrixTest.php └── GTMetrixFunctionalTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | doc 2 | build 3 | composer.lock 4 | 5 | .DS_Store 6 | 7 | # Created by .ignore support plugin (hsz.mobi) 8 | ### Composer template 9 | composer.phar 10 | vendor/ 11 | 12 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file 13 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file 14 | # composer.lock 15 | 16 | 17 | ### JetBrains template 18 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion 19 | 20 | *.iml 21 | 22 | ## Directory-based project format: 23 | .idea/ 24 | # if you remove the above rule, at least ignore the following: 25 | 26 | # User-specific stuff: 27 | # .idea/workspace.xml 28 | # .idea/tasks.xml 29 | # .idea/dictionaries 30 | 31 | # Sensitive or high-churn files: 32 | # .idea/dataSources.ids 33 | # .idea/dataSources.xml 34 | # .idea/sqlDataSources.xml 35 | # .idea/dynamic.xml 36 | # .idea/uiDesigner.xml 37 | 38 | # Gradle: 39 | # .idea/gradle.xml 40 | # .idea/libraries 41 | 42 | # Mongo Explorer plugin: 43 | # .idea/mongoSettings.xml 44 | 45 | ## File-based project format: 46 | *.ipr 47 | *.iws 48 | 49 | ## Plugin-specific files: 50 | 51 | # IntelliJ 52 | /out/ 53 | 54 | # mpeltonen/sbt-idea plugin 55 | .idea_modules/ 56 | 57 | # JIRA plugin 58 | atlassian-ide-plugin.xml 59 | 60 | # Crashlytics plugin (for Android Studio and IntelliJ) 61 | com_crashlytics_export_strings.xml 62 | crashlytics.properties 63 | crashlytics-build.properties 64 | 65 | 66 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 7.0 4 | - 5.6 5 | - 5.5 6 | - 5.4 7 | - 5.3 8 | - hhvm 9 | install: 10 | - composer remove --dev apigen/apigen 11 | - composer install 12 | script: ./vendor/bin/phing tests 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Opsbears 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 4 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 5 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit 6 | persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the 9 | Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 12 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 13 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 14 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GTMetrix API client for PHP 2 | 3 | **This package is abandoned.** We are no longer using GTMetrix from PHP, and are therefore no longer able to provide updates or support for this package. Please use [philcook/gtmetrix](https://github.com/philcook/php-gtmetrix) instead. 4 | -------------------------------------------------------------------------------- /assets/entrecore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superaligned/php-gtmetrix/17cc2941242cb7ea7a3dcb0056643f17b9c56a4b/assets/entrecore.png -------------------------------------------------------------------------------- /assets/opsbears.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/superaligned/php-gtmetrix/17cc2941242cb7ea7a3dcb0056643f17b9c56a4b/assets/opsbears.png -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "entrecore/gtmetrix", 3 | "description": "GTMetrix API client for PHP", 4 | "license": "MIT", 5 | "autoload": { 6 | "psr-4": { 7 | "Entrecore\\GTMetrixClient\\": "src/" 8 | } 9 | }, 10 | "require": { 11 | "php": ">=5.3.3", 12 | "ext-curl": "*" 13 | }, 14 | "require-dev": { 15 | "phpunit/phpunit": "~4.6", 16 | "apigen/apigen": "~4.1", 17 | "phing/phing": "~2.11" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | tests 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/GTMetrixBrowser.php: -------------------------------------------------------------------------------- 1 | id; 45 | } 46 | 47 | /** 48 | * @param string $id 49 | */ 50 | public function setId($id) { 51 | $this->id = $id; 52 | } 53 | 54 | /** 55 | * @return string 56 | */ 57 | public function getName() { 58 | return $this->name; 59 | } 60 | 61 | /** 62 | * @param string $name 63 | */ 64 | public function setName($name) { 65 | $this->name = $name; 66 | } 67 | 68 | /** 69 | * @return string 70 | */ 71 | public function getPlatform() { 72 | return $this->platform; 73 | } 74 | 75 | /** 76 | * @param string $platform 77 | */ 78 | public function setPlatform($platform) { 79 | $this->platform = $platform; 80 | } 81 | 82 | /** 83 | * @return string 84 | */ 85 | public function getDevice() { 86 | return $this->device; 87 | } 88 | 89 | /** 90 | * @param string $device 91 | */ 92 | public function setDevice($device) { 93 | $this->device = $device; 94 | } 95 | 96 | /** 97 | * @return string 98 | */ 99 | public function getBrowser() { 100 | return $this->browser; 101 | } 102 | 103 | /** 104 | * @param string $browser 105 | */ 106 | public function setBrowser($browser) { 107 | $this->browser = $browser; 108 | } 109 | 110 | /** 111 | * @return array 112 | */ 113 | public function getFeatures() { 114 | return $this->features; 115 | } 116 | 117 | /** 118 | * @param array $features 119 | */ 120 | public function setFeatures($features) { 121 | $this->features = $features; 122 | } 123 | 124 | /** 125 | * @param string $feature 126 | * 127 | * @return bool 128 | */ 129 | public function hasFeature($feature) { 130 | if (\array_search($feature, $this->features) !== false) { 131 | return true; 132 | } 133 | return false; 134 | } 135 | 136 | /** 137 | * @param array $data 138 | */ 139 | public function fromArray($data) { 140 | $this->setId($data['id']); 141 | $this->setName($data['name']); 142 | $this->setBrowser($data['browser']); 143 | $this->setDevice($data['device']); 144 | 145 | $features = array(); 146 | foreach ($data['features'] as $feature => $supported) { 147 | if ($supported) { 148 | $features[] = $feature; 149 | } 150 | } 151 | $this->setFeatures($features); 152 | $this->setPlatform($data['platform']); 153 | } 154 | 155 | /** 156 | * @return string 157 | */ 158 | public function __toString() { 159 | return $this->getId(); 160 | } 161 | 162 | } -------------------------------------------------------------------------------- /src/GTMetrixClient.php: -------------------------------------------------------------------------------- 1 | setUsername('your@email.com'); 12 | * $client->setAPIKey('your-gtmetrix-api-key'); 13 | * 14 | * $client->getLocations(); 15 | * $client->getBrowsers(); 16 | * $test = $client->startTest(); 17 | * 18 | * //Wait for result 19 | * while ($test->getState() != GTMetrixTest::STATE_COMPLETED && 20 | * $test->getState() != GTMetrixTest::STATE_ERROR) { 21 | * $client->getTestStatus($test); 22 | * sleep(5); 23 | * } 24 | * 25 | */ 26 | class GTMetrixClient { 27 | /** 28 | * API endpoint. Normally you don't need to change this. 29 | * 30 | * @var string 31 | */ 32 | protected $endpoint = 'https://gtmetrix.com/api/0.1'; 33 | 34 | /** 35 | * GTMetrix username 36 | * 37 | * @var string 38 | */ 39 | protected $username = ''; 40 | 41 | /** 42 | * GTMetrix API key. 43 | * 44 | * @var string 45 | * 46 | * @see http://gtmetrix.com/api/ 47 | */ 48 | protected $apiKey = ''; 49 | 50 | /** 51 | * @return string 52 | */ 53 | public function getUsername() { 54 | return $this->username; 55 | } 56 | 57 | /** 58 | * @param string $username 59 | */ 60 | public function setUsername($username) { 61 | $this->username = $username; 62 | } 63 | 64 | /** 65 | * @return string 66 | */ 67 | public function getAPIKey() { 68 | return $this->apiKey; 69 | } 70 | 71 | /** 72 | * @param string $url 73 | * @param array $data 74 | * @param bool $json 75 | * 76 | * @return array|string 77 | * 78 | * @throws GTMetrixConfigurationException 79 | * @throws GTMetrixException 80 | */ 81 | protected function apiCall($url, $data = array(), $json = true) { 82 | if (!$this->username || !$this->apiKey) { 83 | throw new GTMetrixConfigurationException('Username and API key must be set up before using API calls!' . 84 | 'See setUsername() and setAPIKey() for details.'); 85 | } 86 | 87 | $ch = curl_init($this->endpoint . $url); 88 | if (!empty($data)) { 89 | curl_setopt($ch, CURLOPT_POST, count($data)); 90 | curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); 91 | } 92 | curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 93 | curl_setopt($ch, CURLOPT_USERPWD, $this->username . ':' . $this->apiKey); 94 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 95 | curl_setopt($ch, CURLOPT_CAINFO, dirname(__DIR__) . '/data/ca-bundle.crt'); 96 | $result = curl_exec($ch); 97 | $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 98 | $curlErrNo = curl_errno($ch); 99 | $curlError = curl_error($ch); 100 | curl_close ($ch); 101 | 102 | if (!\preg_match('/^(2|3)/', $statusCode)) { 103 | if ($statusCode == 0) { 104 | throw new GTMetrixException('cURL error ' . $curlErrNo . ': ' . $curlError); 105 | } 106 | throw new GTMetrixException('API error ' . $statusCode . ': ' . $result); 107 | } 108 | 109 | if ($json) { 110 | $data = json_decode($result, true); 111 | if (json_last_error()) { 112 | throw new GTMetrixException('Invalid JSON received: ' . json_last_error_msg()); 113 | } 114 | } else { 115 | $data = $result; 116 | } 117 | 118 | return $data; 119 | } 120 | 121 | /** 122 | * @param string $apiKey 123 | */ 124 | public function setAPIKey($apiKey) { 125 | $this->apiKey = $apiKey; 126 | } 127 | 128 | /** 129 | * @return GTMetrixLocation[] 130 | * 131 | * @throws GTMetrixConfigurationException 132 | */ 133 | public function getLocations() { 134 | $result = $this->apiCall('/locations'); 135 | 136 | $locations = array(); 137 | foreach ($result as $locationData) { 138 | $location = new GTMetrixLocation(); 139 | $location->fromArray($locationData); 140 | $locations[] = $location; 141 | } 142 | return $locations; 143 | } 144 | 145 | /** 146 | * @return GTMetrixBrowser[] 147 | * 148 | * @throws GTMetrixConfigurationException 149 | */ 150 | public function getBrowsers() { 151 | $result = $this->apiCall('/browsers'); 152 | 153 | $browsers = array(); 154 | foreach ($result as $browserData) { 155 | $browser = new GTMetrixBrowser(); 156 | $browser->fromArray($browserData); 157 | $browsers[] = $browser; 158 | } 159 | return $browsers; 160 | } 161 | 162 | /** 163 | * @param string $id 164 | * 165 | * @return GTMetrixBrowser 166 | * @throws GTMetrixConfigurationException 167 | * @throws GTMetrixException 168 | */ 169 | public function getBrowser($id) { 170 | $result = $this->apiCall('/browsers/' . urlencode($id)); 171 | $browser = new GTMetrixBrowser(); 172 | $browser->fromArray($result); 173 | return $browser; 174 | } 175 | 176 | /** 177 | * Start a GTMetrix test 178 | * 179 | * @param string $url 180 | * 181 | * @param null|string $location 182 | * @param null|string $browser 183 | * @param null|string $httpUser 184 | * @param null|string $httpPassword 185 | * 186 | * @return GTMetrixTest 187 | * @throws GTMetrixConfigurationException 188 | * @throws GTMetrixException 189 | */ 190 | public function startTest($url, $location = null, $browser = null, $httpUser = null, $httpPassword = null) { 191 | 192 | $data = array(); 193 | $data['url'] = $url; 194 | if ($location) { 195 | $data['location'] = $location; 196 | } 197 | if ($browser) { 198 | $data['browser'] = $browser; 199 | } 200 | if ($httpUser) { 201 | $data['login-user'] = $httpUser; 202 | } 203 | if ($httpPassword) { 204 | $data['login-pass'] = $httpPassword; 205 | } 206 | $result = $this->apiCall('/test', $data); 207 | 208 | $test = new GTMetrixTest(); 209 | $test->setId($result['test_id']); 210 | $test->setPollStateUrl($result['poll_state_url']); 211 | 212 | return $test; 213 | } 214 | 215 | /** 216 | * @param GTMetrixTest|string $test GTMetrixTest or test ID. This object will be updated 217 | * 218 | * @return GTMetrixTest 219 | */ 220 | public function getTestStatus($test) { 221 | if ($test instanceof GTMetrixTest) { 222 | $testId = $test->getId(); 223 | } else { 224 | $testId = $test; 225 | $test = new GTMetrixTest(); 226 | $test->setId($testId); 227 | } 228 | 229 | $testStatus = $this->apiCall('/test/' . urlencode($testId)); 230 | $test->setState($testStatus['state']); 231 | $test->setError($testStatus['error']); 232 | if ($test->getState() == GTMetrixTest::STATE_COMPLETED) { 233 | $test->setReportUrl($testStatus['results']['report_url']); 234 | $test->setPagespeedScore($testStatus['results']['pagespeed_score']); 235 | $test->setYslowScore($testStatus['results']['yslow_score']); 236 | $test->setHtmlBytes($testStatus['results']['html_bytes']); 237 | $test->setHtmlLoadTime($testStatus['results']['html_load_time']); 238 | $test->setPageBytes($testStatus['results']['page_bytes']); 239 | $test->setPageLoadTime($testStatus['results']['page_load_time']); 240 | $test->setPageElements($testStatus['results']['page_elements']); 241 | $test->setResources($testStatus['resources']); 242 | } 243 | 244 | return $test; 245 | } 246 | } 247 | -------------------------------------------------------------------------------- /src/GTMetrixConfigurationException.php: -------------------------------------------------------------------------------- 1 | id; 33 | } 34 | 35 | /** 36 | * @param string $id 37 | */ 38 | public function setId($id) { 39 | $this->id = $id; 40 | } 41 | 42 | /** 43 | * @return string 44 | */ 45 | public function getName() { 46 | return $this->name; 47 | } 48 | 49 | /** 50 | * @param string $name 51 | */ 52 | public function setName($name) { 53 | $this->name = $name; 54 | } 55 | 56 | /** 57 | * @return boolean 58 | */ 59 | public function isDefault() { 60 | return $this->default; 61 | } 62 | 63 | /** 64 | * @param boolean $default 65 | */ 66 | public function setDefault($default) { 67 | $this->default = $default; 68 | } 69 | 70 | /** 71 | * @return string[] 72 | */ 73 | public function getBrowserIds() { 74 | return $this->browserIds; 75 | } 76 | 77 | /** 78 | * @param string[] $browserIds 79 | */ 80 | public function setBrowserIds($browserIds) { 81 | $this->browserIds = $browserIds; 82 | } 83 | 84 | /** 85 | * @param array $data 86 | */ 87 | public function fromArray($data) { 88 | $this->setId($data['id']); 89 | $this->setName($data['name']); 90 | $this->setDefault($data['default']); 91 | $this->setBrowserIds($data['browsers']); 92 | } 93 | 94 | /** 95 | * @return string 96 | */ 97 | public function __toString() { 98 | return $this->getId(); 99 | } 100 | } -------------------------------------------------------------------------------- /src/GTMetrixTest.php: -------------------------------------------------------------------------------- 1 | id; 88 | } 89 | 90 | /** 91 | * @param string $id 92 | */ 93 | public function setId($id) { 94 | $this->id = $id; 95 | } 96 | 97 | /** 98 | * @return string 99 | */ 100 | public function getPollStateUrl() { 101 | return $this->pollStateUrl; 102 | } 103 | 104 | /** 105 | * @param string $pollStateUrl 106 | */ 107 | public function setPollStateUrl($pollStateUrl) { 108 | $this->pollStateUrl = $pollStateUrl; 109 | } 110 | 111 | /** 112 | * @return string 113 | */ 114 | public function getState() { 115 | return $this->state; 116 | } 117 | 118 | /** 119 | * @param string $state 120 | */ 121 | public function setState($state) { 122 | $this->state = $state; 123 | } 124 | 125 | /** 126 | * @return string 127 | */ 128 | public function getError() { 129 | return $this->error; 130 | } 131 | 132 | /** 133 | * @param string $error 134 | */ 135 | public function setError($error) { 136 | $this->error = $error; 137 | } 138 | 139 | /** 140 | * @return string 141 | */ 142 | public function getReportUrl() { 143 | return $this->reportUrl; 144 | } 145 | 146 | /** 147 | * @param string $reportUrl 148 | */ 149 | public function setReportUrl($reportUrl) { 150 | $this->reportUrl = $reportUrl; 151 | } 152 | 153 | /** 154 | * @return int 155 | */ 156 | public function getPagespeedScore() { 157 | return $this->pagespeedScore; 158 | } 159 | 160 | /** 161 | * @param int $pagespeedScore 162 | */ 163 | public function setPagespeedScore($pagespeedScore) { 164 | $this->pagespeedScore = $pagespeedScore; 165 | } 166 | 167 | /** 168 | * @return int 169 | */ 170 | public function getYslowScore() { 171 | return $this->yslowScore; 172 | } 173 | 174 | /** 175 | * @param int $yslowScore 176 | */ 177 | public function setYslowScore($yslowScore) { 178 | $this->yslowScore = $yslowScore; 179 | } 180 | 181 | /** 182 | * @return int 183 | */ 184 | public function getHtmlBytes() { 185 | return $this->htmlBytes; 186 | } 187 | 188 | /** 189 | * @param int $htmlBytes 190 | */ 191 | public function setHtmlBytes($htmlBytes) { 192 | $this->htmlBytes = $htmlBytes; 193 | } 194 | 195 | /** 196 | * @return int 197 | */ 198 | public function getHtmlLoadTime() { 199 | return $this->htmlLoadTime; 200 | } 201 | 202 | /** 203 | * @param int $htmlLoadTime 204 | */ 205 | public function setHtmlLoadTime($htmlLoadTime) { 206 | $this->htmlLoadTime = $htmlLoadTime; 207 | } 208 | 209 | /** 210 | * @return int 211 | */ 212 | public function getPageBytes() { 213 | return $this->pageBytes; 214 | } 215 | 216 | /** 217 | * @param int $pageBytes 218 | */ 219 | public function setPageBytes($pageBytes) { 220 | $this->pageBytes = $pageBytes; 221 | } 222 | 223 | /** 224 | * @return int 225 | */ 226 | public function getPageLoadTime() { 227 | return $this->pageLoadTime; 228 | } 229 | 230 | /** 231 | * @param int $pageLoadTime 232 | */ 233 | public function setPageLoadTime($pageLoadTime) { 234 | $this->pageLoadTime = $pageLoadTime; 235 | } 236 | 237 | /** 238 | * @return int 239 | */ 240 | public function getPageElements() { 241 | return $this->pageElements; 242 | } 243 | 244 | /** 245 | * @param int $pageElements 246 | */ 247 | public function setPageElements($pageElements) { 248 | $this->pageElements = $pageElements; 249 | } 250 | 251 | /** 252 | * @return array 253 | */ 254 | public function getResources() { 255 | return $this->resources; 256 | } 257 | 258 | /** 259 | * @param array $resources 260 | */ 261 | public function setResources($resources) { 262 | $this->resources = $resources; 263 | } 264 | 265 | /** 266 | * @return string 267 | */ 268 | public function __toString() { 269 | return $this->getId(); 270 | } 271 | } -------------------------------------------------------------------------------- /tests/AbstractGTMetrixTest.php: -------------------------------------------------------------------------------- 1 | client = new GTMetrixClient(); 19 | $this->client->setUsername(getenv('GTMETRIX_USERNAME')); 20 | $this->client->setAPIKey(getenv('GTMETRIX_APIKEY')); 21 | } 22 | } -------------------------------------------------------------------------------- /tests/GTMetrixFunctionalTest.php: -------------------------------------------------------------------------------- 1 | client->getBrowsers(); 13 | foreach ($browsers as $browser) { 14 | $this->assertInstanceOf('Entrecore\GTMetrixClient\GTMetrixBrowser', $browser); 15 | } 16 | } 17 | 18 | public function testGetLocations() { 19 | $locations = $this->client->getLocations(); 20 | foreach ($locations as $location) { 21 | $this->assertInstanceOf('Entrecore\GTMetrixClient\GTMetrixLocation', $location); 22 | } 23 | } 24 | 25 | public function testStart() { 26 | $test = $this->client->startTest('http://www.entrecore.com/'); 27 | $this->assertNotEmpty($test->getId()); 28 | while ($test->getState() != GTMetrixTest::STATE_COMPLETED && 29 | $test->getState() != GTMetrixTest::STATE_ERROR) { 30 | $this->client->getTestStatus($test); 31 | sleep(5); 32 | } 33 | } 34 | } 35 | --------------------------------------------------------------------------------