Article.php 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: 中闽 < 1464674022@qq.com >
  5. * Date: 2019/12/5
  6. * Time: 17:44
  7. */
  8. namespace app\common\model;
  9. use file\PathHelper;
  10. use think\Exception;
  11. use think\Model;
  12. class Article extends Model
  13. {
  14. const STATUS_OPEN = 1;
  15. const STATUS_CLOSE = 0;
  16. //description
  17. public function getDescriptionAttr($value, $data)
  18. {
  19. if (empty($data['seo_description'])) {
  20. //尝试从文章内容提取描述,去掉HTML及PHP标记
  21. return strip_tags(subStrCN($data['content'], 200));
  22. }
  23. return $data['seo_description'];
  24. }
  25. //get_seo_title
  26. public function getGetSeoTitleAttr($value, $data)
  27. {
  28. if (empty($data['seo_title'])) {
  29. return $data['title'];
  30. }
  31. return $data['seo_title'];
  32. }
  33. //content
  34. public function getContentAttr($value, $data)
  35. {
  36. if ($this->article_editor == 'markdown') {
  37. return $data['content2'];
  38. }
  39. return $value;
  40. }
  41. /**
  42. * 获取缩略图
  43. * @param $host bool/string 可指定域名,默认当前域名
  44. * @return bool|mixed|string
  45. */
  46. public function getThumb($host = true)
  47. {
  48. if ($this->thumb) {
  49. return geturl($this->thumb, '', $host);
  50. } else {
  51. //尝试从内容中提取图片
  52. if (empty($this->content)) {
  53. return "";
  54. }
  55. $imgs = matchImg($this->content);
  56. return count($imgs) == 0 ? "" : url($imgs[0], '', false, $host);
  57. }
  58. }
  59. /**
  60. * 按规则生成路径
  61. * @param $catalogPath [uri使用相对路径,生成文件用物理路径]
  62. * @param $rule [文章路径规则]
  63. * @return mixed
  64. * @throws \Exception
  65. */
  66. public function getRulePath($catalogPath, $rule)
  67. {
  68. if (empty($rule)) {
  69. throw new Exception("null articleRule error");
  70. }
  71. $rule = replaceDS($rule);//处理分隔符
  72. $time = $this->getData('create_time');
  73. $search = ["{cpath}", "{Y}", "{M}", "{D}", "{aid}", "{cid}", "{tid}", "{tpath}"];
  74. $replace = [
  75. PathHelper::getDir($catalogPath),
  76. date('Y', $time),
  77. date('m', $time),
  78. date('d', $time),
  79. $this->filename ?: $this->id,
  80. $this->catalog_id,
  81. $this->article_cate_id,
  82. $this->article_cate_id && $this->cate ? $this->cate->tpath() : "",
  83. ];
  84. $rulePath = replaceDS(str_replace($search, $replace, $rule));
  85. if (ifContain($catalogPath, Templet::getRootDir())) {
  86. //生成操作时,处理路径不在根目录里的
  87. if (!ifContain($rulePath, Templet::getRootDir()))
  88. $rulePath = Templet::getRootDir() . deleteStartDS($rulePath);
  89. } else {
  90. //获取URI时,处理路径{aid}.html
  91. $rulePath = appendStartDS($rulePath);
  92. }
  93. return $rulePath;
  94. }
  95. /**
  96. * 获取文章uri
  97. * @param int $catalogId [文章设置了分类,且分类设置了多个栏目时,可指定栏目Id]
  98. * @return mixed|string
  99. * @throws \Exception
  100. */
  101. public function getUri($catalogId = 0)
  102. {
  103. if ($this->article_cate_id && $this->catalog_id) {
  104. throw new \Exception("文章不能同时发布到栏目和分类");
  105. }
  106. if ($this->article_cate_id) {
  107. if (empty($this->cate) || empty($this->cate->catalogs)) {
  108. throw new \Exception("文章{$this->id}找不到对应的栏目");
  109. }
  110. $catalogs = $this->cate->catalogs;
  111. //有多个栏目时,默认第一个栏目,排序最大的
  112. $catalog = $catalogs[0];
  113. //如果有指定 $catalogId ,则获取对应的栏目
  114. if ($catalogId && count($catalogs) > 0) {
  115. foreach ($catalogs as $catalog_) {
  116. if ($catalog_->id == $catalogId)
  117. $catalog = $catalog_;
  118. }
  119. }
  120. } elseif ($this->catalog_id) {
  121. $catalog = $this->catalog;
  122. } else {
  123. return "";
  124. }
  125. return replaceUrlDS($this->getRulePath($catalog->path, $catalog->article_rule));
  126. }
  127. /**
  128. * 当文章发布到多个栏目时,通过匹配路径获取文章uri
  129. * @param string $path_pattern
  130. * @return mixed|string
  131. */
  132. public function getUriByPattern($path_pattern = "/m/")
  133. {
  134. if ($this->article_cate_id) {
  135. $catalogs = $this->cate->catalogs;
  136. foreach ($catalogs as $catalog) {
  137. if (ifContain($catalog->path, $path_pattern)) {
  138. return $this->getUri($catalog->id);
  139. }
  140. }
  141. }
  142. return $this->getUri();
  143. }
  144. /**
  145. * 标签
  146. * @return array 数组
  147. */
  148. public function getTags()
  149. {
  150. if (empty($this->tag)) {
  151. return [];
  152. }
  153. return explode(',', $this->tag);
  154. }
  155. /**
  156. * 上一篇
  157. */
  158. public function last()
  159. {
  160. $where = [
  161. 'status' => self::STATUS_OPEN,
  162. 'article_cate_id' => $this->article_cate_id,
  163. 'catalog_id' => $this->catalog_id
  164. ];
  165. return $this->where("id", "<", $this->id)->where($where)->order('id desc')->find();
  166. }
  167. /**
  168. * 下一篇
  169. */
  170. public function next()
  171. {
  172. $where = [
  173. 'status' => self::STATUS_OPEN,
  174. 'article_cate_id' => $this->article_cate_id,
  175. 'catalog_id' => $this->catalog_id
  176. ];
  177. return $this->where("id", ">", $this->id)->where($where)->order('id asc')->find();
  178. }
  179. /**
  180. * 获取多个栏目属性集合
  181. */
  182. public function getCatalogValues($field = "title")
  183. {
  184. $catalogs = $this->cate->catalogs;
  185. if ($catalogs) {
  186. $name = [];
  187. foreach ($catalogs as $catalog) {
  188. $name[] = $catalog->getData($field);
  189. }
  190. return implode(',', $name);
  191. }
  192. return "";
  193. }
  194. //关联多栏目(通过分类发布到栏目时)
  195. public function catalogs()
  196. {
  197. if (empty($this->article_cate_id) && empty($this->catalog_id)) {
  198. throw new Exception("请先关联栏目或分类");
  199. }
  200. if (!$this->cate) {
  201. throw new Exception("文章{$this->id}找不到对应的分类");
  202. }
  203. if (!$this->cate->catalogs) {
  204. throw new Exception("文章{$this->id}找不到对应的栏目");
  205. }
  206. return $this->cate->catalogs;
  207. }
  208. //获取一个栏目(多栏目时)
  209. public function getFirstCatalog()
  210. {
  211. if (!$this->cate) {
  212. throw new Exception("文章{$this->id}找不到对应的分类");
  213. }
  214. $catalogs = $this->cate->catalogs;
  215. if (empty($catalogs)) {
  216. throw new Exception("文章{$this->id}找不到对应的栏目");
  217. }
  218. //有多个栏目时,默认第一个栏目,排序最大的
  219. return $catalogs[0];
  220. }
  221. //关联栏目(直接发布到栏目时)
  222. public function catalog()
  223. {
  224. return $this->belongsTo('Catalog');
  225. }
  226. //关联分类
  227. public function cate()
  228. {
  229. return $this->belongsTo('ArticleCate');
  230. }
  231. //发布人
  232. public function admin()
  233. {
  234. return $this->belongsTo('Admin');
  235. }
  236. //修改人
  237. public function editor()
  238. {
  239. return $this->belongsTo('Admin', 'edit_admin_id');
  240. }
  241. }