aboutsummaryrefslogtreecommitdiff
path: root/bridges/DribbbleBridge.php
blob: 5058da632162e57730727d451f14c2bf67ad2cb1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
class DribbbleBridge extends BridgeAbstract {

	const MAINTAINER = 'quentinus95';
	const NAME = 'Dribbble popular shots';
	const URI = 'https://dribbble.com';
	const CACHE_TIMEOUT = 1800;
	const DESCRIPTION = 'Returns the newest popular shots from Dribbble.';

	public function getIcon() {
		return 'https://cdn.dribbble.com/assets/
favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
	}

	public function collectData(){
		$html = getSimpleHTMLDOM(self::URI . '/shots')
			or returnServerError('Error while downloading the website content');

		$json = $this->loadEmbeddedJsonData($html);

		foreach($html->find('li[id^="screenshot-"]') as $shot) {
			$item = [];

			$additional_data = $this->findJsonForShot($shot, $json);
			if ($additional_data === null) {
				$item['uri'] = self::URI . $shot->find('a', 0)->href;
				$item['title'] = $shot->find('.dribbble-over strong', 0)->plaintext;
			} else {
				$item['timestamp'] = strtotime($additional_data['published_at']);
				$item['uri'] = self::URI . $additional_data['path'];
				$item['title'] = $additional_data['title'];
			}

			$item['author'] = trim($shot->find('.attribution-user a', 0)->plaintext);

			$description = $shot->find('.comment', 0);
			$item['content'] = $description === null ? '' : $description->plaintext;

			$preview_path = $shot->find('picture source', 0)->attr['srcset'];
			$item['content'] .= $this->getImageTag($preview_path, $item['title']);
			$item['enclosures'] = [$this->getFullSizeImagePath($preview_path)];

			$this->items[] = $item;
		}
	}

	private function loadEmbeddedJsonData($html){
		$json = [];
		$scripts = $html->find('script');

		foreach($scripts as $script) {
			if(strpos($script->innertext, 'newestShots') !== false) {
				// fix single quotes
				$script->innertext = str_replace('\'', '"', $script->innertext);

				// fix JavaScript JSON (why do they not adhere to the standard?)
				$script->innertext = preg_replace('/(\w+):/i', '"\1":', $script->innertext);

				// find beginning of JSON array
				$start = strpos($script->innertext, '[');

				// find end of JSON array, compensate for missing character!
				$end = strpos($script->innertext, '];') + 1;

				// convert JSON to PHP array
				$json = json_decode(substr($script->innertext, $start, $end - $start), true);
				break;
			}
		}

		return $json;
	}

	private function findJsonForShot($shot, $json){
		foreach($json as $element) {
			if(strpos($shot->getAttribute('id'), (string)$element['id']) !== false) {
				return $element;
			}
		}

		return null;
	}

	private function getImageTag($preview_path, $title){
		return sprintf(
			'<br /> <a href="%s"><img src="%s" alt="%s" /></a>',
			$this->getFullSizeImagePath($preview_path),
			$preview_path,
			$title
		);
	}

	private function getFullSizeImagePath($preview_path){
		return str_replace('_1x', '', $preview_path);
	}
}