Completed
Pull Request — master (#10)
by Chad
04:36 queued 03:11
created

Service   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 0
Metric Value
wmc 15
lcom 2
cbo 3
dl 0
loc 122
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 3
A getHtml() 0 14 3
C checkAnswer() 0 38 8
A getSignupUrl() 0 4 1
1
<?php
2
/**
3
 * TraderInteractive\SolveMedia\Service class for accessing the Solve Media API service.
4
 * This component has been heavily modified from it's original form to
5
 * encapsulate the functionality in a class based structure that is
6
 * compatible with class autoloading functionality.
7
 *
8
 * @author Chris Ryan <[email protected]>
9
 */
10
namespace TraderInteractive\SolveMedia;
11
use Guzzle\Http\ClientInterface as GuzzleClient;
12
use Exception;
13
14
final class Service
15
{
16
    /**
17
     * The solvemedia server URL's
18
     */
19
    const ADCOPY_API_SERVER = 'http://api.solvemedia.com';
20
    const ADCOPY_API_SECURE_SERVER = 'https://api-secure.solvemedia.com';
21
    const ADCOPY_VERIFY_SERVER = 'http://verify.solvemedia.com/papi/verify';
22
    const ADCOPY_SIGNUP = 'http://api.solvemedia.com/public/signup';
23
24
    private $_client;
25
    private $_pubkey;
26
    private $_privkey;
27
    private $_hashkey;
28
29
    /**
30
     * Construct a Service object with the required api key values.
31
     *
32
     * @param \Guzzle\Http\Client The guzzle client to send the requests over.
33
     * @param string $pubkey A public key for solvemedia
34
     * @param string $privkey A private key for solvemedia
35
     * @param string $hashkey An optional hash key for verification
36
     * @throws Exception
37
     */
38
    public function __construct(GuzzleClient $client, $pubkey, $privkey, $hashkey = '')
39
    {
40
        if (empty($pubkey) || empty($privkey)) {
41
            throw new Exception('To use solvemedia you must get an API key from ' . self::ADCOPY_SIGNUP);
42
        }
43
44
        $this->_client = $client;
45
        $this->_pubkey = $pubkey;
46
        $this->_privkey = $privkey;
47
        $this->_hashkey = $hashkey;
48
    }
49
50
    /**
51
     * Gets the challenge HTML (javascript and non-javascript version).
52
     * This is called from the browser, and the resulting solvemedia HTML widget
53
     * is embedded within the HTML form it was called from.
54
     *
55
     * @param string $error The error given by solvemedia (optional, default is null)
56
     * @param boolean $useSsl Should the request be made over ssl? (optional, default is false)
57
     * @return string The HTML to be embedded in the user's form.
58
     */
59
    public function getHtml($error = null, $useSsl = false)
60
    {
61
        $server = $useSsl ? self::ADCOPY_API_SECURE_SERVER : self::ADCOPY_API_SERVER;
62
        $errorpart = $error ? ';error=1' : '';
63
64
        return <<<EOS
65
<script type="text/javascript" src="{$server}/papi/challenge.script?k={$this->_pubkey}{$errorpart}"></script>
66
<noscript>
67
    <iframe src="{$server}/papi/challenge.noscript?k={$this->_pubkey}{$errorpart}" height="300" width="500" frameborder="0"></iframe><br/>
68
    <textarea name="adcopy_challenge" rows="3" cols="40"></textarea>
69
    <input type="hidden" name="adcopy_response" value="manual_challenge"/>
70
</noscript>
71
EOS;
72
    }
73
74
    /**
75
     * Calls an HTTP POST function to verify if the user's guess was correct
76
     *
77
     * @param string $remoteip
78
     * @param string $challenge
79
     * @param string $response
80
     * @throws Exception
81
     * @return TraderInteractive\SolveMedia\Response
82
     */
83
    public function checkAnswer($remoteip, $challenge, $response)
84
    {
85
        if (empty($remoteip)) {
86
            throw new Exception('For security reasons, you must pass the remote ip to solvemedia');
87
        }
88
89
        //discard spam submissions
90
        if (empty($challenge) || empty($response)) {
91
            return new Response(false, 'incorrect-solution');
92
        }
93
94
        $httpResponse = $this->_client->post(
95
            self::ADCOPY_VERIFY_SERVER,
96
            ['User-Agent' => 'solvemedia/PHP'],
97
            ['privatekey' => $this->_privkey, 'remoteip' => $remoteip, 'challenge' => $challenge, 'response' => $response]
98
        )->send();
99
100
        if ($httpResponse->getStatusCode() !== 200) {
101
            return new Response(false, $httpResponse->getReasonPhrase());
102
        }
103
104
        $answers = explode("\n", $httpResponse->getBody());
105
106
        if (!empty($this->_hashkey)) {
107
            // validate message authenticator
108
            $hash = sha1($answers[0] . $challenge . $this->_hashkey);
109
110
            if ($hash !== $answers[2]) {
111
                return new Response(false, 'hash-fail');
112
            }
113
        }
114
115
        if (trim($answers[0]) !== 'true') {
116
            return new Response(false, $answers[1]);
117
        }
118
119
        return new Response(true);
120
    }
121
122
    /**
123
     * Gets a URL where the user can sign up for solvemedia. If your application
124
     * has a configuration page where you enter a key, you should provide a link
125
     * using this function.
126
     *
127
     * @param string $domain The domain where the page is hosted
128
     * @param string $appname The name of your application
129
     * @return string url for signup page
130
     */
131
    public function getSignupUrl($domain = null, $appname = null)
132
    {
133
        return self::ADCOPY_SIGNUP . '?' . http_build_query(['domain' => $domain, 'app' => $appname]);
134
    }
135
}
136