Completed
Pull Request — master (#1)
by Victor DA COSTA
01:47
created

WindguruAPI::setSpot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * File WindguruAPI.php
4
 *
5
 * PHP Version 5
6
 *
7
 * @category PHP
8
 * @package  WindguruIO
9
 * @author   Voidtek <[email protected]>
10
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
11
 * @link     https://github.com/voidtek/windguru.io
12
 */
13
14
namespace voidtek\WindguruIO;
15
16
use Http\Discovery\HttpClientDiscovery;
17
use Http\Discovery\MessageFactoryDiscovery;
18
use Monolog\Logger;
19
use Monolog\Handler\StreamHandler;
20
21
/**
22
 * WindguruAPI Class
23
 *
24
 * @category Class
25
 * @package  WindguruIO
26
 * @author   Voidtek <[email protected]>
27
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
28
 * @link     https://github.com/voidtek/windguru.io
29
 */
30
class WindguruAPI
31
{
32
33
    /**
34
     * The default Windguru endpoint template.
35
     * Example: 'https://www.windguru.cz/int/iapi.php?q=ads_spot&id_spot%5B%5D=42'
36
     *
37
     * @var string;
38
    */
39
    const ENDPOINT='https://www.windguru.cz';
40
    const LOGFOLDER='logs';
41
    const CACHEFOLDER='cache';
42
    const CACHETIME=10*60;   // secondes
43
44
    /**
45
     * Private Id of the Spot
46
     *
47
     * @var string
48
     */
49
    private $_idSpot;
50
51
    /**
52
     * Private data of the Spot
53
     *
54
     * @var SimpleXMLElement
55
     */
56
    private $_data;
57
58
    /**
59
     * Private HttpClient
60
     *
61
     * @var HttpClient
62
     */
63
    private $_httpClient;
64
65
    /**
66
     * Private MessageFactory
67
     *
68
     * @var MessageFactory
69
     */
70
    private $_messageFactory;
71
72
    /**
73
     * Private MessageFactory
74
     *
75
     * @var MessageFactory
76
     */
77
    private $_log;
78
79
    /**
80
     * Constructor WindguruAPI
81
     *
82
     * @param HttpClient|null     $httpClient     The HttpClient parameter.
83
     * @param MessageFactory|null $messageFactory The messageFactory parameter.
84
     */
85
    public function __construct(
86
        HttpClient $httpClient = null,
87
        MessageFactory $messageFactory = null
88
    ) {
89
        date_default_timezone_set('UTC');
90
91
        $this->_httpClient = $httpClient ?: HttpClientDiscovery::find();
0 ignored issues
show
Documentation Bug introduced by
It seems like $httpClient ?: \Http\Dis...ClientDiscovery::find() can also be of type object<Http\Client\HttpClient>. However, the property $_httpClient is declared as type object<voidtek\WindguruIO\HttpClient>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
92
        $this->_messageFactory = $messageFactory ?: MessageFactoryDiscovery::find();
0 ignored issues
show
Documentation Bug introduced by
It seems like $messageFactory ?: \Http...actoryDiscovery::find() can also be of type object<Http\Message\MessageFactory>. However, the property $_messageFactory is declared as type object<voidtek\WindguruIO\MessageFactory>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
93
94
        if(!file_exists(self::CACHEFOLDER)) {
95
          mkdir(self::CACHEFOLDER, 0777, true);
96
        }
97
98
        if(!file_exists(self::LOGFOLDER)) {
99
          mkdir(self::LOGFOLDER, 0777, true);
100
        }
101
102
        $this->_log = new Logger('WindguruAPI');
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Monolog\Logger('WindguruAPI') of type object<Monolog\Logger> is incompatible with the declared type object<voidtek\WindguruIO\MessageFactory> of property $_log.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
103
        $this->_log->pushHandler(new StreamHandler(self::LOGFOLDER . '/' . date('Ymd') . '.log', Logger::WARNING));
104
    }
105
106
    /**
107
     * Set the Id of the Spot.
108
     *
109
     * @param string $someArgument The Argument for this call.
0 ignored issues
show
Bug introduced by
There is no parameter named $someArgument. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
110
     */
111
    public function setSpot($idSpot)
112
    {
113
        $this->_idSpot = $idSpot;
114
    }
115
116
    /**
117
     * Get the Id of the Spot.
118
     *
119
     * @return string
120
     */
121
    public function getSpot()
122
    {
123
        return $this->_idSpot;
124
    }
125
126
    /**
127
     * Set Data from Online source.
128
     *
129
     * @return DOMDocument
130
     */
131
    public function getData()
132
    {
133
      if(file_exists(self::CACHEFOLDER.'/'.$this->_idSpot)) {
134
        $this->getCacheData();
135
      } else {
136
        $this->getOnlineData();
137
      }
138
    }
139
140
    /**
141
     * Set Data from Online source.
142
     *
143
     * @return DOMDocument
144
     */
145
    public function getOnlineData()
146
    {
147
        $request = $this->_messageFactory
148
            ->createRequest(
149
                'GET',
150
                self::ENDPOINT.'/'.$this->_idSpot
151
            );
152
153
        try {
154
            $response = $this->_httpClient->sendRequest($request);
155
        } catch (\Http\Client\Exception $e) {
156
            throw new \RuntimeException('Something happened during HTTP request');
157
        }
158
159
        $domDoc = new \DOMDocument();
160
        libxml_use_internal_errors(true);
161
        $domDoc->loadHtml($response->getBody());
162
        libxml_use_internal_errors(false);
163
        $element = $domDoc->getElementById('forecasts-page');
164
        $nodes = $element->childNodes;
165
166
        $xml = new \SimpleXMLElement('<xml/>');
167
        $xml->addAttribute('updated', time());
168
        $number = 1;
169
170
        foreach ($nodes as $node) {
171
          if($node->nodeName == "script") {
172
            $nodeData = $xml->addChild('tab');
173
            $nodeData->addChild('number',$number);
174
            $nodeData->addChild(
175
              'wg_fcst_tab_data',
176
              $this->extractVariableIntoScript(
177
                $node->nodeValue,
178
                'wg_fcst_tab_data_'.$number
179
              )
180
            );
181
            $nodeData->addChild(
182
              'wgopts',
183
              $this->extractVariableIntoScript(
184
                $node->nodeValue,
185
                'wgopts_'.$number
186
              )
187
            );
188
            $number++;
189
          }
190
        }
191
192
        $this->_data = $xml;
0 ignored issues
show
Documentation Bug introduced by
It seems like $xml of type object<SimpleXMLElement> is incompatible with the declared type object<voidtek\WindguruIO\SimpleXMLElement> of property $_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
193
        $this->setCacheData();
194
195
        $this->_log->warning($this->_idSpot . ": Load online data.");
196
    }
197
198
    /**
199
     * Extract value of a variable into the JS.
200
     *
201
     * @param string $script The String.
202
     * @param string $variable The variable.
203
     *
204
     * @return string
205
     */
206
    private function extractVariableIntoScript($script, $variable)
207
    {
208
      preg_match('/var ' . $variable . ' = (.*);/', $script, $m );
209
      return $m[1];
210
    }
211
212
    /**
213
     * Set the data of the Spot on cache.
214
     *
215
     * @param string $data The Data.
0 ignored issues
show
Bug introduced by
There is no parameter named $data. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
216
     */
217
    private function setCacheData()
218
    {
219
      // todo assert notNull $this->_data.
220
221
      file_put_contents(self::CACHEFOLDER.'/'.$this->_idSpot, $this->_data->asXML());
222
    }
223
224
    /**
225
     * Get the data of the Spot of cache.
226
     *
227
     * @return string/NULL.
0 ignored issues
show
Documentation introduced by
The doc-type string/NULL. could not be parsed: Unknown type name "string/NULL." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
228
     */
229
    private function getCacheData()
230
    {
231
      $current = file_get_contents(self::CACHEFOLDER.'/'.$this->_idSpot);
232
      $xml = new \SimpleXMLElement($current);
233
      if(time() - $xml['updated'] <= self::CACHETIME) {
234
        $this->_data = $xml;
0 ignored issues
show
Documentation Bug introduced by
It seems like $xml of type object<SimpleXMLElement> is incompatible with the declared type object<voidtek\WindguruIO\SimpleXMLElement> of property $_data.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
235
        $this->_log->warning($this->_idSpot . ": Load cache data.");
236
      } else {
237
        $this->getOnlineData();
238
      }
239
    }
240
241
}
242