PageRenderTime 63ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/application/models/comic.php

https://github.com/fcibecchini/FoOlSlide
PHP | 1064 lines | 680 code | 136 blank | 248 comment | 105 complexity | 1cec1f790d934336f9dd597bd231fa74 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, GPL-2.0
  1. <?php
  2. if (!defined('BASEPATH'))
  3. exit('No direct script access allowed');
  4. class Comic extends DataMapper
  5. {
  6. static $cached = array();
  7. var $has_one = array();
  8. var $has_many = array('chapter', 'license');
  9. var $validation = array(
  10. 'name' => array(
  11. 'rules' => array('required', 'max_length' => 256),
  12. 'label' => 'Name',
  13. 'type' => 'input',
  14. 'placeholder' => 'required',
  15. ),
  16. 'stub' => array(
  17. 'rules' => array('required', 'stub', 'unique', 'max_length' => 256),
  18. 'label' => 'Stub'
  19. ),
  20. 'uniqid' => array(
  21. 'rules' => array('required', 'max_length' => 256),
  22. 'label' => 'Uniqid'
  23. ),
  24. 'author' => array(
  25. 'rules' => array(),
  26. 'label' => 'Author',
  27. 'type' => 'input'
  28. ),
  29. 'artist' => array(
  30. 'rules' => array(),
  31. 'label' => 'Artist',
  32. 'type' => 'input'
  33. ),
  34. 'description' => array(
  35. 'rules' => array(),
  36. 'label' => 'Description',
  37. 'type' => 'textarea',
  38. ),
  39. 'thumbnail' => array(
  40. 'rules' => array('max_length' => 512),
  41. 'label' => 'Thumbnail',
  42. 'type' => 'upload',
  43. 'display' => 'image',
  44. ),
  45. 'adult' => array(
  46. 'rules' => array('is_int'),
  47. 'label' => 'Adult Notice',
  48. 'type' => 'checkbox',
  49. 'values' => array('0' => 'No', '1' => 'Yes')
  50. ),
  51. 'hidden' => array(
  52. 'rules' => array('is_int'),
  53. 'label' => 'Visibility',
  54. 'type' => 'checkbox',
  55. 'values' => array('0' => 'Visible', '1' => 'Hidden')
  56. ),
  57. 'customchapter' => array(
  58. 'rules' => array(),
  59. 'label' => 'Custom Chapter Title',
  60. 'type' => 'input'
  61. ),
  62. 'format' => array(
  63. 'rules' => array('required'),
  64. 'label' => 'Comic Format',
  65. 'type' => 'dropdowner',
  66. 'value' => 0,
  67. 'values' => array('0' => 'Manga', '1' => 'Long Strip (Web Toons)')
  68. ),
  69. 'lastseen' => array(
  70. 'rules' => array(),
  71. 'label' => 'Lastseen'
  72. ),
  73. 'creator' => array(
  74. 'rules' => array(''),
  75. 'label' => 'Creator'
  76. ),
  77. 'editor' => array(
  78. 'rules' => array(''),
  79. 'label' => 'Editor'
  80. )
  81. );
  82. function __construct($id = NULL)
  83. {
  84. // Set language
  85. $this->help_lang();
  86. if (!is_null($id) && $comic = $this->get_cached($id))
  87. {
  88. parent::__construct();
  89. $this->all[0] = new stdClass();
  90. foreach ($comic->to_array() as $key => $c)
  91. {
  92. $this->$key = $c;
  93. // fill also the all array so result_count() is correctly 1
  94. $this->all[0]->$key = $c;
  95. }
  96. if (isset($comic->licenses))
  97. $this->licenses = $comic->licenses;
  98. if (isset($comic->chapters))
  99. $this->chapters = $comic->chapters;
  100. return TRUE;
  101. }
  102. parent::__construct(NULL);
  103. // We've overwrote the get() function so we need to look for $id from here
  104. if (!empty($id) && is_numeric($id))
  105. {
  106. $this->where('id', $id)->get();
  107. }
  108. }
  109. function post_model_init($from_cache = FALSE)
  110. {
  111. }
  112. /**
  113. * This function sets the translations for the validation values.
  114. *
  115. * @author Woxxy
  116. * @return void
  117. */
  118. function help_lang()
  119. {
  120. $this->validation['name']['label'] = _('Name');
  121. $this->validation['name']['help'] = _('Insert the title of the series.');
  122. $this->validation['author']['label'] = _('Author');
  123. $this->validation['author']['help'] = _('Insert the author of this title.');
  124. $this->validation['artist']['label'] = _('Artist');
  125. $this->validation['artist']['help'] = _('Insert the artist of this title.');
  126. $this->validation['description']['label'] = _('Description');
  127. $this->validation['description']['help'] = _('Insert a description.');
  128. $this->validation['adult']['label'] = _('Adult Notice');
  129. $this->validation['adult']['text'] = _('Enable');
  130. $this->validation['hidden']['label'] = _('Visibility');
  131. $this->validation['hidden']['help'] = _('Hide the series from public view.');
  132. $this->validation['hidden']['text'] = _('Hidden');
  133. $this->validation['thumbnail']['label'] = _('Thumbnail');
  134. $this->validation['thumbnail']['help'] = _('Upload an image to use as thumbnail.');
  135. $this->validation['customchapter']['label'] = _('Custom Chapter Title');
  136. $this->validation['customchapter']['help'] = _('Replace the default chapter title with a custom format. Example: "{num}{ord} Stage" returns "2nd Stage"');
  137. }
  138. /**
  139. * Overwrite of the get() function to add filters to the search.
  140. * Refer to DataMapper ORM for get() function details.
  141. *
  142. * @author Woxxy
  143. * @param integer|NULL $limit Limit the number of results.
  144. * @param integer|NULL $offset Offset the results when limiting.
  145. * @return DataMapper Returns self for method chaining.
  146. */
  147. public function get($limit = NULL, $offset = NULL)
  148. {
  149. // Get the CodeIgniter instance, since it isn't set in this file.
  150. $CI = & get_instance();
  151. // Check if the user is allowed to see protected chapters.
  152. if (!$CI->tank_auth->is_allowed())
  153. {
  154. $this->where('hidden', 0);
  155. }
  156. $result = parent::get($limit, $offset);
  157. $this->get_licenses();
  158. $CI = & get_instance();
  159. if (!$CI->tank_auth->is_allowed() && !$CI->tank_auth->is_team())
  160. {
  161. // Remove from the array the serie licensed in the user's nation
  162. foreach ($this->all as $key => $item)
  163. {
  164. if (in_array($CI->session->userdata('nation'), $this->licenses))
  165. {
  166. unset($this->all[$key]);
  167. }
  168. }
  169. if (in_array($CI->session->userdata('nation'), $this->licenses))
  170. {
  171. $this->clear();
  172. }
  173. }
  174. // let's put the result in a small cache, since teams are always the same
  175. foreach ($this->all as $comic)
  176. {
  177. // if it's not yet cached, let's cache it
  178. if (!$this->get_cached($comic->id))
  179. {
  180. if (count(self::$cached) > 10)
  181. array_shift(self::$cached);
  182. self::$cached[] = $comic->get_clone();
  183. }
  184. }
  185. return $result;
  186. }
  187. /**
  188. * Returns the series that have been already called before
  189. *
  190. * @author Woxxy
  191. * @param int $id team_id
  192. */
  193. public function get_cached($id)
  194. {
  195. foreach (self::$cached as $cache)
  196. {
  197. if ($cache->id == $id)
  198. {
  199. return $cache;
  200. }
  201. }
  202. return FALSE;
  203. }
  204. /**
  205. * Overwrite of the get_iterated() function to add filters to the search.
  206. * Refer to DataMapper ORM for get_iterated() function details.
  207. *
  208. * @author Woxxy
  209. * @param integer|NULL $limit Limit the number of results.
  210. * @param integer|NULL $offset Offset the results when limiting.
  211. * @return DataMapper Returns self for method chaining.
  212. */
  213. public function get_iterated($limit = NULL, $offset = NULL)
  214. {
  215. // Get the CodeIgniter instance, since it isn't set in this file.
  216. $CI = & get_instance();
  217. // Check if the user is allowed to see protected chapters.
  218. if (!$CI->tank_auth->is_allowed())
  219. $this->where('hidden', 0);
  220. /**
  221. * @todo figure out why those variables don't get unset... it would be
  222. * way better to use the iterated in almost all cases in FoOlSlide
  223. */
  224. return parent::get_iterated($limit, $offset);
  225. }
  226. /**
  227. * Comodity get() function that fetches extra data for the series selected.
  228. * It doesn't get the chapters.
  229. *
  230. * CURRENTLY USELESS.
  231. *
  232. * @author Woxxy
  233. * @param integer|NULL $limit Limit the number of results.
  234. * @param integer|NULL $offset Offset the results when limiting.
  235. * @return DataMapper Returns self for method chaining.
  236. */
  237. public function get_bulk($limit = NULL, $offset = NULL)
  238. {
  239. // Call the get()
  240. $result = $this->get($limit, $offset);
  241. // Return instantly on false.
  242. if (!$result)
  243. return $result;
  244. // For each item we fetched, add the data, beside the pages
  245. foreach ($this->all as $item)
  246. {
  247. }
  248. return $result;
  249. }
  250. /**
  251. * Gets the nations where the series is licensed
  252. *
  253. * @author Woxxy
  254. * @return bool true on success
  255. */
  256. public function get_licenses()
  257. {
  258. if (isset($this->licenses))
  259. return true;
  260. $license = new License();
  261. $this->licenses = $license->get_by_comic($this->id);
  262. // Check if the variable is not yet set, in order to save a databse read.
  263. foreach ($this->all as $item)
  264. {
  265. if (isset($item->licenses))
  266. continue;
  267. $license = new License();
  268. $item->licenses = $license->get_by_comic($item->id);
  269. }
  270. // All good, return true.
  271. return true;
  272. }
  273. /**
  274. * Function to create a new entry for a series from scratch. It creates
  275. * both a directory and a database entry, and removes them if something
  276. * goes wrong.
  277. *
  278. * @author Woxxy
  279. * @param array $data with the minimal values, or the function will return
  280. * false and do nothing.
  281. * @return Returns true on success, false on failure.
  282. */
  283. public function add($data = array())
  284. {
  285. // For the series, the stub is just the name.
  286. $this->to_stub = $data['name'];
  287. // Uniqid to prevent directory clash
  288. $this->uniqid = uniqid();
  289. // stub() checks for to_stub and makes a stub.
  290. $this->stub = $this->stub();
  291. // Check if the series database entry and remove dir in case it's not.
  292. // GUI errors are inner to the function
  293. if (!$this->update_comic_db($data))
  294. {
  295. log_message('error', 'add_comic: failed writing to database');
  296. return false;
  297. }
  298. // Check if dir is created. GUI errors in inner function.
  299. if (!$this->add_comic_dir())
  300. {
  301. log_message('error', 'add_comic: failed creating dir');
  302. return false;
  303. }
  304. // Good job!
  305. return true;
  306. }
  307. /**
  308. * Removes series from database, all its pages, chapters, and its directory.
  309. * There's no going back from this!
  310. *
  311. * @author Woxxy
  312. * @return boolean true on success, false on failure
  313. */
  314. public function remove()
  315. {
  316. // Remove the directory through function
  317. if (!$this->remove_comic_dir())
  318. {
  319. log_message('error', 'remove_comic: failed to delete dir');
  320. return false;
  321. }
  322. // Remove database entry through function
  323. if (!$this->remove_comic_db())
  324. {
  325. log_message('error', 'remove_comic: failed to delete database entry');
  326. return false;
  327. }
  328. return true;
  329. }
  330. /**
  331. * Handles both creating of new series in the database and editing old ones.
  332. * It determines if it should update or not by checking if $this->id has
  333. * been set. It can get the values from both the $data array and direct
  334. * variable assignation. Be aware that array > variables. The latter ones
  335. * will be overwritten. Particularly, the variables that the user isn't
  336. * allowed to set personally are unset and reset with the automated values.
  337. * It's quite safe to throw stuff at it.
  338. *
  339. * @author Woxxy
  340. * @param array $data contains the minimal data
  341. * @return boolean true on success, false on failure
  342. */
  343. public function update_comic_db($data = array())
  344. {
  345. // Check if we're updating or creating a new series by looking at $data["id"].
  346. // False is returned if the chapter ID was not found.
  347. if (isset($data["id"]) && $data['id'] != '')
  348. {
  349. $this->where("id", $data["id"])->get();
  350. if ($this->result_count() == 0)
  351. {
  352. set_notice('error', _('The series you wanted to edit doesn\'t exist.'));
  353. log_message('error', 'update_comic_db: failed to find requested id');
  354. return false;
  355. }
  356. // Save the stub in a variable in case it gets changed, so we can change folder name
  357. $old_stub = $this->stub;
  358. $old_name = $this->name;
  359. }
  360. else
  361. {
  362. // let's set the creator name if it's a new entry
  363. $this->creator = $this->logged_id();
  364. }
  365. // always set the editor name
  366. $this->editor = $this->logged_id();
  367. // Unset sensible variables
  368. unset($data["creator"]);
  369. unset($data["editor"]);
  370. unset($data["uniqid"]);
  371. unset($data["stub"]);
  372. // Allow only admins and mods to arbitrarily change the release date
  373. $CI = & get_instance();
  374. if (!$CI->tank_auth->is_allowed())
  375. unset($data["created"]);
  376. if (!$CI->tank_auth->is_allowed())
  377. unset($data["edited"]);
  378. // Loop over the array and assign values to the variables.
  379. foreach ($data as $key => $value)
  380. {
  381. $this->$key = $value;
  382. }
  383. // Double check that we have all the necessary automated variables
  384. if (!isset($this->uniqid))
  385. $this->uniqid = uniqid();
  386. if (!isset($this->stub))
  387. $this->stub = $this->stub();
  388. // Create a new stub if the name has changed
  389. if (isset($old_name) && isset($old_stub) && ($old_name != $this->name))
  390. {
  391. // Prepare a new stub.
  392. $this->stub = $this->name;
  393. // stub() is also able to restub the $this->stub. Already stubbed values won't change.
  394. $this->stub = $this->stub();
  395. }
  396. // Make so there's no intersecting stubs, and make a stub with a number in case of duplicates
  397. // In case this chapter already has a stub and it wasn't changed, don't change it!
  398. if ((!isset($this->id) || $this->id == '') || (isset($old_stub) && $old_stub != $this->stub))
  399. {
  400. $i = 1;
  401. $found = FALSE;
  402. $comic = new Comic();
  403. $comic->where('stub', $this->stub)->get();
  404. if ($comic->result_count() == 0)
  405. {
  406. $found = TRUE;
  407. }
  408. while (!$found)
  409. {
  410. $i++;
  411. $pre_stub = $this->stub . '_' . $i;
  412. $comic = new Comic();
  413. $comic->where('stub', $pre_stub)->get();
  414. if ($comic->result_count() == 0)
  415. {
  416. $this->stub = $pre_stub;
  417. $found = TRUE;
  418. }
  419. }
  420. }
  421. // This is necessary to make the checkbox work.
  422. /**
  423. * @todo make the checkbox work consistently across the whole framework
  424. */
  425. if (!isset($data['adult']) || $data['adult'] != 1)
  426. $this->adult = 0;
  427. if (!isset($data['hidden']) || $data['hidden'] != 1)
  428. $this->hidden = 0;
  429. // rename the folder if the stub changed
  430. if (isset($old_stub) && $old_stub != $this->stub && is_dir("content/comics/" . $old_stub . "_" . $this->uniqid))
  431. {
  432. $dir_old = "content/comics/" . $old_stub . "_" . $this->uniqid;
  433. $dir_new = "content/comics/" . $this->stub . "_" . $this->uniqid;
  434. rename($dir_old, $dir_new);
  435. }
  436. // let's save and give some error check. Push false if fail, true if good.
  437. $success = $this->save();
  438. if (!$success)
  439. {
  440. if (!$this->valid)
  441. {
  442. set_notice('error', _('Check that you have inputted all the required fields.'));
  443. log_message('error', 'update_comic_db: failed validation');
  444. }
  445. else
  446. {
  447. set_notice('error', _('Failed saving the series to database for unknown reasons.'));
  448. log_message('error', 'update_comic_db: failed to save');
  449. }
  450. return false;
  451. }
  452. if (!isset($data['licensed']))
  453. {
  454. $data['licensed'] = array();
  455. }
  456. // update license data
  457. $license = new License();
  458. $license->update($this->id, $data['licensed']);
  459. // Good job!
  460. return true;
  461. }
  462. /**
  463. * Removes the series from the database, but before it removes all the
  464. * related chapters and their pages from the database (not the files).
  465. *
  466. * @author Woxxy
  467. * @return object a copy of the series that has been deleted
  468. */
  469. public function remove_comic_db()
  470. {
  471. // Get all its chapters
  472. $chapters = new Chapter();
  473. $chapters->where("comic_id", $this->id)->get_iterated();
  474. // Remove all the chapters from the database. This will also remove all the pages
  475. foreach ($chapters as $chapter)
  476. {
  477. $chapter->remove_chapter_db();
  478. }
  479. // We need a clone if we want to keep the variables after deletion
  480. $temp = $this->get_clone();
  481. $success = $this->delete();
  482. if (!$success)
  483. {
  484. set_notice('error', _('The series couldn\'t be removed from the database for unknown reasons.'));
  485. log_message('error', 'remove_comic_db: id found but entry not removed');
  486. return false;
  487. }
  488. // Return the comic clone
  489. return $temp;
  490. }
  491. /**
  492. * Creates the necessary empty folder for the comic
  493. *
  494. * @author Woxxy
  495. * @return boolean true if success, false if failure.
  496. */
  497. public function add_comic_dir()
  498. {
  499. // Just create the folder
  500. if (!mkdir("content/comics/" . $this->directory()))
  501. {
  502. set_notice('error', _('The directory could not be created. Please, check file permissions.'));
  503. log_message('error', 'add_comic_dir: folder could not be created');
  504. return false;
  505. }
  506. return true;
  507. }
  508. /**
  509. * Removes the series directory with all the data that was inside of it.
  510. * This means chapters, pages and props too.
  511. *
  512. * @author Woxxy
  513. * @return boolean true if success, false if failure.
  514. */
  515. public function remove_comic_dir()
  516. {
  517. $dir = "content/comics/" . $this->directory() . "/";
  518. // Delete all inner files
  519. if (!delete_files($dir, TRUE))
  520. {
  521. set_notice('error', _('The files inside the series directory could not be removed. Please, check the file permissions.'));
  522. log_message('error', 'remove_comic_dir: files inside folder could not be removed');
  523. return false;
  524. }
  525. else
  526. {
  527. // On success delete the directory itself
  528. if (!rmdir($dir))
  529. {
  530. set_notice('error', _('The directory could not be removed. Please, check file permissions.'));
  531. log_message('error', 'remove_comic_dir: folder could not be removed');
  532. return false;
  533. }
  534. }
  535. return true;
  536. }
  537. public function check($repair = FALSE, $recursive = FALSE)
  538. {
  539. $dir = "content/comics/" . $this->directory() . "/";
  540. $errors = array();
  541. if (!is_dir($dir))
  542. {
  543. $errors[] = 'comic_directory_not_found';
  544. set_notice('warning', _('No directory found for:') . ' ' . $this->name . ' (' . $this->directory() . ')');
  545. log_message('debug', 'check: comic directory missing at ' . $dir);
  546. if ($repair)
  547. {
  548. // the best we can do is removing the database entry
  549. $this->remove_comic_db();
  550. }
  551. }
  552. else
  553. {
  554. // check that there are no unidentified files in the comic folder
  555. $map = directory_map($dir, 1);
  556. foreach ($map as $key => $item)
  557. {
  558. $item_path = $dir . $item;
  559. if (is_dir($item_path))
  560. {
  561. // gotta split the directory to get stub and uniqid
  562. $item_arr = explode('_', $item);
  563. $uniqid = end($item_arr);
  564. $stub = str_replace('_' . $uniqid, '', $item);
  565. $chapter = new Chapter();
  566. $chapter->where('stub', $stub)->where('uniqid', $uniqid)->get();
  567. if ($chapter->result_count() == 0)
  568. {
  569. $errors[] = 'comic_unidentified_directory_found';
  570. set_notice('warning', _('Unidentified directory found at:') . ' ' . $item_path);
  571. log_message('debug', 'check: unidentified directory found at ' . $item_path);
  572. if ($repair)
  573. {
  574. // you have to remove all the files in the folder first
  575. delete_files($item_path, TRUE);
  576. rmdir($item_path);
  577. }
  578. }
  579. }
  580. else
  581. {
  582. if ($item != $this->thumbnail && $item != 'thumb_' . $this->thumbnail)
  583. {
  584. $ext = strtolower(substr($item, -4));
  585. if (in_array($ext, array('.zip')))
  586. {
  587. $archive = new Archive();
  588. $archive->where('comic_id', $this->id)->where('filename', $item)->get();
  589. if ($archive->result_count())
  590. {
  591. continue;
  592. }
  593. }
  594. // if it's not the thumbnail image, it's an unidentified file
  595. $errors[] = 'comic_unidentified_file_found';
  596. set_notice('warning', _('Unidentified file found at:') . ' ' . $item_path);
  597. log_message('debug', 'check: unidentified file found at ' . $item_path);
  598. if ($repair)
  599. {
  600. unlink($item_path);
  601. }
  602. }
  603. }
  604. }
  605. }
  606. return $errors;
  607. }
  608. public function check_external($repair = FALSE, $recursive = FALSE)
  609. {
  610. $this->load->helper('directory');
  611. // check if all that is inside is writeable
  612. if (!$this->check_writable('content/comics/'))
  613. {
  614. return FALSE;
  615. }
  616. // check that every folder has a correpsonding comic
  617. $map = directory_map('content/comics/', 1);
  618. foreach ($map as $key => $item)
  619. {
  620. // gotta split the directory to get stub and uniqid
  621. $item_arr = explode('_', $item);
  622. $uniqid = end($item_arr);
  623. $stub = str_replace('_' . $uniqid, '', $item);
  624. $comic = new Comic();
  625. $comic->where('stub', $stub)->where('uniqid', $uniqid)->get();
  626. if ($comic->result_count() == 0)
  627. {
  628. $errors[] = 'comic_entry_not_found';
  629. set_notice('warning', _('No database entry found for:') . ' ' . $stub);
  630. log_message('debug', 'check: database entry missing for ' . $stub);
  631. if ($repair)
  632. {
  633. if (is_dir('content/comics/' . $item))
  634. {
  635. // you have to remove all the files in the folder first
  636. delete_files('content/comics/' . $item, TRUE);
  637. rmdir('content/comics/' . $item);
  638. }
  639. else
  640. {
  641. unlink('content/comics/' . $item);
  642. }
  643. }
  644. }
  645. }
  646. // check the database entries
  647. $comics = new Comic();
  648. $comics->get();
  649. foreach ($comics->all as $key => $comic)
  650. {
  651. $comic->check($repair);
  652. }
  653. // if recursive, this will go through a through (and long) check of all chapters
  654. if ($recursive)
  655. {
  656. $chapters = new Chapter();
  657. $chapters->get_iterated();
  658. foreach ($chapters as $chapter)
  659. {
  660. $chapter->check($repair);
  661. }
  662. // viceversa, check that all the database entries have a matching file
  663. $pages = new Page();
  664. $pages->get_iterated();
  665. foreach ($pages as $page)
  666. {
  667. $page->check($repair);
  668. }
  669. }
  670. }
  671. private function check_writable($path)
  672. {
  673. $map = directory_map($path, 1);
  674. foreach ($map as $key => $item)
  675. {
  676. if (is_dir($path . $item))
  677. {
  678. // check if even the dir itself is writable
  679. if (!is_writable($path . $item . '/'))
  680. {
  681. $errors[] = 'non_writable_directory';
  682. set_notice('warning', _('Found a non-writable directory.'));
  683. log_message('debug', 'check: non-writable directory found: ' . $item);
  684. return FALSE;
  685. }
  686. // use the recursive check function
  687. if (!$this->check_writable($path . $item . '/'))
  688. {
  689. return FALSE;
  690. }
  691. }
  692. else
  693. {
  694. if (!is_writable($path . $item))
  695. {
  696. $errors[] = 'comic_non_writable_file';
  697. set_notice('warning', _('Found a non-writable file.'));
  698. log_message('debug', 'check: non-writable file: ' . $item);
  699. return FALSE;
  700. }
  701. }
  702. }
  703. return TRUE;
  704. }
  705. /**
  706. * Creates the thumbnail and saves the original as well
  707. *
  708. * @author Woxxy
  709. * @param array|$filedata a standard array coming from CodeIgniter's upload
  710. * @return boolean true on success, false on failure
  711. */
  712. public function add_comic_thumb($filedata)
  713. {
  714. // If there's already one, remove it.
  715. if ($this->thumbnail != "")
  716. $this->remove_comic_thumb();
  717. // Get directory variable
  718. $dir = "content/comics/" . $this->directory() . "/";
  719. // Copy the full image over
  720. if (!copy($filedata["server_path"], $dir . $filedata["name"]))
  721. {
  722. set_notice('error', _('Failed to create the thumbnail image for the series. Check file permissions.'));
  723. log_message('error', 'add_comic_thumb: failed to create/copy the image');
  724. return false;
  725. }
  726. // Load the image library
  727. $CI = & get_instance();
  728. $CI->load->library('image_lib');
  729. // Let's setup the thumbnail creation and pass it to the image library
  730. $image = "thumb_" . $filedata["name"];
  731. $img_config['image_library'] = 'GD2';
  732. $img_config['source_image'] = $filedata["server_path"];
  733. $img_config["new_image"] = $dir . $image;
  734. $img_config['maintain_ratio'] = TRUE;
  735. $img_config['width'] = 250;
  736. $img_config['height'] = 250;
  737. $img_config['maintain_ratio'] = TRUE;
  738. $img_config['master_dim'] = 'auto';
  739. $CI->image_lib->initialize($img_config);
  740. // Resize! And return false of failure
  741. if (!$CI->image_lib->resize())
  742. {
  743. set_notice('error', _('Failed to create the thumbnail image for the series. Resize function didn\'t work'));
  744. log_message('error', 'add_comic_thumb: failed to create thumbnail');
  745. return false;
  746. }
  747. // Whatever we might want to do later, we better clear the library now!
  748. $CI->image_lib->clear();
  749. // The thumbnail is actually the filename of the original for series thumbnails
  750. // It's different from page thumbnails - those have "thumb_" in thiserie s variable!
  751. $this->thumbnail = $filedata["name"];
  752. // Save hoping we're lucky
  753. if (!$this->save())
  754. {
  755. set_notice('error', _('Failed to save the thumbnail image in the database.'));
  756. log_message('error', 'add_comic_thumb: failed to add to database');
  757. return false;
  758. }
  759. // Alright!
  760. return true;
  761. }
  762. /**
  763. * Removes the thumbnail and its original image both from database and directory.
  764. *
  765. * @author Woxxy
  766. * @return string true on success, false on failure.
  767. */
  768. public function remove_comic_thumb()
  769. {
  770. // Get directory
  771. $dir = "content/comics/" . $this->directory() . "/";
  772. // Remove the full image
  773. if (!unlink($dir . $this->thumbnail))
  774. {
  775. set_notice('error', _('Failed to remove the thumbnail\'s original image. Please, check file permissions.'));
  776. log_message('error', 'Model: comic_model.php/remove_comic_thumb: failed to delete image');
  777. return false;
  778. }
  779. // Remove the thumbnail
  780. if (!unlink($dir . "thumb_" . $this->thumbnail))
  781. {
  782. set_notice('error', _('Failed to remove the thumbnail image. Please, check file permissions.'));
  783. log_message('error', 'Model: comic_model.php/remove_comic_thumb: failed to delete thumbnail');
  784. return false;
  785. }
  786. // Set the thumbnail variable to empty and save to database
  787. $this->thumbnail = "";
  788. if (!$this->save())
  789. {
  790. set_notice('error', _('Failed to remove the thumbnail image from the database.'));
  791. log_message('error', 'Model: comic_model.php/remove_comic_thumb: failed to remove from database');
  792. return false;
  793. }
  794. // All's good.
  795. return true;
  796. }
  797. /**
  798. * Returns href to thumbnail. Uses load-balancer system.
  799. *
  800. * @author Woxxy
  801. * @param boolean|$full if set to true, the function returns the full image
  802. * @return string href to thumbnail.
  803. */
  804. public function get_thumb($full = FALSE)
  805. {
  806. if ($this->thumbnail != "")
  807. return site_url() . "content/comics/" . $this->stub . "_" . $this->uniqid . "/" . ($full ? "" : "thumb_") . $this->thumbnail;
  808. return false;
  809. }
  810. function update_license($nations)
  811. {
  812. $comic_id = $this->id;
  813. $licenses = new License();
  814. $licenses->where('comic_id', $comic_id)->get();
  815. $removeme = array();
  816. foreach ($licenses->all as $key => $license)
  817. {
  818. $removeme[$key] = $license->nation;
  819. }
  820. $temp_nations = $nations;
  821. foreach ($nations as $key => $nation)
  822. {
  823. $found = false;
  824. foreach ($licenses->all as $subkey => $license)
  825. {
  826. if ($nation == $license->nation)
  827. {
  828. unset($removeme[$subkey]);
  829. $found = true;
  830. }
  831. }
  832. if (!$found && $nation != "")
  833. {
  834. $new_license = new License();
  835. $new_license->comic_id = $comic_id;
  836. $new_license->nation = $nation;
  837. $new_license->save();
  838. }
  839. }
  840. foreach ($removeme as $key => $nation)
  841. {
  842. $remove = new License();
  843. $remove->where('comic_id', $comic_id)->where('nation', $nation)->get()->remove();
  844. }
  845. }
  846. /**
  847. * Returns directory name without slashes
  848. *
  849. * @author Woxxy
  850. * @return string Directory name.
  851. */
  852. public function directory()
  853. {
  854. return $this->stub . '_' . $this->uniqid;
  855. }
  856. /**
  857. * Returns a ready to use html <a> link that points to the reader
  858. *
  859. * @author Woxxy
  860. * @return string <a> to reader
  861. */
  862. public function url()
  863. {
  864. return '<a href="' . $this->href() . '" title="' . $this->title() . '">' . $this->title() . '</a>';
  865. }
  866. /**
  867. * Returns a nicely built title for a chapter
  868. *
  869. * @author Woxxy
  870. * @return string the formatted title for the chapter, with chapter and subchapter
  871. */
  872. public function title()
  873. {
  874. return $this->name;
  875. }
  876. /**
  877. * Returns the href to the chapter editing
  878. *
  879. * @author Woxxy
  880. * @return string href to chapter editing
  881. */
  882. public function edit_href()
  883. {
  884. $CI = & get_instance();
  885. if (!$CI->tank_auth->is_allowed())
  886. return "";
  887. return site_url('/admin/series/series/' . $this->stub);
  888. }
  889. /**
  890. * Returns the url to the chapter editing
  891. *
  892. * @author Woxxy
  893. * @return string <a> to chapter editing
  894. */
  895. public function edit_url()
  896. {
  897. $CI = & get_instance();
  898. if (!$CI->tank_auth->is_allowed())
  899. return "";
  900. return '<a href="' . $this->edit_href() . '" title="' . _('Edit') . ' ' . $this->title() . '">' . _('Edit') . '</a>';
  901. }
  902. /**
  903. * Returns the href to the reader. This will create the shortest possible URL.
  904. *
  905. * @author Woxxy
  906. * @returns string href to reader.
  907. */
  908. public function href()
  909. {
  910. return site_url('series/' . $this->stub);
  911. }
  912. /**
  913. * Overwrites the original DataMapper to_array() to add some elements
  914. *
  915. * @param array $fields
  916. * @return array
  917. */
  918. public function to_array($fields = '')
  919. {
  920. $result = parent::to_array($fields = '');
  921. $result["thumb_url"] = $this->get_thumb();
  922. $result["fullsized_thumb_url"] = $this->get_thumb(true);
  923. $result["href"] = $this->href();
  924. return $result;
  925. }
  926. }
  927. /* End of file comic.php */
  928. /* Location: ./application/models/comic.php */