ChapterService.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. /**
  3. */
  4. namespace Modules\ContentManage\Services\Books;
  5. use Modules\ContentManage\Models\BookChapterContents;
  6. use Modules\ContentManage\Models\BookChapters;
  7. class ChapterService{
  8. /**
  9. * 解析导入的文件,可以从中间章节导入,但是比空虚连续,比如可以从第5章导入$start_sequence=5,可以支持覆盖导入
  10. * 比如如果之前导入的第10-20章有问题,可以重新导入第10-20章,此时$start_sequence=10,会覆盖之前第10-20章的内容
  11. * @param [int] $bid
  12. * @param [itn] $start_sequence 开始序号,可以支持
  13. * @param [int] $vip_start vip起始章节
  14. * @param [string] $path 文件目录
  15. * @return void
  16. */
  17. public static function createChapterFromFile($bid,$start_sequence,$vip_start,$path){
  18. if( !file_exists($path)){
  19. return ;
  20. }
  21. $handle = fopen($path, "r");
  22. $i = $start_sequence;
  23. $content = '';
  24. $last_name = '';
  25. $last_chapter = '';
  26. $size = 0;
  27. $first_cid = 0;
  28. $last_cid = 0;
  29. //一行行读入文件,如果当前行是以###开头,则表示此行是章节标题,直到读到下一个标题,两个标题中间的内容就是正文
  30. while (($buffer = fgets($handle)) !== false) {
  31. $buffer = trim($buffer);
  32. $buffer = trim($buffer,' ');
  33. $buffer = preg_replace('/\s+/','',$buffer);
  34. if (!$buffer) continue;
  35. $temp =$buffer;
  36. //解析标题
  37. if($name = self::parseName($temp)){
  38. if(!$last_name){
  39. //第一行直接过
  40. $last_name = $name;
  41. }else{
  42. //第二行,中间的部分是内容,此时可以保存数据库
  43. $is_vip = $i >= $vip_start? 1:0;
  44. $size += mb_strlen($content);
  45. $cid = self::createOrUpdateContent($bid,$i,$last_name,$content,$is_vip);
  46. if($i == $start_sequence){
  47. $first_cid = $cid;
  48. }
  49. $i++;$content = '';
  50. $last_name = $name;
  51. }
  52. }else{
  53. $content .= $temp."\r\n";
  54. }
  55. }
  56. //当前是最后一张
  57. $is_vip = $i >= $vip_start? 1:0;
  58. $last_cid = self::createOrUpdateContent($bid,$i,$last_name,$content,$is_vip);
  59. $last_chapter = $last_name;
  60. $size += mb_strlen($content);
  61. fclose($handle);
  62. return ['size'=>$size,'chapter_count'=>$i,'first_cid'=>$first_cid,'last_cid'=>$last_cid,'last_chapter'=>$last_chapter];
  63. }
  64. /**
  65. * 保存章节,支持覆盖
  66. *
  67. * @param [type] $bid
  68. * @param [type] $sequence
  69. * @param [type] $name
  70. * @param [type] $content
  71. * @param [type] $is_vip
  72. * @return void
  73. */
  74. private static function createOrUpdateContent($bid,$sequence,$name,$content,$is_vip){
  75. $name = mb_convert_encoding($name,'UTF-8');
  76. $content = mb_convert_encoding($content,'UTF-8');
  77. $chapter_info = BookChapters::where('bid',$bid)->where('sequence',$sequence)->first();
  78. if($chapter_info){
  79. $content_info = BookChapterContents::where('id',$chapter_info->chapter_content_id)->first();
  80. if($content_info){
  81. $content_info->chapter_name = $name;
  82. $content_info->content = $content;
  83. $content_info->save();
  84. }else{
  85. $content_info = BookChapterContents::create(['bid'=>$bid,'chapter_name'=>$name,'content'=>$content]);
  86. }
  87. $chapter_info->name = $name;
  88. $chapter_info->size = mb_strlen($content);
  89. $chapter_info->chapter_content_id = $content_info->id;
  90. $chapter_info->save();
  91. }else{
  92. $content_info = BookChapterContents::create(['bid'=>$bid,'chapter_name'=>$name,'content'=>$content]);
  93. $chapter_info = BookChapters::create([
  94. 'bid'=>$bid,'name'=>$name,'sequence'=>$sequence,'size'=>mb_strlen($content),
  95. 'is_vip'=>$is_vip,'prev_cid'=>0,'next_cid'=>0,'chapter_content_id'=>$content_info->id
  96. ]);
  97. }
  98. return $chapter_info->id;
  99. }
  100. /**
  101. * 解析章节标题
  102. *
  103. * @param [type] $content
  104. * @return void
  105. */
  106. private static function parseName($content){
  107. if(stripos($content,'###') !== false){
  108. return str_replace('###','',$content);
  109. }
  110. /*
  111. $status = preg_match('/^第.*?章/',$content);
  112. if($status){
  113. return $content;
  114. }*/
  115. return '';
  116. }
  117. }