Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Spam/Checker/Akismet.php
<?php

namespace XF\Spam\Checker;

use
GuzzleHttp\Psr7\Request;

class
Akismet extends AbstractProvider implements ContentCheckerInterface
{
    protected
$client;

   
/**
     * @var array Map of XenForo content_type to Akismet comment_type.
     *            See https://akismet.com/development/api/#comment-check
     */
   
protected $commentTypes = [
       
'thread'                => 'forum-post',
       
'post'                  => 'reply',
       
'profile_post'          => 'blog',
       
'profile_post_comment'  => 'comment',
       
'user'                  => 'signup',
       
'conversation_message'  => 'message',
       
'contact'               => 'contact-form',

       
// * - These are (probably) not officially supported by Akismet

       
'user_signature'        => 'user-signature',    // *

       
'media'                 => 'multi-media',       // *
       
'album'                 => 'album',             // *
       
'media_comment'         => 'comment',
       
'media_album_comment'   => 'comment',

       
'resource_rating'       => 'review',            // *
       
'resource_update'       => 'blog-post',
    ];

    protected function
getType()
    {
        return
'Akismet';
    }

    public function
check(\XF\Entity\User $user, $message, array $extraParams = [])
    {
       
$decision = 'allowed';

        try
        {
           
$isSpam = $this->isSpam($user, $message, $extraParams);
            if (
$isSpam)
            {
               
$decision = 'moderated';

               
$this->logDetail('akismet_matched');
            }

           
$this->logParam('akismetIsSpam', $isSpam);
           
$this->logParam('akismet', $this->getParams($user, $message, $extraParams));
        }
        catch (\
GuzzleHttp\Exception\RequestException $e) { $this->app()->logException($e, false, 'Akismet HTTP error: '); }
        catch (\
InvalidArgumentException $e) { $this->app()->logException($e, false, 'Akismet service error: '); }

       
$this->logDecision($decision);
    }

    public function
submitSpam($contentType, $contentIds)
    {
        foreach (
$this->getContentSpamCheckParams($contentType, $contentIds) AS $contentId => $params)
        {
            if (
$params)
            {
               
$this->_submitSpam($params);
            }
        }
    }

    protected function
_submitSpam($params)
    {
        if (!empty(
$params['akismetIsSpam']))
        {
            return;
// Akismet already told us this is spam, so do not submit again.
       
}

        if (!empty(
$params['akismet']))
        {
            try
            {
               
$params = [
                   
'headers' => [
                       
'User-Agent' => $this->getUserAgent()
                    ],
                   
'form_params' => $params['akismet'],
                ];

               
$response = $this->getHttpClient()->post('https://' . $this->getApiKey() . '.rest.akismet.com/1.1/submit-spam', $params);
               
$response = trim($response->getBody()->getContents());

                if (
$response == 'invalid')
                {
                    throw new \
InvalidArgumentException("Invalid API key");
                }
            }
            catch (\
GuzzleHttp\Exception\RequestException $e) { $this->app()->logException($e, false, 'Akismet HTTP error: '); }
            catch (\
InvalidArgumentException $e) { $this->app()->logException($e, false, 'Akismet service error: '); }
        }
    }

    public function
submitHam($contentType, $contentIds)
    {
        foreach (
$this->getContentSpamCheckParams($contentType, $contentIds) AS $contentId => $params)
        {
            if (
$params)
            {
               
$this->_submitHam($params);
            }
        }
    }

    protected function
_submitHam($params)
    {
        if (empty(
$params['akismetIsSpam']))
        {
            return;
// Akismet already told us this wasn't spam, so do not submit as ham.
       
}

        if (!empty(
$params['akismet']))
        {
            try
            {
               
$params = [
                   
'headers' => [
                       
'User-Agent' => $this->getUserAgent()
                    ],
                   
'form_params' => $params['akismet'],
                ];

               
$response = $this->getHttpClient()->post('https://' . $this->getApiKey() . '.rest.akismet.com/1.1/submit-ham', $params);
               
$response = trim($response->getBody()->getContents());

                if (
$response == 'invalid')
                {
                    throw new \
InvalidArgumentException("Invalid API key");
                }
            }
            catch (\
GuzzleHttp\Exception\RequestException $e) { $this->app()->logException($e, false, 'Akismet HTTP error: '); }
            catch (\
InvalidArgumentException $e) { $this->app()->logException($e, false, 'Akismet service error: '); }
        }
    }

    protected function
getParams(\XF\Entity\User $user, $message, $extraParams)
    {
       
$options = $this->app()->options();
       
$request = $this->app()->request();

       
$params = [
           
'blog' => $options->boardUrl,
           
'user_ip' => $request->getIp(),
           
'user_agent' => $request->getUserAgent(),
           
'referrer' => $request->getReferrer() ?: '',
           
'comment_type' => 'comment',
           
'comment_author' => $user->username,
           
'comment_author_email' => $user->email,
           
'comment_author_url' => $user->Profile ? $user->Profile->website : '',
           
'comment_content' => $message
       
];
        if (isset(
$extraParams['content_type']))
        {
           
$params['comment_type'] = $this->getCommentType($extraParams['content_type']);
        }
        if (isset(
$extraParams['permalink']))
        {
           
$params['permalink'] = $extraParams['permalink'];
        }

        return
$params;
    }

    protected function
isSpam(\XF\Entity\User $user, $message, $extraParams)
    {
       
$params = [
           
'headers' => [
               
'User-Agent' => $this->getUserAgent()
            ],
           
'form_params' => $this->getParams($user, $message, $extraParams),
        ];

       
$response = $this->getHttpClient()->post('https://' . $this->getApiKey() . '.rest.akismet.com/1.1/comment-check', $params);
       
$response = trim($response->getBody()->getContents());

        if (
$response == 'invalid')
        {
            throw new \
InvalidArgumentException("Invalid API key");
        }

        return (
$response == 'true');
    }

   
/**
     * @return \GuzzleHttp\Client
     */
   
protected function getHttpClient()
    {
        if (!
$this->client)
        {
           
$this->client = $this->app->http()->client();
        }

        return
$this->client;
    }

   
/**
     * @return Request
     */
   
protected function getHttpRequest($url = null, $method = 'POST')
    {
       
$client = $this->getHttpClient();
       
$request = new Request($method, $url, [
           
'headers' => [
               
'User-Agent' => $this->getUserAgent()
            ]
        ]);

        return
$request;
    }

    protected function
getUserAgent()
    {
       
$version = \XF::$version;
        return
'XenForo/' . $version . ' | Akismet/' . $version;
    }

    protected function
getCommentType($contentType)
    {
        if (isset(
$this->commentTypes[$contentType]))
        {
            return
$this->commentTypes[$contentType];
        }

        return
'comment';
    }

    protected function
getApiKey()
    {
        return
trim($this->app()->options()->akismetKey);
    }
}