PageRenderTime 559ms CodeModel.GetById 90ms app.highlight 336ms RepoModel.GetById 110ms app.codeStats 2ms

/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
  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 */
 28class 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		
121		$data[$this->name]['user_id'] = $authUser['User']['id'];
122		$data[$this->name]['posts_date'] = date('Y/m/d H:i:s');
123		$data[$this->name]['status'] = 0;
124		return $data;
125		
126	}
127/**
128 * ブログの月別一覧を取得する
129 *
130 * @param array $blogContentId
131 * @param array $options
132 * @return array 月別リストデータ
133 * @access public
134 */
135	function getPostedDates($blogContentId, $options) {
136
137		$options = array_merge(array(
138			'category'	=> false,
139			'limit'		=> false, 
140			'viewCount'	=> false, 
141			'type'		=> 'month'	// month Or year
142		), $options);
143		
144		extract($options);
145		$conditions = array('BlogPost.blog_content_id'=>$blogContentId);
146		$conditions = am($conditions, $this->getConditionAllowPublish());
147		// TODO CSVDBではGROUP BYが実装されていない為、取り急ぎPHPで処理
148		/*$dates = $this->find('all',array('fields'=>array('YEAR(posts_date) as year','MONTH(posts_date) as month','COUNT(id)' as count),
149                                          $conditions,
150                                          'group'=>array('YEAR(posts_date)','MONTH(posts_date)'))));*/
151		
152		if($category) {
153			$recursive = 1;
154			$this->unbindModel(array(
155				'belongsTo'				=> array('User', 'BlogContent'),
156				'hasAndBelongsToMany'	=> array('BlogTag')
157			));
158		} else {
159			$recursive = -1;
160		}
161		
162		// 毎秒抽出条件が違うのでキャッシュしない
163		$posts = $this->find('all',array(
164			'conditions'=> $conditions, 
165			'order'		=> 'BlogPost.posts_date DESC', 
166			'recursive' => $recursive,
167			'cache'		=> false
168		));
169
170		$dates = array();
171		$counter = 0;
172
173		foreach($posts as $post) {
174			
175			$exists = false;
176			$_date = array();
177			$year = date('Y',strtotime($post['BlogPost']['posts_date']));
178			$month = date('m',strtotime($post['BlogPost']['posts_date']));
179			$categoryId = $post['BlogPost']['blog_category_id'];
180			
181			foreach($dates as $key => $date) {
182				
183				if(!$category || $date['BlogCategory']['id'] == $categoryId) {
184					if($type == 'year' && $date['year'] == $year) {
185						$exists = true;
186					}
187					if($type == 'month' && $date['year'] == $year && $date['month'] == $month) {				
188						$exists = true;
189					}
190				}
191				
192				if($exists) {				
193					if($viewCount) {
194						$dates[$key]['count']++;
195					}
196					break;
197				}
198				
199			}
200			
201			if(!$exists) {
202				if($type == 'year') {
203					$_date['year'] = $year;
204				} elseif($type == 'month') {
205					$_date['year'] = $year;
206					$_date['month'] = $month;
207				}
208				if($category) {
209					$_date['BlogCategory']['id'] = $categoryId;
210					$_date['BlogCategory']['name'] = $post['BlogCategory']['name'];
211					$_date['BlogCategory']['title'] = $post['BlogCategory']['title'];
212				}
213				if($viewCount) {
214					$_date['count'] = 1;
215				}
216				$dates[] = $_date;
217				$counter++;
218			}
219			
220			if($limit !== false && $limit <= $counter) {
221				break;
222			}
223			
224		}
225		
226		return $dates;
227
228	}
229/**
230 * カレンダー用に指定した月で記事の投稿がある日付のリストを取得する
231 * 
232 * @param int $contentId
233 * @param int $year
234 * @param int $month
235 * @return array
236 * @access public
237 */
238	function getEntryDates($contentId,$year,$month) {
239
240		$entryDates = $this->find('all', array(
241			'fields'	=> array('BlogPost.posts_date'),
242			'conditions'=> $this->_getEntryDatesConditions($contentId,$year,$month), 
243			'recursive'	=> -1,
244			'cache'		=> false
245		));
246		$entryDates = Set::extract('/BlogPost/posts_date',$entryDates);
247		foreach($entryDates as $key => $entryDate) {
248			$entryDates[$key] = date('Y-m-d',strtotime($entryDate));
249		}
250		return $entryDates;
251
252	}
253/**
254 * 指定した月の記事が存在するかチェックする
255 *
256 * @param	int $contentId
257 * @param	int $year
258 * @param	int $month
259 * @return	boolean
260 */
261	function existsEntry($contentId,$year,$month) {
262		
263		if($this->find('first', array(
264			'fields'	=> array('BlogPost.id'),
265			'conditions'=> $this->_getEntryDatesConditions($contentId,$year,$month), 
266			'recursive'	=> -1,
267			'cache'		=> false
268		))) {
269			return true;
270		} else {
271			return false;
272		}
273		
274	}
275/**
276 * 年月を指定した検索条件を生成
277 * データベースごとに構文が違う
278 * 
279 * @param int $contentId
280 * @param int $year
281 * @param int $month
282 * @return string
283 * @access private
284 */
285	function _getEntryDatesConditions($contentId,$year,$month) {
286
287		$dbConfig = new DATABASE_CONFIG();
288		$driver = preg_replace('/^bc_/', '', $dbConfig->plugin['driver']);
289
290		switch($driver) {
291			case 'mysql':
292			case 'csv':
293				if(!empty($year)) {
294					$conditions["YEAR(`BlogPost`.`posts_date`)"] = $year;
295				}else {
296					$conditions["YEAR(`BlogPost`.`posts_date`)"] = date('Y');
297				}
298				if(!empty($month)) {
299					$conditions["MONTH(`BlogPost`.`posts_date`)"] = $month;
300				}else {
301					$conditions["MONTH(`BlogPost`.`posts_date`)"] = date('m');
302				}
303				break;
304
305			case 'postgres':
306				if(!empty($year)) {
307					$conditions["date_part('year', \"BlogPost\".\"posts_date\")"] = $year;
308				}else {
309					$conditions["date_part('year', \"BlogPost\".\"posts_date\")"] = date('Y');
310				}
311				if(!empty($month)) {
312					$conditions["date_part('month', \"BlogPost\".\"posts_date\")"] = $month;
313				}else {
314					$conditions["date_part('month', \"BlogPost\".\"posts_date\")"] = date('m');
315				}
316				break;
317
318			case 'sqlite':
319			case 'sqlite3':
320				if(!empty($year)) {
321					$conditions["strftime('%Y',BlogPost.posts_date)"] = $year;
322				}else {
323					$conditions["strftime('%Y',BlogPost.posts_date)"] = date('Y');
324				}
325				if(!empty($month)) {
326					$conditions["strftime('%m',BlogPost.posts_date)"] = sprintf('%02d',$month);
327				}else {
328					$conditions["strftime('%m',BlogPost.posts_date)"] = date('m');
329				}
330				break;
331
332		}
333
334		$conditions = am($conditions,  array('BlogPost.blog_content_id'=>$contentId), $this->getConditionAllowPublish());
335		return $conditions;
336		
337	}
338/**
339 * コントロールソースを取得する
340 *
341 * @param string $field フィールド名
342 * @param	array	$options
343 * @return	array	コントロールソース
344 * @access	public
345 */
346	function getControlSource($field, $options = array()) {
347
348		switch ($field) {
349			case 'blog_category_id':
350				
351				extract($options);
352				$catOption = array('blogContentId' => $blogContentId);
353				$isSuperAdmin = false;
354
355				if(!empty($userGroupId)) {
356					
357					if(!isset($blogCategoryId)) {
358						$blogCategoryId = '';
359					}
360
361					if($userGroupId == 1) {
362						$isSuperAdmin = true;
363					}
364
365					// 現在のページが編集不可の場合、現在表示しているカテゴリも取得する
366					if(!$postEditable && $blogCategoryId) {
367						$catOption['conditions'] = array('OR' => array('BlogCategory.id' => $blogCategoryId));
368					}
369
370					// super admin でない場合は、管理許可のあるカテゴリのみ取得
371					if(!$isSuperAdmin) {
372						$catOption['ownerId'] = $userGroupId;
373					}
374				
375					if($postEditable && !$rootEditable && !$isSuperAdmin) {
376						unset($empty);
377					}
378				
379				}
380				
381				$categories = $this->BlogCategory->getControlSource('parent_id', $catOption);
382				
383				// 「指定しない」追加
384				if(isset($empty)) {
385					if($categories) {
386						$categories = array('' => $empty) + $categories;
387					} else {
388						$categories = array('' => $empty);
389					}
390				}
391				
392				$controlSources['blog_category_id'] = $categories;
393				
394				break;
395			case 'user_id':
396				$controlSources['user_id'] = $this->User->getUserList($options);
397				break;
398			case 'blog_tag_id':
399				$controlSources['blog_tag_id'] = $this->BlogTag->find('list');
400				break;
401		}
402		if(isset($controlSources[$field])) {
403			return $controlSources[$field];
404		}else {
405			return false;
406		}
407
408	}
409/**
410 * 公開状態を取得する
411 *
412 * @param array データリスト
413 * @return boolean 公開状態
414 * @access public
415 */
416	function allowPublish($data){
417
418		if(isset($data['BlogPost'])){
419			$data = $data['BlogPost'];
420		}
421
422		$allowPublish = (int)$data['status'];
423
424		if($data['publish_begin'] == '0000-00-00 00:00:00') {
425			$data['publish_begin'] = NULL;
426		}
427		if($data['publish_end'] == '0000-00-00 00:00:00') {
428			$data['publish_end'] = NULL;
429		}
430
431		// 期限を設定している場合に条件に該当しない場合は強制的に非公開とする
432		if(($data['publish_begin'] && $data['publish_begin'] >= date('Y-m-d H:i:s')) ||
433				($data['publish_end'] && $data['publish_end'] <= date('Y-m-d H:i:s'))){
434			$allowPublish = false;
435		}
436
437		return $allowPublish;
438
439	}
440/**
441 * 公開済の conditions を取得
442 * 
443 * @return array
444 * @access public 
445 */
446	function getConditionAllowPublish() {
447		
448		$conditions[$this->alias.'.status'] = true;
449		$conditions[] = array('or'=> array(array($this->alias.'.publish_begin <=' => date('Y-m-d H:i:s')),
450										array($this->alias.'.publish_begin' => NULL),
451										array($this->alias.'.publish_begin' => '0000-00-00 00:00:00')));
452		$conditions[] = array('or'=> array(array($this->alias.'.publish_end >=' => date('Y-m-d H:i:s')),
453										array($this->alias.'.publish_end' => NULL),
454										array($this->alias.'.publish_end' => '0000-00-00 00:00:00')));
455		return $conditions;
456		
457	}
458/**
459 * 公開状態の記事を取得する
460 *
461 * @param array $options
462 * @return array
463 * @access public
464 */
465	function getPublishes ($options) {
466
467		if(!empty($options['conditions'])) {
468			$options['conditions'] = array_merge($this->getConditionAllowPublish(), $options['conditions']);
469		} else {
470			$options['conditions'] = $this->getConditionAllowPublish();
471		}
472		// 毎秒抽出条件が違うのでキャッシュしない
473		$options['cache'] = false;
474		$datas = $this->find('all', $options);
475		return $datas;
476
477	}
478/**
479 * afterSave
480 *
481 * @param boolean $created
482 * @return boolean
483 * @access public
484 */
485	function afterSave($created) {
486
487		// 検索用テーブルへの登録・削除
488		if(!$this->data['BlogPost']['exclude_search']) {
489			$this->saveContent($this->createContent($this->data));
490		} else {
491			$this->deleteContent($this->data['BlogPost']['id']);
492		}
493		
494	}
495/**
496 * 検索用データを生成する
497 *
498 * @param array $data
499 * @return array
500 * @access public
501 */
502	function createContent($data) {
503
504		if(isset($data['BlogPost'])) {
505			$data = $data['BlogPost'];
506		}
507
508		$_data = array();
509		$_data['Content']['type'] = 'ブログ';
510		$_data['Content']['model_id'] = $this->id;
511		$_data['Content']['category'] = '';
512		if(!empty($data['blog_category_id'])) {
513			$BlogCategory = ClassRegistry::init('Blog.BlogCategory');
514			$categoryPath = $BlogCategory->getPath($data['blog_category_id'], array('title'));
515			if($categoryPath) {
516				$_data['Content']['category'] = $categoryPath[0]['BlogCategory']['title'];
517			}
518		}
519		$_data['Content']['title'] = $data['name'];
520		$_data['Content']['detail'] = $data['content'].' '.$data['detail'];
521		$PluginContent = ClassRegistry::init('PluginContent');
522		$_data['Content']['url'] = '/'.$PluginContent->field('name', array('PluginContent.content_id' => $data['blog_content_id'], 'plugin' => 'blog')).'/archives/'.$data['no'];
523		$_data['Content']['status'] = $this->allowPublish($data);
524
525		return $_data;
526
527	}
528/**
529 * beforeDelete
530 *
531 * @return boolean
532 * @access public
533 */
534	function beforeDelete() {
535
536		return $this->deleteContent($this->id);
537
538	}
539/**
540 * コピーする
541 * 
542 * @param int $id
543 * @param array $data
544 * @return mixed page Or false
545 */
546	function copy($id = null, $data = array()) {
547		
548		$data = array();
549		if($id) {
550			$data = $this->find('first', array('conditions' => array('BlogPost.id' => $id), 'recursive' => 1));
551		}
552		if(!empty($_SESSION['Auth']['User'])) {
553			$data['BlogPost']['user_id'] = $_SESSION['Auth']['User']['id'];
554		}
555		
556		$data['BlogPost']['name'] .= '_copy';
557		$data['BlogPost']['no'] = $this->getMax('no', array('BlogPost.blog_content_id' => $data['BlogPost']['blog_content_id']))+1;
558		$data['BlogPost']['status'] = false;
559		
560		unset($data['BlogPost']['id']);
561		unset($data['BlogPost']['created']);
562		unset($data['BlogPost']['modified']);
563		if(!empty($data['BlogTag'])) {
564			foreach($data['BlogTag'] as $key => $tag) {
565				$data['BlogTag'][$key] = $tag['id'];
566			}
567		}
568		
569		$this->create($data);
570		$result = $this->save();
571		if($result) {
572			return $result;
573		} else {
574			if(isset($this->validationErrors['name'])) {
575				return $this->copy(null, $data);
576			} else {
577				return false;
578			}
579		}
580		
581	}
582	
583}
584?>