PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/baser/plugins/blog/models/blog_post.php

https://github.com/hashing/basercms
PHP | 584 lines | 348 code | 67 blank | 169 comment | 70 complexity | 8b7ef3ef357f8f2abae31ba2edeb5558 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * 記事モデル
  5. *
  6. * PHP versions 5
  7. *
  8. * baserCMS : Based Website Development Project <http://basercms.net>
  9. * Copyright 2008 - 2012, baserCMS Users Community <http://sites.google.com/site/baserusers/>
  10. *
  11. * @copyright Copyright 2008 - 2012, baserCMS Users Community
  12. * @link http://basercms.net baserCMS Project
  13. * @package baser.plugins.blog.models
  14. * @since baserCMS v 0.1.0
  15. * @version $Revision$
  16. * @modifiedby $LastChangedBy$
  17. * @lastmodified $Date$
  18. * @license http://basercms.net/license/index.html
  19. */
  20. /**
  21. * Include files
  22. */
  23. /**
  24. * 記事モデル
  25. *
  26. * @package baser.plugins.blog.models
  27. */
  28. class BlogPost extends BlogAppModel {
  29. /**
  30. * クラス名
  31. *
  32. * @var string
  33. * @access public
  34. */
  35. var $name = 'BlogPost';
  36. /**
  37. * ビヘイビア
  38. *
  39. * @var array
  40. * @access public
  41. */
  42. var $actsAs = array('BcContentsManager', 'BcCache');
  43. /**
  44. * belongsTo
  45. *
  46. * @var array
  47. * @access public
  48. */
  49. var $belongsTo = array(
  50. 'BlogCategory' => array( 'className'=>'Blog.BlogCategory',
  51. 'foreignKey'=>'blog_category_id'),
  52. 'User' => array( 'className'=>'User',
  53. 'foreignKey'=>'user_id'),
  54. 'BlogContent' => array( 'className'=>'Blog.BlogContent',
  55. 'foreignKey'=>'blog_content_id')
  56. );
  57. /**
  58. * hasMany
  59. *
  60. * @var array
  61. * @access public
  62. */
  63. var $hasMany = array('BlogComment'=>
  64. array('className'=>'Blog.BlogComment',
  65. 'order'=>'created',
  66. 'foreignKey'=>'blog_post_id',
  67. 'dependent'=>true,
  68. 'exclusive'=>false,
  69. 'finderQuery'=>''));
  70. /**
  71. * HABTM
  72. *
  73. * @var array
  74. * @access public
  75. */
  76. var $hasAndBelongsToMany = array(
  77. 'BlogTag' => array(
  78. 'className' => 'Blog.BlogTag',
  79. 'joinTable' => 'blog_posts_blog_tags',
  80. 'foreignKey' => 'blog_post_id',
  81. 'associationForeignKey' => 'blog_tag_id',
  82. 'conditions' => '',
  83. 'order' => '',
  84. 'limit' => '',
  85. 'unique' => true,
  86. 'finderQuery' => '',
  87. 'deleteQuery' => ''
  88. ));
  89. /**
  90. * validate
  91. *
  92. * @var array
  93. * @access public
  94. */
  95. var $validate = array(
  96. 'name' => array(
  97. array( 'rule' => array('notEmpty'),
  98. 'message' => 'タイトルを入力してください。',
  99. 'required' => true),
  100. array( 'rule' => array('maxLength', 255),
  101. 'message' => 'タイトルは255文字以内で入力してください。')
  102. ),
  103. 'posts_date' => array(
  104. array( 'rule' => array('notEmpty'),
  105. 'message' => '投稿日を入力してください。',
  106. 'required' => true)
  107. ),
  108. 'user_id' => array(
  109. array( 'rule' => array('notEmpty'),
  110. 'message' => '投稿者を選択してください。')
  111. )
  112. );
  113. /**
  114. * 初期値を取得する
  115. *
  116. * @return array $authUser 初期値データ
  117. * @access public
  118. */
  119. function getDefaultValue($authUser) {
  120. $data[$this->name]['user_id'] = $authUser['User']['id'];
  121. $data[$this->name]['posts_date'] = date('Y/m/d H:i:s');
  122. $data[$this->name]['status'] = 0;
  123. return $data;
  124. }
  125. /**
  126. * ブログの月別一覧を取得する
  127. *
  128. * @param array $blogContentId
  129. * @param array $options
  130. * @return array 月別リストデータ
  131. * @access public
  132. */
  133. function getPostedDates($blogContentId, $options) {
  134. $options = array_merge(array(
  135. 'category' => false,
  136. 'limit' => false,
  137. 'viewCount' => false,
  138. 'type' => 'month' // month Or year
  139. ), $options);
  140. extract($options);
  141. $conditions = array('BlogPost.blog_content_id'=>$blogContentId);
  142. $conditions = am($conditions, $this->getConditionAllowPublish());
  143. // TODO CSVDBではGROUP BYが実装されていない為、取り急ぎPHPで処理
  144. /*$dates = $this->find('all',array('fields'=>array('YEAR(posts_date) as year','MONTH(posts_date) as month','COUNT(id)' as count),
  145. $conditions,
  146. 'group'=>array('YEAR(posts_date)','MONTH(posts_date)'))));*/
  147. if($category) {
  148. $recursive = 1;
  149. $this->unbindModel(array(
  150. 'belongsTo' => array('User', 'BlogContent'),
  151. 'hasAndBelongsToMany' => array('BlogTag')
  152. ));
  153. } else {
  154. $recursive = -1;
  155. }
  156. // 毎秒抽出条件が違うのでキャッシュしない
  157. $posts = $this->find('all',array(
  158. 'conditions'=> $conditions,
  159. 'order' => 'BlogPost.posts_date DESC',
  160. 'recursive' => $recursive,
  161. 'cache' => false
  162. ));
  163. $dates = array();
  164. $counter = 0;
  165. foreach($posts as $post) {
  166. $exists = false;
  167. $_date = array();
  168. $year = date('Y',strtotime($post['BlogPost']['posts_date']));
  169. $month = date('m',strtotime($post['BlogPost']['posts_date']));
  170. $categoryId = $post['BlogPost']['blog_category_id'];
  171. foreach($dates as $key => $date) {
  172. if(!$category || $date['BlogCategory']['id'] == $categoryId) {
  173. if($type == 'year' && $date['year'] == $year) {
  174. $exists = true;
  175. }
  176. if($type == 'month' && $date['year'] == $year && $date['month'] == $month) {
  177. $exists = true;
  178. }
  179. }
  180. if($exists) {
  181. if($viewCount) {
  182. $dates[$key]['count']++;
  183. }
  184. break;
  185. }
  186. }
  187. if(!$exists) {
  188. if($type == 'year') {
  189. $_date['year'] = $year;
  190. } elseif($type == 'month') {
  191. $_date['year'] = $year;
  192. $_date['month'] = $month;
  193. }
  194. if($category) {
  195. $_date['BlogCategory']['id'] = $categoryId;
  196. $_date['BlogCategory']['name'] = $post['BlogCategory']['name'];
  197. $_date['BlogCategory']['title'] = $post['BlogCategory']['title'];
  198. }
  199. if($viewCount) {
  200. $_date['count'] = 1;
  201. }
  202. $dates[] = $_date;
  203. $counter++;
  204. }
  205. if($limit !== false && $limit <= $counter) {
  206. break;
  207. }
  208. }
  209. return $dates;
  210. }
  211. /**
  212. * カレンダー用に指定した月で記事の投稿がある日付のリストを取得する
  213. *
  214. * @param int $contentId
  215. * @param int $year
  216. * @param int $month
  217. * @return array
  218. * @access public
  219. */
  220. function getEntryDates($contentId,$year,$month) {
  221. $entryDates = $this->find('all', array(
  222. 'fields' => array('BlogPost.posts_date'),
  223. 'conditions'=> $this->_getEntryDatesConditions($contentId,$year,$month),
  224. 'recursive' => -1,
  225. 'cache' => false
  226. ));
  227. $entryDates = Set::extract('/BlogPost/posts_date',$entryDates);
  228. foreach($entryDates as $key => $entryDate) {
  229. $entryDates[$key] = date('Y-m-d',strtotime($entryDate));
  230. }
  231. return $entryDates;
  232. }
  233. /**
  234. * 指定した月の記事が存在するかチェックする
  235. *
  236. * @param int $contentId
  237. * @param int $year
  238. * @param int $month
  239. * @return boolean
  240. */
  241. function existsEntry($contentId,$year,$month) {
  242. if($this->find('first', array(
  243. 'fields' => array('BlogPost.id'),
  244. 'conditions'=> $this->_getEntryDatesConditions($contentId,$year,$month),
  245. 'recursive' => -1,
  246. 'cache' => false
  247. ))) {
  248. return true;
  249. } else {
  250. return false;
  251. }
  252. }
  253. /**
  254. * 年月を指定した検索条件を生成
  255. * データベースごとに構文が違う
  256. *
  257. * @param int $contentId
  258. * @param int $year
  259. * @param int $month
  260. * @return string
  261. * @access private
  262. */
  263. function _getEntryDatesConditions($contentId,$year,$month) {
  264. $dbConfig = new DATABASE_CONFIG();
  265. $driver = preg_replace('/^bc_/', '', $dbConfig->plugin['driver']);
  266. switch($driver) {
  267. case 'mysql':
  268. case 'csv':
  269. if(!empty($year)) {
  270. $conditions["YEAR(`BlogPost`.`posts_date`)"] = $year;
  271. }else {
  272. $conditions["YEAR(`BlogPost`.`posts_date`)"] = date('Y');
  273. }
  274. if(!empty($month)) {
  275. $conditions["MONTH(`BlogPost`.`posts_date`)"] = $month;
  276. }else {
  277. $conditions["MONTH(`BlogPost`.`posts_date`)"] = date('m');
  278. }
  279. break;
  280. case 'postgres':
  281. if(!empty($year)) {
  282. $conditions["date_part('year', \"BlogPost\".\"posts_date\")"] = $year;
  283. }else {
  284. $conditions["date_part('year', \"BlogPost\".\"posts_date\")"] = date('Y');
  285. }
  286. if(!empty($month)) {
  287. $conditions["date_part('month', \"BlogPost\".\"posts_date\")"] = $month;
  288. }else {
  289. $conditions["date_part('month', \"BlogPost\".\"posts_date\")"] = date('m');
  290. }
  291. break;
  292. case 'sqlite':
  293. case 'sqlite3':
  294. if(!empty($year)) {
  295. $conditions["strftime('%Y',BlogPost.posts_date)"] = $year;
  296. }else {
  297. $conditions["strftime('%Y',BlogPost.posts_date)"] = date('Y');
  298. }
  299. if(!empty($month)) {
  300. $conditions["strftime('%m',BlogPost.posts_date)"] = sprintf('%02d',$month);
  301. }else {
  302. $conditions["strftime('%m',BlogPost.posts_date)"] = date('m');
  303. }
  304. break;
  305. }
  306. $conditions = am($conditions, array('BlogPost.blog_content_id'=>$contentId), $this->getConditionAllowPublish());
  307. return $conditions;
  308. }
  309. /**
  310. * コントロールソースを取得する
  311. *
  312. * @param string $field フィールド名
  313. * @param array $options
  314. * @return array コントロールソース
  315. * @access public
  316. */
  317. function getControlSource($field, $options = array()) {
  318. switch ($field) {
  319. case 'blog_category_id':
  320. extract($options);
  321. $catOption = array('blogContentId' => $blogContentId);
  322. $isSuperAdmin = false;
  323. if(!empty($userGroupId)) {
  324. if(!isset($blogCategoryId)) {
  325. $blogCategoryId = '';
  326. }
  327. if($userGroupId == 1) {
  328. $isSuperAdmin = true;
  329. }
  330. // 現在のページが編集不可の場合、現在表示しているカテゴリも取得する
  331. if(!$postEditable && $blogCategoryId) {
  332. $catOption['conditions'] = array('OR' => array('BlogCategory.id' => $blogCategoryId));
  333. }
  334. // super admin でない場合は、管理許可のあるカテゴリのみ取得
  335. if(!$isSuperAdmin) {
  336. $catOption['ownerId'] = $userGroupId;
  337. }
  338. if($postEditable && !$rootEditable && !$isSuperAdmin) {
  339. unset($empty);
  340. }
  341. }
  342. $categories = $this->BlogCategory->getControlSource('parent_id', $catOption);
  343. // 「指定しない」追加
  344. if(isset($empty)) {
  345. if($categories) {
  346. $categories = array('' => $empty) + $categories;
  347. } else {
  348. $categories = array('' => $empty);
  349. }
  350. }
  351. $controlSources['blog_category_id'] = $categories;
  352. break;
  353. case 'user_id':
  354. $controlSources['user_id'] = $this->User->getUserList($options);
  355. break;
  356. case 'blog_tag_id':
  357. $controlSources['blog_tag_id'] = $this->BlogTag->find('list');
  358. break;
  359. }
  360. if(isset($controlSources[$field])) {
  361. return $controlSources[$field];
  362. }else {
  363. return false;
  364. }
  365. }
  366. /**
  367. * 公開状態を取得する
  368. *
  369. * @param array データリスト
  370. * @return boolean 公開状態
  371. * @access public
  372. */
  373. function allowPublish($data){
  374. if(isset($data['BlogPost'])){
  375. $data = $data['BlogPost'];
  376. }
  377. $allowPublish = (int)$data['status'];
  378. if($data['publish_begin'] == '0000-00-00 00:00:00') {
  379. $data['publish_begin'] = NULL;
  380. }
  381. if($data['publish_end'] == '0000-00-00 00:00:00') {
  382. $data['publish_end'] = NULL;
  383. }
  384. // 期限を設定している場合に条件に該当しない場合は強制的に非公開とする
  385. if(($data['publish_begin'] && $data['publish_begin'] >= date('Y-m-d H:i:s')) ||
  386. ($data['publish_end'] && $data['publish_end'] <= date('Y-m-d H:i:s'))){
  387. $allowPublish = false;
  388. }
  389. return $allowPublish;
  390. }
  391. /**
  392. * 公開済の conditions を取得
  393. *
  394. * @return array
  395. * @access public
  396. */
  397. function getConditionAllowPublish() {
  398. $conditions[$this->alias.'.status'] = true;
  399. $conditions[] = array('or'=> array(array($this->alias.'.publish_begin <=' => date('Y-m-d H:i:s')),
  400. array($this->alias.'.publish_begin' => NULL),
  401. array($this->alias.'.publish_begin' => '0000-00-00 00:00:00')));
  402. $conditions[] = array('or'=> array(array($this->alias.'.publish_end >=' => date('Y-m-d H:i:s')),
  403. array($this->alias.'.publish_end' => NULL),
  404. array($this->alias.'.publish_end' => '0000-00-00 00:00:00')));
  405. return $conditions;
  406. }
  407. /**
  408. * 公開状態の記事を取得する
  409. *
  410. * @param array $options
  411. * @return array
  412. * @access public
  413. */
  414. function getPublishes ($options) {
  415. if(!empty($options['conditions'])) {
  416. $options['conditions'] = array_merge($this->getConditionAllowPublish(), $options['conditions']);
  417. } else {
  418. $options['conditions'] = $this->getConditionAllowPublish();
  419. }
  420. // 毎秒抽出条件が違うのでキャッシュしない
  421. $options['cache'] = false;
  422. $datas = $this->find('all', $options);
  423. return $datas;
  424. }
  425. /**
  426. * afterSave
  427. *
  428. * @param boolean $created
  429. * @return boolean
  430. * @access public
  431. */
  432. function afterSave($created) {
  433. // 検索用テーブルへの登録・削除
  434. if(!$this->data['BlogPost']['exclude_search']) {
  435. $this->saveContent($this->createContent($this->data));
  436. } else {
  437. $this->deleteContent($this->data['BlogPost']['id']);
  438. }
  439. }
  440. /**
  441. * 検索用データを生成する
  442. *
  443. * @param array $data
  444. * @return array
  445. * @access public
  446. */
  447. function createContent($data) {
  448. if(isset($data['BlogPost'])) {
  449. $data = $data['BlogPost'];
  450. }
  451. $_data = array();
  452. $_data['Content']['type'] = 'ブログ';
  453. $_data['Content']['model_id'] = $this->id;
  454. $_data['Content']['category'] = '';
  455. if(!empty($data['blog_category_id'])) {
  456. $BlogCategory = ClassRegistry::init('Blog.BlogCategory');
  457. $categoryPath = $BlogCategory->getPath($data['blog_category_id'], array('title'));
  458. if($categoryPath) {
  459. $_data['Content']['category'] = $categoryPath[0]['BlogCategory']['title'];
  460. }
  461. }
  462. $_data['Content']['title'] = $data['name'];
  463. $_data['Content']['detail'] = $data['content'].' '.$data['detail'];
  464. $PluginContent = ClassRegistry::init('PluginContent');
  465. $_data['Content']['url'] = '/'.$PluginContent->field('name', array('PluginContent.content_id' => $data['blog_content_id'], 'plugin' => 'blog')).'/archives/'.$data['no'];
  466. $_data['Content']['status'] = $this->allowPublish($data);
  467. return $_data;
  468. }
  469. /**
  470. * beforeDelete
  471. *
  472. * @return boolean
  473. * @access public
  474. */
  475. function beforeDelete() {
  476. return $this->deleteContent($this->id);
  477. }
  478. /**
  479. * コピーする
  480. *
  481. * @param int $id
  482. * @param array $data
  483. * @return mixed page Or false
  484. */
  485. function copy($id = null, $data = array()) {
  486. $data = array();
  487. if($id) {
  488. $data = $this->find('first', array('conditions' => array('BlogPost.id' => $id), 'recursive' => 1));
  489. }
  490. if(!empty($_SESSION['Auth']['User'])) {
  491. $data['BlogPost']['user_id'] = $_SESSION['Auth']['User']['id'];
  492. }
  493. $data['BlogPost']['name'] .= '_copy';
  494. $data['BlogPost']['no'] = $this->getMax('no', array('BlogPost.blog_content_id' => $data['BlogPost']['blog_content_id']))+1;
  495. $data['BlogPost']['status'] = false;
  496. unset($data['BlogPost']['id']);
  497. unset($data['BlogPost']['created']);
  498. unset($data['BlogPost']['modified']);
  499. if(!empty($data['BlogTag'])) {
  500. foreach($data['BlogTag'] as $key => $tag) {
  501. $data['BlogTag'][$key] = $tag['id'];
  502. }
  503. }
  504. $this->create($data);
  505. $result = $this->save();
  506. if($result) {
  507. return $result;
  508. } else {
  509. if(isset($this->validationErrors['name'])) {
  510. return $this->copy(null, $data);
  511. } else {
  512. return false;
  513. }
  514. }
  515. }
  516. }
  517. ?>