/application/controllers/content.php

https://github.com/busaway/FoOlSlide · PHP · 343 lines · 221 code · 51 blank · 71 comment · 45 complexity · 5ff52cbd3ebf87244c4124c38862381b MD5 · raw file

  1. <?php
  2. if (!defined('BASEPATH'))
  3. exit('No direct script access allowed');
  4. class Content extends MY_Controller
  5. {
  6. function __construct()
  7. {
  8. parent::__construct();
  9. // If the balancer master URL is not set, this is not a balancer
  10. if (!get_setting('fs_balancer_master_url'))
  11. {
  12. show_404();
  13. }
  14. }
  15. /**
  16. * PHP implementation of lastIndexOf
  17. *
  18. * @param string $string
  19. * @param string $item
  20. * @return string
  21. */
  22. public function _lastIndexOf($string, $item)
  23. {
  24. $index = strpos(strrev($string), strrev($item));
  25. if ($index)
  26. {
  27. $index = strlen($string) - strlen($item) - $index;
  28. return $index;
  29. }
  30. else
  31. return -1;
  32. }
  33. /**
  34. * Grabs the failed tries to get to the comics, and if this Slide is active
  35. * as a load balancer, it will fetch data from the master Slide, copy and
  36. * serve it.
  37. *
  38. * @author Woxxy
  39. */
  40. public function comics()
  41. {
  42. // grab the urls
  43. $this->comic_dir = $this->uri->segment(3);
  44. $this->chapter_dir = $this->uri->segment(4);
  45. $this->filename = $this->uri->segment(5);
  46. // check that $comic is actually the interesting kind of foldername
  47. // get the divider index
  48. if (($comic_split = $this->_lastIndexOf($this->comic_dir, '_')) == -1)
  49. {
  50. show_404();
  51. }
  52. // check that $chapter is actually the interesting kind of foldername
  53. // get the divider index
  54. if (($chapter_split = $this->_lastIndexOf($this->chapter_dir, '_')) == -1)
  55. {
  56. show_404();
  57. }
  58. if (!$this->filename)
  59. {
  60. show_404();
  61. }
  62. // separate stub and uniqid from both folders
  63. $this->comic_stub = substr($this->comic_dir, 0, $comic_split);
  64. $this->comic_uniqid = substr($this->comic_dir, $comic_split + 1);
  65. $this->chapter_stub = substr($this->chapter_dir, 0, $chapter_split);
  66. $this->chapter_uniqid = substr($this->chapter_dir, $chapter_split + 1);
  67. // flag that forces updating the data for this chapter
  68. $this->update = FALSE;
  69. // flat that allows us not to send an image, used if we're at least cleaning up
  70. $this->give_404 = FALSE;
  71. // check that the comic exists in the database
  72. $this->comic = new Comic();
  73. $this->comic->where('stub', $this->comic_stub)->where('uniqid', $this->comic_uniqid)->limit(1)->get();
  74. // if there's a result, let's check if there's the chapter available
  75. if ($this->comic->result_count() == 1)
  76. {
  77. // we got the comic! let's see if we got the chapter
  78. $this->chapter = new Chapter();
  79. $this->chapter->where('stub', $this->chapter_stub)->where('uniqid', $this->chapter_uniqid)->limit(1)->get();
  80. if ($this->chapter->result_count() == 1)
  81. {
  82. // we got the chapter! let's see if we're lucky and we already have its page data
  83. $this->page = new Page();
  84. $this->page->where('chapter_id', $this->chapter->id)->where('filename', $this->filename)->get();
  85. if ($this->page->result_count() == 1)
  86. {
  87. // we got its pagedata! let's grab the image
  88. if ($this->_grab_page())
  89. {
  90. $this->output
  91. ->set_content_type($this->page->mime)
  92. ->set_output($this->file);
  93. // good end
  94. return TRUE;
  95. }
  96. }
  97. }
  98. }
  99. // we will need the url to the master Slide anyway
  100. $this->url = get_setting('fs_balancer_master_url');
  101. // we want it always with a trailing slash
  102. if (substr($this->url, -1, 0) != '/')
  103. {
  104. $this->url = $this->url . '/';
  105. }
  106. $this->load->library('curl');
  107. // first of all, does the image even exist? Since we're going to grab
  108. // the image anyway if it exists, lets get ahead and grab it first
  109. // uri_string starts with a slash, so we have to remove it
  110. echo $this->file = $this->curl->simple_get($this->url . 'content/comics/' . $this->comic_stub . '_' . $this->comic_uniqid . '/' . $this->chapter_stub . '_' . $this->chapter_uniqid . '/' . $this->filename);
  111. // if the file doesn't exist, let's not go through the rest of the mess
  112. if (!$this->file)
  113. {
  114. show_404();
  115. }
  116. // oh no, this chapter might not be up to date! let's grab the comic data
  117. // /api/reader/comic gives us the comic data and all its chapters!
  118. // form the get request and decode the result
  119. // if the master server works it should be trustable
  120. $request_url = $this->url . 'api/reader/comic/stub/' . $this->comic_stub . '/uniqid/' . $this->comic_uniqid . '/chapter_stub/' . $this->chapter_stub . '/chapter_uniqid/' . $this->chapter_uniqid . '/format/json';
  121. $result = $this->curl->simple_get($request_url);
  122. $result = json_decode($result, TRUE);
  123. // if there's PHP errors in the $result, the json_decode might fail
  124. // and return NULL, show a 404.
  125. if (is_null($result))
  126. {
  127. log_message('error', 'content:comics() json_decode failed');
  128. show_404();
  129. }
  130. // just show 404 if the API gives a formal error
  131. if (isset($result["error"]))
  132. {
  133. log_message('error', 'content:comics() json had an error: ' . $result["error"]);
  134. show_404();
  135. }
  136. // search for the value of the chapter, so we don't bother anymore
  137. // if it doesn't exist in database - though it should
  138. $found = FALSE;
  139. foreach ($result["chapters"] as $key => $item)
  140. {
  141. if ($item["chapter"]["stub"] == $this->chapter_stub && $item["chapter"]["uniqid"] == $this->chapter_uniqid)
  142. {
  143. // update the comic in the database
  144. $comic = new Comic($result["comic"]["id"]);
  145. // the comic array fits just right, an update costs nearly nothing
  146. $comic->from_array($result["comic"]);
  147. if ($comic->result_count() == 0)
  148. {
  149. $comic->save_as_new();
  150. }
  151. else
  152. {
  153. $comic->save();
  154. }
  155. // remove remainants of deleted or updated chapters
  156. // we need an array of chapters
  157. $chapter_objects = array();
  158. foreach ($result["chapters"] as $k => $i)
  159. {
  160. $chapter_objects[] = $i["chapter"];
  161. }
  162. $this->_clean_comic($result["comic"]["id"], $chapter_objects);
  163. $this->_clean_chapter($item["chapter"]["id"], $item["chapter"]["pages"]);
  164. $found = TRUE;
  165. break;
  166. }
  167. }
  168. if (!$found)
  169. {
  170. log_message('error', 'content:comics() chapter was not in the json array');
  171. show_404();
  172. }
  173. $this->_grab_page();
  174. }
  175. /**
  176. * Saves the image, when found. Ignorant of thumb_, it will do those too.
  177. *
  178. * @return String file
  179. */
  180. public function _grab_page()
  181. {
  182. // we will need the url to the master Slide anyway
  183. $url = get_setting('fs_balancer_master_url');
  184. // we want it always with a trailing slash
  185. if (substr($url, -1, 0) != '/')
  186. {
  187. $url = $url . '/';
  188. }
  189. $this->load->library('curl');
  190. // maybe we already have the file, in that case just use it
  191. if (!isset($this->file))
  192. $this->file = $this->curl->simple_get($url . 'content/comics/' . $this->comic->directory() . '/' . $this->chapter->directory() . '/' . $this->filename);
  193. if (!$this->file)
  194. {
  195. log_message('error', '_grab_page(): file not found');
  196. return FALSE;
  197. }
  198. // make sure
  199. if(!is_dir('content/comics/' . $this->comic->directory()))
  200. @mkdir('content/comics/' . $this->comic->directory());
  201. if(!is_dir('content/comics/' . $this->comic->directory() . '/' . $this->chapter->directory()))
  202. @mkdir('content/comics/' . $this->comic->directory() . '/' . $this->chapter->directory());
  203. file_put_contents('content/comics/' . $this->comic->directory() . '/' . $this->chapter->directory() . '/' . $this->filename, $this->file);
  204. return TRUE;
  205. }
  206. /**
  207. * When missing chapters are found, this cleans up and adds new chapters
  208. *
  209. * @param int $comic_id
  210. * @param array $new_chapters_array
  211. */
  212. public function _clean_comic($comic_id, $new_chapters_array)
  213. {
  214. // found, let's get all chapters for this comic
  215. $chapters = new Chapter();
  216. $chapters->where('comic_id', $comic_id)->get();
  217. $chapters = $chapters->all_to_array();
  218. foreach ($new_chapters_array as $key => $item)
  219. {
  220. foreach ($chapters as $k => $i)
  221. {
  222. if ($item["id"] == $i["id"])
  223. {
  224. if ($item["stub"] != $i["stub"] || $item["uniqid"] != $i["uniqid"])
  225. {
  226. $chapter = new Chapter($item["id"]);
  227. $chapter->remove();
  228. unset($chapters[$k]);
  229. break;
  230. }
  231. unset($chapters[$k]);
  232. unset($new_chapters_array[$key]);
  233. break;
  234. }
  235. }
  236. }
  237. foreach ($new_chapters_array as $key => $item)
  238. {
  239. $chapter = new Chapter();
  240. $chapter->from_array($item);
  241. $chapter->save_as_new();
  242. }
  243. foreach ($chapters as $key => $item)
  244. {
  245. $chapter = new Chapter($item["id"]);
  246. $chapter->remove();
  247. }
  248. }
  249. /**
  250. * When you pages are added, this cleans up the chapter and adds new pages
  251. *
  252. * @param int $chapter_id
  253. * @param array $new_pages_array
  254. */
  255. public function _clean_chapter($chapter_id, $new_pages_array)
  256. {
  257. // found, let's get all chapters for this comic
  258. $pages = new Page();
  259. $pages->where('chapter_id', $chapter_id)->get();
  260. $pages = $pages->all_to_array();
  261. foreach ($new_pages_array as $key => $item)
  262. {
  263. foreach ($pages as $k => $i)
  264. {
  265. if ($item["id"] == $i["id"])
  266. {
  267. if ($item["filename"] != $i["filename"] || $item["size"] != $i["size"])
  268. {
  269. $page = new Page($item["id"]);
  270. $page->remove_page();
  271. unset($pages[$k]);
  272. break;
  273. }
  274. unset($pages[$k]);
  275. unset($new_pages_array[$key]);
  276. break;
  277. }
  278. }
  279. }
  280. foreach ($new_pages_array as $key => $item)
  281. {
  282. $page = new Page();
  283. $page->from_array($item);
  284. $page->save_as_new();
  285. }
  286. foreach ($pages as $key => $item)
  287. {
  288. $page = new Page();
  289. $page->remove_page();
  290. }
  291. }
  292. }