diff --git a/recaptcha-php/README.md b/recaptcha-php/README.md
index fac73b8622747c1878744704c0aec27ed133074c..6e81a8edafbc891e3fdb2c37a967b417be920bb6 100644
--- a/recaptcha-php/README.md
+++ b/recaptcha-php/README.md
@@ -6,7 +6,7 @@
* Project page: http://www.google.com/recaptcha/
* Repository: https://github.com/google/recaptcha
-* Version: 1.1.0
+* Version: 1.1.2
* License: BSD, see [LICENSE](LICENSE)
## Description
@@ -17,15 +17,60 @@ with reCAPTCHA.
## Installation
-Use [Composer](https://getcomposer.org/) to install the library. Either use
-`composer require google/recaptcha "~1.1"` or add the following to your
-`composer.json`:
+### Composer (Recommended)
+
+[Composer](https://getcomposer.org/) is a widely used dependency manager for PHP
+packages. This reCAPTCHA client is available on Packagist as
+[`google/recaptcha`](https://packagist.org/packages/google/recaptcha) and can be
+installed either by running the `composer require` command or adding the library
+to your `composer.json`. To enable Composer for you project, refer to the
+project's [Getting Started](https://getcomposer.org/doc/00-intro.md)
+documentation.
+
+To add this dependency using the command, run the following from within your
+project directory:
+```
+composer require google/recaptcha "~1.1"
+```
+
+Alternatively, add the dependency directly to your `composer.json` file:
```json
- "require": {
- "google/recaptcha": "~1.1"
- }
+"require": {
+ "google/recaptcha": "~1.1"
+}
+```
+
+### Direct download (no Composer)
+
+If you wish to install the library manually (i.e. without Composer), then you
+can use the links on the main project page to either clone the repo or download
+the [ZIP file](https://github.com/google/recaptcha/archive/master.zip). For
+convenience, an autoloader script is provided in `src/autoload.php` which you
+can require into your script instead of Composer's `vendor/autoload.php`. For
+example:
+
+```php
+require('/path/to/recaptcha/src/autoload.php');
+$recaptcha = new \ReCaptcha\ReCaptcha($secret);
```
+The classes in the project are structured according to the
+[PSR-4](http://www.php-fig.org/psr/psr-4/) standard, so you may of course also
+use your own autoloader or require the needed files directly in your code.
+
+### Development install
+
+If you would like to contribute to this project or run the unit tests on within
+your own environment you will need to install the development dependencies, in
+this case that means [PHPUnit](https://phpunit.de/). If you clone the repo and
+run `composer install` from within the repo, this will also grab PHPUnit and all
+its dependencies for you. If you only need the autoloader installed, then you
+can always specify to Composer not to run in development mode, e.g. `composer
+install --no-dev`.
+
+*Note:* These dependencies are only required for development, there's no
+requirement for them to be included in your production code.
+
## Usage
First, register keys for your site at https://www.google.com/recaptcha/admin
@@ -43,21 +88,23 @@ if ($resp->isSuccess()) {
}
```
-You can see an end-to-end working example in [examples/example-captcha.php](examples/example-captcha.php)
+You can see an end-to-end working example in
+[examples/example-captcha.php](examples/example-captcha.php)
## Upgrading
### From 1.0.0
-The previous version of this client is still available on the `1.0.0` tag
-[in this repo](https://github.com/google/recaptcha/tree/1.0.0) but it is purely
-for reference and will not receive any updates.
+The previous version of this client is still available on the `1.0.0` tag [in
+this repo](https://github.com/google/recaptcha/tree/1.0.0) but it is purely for
+reference and will not receive any updates.
The major changes in 1.1.0 are:
- * installation now via Composer;
- * class loading also via Composer;
- * classes now namespaced;
- * old method call was `$rc->verifyResponse($remoteIp, $response)`, new call is `$rc->verify($response, $remoteIp)`
+* installation now via Composer;
+* class loading also via Composer;
+* classes now namespaced;
+* old method call was `$rc->verifyResponse($remoteIp, $response)`, new call is
+ `$rc->verify($response, $remoteIp)`
## Contributing
diff --git a/recaptcha-php/examples/example-captcha.php b/recaptcha-php/examples/example-captcha.php
index e76723938a745252aa809bc2d7c7057ed7e1567e..8875171b8b6aa5215040dd530c2dbd3600b1886a 100644
--- a/recaptcha-php/examples/example-captcha.php
+++ b/recaptcha-php/examples/example-captcha.php
@@ -30,7 +30,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-// Initiate the autoloader.
+// Initiate the autoloader. The file should be generated by Composer.
+// You will provide your own autoloader or require the files directly if you did
+// not install via Composer.
require_once __DIR__ . '/../vendor/autoload.php';
// Register API keys at https://www.google.com/recaptcha/admin
@@ -98,7 +100,7 @@ elseif (isset($_POST['g-recaptcha-response'])):
Something went wrong
The following error was returned: getErrorCodes() as $code) {
- echo '' . $code . ' ';
+ echo '' , $code , ' ';
}
?>
Check the error code reference at https://developers.google.com/recaptcha/docs/verify#error-code-reference.
diff --git a/recaptcha-php/phpunit.xml.dist b/recaptcha-php/phpunit.xml.dist
index c4a8896142d0e52d46b98f0becfc15eefcd5b8af..437667880aefff4702d82bb20956fe5e866b4733 100644
--- a/recaptcha-php/phpunit.xml.dist
+++ b/recaptcha-php/phpunit.xml.dist
@@ -1,8 +1,9 @@
+ verbose="true"
+ bootstrap="src/autoload.php">
tests/ReCaptcha/
diff --git a/recaptcha-php/src/ReCaptcha/ReCaptcha.php b/recaptcha-php/src/ReCaptcha/ReCaptcha.php
index 414c52159d44d66c43fb5b030c21860ded920cfe..e2f7c347ebfc4e2da61480e1a1e31301847d165d 100644
--- a/recaptcha-php/src/ReCaptcha/ReCaptcha.php
+++ b/recaptcha-php/src/ReCaptcha/ReCaptcha.php
@@ -35,7 +35,7 @@ class ReCaptcha
* Version of this client library.
* @const string
*/
- const VERSION = 'php_1.1.0';
+ const VERSION = 'php_1.1.2';
/**
* Shared secret for the site.
diff --git a/recaptcha-php/src/ReCaptcha/RequestMethod/Curl.php b/recaptcha-php/src/ReCaptcha/RequestMethod/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..20ee53099c7a7cc1a5ca9446b40b50117766faa0
--- /dev/null
+++ b/recaptcha-php/src/ReCaptcha/RequestMethod/Curl.php
@@ -0,0 +1,74 @@
+curl = $curl;
+ } else {
+ $this->curl = new Curl();
+ }
+ }
+
+ /**
+ * Submit the cURL request with the specified parameters.
+ *
+ * @param RequestParameters $params Request parameters
+ * @return string Body of the reCAPTCHA response
+ */
+ public function submit(RequestParameters $params)
+ {
+ $handle = $this->curl->init(self::SITE_VERIFY_URL);
+
+ $options = array(
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => $params->toQueryString(),
+ CURLOPT_HTTPHEADER => array(
+ 'Content-Type: application/x-www-form-urlencoded'
+ ),
+ CURLINFO_HEADER_OUT => false,
+ CURLOPT_HEADER => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_SSL_VERIFYPEER => true
+ );
+ $this->curl->setoptArray($handle, $options);
+
+ $response = $this->curl->exec($handle);
+ $this->curl->close($handle);
+
+ return $response;
+ }
+}
diff --git a/recaptcha-php/src/ReCaptcha/RequestMethod/Socket.php b/recaptcha-php/src/ReCaptcha/RequestMethod/Socket.php
index e74fc49d62331edcc4291eae0ef8f2fc78c359b4..d3c87922d224e4b88cc0d542f09eb7c98bbe2949 100644
--- a/recaptcha-php/src/ReCaptcha/RequestMethod/Socket.php
+++ b/recaptcha-php/src/ReCaptcha/RequestMethod/Socket.php
@@ -74,6 +74,7 @@ class Socket
*
* @see http://php.net/fgets
* @param int $length
+ * @return string
*/
public function fgets($length = null)
{
diff --git a/recaptcha-php/src/ReCaptcha/RequestMethod/SocketPost.php b/recaptcha-php/src/ReCaptcha/RequestMethod/SocketPost.php
index 4f0c61a3fdea622e204dcd6153b0c4dec0b6671c..47541215f046f893d824a494ce972ab9af5c3567 100644
--- a/recaptcha-php/src/ReCaptcha/RequestMethod/SocketPost.php
+++ b/recaptcha-php/src/ReCaptcha/RequestMethod/SocketPost.php
@@ -30,15 +30,15 @@ use ReCaptcha\RequestMethod;
use ReCaptcha\RequestParameters;
/**
- * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
- * instead of get_file_contents(). This is to account for people who may be on
+ * Sends a POST request to the reCAPTCHA service, but makes use of fsockopen()
+ * instead of get_file_contents(). This is to account for people who may be on
* servers where allow_furl_open is disabled.
*/
class SocketPost implements RequestMethod
{
/**
* reCAPTCHA service host.
- * @const string
+ * @const string
*/
const RECAPTCHA_HOST = 'www.google.com';
@@ -65,7 +65,7 @@ class SocketPost implements RequestMethod
/**
* Constructor
- *
+ *
* @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
*/
public function __construct(Socket $socket = null)
@@ -88,33 +88,34 @@ class SocketPost implements RequestMethod
$errno = 0;
$errstr = '';
- if ($this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30) !== false) {
- $content = $params->toQueryString();
+ if (false === $this->socket->fsockopen('ssl://' . self::RECAPTCHA_HOST, 443, $errno, $errstr, 30)) {
+ return self::BAD_REQUEST;
+ }
- $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
- $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
- $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
- $request .= "Content-length: " . strlen($content) . "\r\n";
- $request .= "Connection: close\r\n\r\n";
- $request .= $content . "\r\n\r\n";
+ $content = $params->toQueryString();
- $this->socket->fwrite($request);
- $response = '';
+ $request = "POST " . self::SITE_VERIFY_PATH . " HTTP/1.1\r\n";
+ $request .= "Host: " . self::RECAPTCHA_HOST . "\r\n";
+ $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
+ $request .= "Content-length: " . strlen($content) . "\r\n";
+ $request .= "Connection: close\r\n\r\n";
+ $request .= $content . "\r\n\r\n";
- while (!$this->socket->feof()) {
- $response .= $this->socket->fgets(4096);
- }
+ $this->socket->fwrite($request);
+ $response = '';
- $this->socket->fclose();
+ while (!$this->socket->feof()) {
+ $response .= $this->socket->fgets(4096);
+ }
- if (0 === strpos($response, 'HTTP/1.1 200 OK')) {
- $parts = preg_split("#\n\s*\n#Uis", $response);
- return $parts[1];
- }
+ $this->socket->fclose();
+ if (0 !== strpos($response, 'HTTP/1.1 200 OK')) {
return self::BAD_RESPONSE;
}
- return self::BAD_REQUEST;
+ $parts = preg_split("#\n\s*\n#Uis", $response);
+
+ return $parts[1];
}
}
diff --git a/recaptcha-php/src/ReCaptcha/RequestParameters.php b/recaptcha-php/src/ReCaptcha/RequestParameters.php
index f446842839dcadb6b65e54cccdf256aca7cab008..cb66f26cf4b6c76edc3707549c9c4f24ad08a295 100644
--- a/recaptcha-php/src/ReCaptcha/RequestParameters.php
+++ b/recaptcha-php/src/ReCaptcha/RequestParameters.php
@@ -98,6 +98,6 @@ class RequestParameters
*/
public function toQueryString()
{
- return http_build_query($this->toArray());
+ return http_build_query($this->toArray(), '', '&');
}
}
diff --git a/recaptcha-php/src/autoload.php b/recaptcha-php/src/autoload.php
new file mode 100644
index 0000000000000000000000000000000000000000..a53cbd78bf25c41ac1776f775e4e39d5be278b2f
--- /dev/null
+++ b/recaptcha-php/src/autoload.php
@@ -0,0 +1,38 @@
+markTestSkipped(
+ 'The cURL extension is not available.'
+ );
+ }
+ }
+
+ public function testSubmit()
+ {
+ $curl = $this->getMock('\\ReCaptcha\\RequestMethod\\Curl',
+ array('init', 'setoptArray', 'exec', 'close'));
+ $curl->expects($this->once())
+ ->method('init')
+ ->willReturn(new \stdClass);
+ $curl->expects($this->once())
+ ->method('setoptArray')
+ ->willReturn(true);
+ $curl->expects($this->once())
+ ->method('exec')
+ ->willReturn('RESPONSEBODY');
+ $curl->expects($this->once())
+ ->method('close');
+
+ $pc = new CurlPost($curl);
+ $response = $pc->submit(new RequestParameters("secret", "response"));
+ $this->assertEquals('RESPONSEBODY', $response);
+ }
+}