The version of vichan running on lainchan.org
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

192 lignes
5.0KB

  1. <?php
  2. /*
  3. * Copyright (c) 2010-2013 Tinyboard Development Group
  4. */
  5. defined('TINYBOARD') or exit;
  6. /**
  7. * Class for generating json API compatible with 4chan API
  8. */
  9. class Api {
  10. function __construct(){
  11. global $config;
  12. /**
  13. * Translation from local fields to fields in 4chan-style API
  14. */
  15. $this->config = $config;
  16. $this->postFields = array(
  17. 'id' => 'no',
  18. 'thread' => 'resto',
  19. 'subject' => 'sub',
  20. 'body' => 'com',
  21. 'email' => 'email',
  22. 'name' => 'name',
  23. 'trip' => 'trip',
  24. 'capcode' => 'capcode',
  25. 'time' => 'time',
  26. 'omitted' => 'omitted_posts',
  27. 'omitted_images' => 'omitted_images',
  28. 'replies' => 'replies',
  29. 'images' => 'images',
  30. 'sticky' => 'sticky',
  31. 'locked' => 'locked',
  32. 'cycle' => 'cyclical',
  33. 'bump' => 'last_modified',
  34. 'embed' => 'embed',
  35. );
  36. $this->threadsPageFields = array(
  37. 'id' => 'no',
  38. 'bump' => 'last_modified'
  39. );
  40. $this->fileFields = array(
  41. 'thumbheight' => 'tn_h',
  42. 'thumbwidth' => 'tn_w',
  43. 'height' => 'h',
  44. 'width' => 'w',
  45. 'size' => 'fsize',
  46. );
  47. if (isset($config['api']['extra_fields']) && gettype($config['api']['extra_fields']) == 'array'){
  48. $this->postFields = array_merge($this->postFields, $config['api']['extra_fields']);
  49. }
  50. }
  51. private static $ints = array(
  52. 'no' => 1,
  53. 'resto' => 1,
  54. 'time' => 1,
  55. 'tn_w' => 1,
  56. 'tn_h' => 1,
  57. 'w' => 1,
  58. 'h' => 1,
  59. 'fsize' => 1,
  60. 'omitted_posts' => 1,
  61. 'omitted_images' => 1,
  62. 'replies' => 1,
  63. 'images' => 1,
  64. 'sticky' => 1,
  65. 'locked' => 1,
  66. 'last_modified' => 1
  67. );
  68. private function translateFields($fields, $object, &$apiPost) {
  69. foreach ($fields as $local => $translated) {
  70. if (!isset($object->$local))
  71. continue;
  72. $toInt = isset(self::$ints[$translated]);
  73. $val = $object->$local;
  74. if ($val !== null && $val !== '') {
  75. $apiPost[$translated] = $toInt ? (int) $val : $val;
  76. }
  77. }
  78. }
  79. private function translateFile($file, $post, &$apiPost) {
  80. $this->translateFields($this->fileFields, $file, $apiPost);
  81. $apiPost['filename'] = @substr($file->name, 0, strrpos($file->name, '.'));
  82. $dotPos = strrpos($file->file, '.');
  83. $apiPost['ext'] = substr($file->file, $dotPos);
  84. $apiPost['tim'] = substr($file->file, 0, $dotPos);
  85. if (isset ($file->hash) && $file->hash) {
  86. $apiPost['md5'] = base64_encode(hex2bin($file->hash));
  87. }
  88. else if (isset ($post->filehash) && $post->filehash) {
  89. $apiPost['md5'] = base64_encode(hex2bin($post->filehash));
  90. }
  91. }
  92. private function translatePost($post, $threadsPage = false) {
  93. global $config, $board;
  94. $apiPost = array();
  95. $fields = $threadsPage ? $this->threadsPageFields : $this->postFields;
  96. $this->translateFields($fields, $post, $apiPost);
  97. if (isset($config['poster_ids']) && $config['poster_ids']) $apiPost['id'] = poster_id($post->ip, $post->thread, $board['uri']);
  98. if ($threadsPage) return $apiPost;
  99. // Handle country field
  100. if (isset($post->body_nomarkup) && $this->config['country_flags']) {
  101. $modifiers = extract_modifiers($post->body_nomarkup);
  102. if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', $modifiers['flag'])) {
  103. $country = strtoupper($modifiers['flag']);
  104. if ($country) {
  105. $apiPost['country'] = $country;
  106. $apiPost['country_name'] = $modifiers['flag alt'];
  107. }
  108. }
  109. }
  110. if ($config['slugify'] && !$post->thread) {
  111. $apiPost['semantic_url'] = $post->slug;
  112. }
  113. // Handle files
  114. // Note: 4chan only supports one file, so only the first file is taken into account for 4chan-compatible API.
  115. if (isset($post->files) && $post->files && !$threadsPage) {
  116. $file = $post->files[0];
  117. $this->translateFile($file, $post, $apiPost);
  118. if (sizeof($post->files) > 1) {
  119. $extra_files = array();
  120. foreach ($post->files as $i => $f) {
  121. if ($i == 0) continue;
  122. $extra_file = array();
  123. $this->translateFile($f, $post, $extra_file);
  124. $extra_files[] = $extra_file;
  125. }
  126. $apiPost['extra_files'] = $extra_files;
  127. }
  128. }
  129. return $apiPost;
  130. }
  131. function translateThread(Thread $thread, $threadsPage = false) {
  132. $apiPosts = array();
  133. $op = $this->translatePost($thread, $threadsPage);
  134. if (!$threadsPage) $op['resto'] = 0;
  135. $apiPosts['posts'][] = $op;
  136. foreach ($thread->posts as $p) {
  137. $apiPosts['posts'][] = $this->translatePost($p, $threadsPage);
  138. }
  139. return $apiPosts;
  140. }
  141. function translatePage(array $threads) {
  142. $apiPage = array();
  143. foreach ($threads as $thread) {
  144. $apiPage['threads'][] = $this->translateThread($thread);
  145. }
  146. return $apiPage;
  147. }
  148. function translateCatalogPage(array $threads, $threadsPage = false) {
  149. $apiPage = array();
  150. foreach ($threads as $thread) {
  151. $ts = $this->translateThread($thread, $threadsPage);
  152. $apiPage['threads'][] = current($ts['posts']);
  153. }
  154. return $apiPage;
  155. }
  156. function translateCatalog($catalog, $threadsPage = false) {
  157. $apiCatalog = array();
  158. foreach ($catalog as $page => $threads) {
  159. $apiPage = $this->translateCatalogPage($threads, $threadsPage);
  160. $apiPage['page'] = $page;
  161. $apiCatalog[] = $apiPage;
  162. }
  163. return $apiCatalog;
  164. }
  165. }