Skip to content

Commit eca1cd5

Browse files
author
George Mihailov
committed
Separate repository.
0 parents  commit eca1cd5

17 files changed

+853
-0
lines changed

Bpi/Sdk/Document.php

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
<?php
2+
namespace Bpi\Sdk;
3+
4+
use Goutte\Client;
5+
use Symfony\Component\DomCrawler\Crawler;
6+
7+
class Document implements \Iterator, \Countable
8+
{
9+
protected $http_client;
10+
11+
/**
12+
*
13+
* @var Symfony\Component\DomCrawler\Crawler
14+
*/
15+
protected $crawler;
16+
17+
/**
18+
*
19+
* @var Symfony\Component\DomCrawler\Crawler
20+
*/
21+
protected $iterator;
22+
23+
/**
24+
*
25+
* @param \Goutte\Client $client
26+
*/
27+
public function __construct(Client $client)
28+
{
29+
$this->http_client = $client;
30+
}
31+
32+
/**
33+
* Gateway to make direct requests to API
34+
*
35+
* @param string $method
36+
* @param string $uri
37+
* @param array $params
38+
*/
39+
public function request($method, $uri, array $params = array())
40+
{
41+
$this->crawler = $this->http_client->request($method, $uri, $params, array(), array( 'HTTP_Content_Type' => 'application/vnd.bpi.api+xml'));
42+
$this->rewind();
43+
}
44+
45+
/**
46+
*
47+
* @return \Symfony\Component\DomCrawler\Crawler crawler copy
48+
*/
49+
public function getCrawler()
50+
{
51+
return clone $this->crawler;
52+
}
53+
54+
/**
55+
* Access hypermedia link.
56+
*
57+
* @param string $rel
58+
* @return \Bpi\Sdk\Link
59+
*/
60+
public function link($rel)
61+
{
62+
$crawler = $this->crawler
63+
->filter("hypermedia > link[rel='{$rel}']")
64+
->first()
65+
;
66+
67+
return new Link($crawler);
68+
}
69+
70+
/**
71+
* Click on link.
72+
*
73+
* @param \Bpi\Sdk\Link $link
74+
*/
75+
public function followLink(Link $link)
76+
{
77+
$link->follow($this);
78+
}
79+
80+
/**
81+
* Access hypermedia query.
82+
*
83+
* @param string $rel
84+
* @return \Bpi\Sdk\Query
85+
*/
86+
public function query($rel)
87+
{
88+
$query = $this->crawler
89+
->filter("hypermedia > query[rel='{$rel}']")
90+
->first()
91+
;
92+
93+
return new Query($query);
94+
}
95+
96+
/**
97+
* Send query.
98+
*
99+
* @param \Bpi\Sdk\Query $query
100+
* @param array $params
101+
*/
102+
public function sendQuery(Query $query, $params)
103+
{
104+
$query->send($this, $params);
105+
}
106+
107+
/**
108+
* Access hypermedia template.
109+
*
110+
* @param string $rel
111+
* @return \Bpi\Sdk\Template
112+
*/
113+
public function template($rel)
114+
{
115+
$query = $this->crawler
116+
->filter("hypermedia > template[rel='{$rel}']")
117+
->first()
118+
;
119+
120+
return new Template($query);
121+
}
122+
123+
/**
124+
* Post rendered template.
125+
*
126+
* @param \Bpi\Sdk\Template $template
127+
*/
128+
public function postTemplate(Template $template)
129+
{
130+
$template->post($this);
131+
}
132+
133+
/**
134+
* Checks current item type
135+
*
136+
* @param string $type
137+
* @return bool
138+
*/
139+
public function isTypeOf($type)
140+
{
141+
return $this->iterator->current()->getAttribute('type') == $type;
142+
}
143+
144+
/**
145+
* Returns all available properties of current item
146+
*
147+
* @return array
148+
*/
149+
public function getProperties()
150+
{
151+
$crawler = new Crawler($this->iterator->current());
152+
return $crawler->children()->filter('*[type]')->each(function($e) {
153+
return array('name' => $e->tagName, 'value' => $e->nodeValue);
154+
});
155+
}
156+
157+
/**
158+
* Iterator interface implementation
159+
*
160+
* @group Iterator
161+
*/
162+
function rewind()
163+
{
164+
$this->iterator = $this->crawler->filter('bpi > item');
165+
$this->iterator->rewind();
166+
}
167+
168+
/**
169+
* Returns same instance but with internal pointer to current item in collection
170+
*
171+
* @group Iterator
172+
* @return \Bpi\Sdk\Document will return same instance
173+
*/
174+
function current()
175+
{
176+
return $this;
177+
}
178+
179+
/**
180+
* Key of current iteration position
181+
*
182+
* @group Iterator
183+
*/
184+
function key()
185+
{
186+
return $this->iterator->key();
187+
}
188+
189+
/**
190+
* Iterate to next item
191+
*
192+
* @group Iterator
193+
*/
194+
function next()
195+
{
196+
$this->iterator->next();
197+
}
198+
199+
/**
200+
* Checks if is ready for iteration
201+
*
202+
* @group Iterator
203+
* @return boolean
204+
*/
205+
function valid()
206+
{
207+
return $this->iterator->valid();
208+
}
209+
210+
/**
211+
* Length of items in document
212+
*
213+
* @group Iterator
214+
*/
215+
public function count()
216+
{
217+
return $this->iterator->count();
218+
}
219+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
namespace Bpi\Sdk\Exception;
3+
4+
class InvalidQueryParameter extends SDKException {}

Bpi/Sdk/Exception/SDKException.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
namespace Bpi\Sdk\Exception;
3+
4+
class SDKException extends \Exception {}

Bpi/Sdk/Link.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
namespace Bpi\Sdk;
3+
4+
use Symfony\Component\DomCrawler\Crawler;
5+
6+
class Link
7+
{
8+
/**
9+
*
10+
* @var \Symfony\Component\DomCrawler\Crawler
11+
*/
12+
protected $crawler;
13+
14+
/**
15+
*
16+
* @param \Symfony\Component\DomCrawler\Crawler $crawler
17+
*/
18+
public function __construct(Crawler $crawler)
19+
{
20+
$this->crawler = $crawler;
21+
}
22+
23+
/**
24+
*
25+
* @param \Bpi\Sdk\Document $document
26+
*/
27+
public function follow(Document $document)
28+
{
29+
$document->request('GET', $this->crawler->attr('href'));
30+
}
31+
32+
/**
33+
*
34+
* @return array properties
35+
*/
36+
public function toArray()
37+
{
38+
$properties = array();
39+
foreach($this->crawler as $node)
40+
{
41+
foreach ($node->attributes as $attr_name => $attr)
42+
{
43+
$properties[$attr_name] = $attr->value;
44+
}
45+
}
46+
return $properties;
47+
}
48+
}

Bpi/Sdk/Query.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
namespace Bpi\Sdk;
3+
4+
use Symfony\Component\DomCrawler\Crawler;
5+
6+
class Query
7+
{
8+
/**
9+
*
10+
* @var Symfony\Component\DomCrawler\Crawler
11+
*/
12+
protected $crawler;
13+
14+
/**
15+
*
16+
* @param \Symfony\Component\DomCrawler\Crawler $crawler
17+
*/
18+
public function __construct(Crawler $crawler)
19+
{
20+
$this->crawler = $crawler;
21+
}
22+
23+
/**
24+
*
25+
* @param array $params
26+
* @throws Exception\InvalidQueryParameter
27+
*/
28+
protected function validate(array $params)
29+
{
30+
foreach ($params as $user_param => $value)
31+
{
32+
if ($this->crawler->filter("param[name='{$user_param}']")->count() <= 0)
33+
{
34+
throw new Exception\InvalidQueryParameter(sprintf('The API has no such query parameter [%s] on page [%s]', $user_param, $this->crawler->attr('href')));
35+
}
36+
}
37+
}
38+
39+
/**
40+
* Transform query to array
41+
*
42+
* @return array
43+
*/
44+
public function toArray()
45+
{
46+
$result = array();
47+
foreach($this->crawler as $node)
48+
{
49+
foreach ($node->attributes as $attr_name => $attr)
50+
{
51+
$result[$attr_name] = $attr->value;
52+
}
53+
}
54+
55+
foreach ($this->crawler->filter('param') as $node)
56+
{
57+
foreach ($node->attributes as $attr_name => $attr)
58+
{
59+
$result['params'][$attr_name] = $attr->value;
60+
}
61+
}
62+
63+
return $result;
64+
}
65+
66+
/**
67+
*
68+
* @param \Bpi\Sdk\Document $document
69+
* @param array $params
70+
*/
71+
public function send(Document $document, array $params)
72+
{
73+
$this->validate($params);
74+
$document->request('GET', $this->crawler->attr('href'), $params);
75+
}
76+
}

0 commit comments

Comments
 (0)