gothick /
php-akismet
| 1 | <?php |
||
| 2 | namespace Gothick\AkismetClient; |
||
| 3 | |||
| 4 | use \Gothick\AkismetClient\Result\VerifyKeyResult; |
||
|
0 ignored issues
–
show
|
|||
| 5 | use \Gothick\AkismetClient\Result\CommentCheckResult; |
||
|
0 ignored issues
–
show
The type
\Gothick\AkismetClient\Result\CommentCheckResult was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 6 | use \Gothick\AkismetClient\Result\SubmitHamResult; |
||
|
0 ignored issues
–
show
The type
\Gothick\AkismetClient\Result\SubmitHamResult was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 7 | use \Gothick\AkismetClient\Result\SubmitSpamResult; |
||
|
0 ignored issues
–
show
The type
\Gothick\AkismetClient\Result\SubmitSpamResult was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||
| 8 | |||
| 9 | /** |
||
| 10 | * Akismet API client. |
||
| 11 | * @author matt |
||
| 12 | * |
||
| 13 | */ |
||
| 14 | class Client |
||
| 15 | { |
||
| 16 | const VERB_VERIFY_KEY = 'verify-key'; |
||
| 17 | const VERB_COMMENT_CHECK = 'comment-check'; |
||
| 18 | const VERB_SUBMIT_SPAM = 'submit-spam'; |
||
| 19 | const VERB_SUBMIT_HAM = 'submit-ham'; |
||
| 20 | /** |
||
| 21 | * Akismet API key |
||
| 22 | * |
||
| 23 | * @var string |
||
| 24 | */ |
||
| 25 | private $api_key; |
||
| 26 | |||
| 27 | /** |
||
| 28 | * Our Guzzle client. |
||
| 29 | * This can be passed in for DI, or if not we'll create a default one ouselves. |
||
| 30 | * |
||
| 31 | * @var \GuzzleHttp\Client |
||
| 32 | */ |
||
| 33 | private $guzzle_client; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * URL of the site using us. |
||
| 37 | * Akismet calls this "blog", because WordPress. |
||
| 38 | * |
||
| 39 | * @var string |
||
| 40 | */ |
||
| 41 | private $blog; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * Name of the site using us. |
||
| 45 | * |
||
| 46 | * @var string |
||
| 47 | */ |
||
| 48 | private $app_name; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * Version string of the site using us. |
||
| 52 | * |
||
| 53 | * @var string |
||
| 54 | */ |
||
| 55 | private $app_version; |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Version of this Client. |
||
| 59 | * Akismet likes to know. We should bump this every time |
||
| 60 | * we package a new version. |
||
| 61 | * |
||
| 62 | * @var string |
||
| 63 | */ |
||
| 64 | const VERSION = '0.1'; |
||
| 65 | |||
| 66 | /** |
||
| 67 | * Make an Akismet API client. |
||
| 68 | * Typically you'd provide an API key in $api_key, at which point you can make any call. Without the optional |
||
| 69 | * $api_key you're limited to calling verifyApiKey. Once you've verified a key you can call setApiKey() |
||
| 70 | * later and start using the rest of the API. |
||
| 71 | * |
||
| 72 | * @param string $app_url |
||
| 73 | * e.g. http://forum.example.com/ |
||
| 74 | * @param string $app_name |
||
| 75 | * e.g. phpBB |
||
| 76 | * @param string $app_version |
||
| 77 | * e.g. 3.2.1 |
||
| 78 | * @param string $api_key |
||
| 79 | * (optional) Akismet API key |
||
| 80 | * @param |
||
| 81 | * \GuzzleHttp\Client (optional) $guzzle_client. You can inject a mock, or a non-Curl-using Guzzle |
||
| 82 | * client here, say. Otherwise we'll just make one. |
||
| 83 | * @throws \Gothick\AkismetClient\AkismetException |
||
| 84 | */ |
||
| 85 | 69 | public function __construct($app_url, $app_name, $app_version, $api_key = null, $guzzle_client = null) |
|
| 86 | { |
||
| 87 | 69 | if ((empty($app_url)) || (empty($app_name)) || (empty($app_version))) |
|
| 88 | { |
||
| 89 | 6 | throw new AkismetException('Must supply app URL, name and version in ' . __METHOD__); |
|
| 90 | } |
||
| 91 | // The Akismet API calls it a blog, so keep consistent. |
||
| 92 | 63 | $this->blog = $app_url; |
|
| 93 | |||
| 94 | 63 | $this->app_name = $app_name; |
|
| 95 | 63 | $this->app_version = $app_version; |
|
| 96 | 63 | $this->api_key = $api_key; |
|
| 97 | |||
| 98 | // Our client is passed in, as dependency injection is helpful for |
||
| 99 | // testing, but in the normal course of things we'll probably just |
||
| 100 | // create it ourselves. |
||
| 101 | 63 | $this->guzzle_client = $guzzle_client; |
|
| 102 | 63 | if (!isset($this->guzzle_client)) |
|
| 103 | { |
||
| 104 | 9 | $this->guzzle_client = new \GuzzleHttp\Client(); |
|
| 105 | } |
||
| 106 | } |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Headers to be sent on every API call |
||
| 110 | * |
||
| 111 | * @return string[] |
||
| 112 | */ |
||
| 113 | 51 | private function getStandardHeaders() |
|
| 114 | { |
||
| 115 | // I'd use Guzzle middleware for this, as we want to add it on |
||
| 116 | // every request, but how do I do that and support dependency |
||
| 117 | // injection of our client? You can't add middleware to a |
||
| 118 | // Guzzle client after it's been constructed, right? |
||
| 119 | 51 | return array( |
|
| 120 | 51 | 'User-Agent' => $this->getOurUserAgent() |
|
| 121 | 51 | ); |
|
| 122 | } |
||
| 123 | |||
| 124 | /** |
||
| 125 | * From the docs: |
||
| 126 | * Setting your user agent If possible, your user agent string should always use the following format: Application Name/Version | Plugin Name/Version |
||
| 127 | * e.g. WordPress/4.4.1 | Akismet/3.1.7 |
||
| 128 | * |
||
| 129 | * @return string |
||
| 130 | */ |
||
| 131 | 51 | private function getOurUserAgent() |
|
| 132 | { |
||
| 133 | 51 | return "{$this->app_name}/{$this->app_version} | Gothick\\AkismetClient/" . self::VERSION; |
|
| 134 | } |
||
| 135 | |||
| 136 | /** |
||
| 137 | * You may want to verify a key before you use it. To do that, construct a Client without an API |
||
| 138 | * key, then use verifyKey($key) to verify the key, then use setKey($key) to set the validated |
||
| 139 | * key. You can call verifyKey without a key set, but you must set a key before calling any other |
||
| 140 | * API method. |
||
| 141 | * |
||
| 142 | * @param string $api_key |
||
| 143 | * @throws \Gothick\AkismetClient\AkismetException |
||
| 144 | */ |
||
| 145 | 11 | public function setKey($api_key) |
|
| 146 | { |
||
| 147 | 11 | if (empty($api_key)) |
|
| 148 | { |
||
| 149 | 2 | throw new AkismetException('Must provide an API key in ' . __METHOD__); |
|
| 150 | } |
||
| 151 | 9 | $this->api_key = $api_key; |
|
| 152 | } |
||
| 153 | |||
| 154 | /** |
||
| 155 | * Verify an Akismet API key. |
||
| 156 | * @param string $api_key |
||
| 157 | * @param string[] $params Optional parameters. In verify-key, the only useful parameter is "is_test", |
||
| 158 | * which you should only pass when testing. To be honest, it's not even clear |
||
| 159 | * from the documentation if that parameter is used in verify-key, but better |
||
| 160 | * safe than sorry... |
||
| 161 | * @throws \Gothick\AkismetClient\AkismetException |
||
| 162 | * @return \Gothick\AkismetClient\Result\VerifyKeyResult |
||
| 163 | */ |
||
| 164 | 15 | public function verifyKey($api_key = null, $params = array()) |
|
| 165 | { |
||
| 166 | 15 | $key_to_verify = empty($api_key) ? $this->api_key : $api_key; |
|
| 167 | |||
| 168 | 15 | if (empty($key_to_verify)) |
|
| 169 | { |
||
| 170 | 1 | throw new AkismetException('Must provide or pre-configure a key in ' . __METHOD__); |
|
| 171 | } |
||
| 172 | |||
| 173 | try |
||
| 174 | { |
||
| 175 | 14 | $params = array_merge( |
|
| 176 | 14 | $params, |
|
| 177 | 14 | [ |
|
| 178 | 14 | "key" => $key_to_verify, |
|
| 179 | 14 | "blog" => $this->blog |
|
| 180 | 14 | ] |
|
| 181 | 14 | ); |
|
| 182 | 14 | $response = $this->callApiMethod(self::VERB_VERIFY_KEY, $params); |
|
| 183 | 1 | } catch (\Exception $e) |
|
| 184 | { |
||
| 185 | // Wrap whatever exception we caught up in a new exception of our |
||
| 186 | // own type and throw it along up the line. |
||
| 187 | 1 | throw new AkismetException('Unexpected exception in ' . __METHOD__, 0, $e); |
|
| 188 | } |
||
| 189 | 13 | return new VerifyKeyResult($response); |
|
| 190 | } |
||
| 191 | |||
| 192 | /** |
||
| 193 | * Check a comment for spam. |
||
| 194 | * See the Akismet API documentation for full details: |
||
| 195 | * https://akismet.com/development/api/#comment-check. |
||
| 196 | * Returns a valid CommentCheckResult object or throws an exception. |
||
| 197 | * |
||
| 198 | * @param string[] $params |
||
| 199 | * User IP, User-Agent, the message, etc. See the Akismet API |
||
| 200 | * documentation for details. |
||
| 201 | * @param string[] $server_params |
||
| 202 | * This can just be $_SERVER, if you have access to it |
||
| 203 | * @return \Gothick\AkismetClient\Result\CommentCheckResult |
||
| 204 | */ |
||
| 205 | 18 | public function commentCheck($params = array(), $server_params = array()) |
|
| 206 | { |
||
| 207 | 18 | return new CommentCheckResult($this->callSpamMethod(self::VERB_COMMENT_CHECK, $params, $server_params)); |
|
| 208 | } |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Submit a comment as spam. This must use the same parameters as those used when checking the |
||
| 212 | * comment with commetnCheck. |
||
| 213 | * See the Akismet API documentation for full details: |
||
| 214 | * https://akismet.com/development/api/#comment-check. |
||
| 215 | * Returns a valid SubmitSpamResult object or throws an exception. |
||
| 216 | * |
||
| 217 | * @param string[] $params |
||
| 218 | * User IP, User-Agent, the message, etc. See the Akismet API |
||
| 219 | * documentation for details. |
||
| 220 | * @param string[] $server_params |
||
| 221 | * This can just be $_SERVER, if you have access to it |
||
| 222 | * @return \Gothick\AkismetClient\Result\SubmitSpamResult |
||
| 223 | */ |
||
| 224 | 14 | public function submitSpam($params = array(), $server_params = array()) |
|
| 225 | { |
||
| 226 | 14 | return new SubmitSpamResult($this->callSpamMethod(self::VERB_SUBMIT_SPAM, $params, $server_params)); |
|
| 227 | } |
||
| 228 | |||
| 229 | /** |
||
| 230 | * Submit a comment as ham. This must use the same parameters as those used when checking the |
||
| 231 | * comment with commetnCheck. |
||
| 232 | * See the Akismet API documentation for full details: |
||
| 233 | * https://akismet.com/development/api/#comment-check. |
||
| 234 | * Returns a valid SubmitHamResult object or throws an exception. |
||
| 235 | * |
||
| 236 | * @param string[] $params |
||
| 237 | * User IP, User-Agent, the message, etc. See the Akismet API |
||
| 238 | * documentation for details. |
||
| 239 | * @param string[] $server_params |
||
| 240 | * This can just be $_SERVER, if you have access to it |
||
| 241 | * @return \Gothick\AkismetClient\Result\SubmitHamResult |
||
| 242 | */ |
||
| 243 | 14 | public function submitHam($params = array(), $server_params = array()) |
|
| 244 | { |
||
| 245 | 14 | return new SubmitHamResult($this->callSpamMethod(self::VERB_SUBMIT_HAM, $params, $server_params)); |
|
| 246 | } |
||
| 247 | |||
| 248 | /** |
||
| 249 | * Common code for calling check-comment, submit-ham and submit-spam; these all |
||
| 250 | * work in the same way, just returning slightly different results. |
||
| 251 | * @param string $verb |
||
| 252 | * @param string[] $params |
||
| 253 | * @param string[] $server_params |
||
| 254 | * @throws \Gothick\AkismetClient\AkismetException |
||
| 255 | */ |
||
| 256 | 46 | protected function callSpamMethod($verb, $params, $server_params) |
|
| 257 | { |
||
| 258 | // comment-check, submit-spam and submit-ham all work the same way and take |
||
| 259 | // the same arguments, so this handles them all. |
||
| 260 | 46 | if (empty($params[ 'user_ip' ]) || empty($params[ 'user_agent' ])) |
|
| 261 | { |
||
| 262 | 6 | throw new AkismetException(__METHOD__ . ' requires user_ip and user_agent in $params (' . $verb . ')'); |
|
| 263 | } |
||
| 264 | 40 | $params = array_merge($server_params, $params); |
|
| 265 | 40 | $params = array_merge($params, [ |
|
| 266 | 40 | 'blog' => $this->blog |
|
| 267 | 40 | ]); |
|
| 268 | |||
| 269 | try |
||
| 270 | { |
||
| 271 | 40 | $response = $this->callApiMethod($verb, $params); |
|
| 272 | 3 | } catch (\Exception $e) |
|
| 273 | { |
||
| 274 | 3 | throw new AkismetException('Unexpected exception in ' . __METHOD__ . ' (' . $verb . ')', 0, $e); |
|
| 275 | } |
||
| 276 | 37 | return $response; |
|
| 277 | } |
||
| 278 | /** |
||
| 279 | * Call an Akisemet API method. |
||
| 280 | * @param string $verb |
||
| 281 | * @param array $params |
||
| 282 | * @return \GuzzleHttp\Psr7\Response |
||
| 283 | */ |
||
| 284 | 54 | private function callApiMethod($verb, $params) |
|
| 285 | { |
||
| 286 | 54 | return $this->guzzle_client->request( |
|
| 287 | 54 | 'POST', |
|
| 288 | 54 | $this->apiUri($verb), |
|
| 289 | 54 | [ |
|
| 290 | 54 | 'form_params' => $params, |
|
| 291 | 54 | 'headers' => $this->getStandardHeaders() |
|
| 292 | 54 | ]); |
|
| 293 | } |
||
| 294 | |||
| 295 | /** |
||
| 296 | * Work out the Akismet API URL given the REST verb and our configured key. This would |
||
| 297 | * be far less of a pain if Akismet just had you pass the API key as a parameter or |
||
| 298 | * a header. Gawd knows why they change the host for authenticated calls. |
||
| 299 | * @param string $verb |
||
| 300 | * @throws \Gothick\AkismetClient\AkismetException |
||
| 301 | * @return string |
||
| 302 | */ |
||
| 303 | 54 | private function apiUri($verb) |
|
| 304 | { |
||
| 305 | 54 | if ($verb == self::VERB_VERIFY_KEY) |
|
| 306 | { |
||
| 307 | 14 | return "https://rest.akismet.com/1.1/verify-key"; |
|
| 308 | } else |
||
| 309 | { |
||
| 310 | 40 | if (empty($this->api_key)) |
|
| 311 | { |
||
| 312 | 3 | throw new AkismetException("Can't call authenticated method without setting an API key in " . __METHOD__); |
|
| 313 | } |
||
| 314 | 37 | return "https://{$this->api_key}.rest.akismet.com/1.1/$verb"; |
|
| 315 | } |
||
| 316 | } |
||
| 317 | } |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths