initial commit
This commit is contained in:
1
css/inContact.css
Normal file
1
css/inContact.css
Normal file
@@ -0,0 +1 @@
|
||||
form #website{ display:none; }
|
||||
26
in-contact.php
Normal file
26
in-contact.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: In Contact test
|
||||
Plugin URI: https://krzysztof-turek.com
|
||||
Description: Simple Contact Form
|
||||
Version: 1.0.1
|
||||
Author: Krzysztof Turek
|
||||
Author URI: https://krzysztof-turek.com
|
||||
License: GPL2
|
||||
License URI: https://krzysztof-turek.com
|
||||
*/
|
||||
|
||||
|
||||
use inContact\Init;
|
||||
|
||||
$pluginDirUrl = plugin_dir_url( __FILE__ );
|
||||
$pluginPath = plugin_dir_path( __FILE__ );
|
||||
|
||||
if (file_exists(dirname(__FILE__) . "/inc/autoload.php")) {
|
||||
require_once dirname(__FILE__) . "/inc/autoload.php";
|
||||
}
|
||||
|
||||
if (class_exists("inContact\Init")) {
|
||||
|
||||
Init::getInstance();
|
||||
}
|
||||
23
inc/autoload.php
Normal file
23
inc/autoload.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/*
|
||||
Autoloader klas
|
||||
|
||||
@link https://krzysztof-turek.com
|
||||
|
||||
@package tylkofotografia.pl
|
||||
@version 0.2
|
||||
*/
|
||||
|
||||
function InContactAutoload($class)
|
||||
{
|
||||
|
||||
$class = str_replace('\\', '/', $class);
|
||||
|
||||
$path = dirname(__FILE__) . '/classes/' . $class . '.php';
|
||||
|
||||
if (is_readable($path)) {
|
||||
require_once $path;
|
||||
return;
|
||||
}
|
||||
}
|
||||
spl_autoload_register('InContactAutoload');
|
||||
269
inc/classes/ReCaptcha/ReCaptcha.php
Normal file
269
inc/classes/ReCaptcha/ReCaptcha.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha;
|
||||
|
||||
/**
|
||||
* reCAPTCHA client.
|
||||
*/
|
||||
class ReCaptcha
|
||||
{
|
||||
/**
|
||||
* Version of this client library.
|
||||
* @const string
|
||||
*/
|
||||
const VERSION = 'php_1.2.4';
|
||||
|
||||
/**
|
||||
* URL for reCAPTCHA siteverify API
|
||||
* @const string
|
||||
*/
|
||||
const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
|
||||
|
||||
/**
|
||||
* Invalid JSON received
|
||||
* @const string
|
||||
*/
|
||||
const E_INVALID_JSON = 'invalid-json';
|
||||
|
||||
/**
|
||||
* Could not connect to service
|
||||
* @const string
|
||||
*/
|
||||
const E_CONNECTION_FAILED = 'connection-failed';
|
||||
|
||||
/**
|
||||
* Did not receive a 200 from the service
|
||||
* @const string
|
||||
*/
|
||||
const E_BAD_RESPONSE = 'bad-response';
|
||||
|
||||
/**
|
||||
* Not a success, but no error codes received!
|
||||
* @const string
|
||||
*/
|
||||
const E_UNKNOWN_ERROR = 'unknown-error';
|
||||
|
||||
/**
|
||||
* ReCAPTCHA response not provided
|
||||
* @const string
|
||||
*/
|
||||
const E_MISSING_INPUT_RESPONSE = 'missing-input-response';
|
||||
|
||||
/**
|
||||
* Expected hostname did not match
|
||||
* @const string
|
||||
*/
|
||||
const E_HOSTNAME_MISMATCH = 'hostname-mismatch';
|
||||
|
||||
/**
|
||||
* Expected APK package name did not match
|
||||
* @const string
|
||||
*/
|
||||
const E_APK_PACKAGE_NAME_MISMATCH = 'apk_package_name-mismatch';
|
||||
|
||||
/**
|
||||
* Expected action did not match
|
||||
* @const string
|
||||
*/
|
||||
const E_ACTION_MISMATCH = 'action-mismatch';
|
||||
|
||||
/**
|
||||
* Score threshold not met
|
||||
* @const string
|
||||
*/
|
||||
const E_SCORE_THRESHOLD_NOT_MET = 'score-threshold-not-met';
|
||||
|
||||
/**
|
||||
* Challenge timeout
|
||||
* @const string
|
||||
*/
|
||||
const E_CHALLENGE_TIMEOUT = 'challenge-timeout';
|
||||
|
||||
/**
|
||||
* Shared secret for the site.
|
||||
* @var string
|
||||
*/
|
||||
private $secret;
|
||||
|
||||
/**
|
||||
* Method used to communicate with service. Defaults to POST request.
|
||||
* @var RequestMethod
|
||||
*/
|
||||
private $requestMethod;
|
||||
|
||||
/**
|
||||
* Create a configured instance to use the reCAPTCHA service.
|
||||
*
|
||||
* @param string $secret The shared key between your site and reCAPTCHA.
|
||||
* @param RequestMethod $requestMethod method used to send the request. Defaults to POST.
|
||||
* @throws \RuntimeException if $secret is invalid
|
||||
*/
|
||||
public function __construct($secret, RequestMethod $requestMethod = null)
|
||||
{
|
||||
if (empty($secret)) {
|
||||
throw new \RuntimeException('No secret provided');
|
||||
}
|
||||
|
||||
if (!is_string($secret)) {
|
||||
throw new \RuntimeException('The provided secret must be a string');
|
||||
}
|
||||
|
||||
$this->secret = $secret;
|
||||
$this->requestMethod = (is_null($requestMethod)) ? new RequestMethod\Post() : $requestMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the reCAPTCHA siteverify API to verify whether the user passes
|
||||
* CAPTCHA test and additionally runs any specified additional checks
|
||||
*
|
||||
* @param string $response The user response token provided by reCAPTCHA, verifying the user on your site.
|
||||
* @param string $remoteIp The end user's IP address.
|
||||
* @return Response Response from the service.
|
||||
*/
|
||||
public function verify($response, $remoteIp = null)
|
||||
{
|
||||
// Discard empty solution submissions
|
||||
if (empty($response)) {
|
||||
$recaptchaResponse = new Response(false, array(self::E_MISSING_INPUT_RESPONSE));
|
||||
return $recaptchaResponse;
|
||||
}
|
||||
|
||||
$params = new RequestParameters($this->secret, $response, $remoteIp, self::VERSION);
|
||||
$rawResponse = $this->requestMethod->submit($params);
|
||||
$initialResponse = Response::fromJson($rawResponse);
|
||||
$validationErrors = array();
|
||||
|
||||
if (isset($this->hostname) && strcasecmp($this->hostname, $initialResponse->getHostname()) !== 0) {
|
||||
$validationErrors[] = self::E_HOSTNAME_MISMATCH;
|
||||
}
|
||||
|
||||
if (isset($this->apkPackageName) && strcasecmp($this->apkPackageName, $initialResponse->getApkPackageName()) !== 0) {
|
||||
$validationErrors[] = self::E_APK_PACKAGE_NAME_MISMATCH;
|
||||
}
|
||||
|
||||
if (isset($this->action) && strcasecmp($this->action, $initialResponse->getAction()) !== 0) {
|
||||
$validationErrors[] = self::E_ACTION_MISMATCH;
|
||||
}
|
||||
|
||||
if (isset($this->threshold) && $this->threshold > $initialResponse->getScore()) {
|
||||
$validationErrors[] = self::E_SCORE_THRESHOLD_NOT_MET;
|
||||
}
|
||||
|
||||
if (isset($this->timeoutSeconds)) {
|
||||
$challengeTs = strtotime($initialResponse->getChallengeTs());
|
||||
|
||||
if ($challengeTs > 0 && time() - $challengeTs > $this->timeoutSeconds) {
|
||||
$validationErrors[] = self::E_CHALLENGE_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($validationErrors)) {
|
||||
return $initialResponse;
|
||||
}
|
||||
|
||||
return new Response(
|
||||
false,
|
||||
array_merge($initialResponse->getErrorCodes(), $validationErrors),
|
||||
$initialResponse->getHostname(),
|
||||
$initialResponse->getChallengeTs(),
|
||||
$initialResponse->getApkPackageName(),
|
||||
$initialResponse->getScore(),
|
||||
$initialResponse->getAction()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a hostname to match against in verify()
|
||||
* This should be without a protocol or trailing slash, e.g. www.google.com
|
||||
*
|
||||
* @param string $hostname Expected hostname
|
||||
* @return ReCaptcha Current instance for fluent interface
|
||||
*/
|
||||
public function setExpectedHostname($hostname)
|
||||
{
|
||||
$this->hostname = $hostname;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an APK package name to match against in verify()
|
||||
*
|
||||
* @param string $apkPackageName Expected APK package name
|
||||
* @return ReCaptcha Current instance for fluent interface
|
||||
*/
|
||||
public function setExpectedApkPackageName($apkPackageName)
|
||||
{
|
||||
$this->apkPackageName = $apkPackageName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an action to match against in verify()
|
||||
* This should be set per page.
|
||||
*
|
||||
* @param string $action Expected action
|
||||
* @return ReCaptcha Current instance for fluent interface
|
||||
*/
|
||||
public function setExpectedAction($action)
|
||||
{
|
||||
$this->action = $action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a threshold to meet or exceed in verify()
|
||||
* Threshold should be a float between 0 and 1 which will be tested as response >= threshold.
|
||||
*
|
||||
* @param float $threshold Expected threshold
|
||||
* @return ReCaptcha Current instance for fluent interface
|
||||
*/
|
||||
public function setScoreThreshold($threshold)
|
||||
{
|
||||
$this->threshold = floatval($threshold);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a timeout in seconds to test against the challenge timestamp in verify()
|
||||
*
|
||||
* @param int $timeoutSeconds Expected hostname
|
||||
* @return ReCaptcha Current instance for fluent interface
|
||||
*/
|
||||
public function setChallengeTimeout($timeoutSeconds)
|
||||
{
|
||||
$this->timeoutSeconds = $timeoutSeconds;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
50
inc/classes/ReCaptcha/RequestMethod.php
Normal file
50
inc/classes/ReCaptcha/RequestMethod.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha;
|
||||
|
||||
/**
|
||||
* Method used to send the request to the service.
|
||||
*/
|
||||
interface RequestMethod
|
||||
{
|
||||
|
||||
/**
|
||||
* Submit the request with the specified parameters.
|
||||
*
|
||||
* @param RequestParameters $params Request parameters
|
||||
* @return string Body of the reCAPTCHA response
|
||||
*/
|
||||
public function submit(RequestParameters $params);
|
||||
}
|
||||
82
inc/classes/ReCaptcha/RequestMethod/Curl.php
Normal file
82
inc/classes/ReCaptcha/RequestMethod/Curl.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha\RequestMethod;
|
||||
|
||||
/**
|
||||
* Convenience wrapper around the cURL functions to allow mocking.
|
||||
*/
|
||||
class Curl
|
||||
{
|
||||
|
||||
/**
|
||||
* @see http://php.net/curl_init
|
||||
* @param string $url
|
||||
* @return resource cURL handle
|
||||
*/
|
||||
public function init($url = null)
|
||||
{
|
||||
return curl_init($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://php.net/curl_setopt_array
|
||||
* @param resource $ch
|
||||
* @param array $options
|
||||
* @return bool
|
||||
*/
|
||||
public function setoptArray($ch, array $options)
|
||||
{
|
||||
return curl_setopt_array($ch, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://php.net/curl_exec
|
||||
* @param resource $ch
|
||||
* @return mixed
|
||||
*/
|
||||
public function exec($ch)
|
||||
{
|
||||
return curl_exec($ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see http://php.net/curl_close
|
||||
* @param resource $ch
|
||||
*/
|
||||
public function close($ch)
|
||||
{
|
||||
curl_close($ch);
|
||||
}
|
||||
}
|
||||
104
inc/classes/ReCaptcha/RequestMethod/CurlPost.php
Normal file
104
inc/classes/ReCaptcha/RequestMethod/CurlPost.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha\RequestMethod;
|
||||
|
||||
use ReCaptcha\ReCaptcha;
|
||||
use ReCaptcha\RequestMethod;
|
||||
use ReCaptcha\RequestParameters;
|
||||
|
||||
/**
|
||||
* Sends cURL request to the reCAPTCHA service.
|
||||
* Note: this requires the cURL extension to be enabled in PHP
|
||||
* @see http://php.net/manual/en/book.curl.php
|
||||
*/
|
||||
class CurlPost implements RequestMethod
|
||||
{
|
||||
/**
|
||||
* Curl connection to the reCAPTCHA service
|
||||
* @var Curl
|
||||
*/
|
||||
private $curl;
|
||||
|
||||
/**
|
||||
* URL for reCAPTCHA siteverify API
|
||||
* @var string
|
||||
*/
|
||||
private $siteVerifyUrl;
|
||||
|
||||
/**
|
||||
* Only needed if you want to override the defaults
|
||||
*
|
||||
* @param Curl $curl Curl resource
|
||||
* @param string $siteVerifyUrl URL for reCAPTCHA siteverify API
|
||||
*/
|
||||
public function __construct(Curl $curl = null, $siteVerifyUrl = null)
|
||||
{
|
||||
$this->curl = (is_null($curl)) ? new Curl() : $curl;
|
||||
$this->siteVerifyUrl = (is_null($siteVerifyUrl)) ? ReCaptcha::SITE_VERIFY_URL : $siteVerifyUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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($this->siteVerifyUrl);
|
||||
|
||||
$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);
|
||||
|
||||
if ($response !== false) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return '{"success": false, "error-codes": ["'.ReCaptcha::E_CONNECTION_FAILED.'"]}';
|
||||
}
|
||||
}
|
||||
88
inc/classes/ReCaptcha/RequestMethod/Post.php
Normal file
88
inc/classes/ReCaptcha/RequestMethod/Post.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha\RequestMethod;
|
||||
|
||||
use ReCaptcha\ReCaptcha;
|
||||
use ReCaptcha\RequestMethod;
|
||||
use ReCaptcha\RequestParameters;
|
||||
|
||||
/**
|
||||
* Sends POST requests to the reCAPTCHA service.
|
||||
*/
|
||||
class Post implements RequestMethod
|
||||
{
|
||||
/**
|
||||
* URL for reCAPTCHA siteverify API
|
||||
* @var string
|
||||
*/
|
||||
private $siteVerifyUrl;
|
||||
|
||||
/**
|
||||
* Only needed if you want to override the defaults
|
||||
*
|
||||
* @param string $siteVerifyUrl URL for reCAPTCHA siteverify API
|
||||
*/
|
||||
public function __construct($siteVerifyUrl = null)
|
||||
{
|
||||
$this->siteVerifyUrl = (is_null($siteVerifyUrl)) ? ReCaptcha::SITE_VERIFY_URL : $siteVerifyUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the POST request with the specified parameters.
|
||||
*
|
||||
* @param RequestParameters $params Request parameters
|
||||
* @return string Body of the reCAPTCHA response
|
||||
*/
|
||||
public function submit(RequestParameters $params)
|
||||
{
|
||||
$options = array(
|
||||
'http' => array(
|
||||
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
|
||||
'method' => 'POST',
|
||||
'content' => $params->toQueryString(),
|
||||
// Force the peer to validate (not needed in 5.6.0+, but still works)
|
||||
'verify_peer' => true,
|
||||
),
|
||||
);
|
||||
$context = stream_context_create($options);
|
||||
$response = file_get_contents($this->siteVerifyUrl, false, $context);
|
||||
|
||||
if ($response !== false) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
return '{"success": false, "error-codes": ["'.ReCaptcha::E_CONNECTION_FAILED.'"]}';
|
||||
}
|
||||
}
|
||||
112
inc/classes/ReCaptcha/RequestMethod/Socket.php
Normal file
112
inc/classes/ReCaptcha/RequestMethod/Socket.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha\RequestMethod;
|
||||
|
||||
/**
|
||||
* Convenience wrapper around native socket and file functions to allow for
|
||||
* mocking.
|
||||
*/
|
||||
class Socket
|
||||
{
|
||||
private $handle = null;
|
||||
|
||||
/**
|
||||
* fsockopen
|
||||
*
|
||||
* @see http://php.net/fsockopen
|
||||
* @param string $hostname
|
||||
* @param int $port
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
* @param float $timeout
|
||||
* @return resource
|
||||
*/
|
||||
public function fsockopen($hostname, $port = -1, &$errno = 0, &$errstr = '', $timeout = null)
|
||||
{
|
||||
$this->handle = fsockopen($hostname, $port, $errno, $errstr, (is_null($timeout) ? ini_get("default_socket_timeout") : $timeout));
|
||||
|
||||
if ($this->handle != false && $errno === 0 && $errstr === '') {
|
||||
return $this->handle;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* fwrite
|
||||
*
|
||||
* @see http://php.net/fwrite
|
||||
* @param string $string
|
||||
* @param int $length
|
||||
* @return int | bool
|
||||
*/
|
||||
public function fwrite($string, $length = null)
|
||||
{
|
||||
return fwrite($this->handle, $string, (is_null($length) ? strlen($string) : $length));
|
||||
}
|
||||
|
||||
/**
|
||||
* fgets
|
||||
*
|
||||
* @see http://php.net/fgets
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public function fgets($length = null)
|
||||
{
|
||||
return fgets($this->handle, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* feof
|
||||
*
|
||||
* @see http://php.net/feof
|
||||
* @return bool
|
||||
*/
|
||||
public function feof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* fclose
|
||||
*
|
||||
* @see http://php.net/fclose
|
||||
* @return bool
|
||||
*/
|
||||
public function fclose()
|
||||
{
|
||||
return fclose($this->handle);
|
||||
}
|
||||
}
|
||||
108
inc/classes/ReCaptcha/RequestMethod/SocketPost.php
Normal file
108
inc/classes/ReCaptcha/RequestMethod/SocketPost.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha\RequestMethod;
|
||||
|
||||
use ReCaptcha\ReCaptcha;
|
||||
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
|
||||
* servers where allow_url_open is disabled.
|
||||
*/
|
||||
class SocketPost implements RequestMethod
|
||||
{
|
||||
/**
|
||||
* Socket to the reCAPTCHA service
|
||||
* @var Socket
|
||||
*/
|
||||
private $socket;
|
||||
|
||||
/**
|
||||
* Only needed if you want to override the defaults
|
||||
*
|
||||
* @param \ReCaptcha\RequestMethod\Socket $socket optional socket, injectable for testing
|
||||
* @param string $siteVerifyUrl URL for reCAPTCHA siteverify API
|
||||
*/
|
||||
public function __construct(Socket $socket = null, $siteVerifyUrl = null)
|
||||
{
|
||||
$this->socket = (is_null($socket)) ? new Socket() : $socket;
|
||||
$this->siteVerifyUrl = (is_null($siteVerifyUrl)) ? ReCaptcha::SITE_VERIFY_URL : $siteVerifyUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit the POST request with the specified parameters.
|
||||
*
|
||||
* @param RequestParameters $params Request parameters
|
||||
* @return string Body of the reCAPTCHA response
|
||||
*/
|
||||
public function submit(RequestParameters $params)
|
||||
{
|
||||
$errno = 0;
|
||||
$errstr = '';
|
||||
$urlParsed = parse_url($this->siteVerifyUrl);
|
||||
|
||||
if (false === $this->socket->fsockopen('ssl://' . $urlParsed['host'], 443, $errno, $errstr, 30)) {
|
||||
return '{"success": false, "error-codes": ["'.ReCaptcha::E_CONNECTION_FAILED.'"]}';
|
||||
}
|
||||
|
||||
$content = $params->toQueryString();
|
||||
|
||||
$request = "POST " . $urlParsed['path'] . " HTTP/1.0\r\n";
|
||||
$request .= "Host: " . $urlParsed['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";
|
||||
|
||||
$this->socket->fwrite($request);
|
||||
$response = '';
|
||||
|
||||
while (!$this->socket->feof()) {
|
||||
$response .= $this->socket->fgets(4096);
|
||||
}
|
||||
|
||||
$this->socket->fclose();
|
||||
|
||||
if (0 !== strpos($response, 'HTTP/1.0 200 OK')) {
|
||||
return '{"success": false, "error-codes": ["'.ReCaptcha::E_BAD_RESPONSE.'"]}';
|
||||
}
|
||||
|
||||
$parts = preg_split("#\n\s*\n#Uis", $response);
|
||||
|
||||
return $parts[1];
|
||||
}
|
||||
}
|
||||
111
inc/classes/ReCaptcha/RequestParameters.php
Normal file
111
inc/classes/ReCaptcha/RequestParameters.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha;
|
||||
|
||||
/**
|
||||
* Stores and formats the parameters for the request to the reCAPTCHA service.
|
||||
*/
|
||||
class RequestParameters
|
||||
{
|
||||
/**
|
||||
* The shared key between your site and reCAPTCHA.
|
||||
* @var string
|
||||
*/
|
||||
private $secret;
|
||||
|
||||
/**
|
||||
* The user response token provided by reCAPTCHA, verifying the user on your site.
|
||||
* @var string
|
||||
*/
|
||||
private $response;
|
||||
|
||||
/**
|
||||
* Remote user's IP address.
|
||||
* @var string
|
||||
*/
|
||||
private $remoteIp;
|
||||
|
||||
/**
|
||||
* Client version.
|
||||
* @var string
|
||||
*/
|
||||
private $version;
|
||||
|
||||
/**
|
||||
* Initialise parameters.
|
||||
*
|
||||
* @param string $secret Site secret.
|
||||
* @param string $response Value from g-captcha-response form field.
|
||||
* @param string $remoteIp User's IP address.
|
||||
* @param string $version Version of this client library.
|
||||
*/
|
||||
public function __construct($secret, $response, $remoteIp = null, $version = null)
|
||||
{
|
||||
$this->secret = $secret;
|
||||
$this->response = $response;
|
||||
$this->remoteIp = $remoteIp;
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array representation.
|
||||
*
|
||||
* @return array Array formatted parameters.
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$params = array('secret' => $this->secret, 'response' => $this->response);
|
||||
|
||||
if (!is_null($this->remoteIp)) {
|
||||
$params['remoteip'] = $this->remoteIp;
|
||||
}
|
||||
|
||||
if (!is_null($this->version)) {
|
||||
$params['version'] = $this->version;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query string representation for HTTP request.
|
||||
*
|
||||
* @return string Query string formatted parameters.
|
||||
*/
|
||||
public function toQueryString()
|
||||
{
|
||||
return http_build_query($this->toArray(), '', '&');
|
||||
}
|
||||
}
|
||||
218
inc/classes/ReCaptcha/Response.php
Normal file
218
inc/classes/ReCaptcha/Response.php
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
/**
|
||||
* This is a PHP library that handles calling reCAPTCHA.
|
||||
*
|
||||
* BSD 3-Clause License
|
||||
* @copyright (c) 2019, Google Inc.
|
||||
* @link https://www.google.com/recaptcha
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace ReCaptcha;
|
||||
|
||||
/**
|
||||
* The response returned from the service.
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
* Success or failure.
|
||||
* @var boolean
|
||||
*/
|
||||
private $success = false;
|
||||
|
||||
/**
|
||||
* Error code strings.
|
||||
* @var array
|
||||
*/
|
||||
private $errorCodes = array();
|
||||
|
||||
/**
|
||||
* The hostname of the site where the reCAPTCHA was solved.
|
||||
* @var string
|
||||
*/
|
||||
private $hostname;
|
||||
|
||||
/**
|
||||
* Timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
|
||||
* @var string
|
||||
*/
|
||||
private $challengeTs;
|
||||
|
||||
/**
|
||||
* APK package name
|
||||
* @var string
|
||||
*/
|
||||
private $apkPackageName;
|
||||
|
||||
/**
|
||||
* Score assigned to the request
|
||||
* @var float
|
||||
*/
|
||||
private $score;
|
||||
|
||||
/**
|
||||
* Action as specified by the page
|
||||
* @var string
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* Build the response from the expected JSON returned by the service.
|
||||
*
|
||||
* @param string $json
|
||||
* @return \ReCaptcha\Response
|
||||
*/
|
||||
public static function fromJson($json)
|
||||
{
|
||||
$responseData = json_decode($json, true);
|
||||
|
||||
if (!$responseData) {
|
||||
return new Response(false, array(ReCaptcha::E_INVALID_JSON));
|
||||
}
|
||||
|
||||
$hostname = isset($responseData['hostname']) ? $responseData['hostname'] : null;
|
||||
$challengeTs = isset($responseData['challenge_ts']) ? $responseData['challenge_ts'] : null;
|
||||
$apkPackageName = isset($responseData['apk_package_name']) ? $responseData['apk_package_name'] : null;
|
||||
$score = isset($responseData['score']) ? floatval($responseData['score']) : null;
|
||||
$action = isset($responseData['action']) ? $responseData['action'] : null;
|
||||
|
||||
if (isset($responseData['success']) && $responseData['success'] == true) {
|
||||
return new Response(true, array(), $hostname, $challengeTs, $apkPackageName, $score, $action);
|
||||
}
|
||||
|
||||
if (isset($responseData['error-codes']) && is_array($responseData['error-codes'])) {
|
||||
return new Response(false, $responseData['error-codes'], $hostname, $challengeTs, $apkPackageName, $score, $action);
|
||||
}
|
||||
|
||||
return new Response(false, array(ReCaptcha::E_UNKNOWN_ERROR), $hostname, $challengeTs, $apkPackageName, $score, $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param boolean $success
|
||||
* @param string $hostname
|
||||
* @param string $challengeTs
|
||||
* @param string $apkPackageName
|
||||
* @param float $score
|
||||
* @param string $action
|
||||
* @param array $errorCodes
|
||||
*/
|
||||
public function __construct($success, array $errorCodes = array(), $hostname = null, $challengeTs = null, $apkPackageName = null, $score = null, $action = null)
|
||||
{
|
||||
$this->success = $success;
|
||||
$this->hostname = $hostname;
|
||||
$this->challengeTs = $challengeTs;
|
||||
$this->apkPackageName = $apkPackageName;
|
||||
$this->score = $score;
|
||||
$this->action = $action;
|
||||
$this->errorCodes = $errorCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is success?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isSuccess()
|
||||
{
|
||||
return $this->success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get error codes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorCodes()
|
||||
{
|
||||
return $this->errorCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hostname.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHostname()
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get challenge timestamp
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getChallengeTs()
|
||||
{
|
||||
return $this->challengeTs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get APK package name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApkPackageName()
|
||||
{
|
||||
return $this->apkPackageName;
|
||||
}
|
||||
/**
|
||||
* Get score
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getScore()
|
||||
{
|
||||
return $this->score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get action
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return array(
|
||||
'success' => $this->isSuccess(),
|
||||
'hostname' => $this->getHostname(),
|
||||
'challenge_ts' => $this->getChallengeTs(),
|
||||
'apk_package_name' => $this->getApkPackageName(),
|
||||
'score' => $this->getScore(),
|
||||
'action' => $this->getAction(),
|
||||
'error-codes' => $this->getErrorCodes(),
|
||||
);
|
||||
}
|
||||
}
|
||||
85
inc/classes/inContact/AdminMenu.php
Normal file
85
inc/classes/inContact/AdminMenu.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace inContact;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Klasa Menus
|
||||
*
|
||||
* @link https://krzysztof-turek.com
|
||||
*
|
||||
* @package tylkofotografia.pl
|
||||
* @version 0.2
|
||||
*/
|
||||
class AdminMenu
|
||||
{
|
||||
|
||||
use Singleton;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->setupHooks();
|
||||
}
|
||||
|
||||
protected function setupHooks()
|
||||
{
|
||||
add_action('admin_menu', [$this, 'InContactAdminMenu']);
|
||||
}
|
||||
|
||||
public function InContactAdminMenu($id)
|
||||
{
|
||||
add_menu_page('ustawienia inContact', 'inContact', 'manage_options', 'wp-in-contact', array(
|
||||
$this,
|
||||
'InContactSettings'
|
||||
), 'dashicons-email', 100);
|
||||
}
|
||||
|
||||
public function InContactSettings()
|
||||
{
|
||||
$updated = isset($_POST['updated']) ? $_POST['updated'] : '';
|
||||
$incontactconfig = isset($_REQUEST['incontact-config']) ? $_REQUEST['incontact-config'] : '';
|
||||
if ($updated === 'true' || wp_verify_nonce($incontactconfig, 'incontact-update')) {
|
||||
update_option('incontact-site-key', $_POST['incontact-site-key']);
|
||||
update_option('incontact-secret-key', $_POST['incontact-secret-key']);
|
||||
update_option('incontact-target-mail', $_POST['incontact-target-mail']);
|
||||
?>
|
||||
|
||||
<div class="updated">
|
||||
<p>Ustawienia zostały zapisane!</p>
|
||||
</div> <?php
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h2><span class="dashicons dashicons-email"></span> InContact - Ustawienia</h2>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="updated" value="true"/>
|
||||
<?php wp_nonce_field('incontact-update', 'incontact-config'); ?>
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><label for="incontact-site-key">Klucz witryny</label></th>
|
||||
<td><input name="incontact-site-key" id="incontact-site-key" type="text"
|
||||
value="<?php echo get_option('incontact-site-key'); ?>" class="regular-text"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="incontact-secret-key">Tajny klucz</label></th>
|
||||
<td><input name="incontact-secret-key" id="incontact-secret-key" type="text"
|
||||
value="<?php echo get_option('incontact-secret-key'); ?>" class="regular-text"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="incontact-target-mail">Adresat (email)</label></th>
|
||||
<td><input name="incontact-target-mail" id="incontact-target-mail" type="text"
|
||||
value="<?php echo get_option('incontact-target-mail'); ?>" class="regular-text"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="submit">
|
||||
<input type="submit" name="submit" id="submit" class="button button-primary" value="Zapisz">
|
||||
</p>
|
||||
</form>
|
||||
</div> <?php
|
||||
|
||||
}
|
||||
}
|
||||
29
inc/classes/inContact/Enqueue.php
Normal file
29
inc/classes/inContact/Enqueue.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace inContact;
|
||||
|
||||
/**
|
||||
* Klasa Enqueue
|
||||
*
|
||||
* @link https://krzysztof-turek.com
|
||||
*
|
||||
* @package tylkofotografia.pl
|
||||
* @version 0.2
|
||||
*/
|
||||
|
||||
class Enqueue {
|
||||
|
||||
use Singleton;
|
||||
|
||||
function __construct() {
|
||||
add_action('wp_enqueue_scripts',[ $this, 'enqueueScripts']);
|
||||
}
|
||||
|
||||
public function enqueueScripts() {
|
||||
global $pluginDirUrl, $pluginPath;
|
||||
wp_register_style('ContactCss', $pluginDirUrl.'css/inContact.css', [], filemtime( $pluginPath . 'css/inContact.css'), 'all');
|
||||
|
||||
wp_enqueue_style('ContactCss');
|
||||
|
||||
}
|
||||
}
|
||||
23
inc/classes/inContact/Init.php
Normal file
23
inc/classes/inContact/Init.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace inContact;
|
||||
|
||||
/**
|
||||
Klasa Init
|
||||
|
||||
@link https://krzysztof-turek.com
|
||||
|
||||
@package tylkofotografia.pl
|
||||
@version 0.2
|
||||
*/
|
||||
class Init
|
||||
{
|
||||
use Singleton;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
Enqueue::getInstance();
|
||||
AdminMenu::getInstance();
|
||||
Shortcode::getInstance();
|
||||
}
|
||||
}
|
||||
252
inc/classes/inContact/Shortcode.php
Normal file
252
inc/classes/inContact/Shortcode.php
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace inContact;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Klasa Menus
|
||||
*
|
||||
* @link https://krzysztof-turek.com
|
||||
*
|
||||
* @package tylkofotografia.pl
|
||||
* @version 0.2
|
||||
*/
|
||||
class Shortcode
|
||||
{
|
||||
|
||||
use Singleton;
|
||||
|
||||
function __construct()
|
||||
{
|
||||
$this->addShortcode();
|
||||
}
|
||||
|
||||
protected function addShortcode()
|
||||
{
|
||||
add_shortcode('in-contact', array(
|
||||
$this,
|
||||
'inContact'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
public function inContact($atts)
|
||||
{
|
||||
$em_name = null;
|
||||
$em_mail = null;
|
||||
$em_meeessage = null;
|
||||
$class = null;
|
||||
$html = null;
|
||||
$error = null;
|
||||
$body = null;
|
||||
$telefon = null;
|
||||
|
||||
if(!empty($_POST['website'])) die();
|
||||
$emmsg = (isset($_POST['emmsg']) ? $_POST['emmsg'] : '');
|
||||
if(isset($_POST['em_name'])) { $em_name = $_POST['em_name']; } else {
|
||||
$error .= 'Proszę wprowadź nazwę';
|
||||
}
|
||||
if(isset($_POST['em_mail'])) { $em_mail = $_POST['em_mail']; } else {
|
||||
$error .= 'Proszę wprowadź adres email';
|
||||
}
|
||||
if(isset($_POST['em_meeessage'])) { $em_meeessage = $_POST['em_meeessage']; } else {
|
||||
$error .= 'Proszę wprowadź tersć wiadmości';
|
||||
}
|
||||
|
||||
$targetEmail = 'To: Tylkofotografia <' .get_option('incontact-target-mail') .'>';
|
||||
$mailResult = 0;
|
||||
$headers = "MIME-Version: 1.0" . "\r\n";
|
||||
$headers .= "Content-type: text/html; charset=".get_bloginfo('charset')."" . "\r\n";
|
||||
$headers .= "From: " . $em_name ." <".$em_mail.">" . "\r\n";
|
||||
$headers = array(
|
||||
'Content-Type: text/html; charset=UTF-8',
|
||||
'From: ' . $em_name . ' <'.$em_mail.'>',
|
||||
'Reply-To: ' . $em_name . ' <'.$em_mail.'>'
|
||||
);
|
||||
|
||||
$gRecaptchaResponse = (isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : '');
|
||||
|
||||
$body = '<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Nowa wiadomość z formularza kontaktowego</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background-color: #f5f5f5;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.container {
|
||||
width: 90%;
|
||||
max-width: 600px;
|
||||
margin: 20px auto;
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.header {
|
||||
background-color: #3a7bd5;
|
||||
color: #ffffff;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.content h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
.footer {
|
||||
background-color: #f1f1f1;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
color: #777777;
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
margin-top: 20px;
|
||||
background-color: #3a7bd5;
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.info {
|
||||
background-color: #f9f9f9;
|
||||
border-left: 4px solid #3a7bd5;
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
.container {
|
||||
width: 95%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>📩 Nowa wiadomość z formularza</h1>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h2>Dane kontaktowe</h2>
|
||||
<p><strong>Imię i nazwisko:</strong> {{IMIE_NAZWISKO}}</p>
|
||||
<p><strong>Email:</strong> {{EMAIL}}</p>
|
||||
|
||||
|
||||
<div class="info">
|
||||
<h3>📬 Treść wiadomości:</h3>
|
||||
<p>{{WIADOMOSC}}</p>
|
||||
</div>
|
||||
|
||||
<a href="mailto:{{EMAIL}}" class="button">Odpowiedz na wiadomość</a>
|
||||
</div>
|
||||
<div class="footer">
|
||||
Ten e-mail został wygenerowany automatycznie przez formularz kontaktowy strony.<br>
|
||||
© {{ROK}} Twoja Firma. Wszelkie prawa zastrzeżone.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
';
|
||||
$body = str_replace(
|
||||
['{{IMIE_NAZWISKO}}', '{{EMAIL}}', '{{TELEFON}}', '{{WIADOMOSC}}', '{{ROK}}'],
|
||||
[$em_name, $em_mail, $telefon, nl2br($em_meeessage), date("Y")],
|
||||
$body
|
||||
);
|
||||
|
||||
if (!empty($atts['class'])) {
|
||||
$class = $atts['class'];
|
||||
}
|
||||
if ($emmsg == 'true' && $error) {
|
||||
$html .= '<div class="alert alert-success" role="alert">' . $error . '</div>';
|
||||
|
||||
} elseif ($emmsg == 'true')
|
||||
{
|
||||
|
||||
$secret = get_option('incontact-secret-key');
|
||||
$response = null;
|
||||
/*$reCaptcha = new \ReCaptcha\ReCaptcha($secret);
|
||||
$resp = $reCaptcha->setExpectedHostname($_SERVER['SERVER_NAME'])->verify($gRecaptchaResponse, $_SERVER['REMOTE_ADDR']);
|
||||
if ($resp->isSuccess())
|
||||
{*/
|
||||
$mailResult = wp_mail($targetEmail, $em_name, $body, $headers);
|
||||
/*}
|
||||
else
|
||||
{
|
||||
$errors = $resp->getErrorCodes();
|
||||
}*/
|
||||
}
|
||||
|
||||
wp_enqueue_style('ContactCss', plugins_url( '/css/cform.css', __FILE__ ));
|
||||
|
||||
$html .= '<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||
<script>
|
||||
$(document).ready(function(){window.setTimeout(function(){$(".alert").fadeTo(500,0).slideUp(500,function(){$(this).remove()})},2e3)}),$(document).ready(function(){"use strict";window.addEventListener("load",function(){var t=document.getElementsByClassName("needs-validation");Array.prototype.filter.call(t,function(t){t.addEventListener("submit",function(e){!1===t.checkValidity()&&(e.preventDefault(),e.stopPropagation()),t.classList.add("was-validated")},!1)})},!1)})();
|
||||
</script>'."\n";
|
||||
$html .= '<div class="row justify-content-md-center">
|
||||
<div class="col-12">';
|
||||
if ($mailResult == 1)
|
||||
{
|
||||
$html .= '<div class="alert alert-success" role="alert">Wiadomość wysłana pomyślnie!</div>';
|
||||
}
|
||||
$html .= '<div class="jumbotron"><form action="" class="needs-validation" novalidate method="post" id="demo-form">
|
||||
<input type="hidden" name="emmsg" value="true" />
|
||||
<input type="text" id="website" name="website" />
|
||||
<div class="jumbotron">
|
||||
<div class="form-group">
|
||||
<label for="name" class="col-2 control-label">Nazwa</label>
|
||||
<div class="col-12">
|
||||
<input type="text" class="form-control" id="name" name="em_name" placeholder="Imię i nazwisko" value="" required>
|
||||
<div class="invalid-feedback">
|
||||
Wprowadź nazwę!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email" class="col-2 control-label">Email</label>
|
||||
<div class="col-12">
|
||||
<input type="email" class="form-control" id="email" name="em_mail" placeholder="twoj@email.com" value="" required>
|
||||
<div class="invalid-feedback">
|
||||
Podaj adres email!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<p class="col-2 control-label">Wiadomość</p>
|
||||
<div class="col-12">
|
||||
<textarea class="form-control" rows="4" name="em_meeessage" required></textarea>
|
||||
<div class="invalid-feedback">
|
||||
Wprowadź treść wiadmości!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4">
|
||||
<div class="g-recaptcha" data-sitekey="' . get_option('incontact-site-key') . '"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-4">
|
||||
<button id="submit" name="submit" type="submit" value="Send" class="btn btn-primary">
|
||||
<i class="fas fa-paper-plane"></i> Wyślij
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div></div>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
34
inc/classes/inContact/Singleton.php
Normal file
34
inc/classes/inContact/Singleton.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace inContact;
|
||||
/**
|
||||
* Cecha singleton
|
||||
*
|
||||
* @link https://krzysztof-turek.com
|
||||
*
|
||||
* @package tylkofotografia.pl
|
||||
* @version 0.2
|
||||
*/
|
||||
trait Singleton
|
||||
{
|
||||
private static $instances = [];
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
final protected function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
|
||||
$class = get_called_class();
|
||||
|
||||
if (!isset($instances[$class])) {
|
||||
$instances[$class] = new $class;
|
||||
}
|
||||
return $instances[$class];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user