From ac053b5800eadb45b767b3b50d6a0ae44e79a512 Mon Sep 17 00:00:00 2001 From: elliot sawyer <354793+elliot-sawyer@users.noreply.github.com> Date: Mon, 20 Apr 2020 15:12:14 +1200 Subject: [PATCH] MINOR: Account for undocumented exception in Akismet::getIsSpam (#31) --- src/AkismetField.php | 50 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/AkismetField.php b/src/AkismetField.php index 6b28d67..015af9b 100644 --- a/src/AkismetField.php +++ b/src/AkismetField.php @@ -2,8 +2,11 @@ namespace SilverStripe\Akismet; +use Exception; +use Psr\Log\LoggerInterface; use SilverStripe\Akismet\Service\AkismetService; use SilverStripe\Core\Config\Config; +use SilverStripe\Core\Injector\Injector; use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\Validator; use SilverStripe\ORM\ValidationResult; @@ -20,6 +23,13 @@ */ class AkismetField extends FormField { + /** + * If the Akismet network response fails, it is neither true or false + * This is the value assigned on a 400 + * + * @var boolean + */ + private static $is_spam_when_response_fails = false; /** * @var array */ @@ -30,7 +40,7 @@ class AkismetField extends FormField * @var boolean */ protected $isSpam = null; - + /** * Get the nested confirmation checkbox field * @@ -43,7 +53,7 @@ protected function confirmationField() if (empty($requireConfirmation)) { return null; } - + // If confirmation is required then return a checkbox return CheckboxField::create( $this->getName(), @@ -56,7 +66,7 @@ protected function confirmationField() ->setMessage($this->getMessage(), $this->getMessageType()) ->setForm($this->getForm()); } - + public function Field($properties = array()) { $checkbox = $this->confirmationField(); @@ -64,7 +74,7 @@ public function Field($properties = array()) return $checkbox->Field($properties); } } - + public function FieldHolder($properties = array()) { $checkbox = $this->confirmationField(); @@ -72,7 +82,7 @@ public function FieldHolder($properties = array()) return $checkbox->FieldHolder($properties); } } - + /** * @return array */ @@ -81,7 +91,7 @@ public function getSpamMappedData() if (empty($this->fieldMapping)) { return null; } - + $result = array(); $data = $this->form->getData(); @@ -91,7 +101,7 @@ public function getSpamMappedData() return $result; } - + /** * This function first gets values from mapped fields and then checks these values against * akismet and then notifies callback object with the spam checking result. @@ -102,7 +112,7 @@ public function getSpamMappedData() */ public function validate($validator) { - + // Check that, if necessary, the user has given permission to check for spam $requireConfirmation = Config::inst()->get(AkismetSpamProtector::class, 'require_confirmation'); if ($requireConfirmation && !$this->Value()) { @@ -116,7 +126,7 @@ public function validate($validator) ); return false; } - + // Check result $isSpam = $this->getIsSpam(); if (!$isSpam) { @@ -184,10 +194,28 @@ public function getIsSpam() // Check result /** @var AkismetService $api */ $api = AkismetSpamProtector::singleton()->getService(); - $this->isSpam = $api && $api->isSpam($content, $author, $email, $url); + $this->isSpam = false; + try { + $this->isSpam = $api && $api->isSpam($content, $author, $email, $url); + } catch (Exception $e) { + //if the network response fails, it still needs to be true/false + $this->isSpam = (bool) $this->config()->is_spam_when_response_fails; + $errorMessage = sprintf( + "%s: %s", + $e->getMessage(), + _t( + __CLASS__ . '.SPAM', + "Your submission has been rejected because it was treated as spam." + ) + ); + Injector::inst() + ->get(LoggerInterface::class) + ->error($errorMessage); + } + return $this->isSpam; } - + /** * Get the fields to map spam protection too *