comment.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <?php
  2. /**
  3. * Gasteizko Margolariak API v3 - Comment
  4. *
  5. * Used to post comments from apps.
  6. * This file is to be called directly from a URL request.
  7. *
  8. * https://margolariak.com/API/v3/help/
  9. *
  10. * @since 1.0.0
  11. */
  12. // Valid comment target
  13. define('TARGET_PHOTO', 'photo');
  14. define('TARGET_POST', 'post');
  15. define('TARGET_ACTIVITY', 'activity');
  16. // Default target
  17. define('DEF_TARGET', TARGET_ALL);
  18. // $_GET valid parameters
  19. define('GET_CLIENT', 'client');
  20. define('GET_USER', 'user');
  21. define('GET_TARGET', 'target');
  22. define('GET_ID', 'id');
  23. define('GET_PERMALINK', 'permalink');
  24. define('GET_TEXT', 'text');
  25. define('GET_USERNAME', 'username');
  26. define('GET_LANG', 'lang');
  27. /**
  28. * Initializes the MySQL database connection.
  29. *
  30. * Called at the beggining of the script. It connects to the database using the
  31. * parameters in the .htpasswd file. It also sets database and page encodings.
  32. *
  33. * @since 1.0.0
  34. * @return object Database connection.
  35. */
  36. function startdb(){
  37. //Include the db configuration file. It's somehow like this
  38. /*
  39. <?php
  40. $host = 'XXXX';
  41. $db_name = 'XXXX';
  42. $comment["username"]_ro = 'XXXX';
  43. $comment["username"]_rw = 'XXXX';
  44. $pass_ro = 'XXXX';
  45. $pass_rw = 'XXXX';
  46. ?>
  47. */
  48. include('../../.htpasswd');
  49. //Connect to to database
  50. $con = mysqli_connect($host, $comment["username"]_rw, $pass_rw, $db_name);
  51. //Set encoding options
  52. mysqli_set_charset($con, 'utf-8');
  53. header('Content-Type: text/html; charset=utf8');
  54. mysqli_query($con, 'SET NAMES utf8;');
  55. //Return the db connection
  56. return $con;
  57. }
  58. /**
  59. * Detects client language.
  60. *
  61. * Tries to detect the client language by detecting language cookie. It is
  62. * not to be used from external apps, only from the site. Only detects
  63. * spanish, basque or english.
  64. *
  65. * @since 3.0.0
  66. * @return string Two letter language code ('es', 'en' 'eu') or null.
  67. */
  68. function detect_language(){
  69. //Try to read cookie.
  70. header('Cache-control: private');
  71. if (isSet($_COOKIE['lang'])){
  72. $lang = $_COOKIE['lang'];
  73. if ($lang == 'es' || $lang == 'en' || $lang == 'eu'){
  74. return $lang;
  75. }
  76. else{
  77. return null;
  78. }
  79. }
  80. }
  81. /**
  82. * Gets information about the comment.
  83. *
  84. * Gets all the information about the comment and the client from the
  85. * request parameters and the browser info and packs it into an array.
  86. * It also validates the data and check the permissions for posting the
  87. * comment.
  88. *
  89. * @since 3.0.0
  90. * @param object $con Open database connection.
  91. * @param array $get Optional. Array with the request parameters. Default
  92. * is $_GET.
  93. * @return array {
  94. * @type string client Client identifier. Empty if not provided.
  95. * @type string user User identifier. Empty if not provided.
  96. * @type string target The kind of content that the comment is meant
  97. * to. 'photo', 'post' or 'activity'.
  98. * @type int id Photo, post, or activity ID.
  99. * @type string permalink Optional. Photo, post, or activity permalink.
  100. * @type string username Poster username.
  101. * @type string text Comment text.
  102. * @type string lang Two letter language code.
  103. * @type string status Request status to be returned based on comment
  104. * content. 204 (all good), 400 (bad data) or 403 (good
  105. * data, but comments in the content are closed).
  106. * }
  107. */
  108. function get_comment_info($con, $get = $_GET){
  109. $comment = array();
  110. //Get data from URL
  111. $comment["client"] = mysqli_real_escape_string($con, $get[GET_CLIENT]);
  112. $comment["user"] = mysqli_real_escape_string($con, $get[GET_USER]);
  113. $comment["target"] = strtolower(mysqli_real_escape_string($con, $get[GET_TARGET]));
  114. $comment["id"] = strtolower(mysqli_real_escape_string($con, $get[GET_ID]));
  115. $comment["permalink"] = strtolower(mysqli_real_escape_string($con, $get[GET_PERMALINK]));
  116. $comment["username"] = mysqli_real_escape_string($con, $get[GET_USERNAME]);
  117. $comment["text"] = mysqli_real_escape_string($con, $get[GET_TEXT]);
  118. if(isset($get[GET_LANG])){
  119. $comment["lang"] = mysqli_real_escape_string($con, $get[GET_LANG]);
  120. }
  121. else{
  122. $comment["lang"] = null;
  123. }
  124. $comment["status"] = 204; // No content status code: No error.
  125. //Validate data
  126. if (strlen($comment["client"]) < 1){
  127. $comment["status"] = 400; // Bad request status code.
  128. }
  129. if (strlen($comment["user"]) < 1){
  130. $comment["user"] = '';
  131. }
  132. if (strlen($comment["target"]) < 1){
  133. $comment["status"] = 400; // Bad request status code.
  134. }
  135. if ($comment["target"] != TARGET_PHOTO && $comment["target"] != TARGET_POST && $comment["target"] != TARGET_ACTIVITY){
  136. $comment["status"] = 400; // Bad request status code.
  137. }
  138. if (strlen($comment["username"]) < 1){
  139. $comment["status"] = 400; // Bad request status code.
  140. }
  141. if (strlen($comment["lang"]) == null){
  142. strlen($comment["lang"]) = detect_language()
  143. }
  144. //Check id and/or permalink. Several cases:
  145. //1st case: id and permalink empty: Error.
  146. if (strlen($comment["id"]) < 1 && strlen($comment["permalink"]) < 1){
  147. $comment["status"] = 400; // Bad request status code.
  148. }
  149. //2nd case: Comment for post, permalink and no id.
  150. elseif ($comment["target"] == TARGET_POST && strlen($comment["id"]) < 1 && strlen($comment["permalink"]) >= 1){
  151. //Check if post exists...
  152. $q = mysqli_query($con, "SELECT id, comments FROM post WHERE visible = 1 AND permalink = '$comment[permalink]';");
  153. if (mysqli_num_rows($q) == 0){
  154. $comment["status"] = 400; // Bad request status code.
  155. }
  156. else{
  157. //... and if it does, check if can be commented.
  158. $r = mysqli_fetch_array($q);
  159. $item_id = $r['id'];
  160. if ($r['comments'] != 1){
  161. $comment["status"] = 403; // Forbidden status code.
  162. }
  163. }
  164. }
  165. //3rd case: Comment for post, id and no permalink.
  166. elseif ($comment["target"] == TARGET_POST && strlen($comment["id"]) >= 1 && strlen($comment["permalink"]) < 1){
  167. //Check if post exists...
  168. $q = mysqli_query($con, "SELECT id, comments FROM post WHERE visible = 1 AND id = $comment[id];");
  169. if (mysqli_num_rows($q) == 0){
  170. $comment["status"] = 400; // Bad request status code.
  171. }
  172. else{
  173. //... and if it does, check if can be commented.
  174. $r = mysqli_fetch_array($q);
  175. $item_id = $r['id'];
  176. if ($r['comments'] != 1){
  177. $comment["status"] = 403; // Forbidden status code.
  178. }
  179. }
  180. }
  181. //4th case: Comment for post, permalink and id.
  182. elseif ($comment["target"] == TARGET_POST && strlen($comment["id"]) >= 1 && strlen($comment["permalink"]) >= 1){
  183. //Check if post exists...
  184. $q = mysqli_query($con, "SELECT id, comments FROM post WHERE visible = 1 AND permalink = '$comment[permalink]' AND id = $comment[id] ;");
  185. if (mysqli_num_rows($q) == 0){
  186. $comment["status"] = 400; // Bad request status code.
  187. }
  188. else{
  189. //... and if it does, check if can be commented.
  190. $r = mysqli_fetch_array($q);
  191. $item_id = $r['id'];
  192. if ($r['comments'] != 1){
  193. $comment["status"] = 403; // Forbidden status code.
  194. }
  195. }
  196. }
  197. //5th case: Comment for photo, permalink and no id.
  198. elseif ($comment["target"] == TARGET_PHOTO && strlen($comment["id"]) < 1 && strlen($comment["permalink"]) >= 1){
  199. //Check if photo exists.
  200. $q = mysqli_query($con, "SELECT id FROM photo WHERE approved = 1 AND permalink = '$comment[permalink]';");
  201. if (mysqli_num_rows($q) == 0){
  202. $comment["status"] = 400; // Bad request status code.
  203. }
  204. else{
  205. $item_id = $r['id'];
  206. }
  207. }
  208. //6th case: Comment for photo, id and no permalink.
  209. elseif ($comment["target"] == TARGET_PHOTO && strlen($comment["id"]) >= 1 && strlen($comment["permalink"]) < 1){
  210. //Check if photo exists.
  211. $q = mysqli_query($con, "SELECT id FROM photo WHERE approved = 1 AND id = $comment[id];");
  212. if (mysqli_num_rows($q) == 0){
  213. $comment["status"] = 400; // Bad request status code.
  214. }
  215. else{
  216. $item_id = $r['id'];
  217. }
  218. }
  219. //7th case: Comment for photo, permalink and id.
  220. elseif ($comment["target"] == TARGET_PHOTO && strlen($comment["id"]) >= 1 && strlen($comment["permalink"]) >= 1){
  221. //Check if photo exists.
  222. $q = mysqli_query($con, "SELECT id FROM photo WHERE approved = 1 AND permalink = '$comment[permalink]' AND id = $comment[id];");
  223. if (mysqli_num_rows($q) == 0){
  224. $comment["status"] = 400; // Bad request status code.
  225. }
  226. else{
  227. $item_id = $r['id'];
  228. }
  229. }
  230. //8th case: Comment for activity, permalink and no id.
  231. elseif ($comment["target"] == TARGET_ACTIVITY && strlen($comment["id"]) < 1 && strlen($comment["permalink"]) >= 1){
  232. //Check if activity exists...
  233. $q = mysqli_query($con, "SELECT id, comments FROM activity WHERE visible = 1 AND permalink = '$comment[permalink]';");
  234. if (mysqli_num_rows($q) == 0){
  235. $comment["status"] = 400; // Bad request status code.
  236. }
  237. else{
  238. //... and if it does, check if can be commented.
  239. $r = mysqli_fetch_array($q);
  240. $item_id = $r['id'];
  241. if ($r['comments'] != 1){
  242. $comment["status"] = 403; // Forbidden status code.
  243. }
  244. }
  245. }
  246. //9th case: Comment for activity, id and no permalink.
  247. elseif ($comment["target"] == TARGET_ACTIVITY && strlen($comment["id"]) >= 1 && strlen($comment["permalink"]) < 1){
  248. //Check if activity exists...
  249. $q = mysqli_query($con, "SELECT id, comments FROM activity WHERE visible = 1 AND id = $comment[id];");
  250. if (mysqli_num_rows($q) == 0){
  251. $comment["status"] = 400; // Bad request status code.
  252. }
  253. else{
  254. //... and if it does, check if can be commented.
  255. $r = mysqli_fetch_array($q);
  256. $item_id = $r['id'];
  257. if ($r['comments'] != 1){
  258. $comment["status"] = 403; // Forbidden status code.
  259. }
  260. }
  261. }
  262. //10th case: Comment for activity, permalink and id.
  263. elseif ($comment["target"] == TARGET_ACTIVITY && strlen($comment["id"]) >= 1 && strlen($comment["permalink"]) >= 1){
  264. //Check if activity exists...
  265. $q = mysqli_query($con, "SELECT id, comments FROM activity WHERE visible = 1 AND permalink = '$comment[permalink]' AND id = $comment[id] ;");
  266. if (mysqli_num_rows($q) == 0){
  267. $comment["status"] = 400; // Bad request status code.
  268. }
  269. else{
  270. //... and if it does, check if can be commented.
  271. $r = mysqli_fetch_array($q);
  272. $item_id = $r['id'];
  273. if ($r['comments'] != 1){
  274. $comment["status"] = 403; // Forbidden status code.
  275. }
  276. }
  277. }
  278. }
  279. /**
  280. * Inserts the comment into the database.
  281. *
  282. * Inserts the comment in the database. The table will be post_comment,
  283. * photo_comment or activity_comment.
  284. *
  285. * @since 3.0.0
  286. * @param object $con Open database connection.
  287. * @param array $comment As returned by {@see get_comment_info($con, $get)}.
  288. */
  289. function insert_comment($con, $comment){
  290. $query = "INSERT INTO ";
  291. switch ($comment["target"]){
  292. case TARGET_POST:
  293. $query = $query . "post_comment (post";
  294. break;
  295. case TARGET_PHOTO:
  296. $query = $query . "photo_comment (photo";
  297. break;
  298. case TARGET_ACTIVITY:
  299. $query = $query . "activity_comment (activity";
  300. break;
  301. }
  302. if ($comment["lang"] == null){
  303. $lang = "'$comment[lang]'";
  304. }
  305. else{
  306. $lang = "null";
  307. }
  308. $query = $query . ", text, username, app, app_user, lang) VALUES ($comment[id], '$comment[text]', '$comment[username]', '$comment[client]', '$comment[user]', $lang);";
  309. mysqli_query($con, $query);
  310. }
  311. // SCRIPT START
  312. //Connect to the database
  313. $con = startdb('rw');
  314. // Get all the info
  315. $comment = get_comment_info($con, $_GET);
  316. // Set return status
  317. http_response_code($comment["status"]);
  318. // Save comment or exit badly.
  319. if ($comment["status"] == 204){ // 4XX or 5XX are errors.
  320. insert_comment($con, $comment);
  321. }
  322. else{
  323. exit(-1);
  324. }
  325. ?>