DribbbleBridge.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <?php
  2. class DribbbleBridge extends BridgeAbstract {
  3. const MAINTAINER = 'quentinus95';
  4. const NAME = 'Dribbble popular shots';
  5. const URI = 'https://dribbble.com';
  6. const CACHE_TIMEOUT = 1800;
  7. const DESCRIPTION = 'Returns the newest popular shots from Dribbble.';
  8. public function collectData(){
  9. $html = getSimpleHTMLDOM(self::URI . '/shots')
  10. or returnServerError('Error while downloading the website content');
  11. $json = $this->loadEmbeddedJsonData($html);
  12. foreach($html->find('li[id^="screenshot-"]') as $shot) {
  13. $item = [];
  14. $additional_data = $this->findJsonForShot($shot, $json);
  15. if ($additional_data === null) {
  16. $item['uri'] = self::URI . $shot->find('a', 0)->href;
  17. $item['title'] = $shot->find('.dribbble-over strong', 0)->plaintext;
  18. } else {
  19. $item['timestamp'] = strtotime($additional_data['published_at']);
  20. $item['uri'] = self::URI . $additional_data['path'];
  21. $item['title'] = $additional_data['title'];
  22. }
  23. $item['author'] = trim($shot->find('.attribution-user a', 0)->plaintext);
  24. $description = $shot->find('.comment', 0);
  25. $item['content'] = $description === null ? '' : $description->plaintext;
  26. $preview_path = $shot->find('picture source', 0)->attr['srcset'];
  27. $item['content'] .= $this->getImageTag($preview_path, $item['title']);
  28. $item['enclosures'] = [$this->getFullSizeImagePath($preview_path)];
  29. $this->items[] = $item;
  30. }
  31. }
  32. private function loadEmbeddedJsonData($html){
  33. $json = [];
  34. $scripts = $html->find('script');
  35. foreach($scripts as $script) {
  36. if(strpos($script->innertext, 'newestShots') !== false) {
  37. // fix single quotes
  38. $script->innertext = str_replace('\'', '"', $script->innertext);
  39. // fix JavaScript JSON (why do they not adhere to the standard?)
  40. $script->innertext = preg_replace('/(\w+):/i', '"\1":', $script->innertext);
  41. // find beginning of JSON array
  42. $start = strpos($script->innertext, '[');
  43. // find end of JSON array, compensate for missing character!
  44. $end = strpos($script->innertext, '];') + 1;
  45. // convert JSON to PHP array
  46. $json = json_decode(substr($script->innertext, $start, $end - $start), true);
  47. break;
  48. }
  49. }
  50. return $json;
  51. }
  52. private function findJsonForShot($shot, $json){
  53. foreach($json as $element) {
  54. if(strpos($shot->getAttribute('id'), (string)$element['id']) !== false) {
  55. return $element;
  56. }
  57. }
  58. return null;
  59. }
  60. private function getImageTag($preview_path, $title){
  61. return sprintf(
  62. '<br /> <a href="%s"><img src="%s" alt="%s" /></a>',
  63. $this->getFullSizeImagePath($preview_path),
  64. $preview_path,
  65. $title
  66. );
  67. }
  68. private function getFullSizeImagePath($preview_path){
  69. return str_replace('_1x', '', $preview_path);
  70. }
  71. }