PageRenderTime 570ms CodeModel.GetById 61ms app.highlight 417ms RepoModel.GetById 27ms app.codeStats 2ms

/baser/models/page.php

https://github.com/hashing/basercms
PHP | 1170 lines | 713 code | 129 blank | 328 comment | 162 complexity | 47f14fc91f8d71b91526b62a08bbac29 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.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 * ページモデル
  22 * 
  23 * @package baser.models
  24 */
  25class Page extends AppModel {
  26/**
  27 * クラス名
  28 * @var string
  29 * @access public
  30 */
  31	var $name = 'Page';
  32/**
  33 * データベース接続
  34 * 
  35 * @var string
  36 * @access public
  37 */
  38	var $useDbConfig = 'baser';
  39/**
  40 * belongsTo
  41 * 
  42 * @var array
  43 * @access public
  44 */
  45	var $belongsTo = array(
  46			'PageCategory' =>   array(  'className'=>'PageCategory',
  47							'foreignKey'=>'page_category_id'),
  48			'User' => array('className'=> 'User',
  49							'foreignKey'=>'author_id'));
  50/**
  51 * ビヘイビア
  52 *
  53 * @var array
  54 * @access public
  55 */
  56	var $actsAs = array('BcContentsManager', 'BcCache');
  57/**
  58 * 更新前のページファイルのパス
  59 * 
  60 * @var string
  61 * @access public
  62 */
  63	var $oldPath = '';
  64/**
  65 * ファイル保存可否
  66 * true の場合、ページデータ保存の際、ページテンプレートファイルにも内容を保存する
  67 * テンプレート読み込み時などはfalseにして保存しないようにする
  68 * 
  69 * @var boolean
  70 * @access public
  71 */
  72	var $fileSave = true;
  73/**
  74 * 検索テーブルへの保存可否
  75 *
  76 * @var boolean
  77 * @access public
  78 */
  79	var $contentSaving = true;
  80/**
  81 * 非公開WebページURLリスト
  82 * キャッシュ用
  83 * 
  84 * @var mixed
  85 * @deprecated
  86 * @access protected
  87 */
  88	var $_unpublishes = -1;
  89/**
  90 * 公開WebページURLリスト
  91 * キャッシュ用
  92 * 
  93 * @var mixed
  94 * @access protected
  95 */
  96	var $_publishes = -1;
  97/**
  98 * WebページURLリスト
  99 * キャッシュ用
 100 * 
 101 * @var mixed
 102 * @access protected
 103 */
 104	var $_pages = -1;
 105/**
 106 * 最終登録ID
 107 * モバイルページへのコピー処理でスーパークラスの最終登録IDが上書きされ、
 108 * コントローラーからは正常なIDが取得できないのでモバイルページへのコピー以外の場合だけ保存する
 109 *
 110 * @var int
 111 * @access private
 112 */
 113	var $__pageInsertID = null;
 114/**
 115 * バリデーション
 116 *
 117 * @var array
 118 * @access	public
 119 */
 120	var $validate = array(
 121		'name' => array(
 122			array(	'rule'		=> array('notEmpty'),
 123					'message'	=> 'ページ名を入力してください。',
 124					'required'	=> true),
 125			array(	'rule'		=> array('maxLength', 50),
 126					'message'	=> 'ページ名は50文字以内で入力してください。'),
 127			array(	'rule'		=> array('pageExists'),
 128					'message'	=> '指定したページは既に存在します。ファイル名、またはカテゴリを変更してください。')
 129		),
 130		'page_category_id' => array(
 131			array(	'rule'		=> array('pageExists'),
 132					'message'	=> '指定したページは既に存在します。ファイル名、またはカテゴリを変更してください。')
 133		),
 134		'title' => array(
 135			array(	'rule'		=> array('maxLength', 255),
 136					'message'	=> 'ページタイトルは255文字以内で入力してください。')
 137		),
 138		'description' => array(
 139			array(	'rule'		=> array('maxLength', 255),
 140					'message'	=> '説明文は255文字以内で入力してください。')
 141		)
 142	);
 143/**
 144 * フォームの初期値を設定する
 145 * 
 146 * @return	array	初期値データ
 147 * @access	public
 148 */
 149	function getDefaultValue() {
 150
 151		if(!empty($_SESSION['Auth']['User'])) {
 152			$data[$this->name]['author_id'] = $_SESSION['Auth']['User']['id'];
 153		}
 154		$data[$this->name]['sort'] = $this->getMax('sort')+1;
 155		$data[$this->name]['status'] = false;
 156		return $data;
 157
 158	}
 159/**
 160 * beforeSave
 161 * 
 162 * @return boolean
 163 * @access public
 164 */
 165	function beforeSave() {
 166
 167		if(!$this->fileSave) {
 168			return true;
 169		}
 170
 171		// 保存前のページファイルのパスを取得
 172		if($this->exists()) {
 173			$this->oldPath = $this->_getPageFilePath(
 174					$this->find('first', array(
 175						'conditions' => array('Page.id' => $this->data['Page']['id']),
 176						'recursive' => -1)
 177					)
 178			);
 179		}else {
 180			$this->oldPath = '';
 181		}
 182
 183		// 新しいページファイルのパスが開けるかチェックする
 184		$result = true;
 185		if(!$this->checkOpenPageFile($this->data)){
 186			$result = false;
 187		}
 188		
 189		if(isset($this->data['Page'])){
 190			$data = $this->data['Page'];
 191		} else {
 192			$data = $this->data;
 193		}
 194		
 195		if(!empty($data['reflect_mobile'])){
 196			$data['url'] = '/'.Configure::read('BcAgent.mobile.prefix').$this->removeAgentPrefixFromUrl($data['url']);
 197			if(!$this->checkOpenPageFile($data)){
 198				$result = false;
 199			}
 200		}
 201		if(!empty($data['reflect_smartphone'])){
 202			$data['url'] = '/'.Configure::read('BcAgent.smartphone.prefix').$this->removeAgentPrefixFromUrl($data['url']);
 203			if(!$this->checkOpenPageFile($data)){
 204				$result = false;
 205			}
 206		}
 207		return $result;
 208
 209	}
 210/**
 211 * プレフィックスを取り除く
 212 * 
 213 * @param type $url
 214 * @return type 
 215 */
 216	function removeAgentPrefixFromUrl($url) {
 217		if(preg_match('/^\/'.Configure::read('BcAgent.mobile.prefix').'\//', $url)) {
 218			$url = preg_replace('/^\/'.Configure::read('BcAgent.mobile.prefix').'\//', '/', $url);
 219		} elseif(preg_match('/^\/'.Configure::read('BcAgent.smartphone.prefix').'\//', $url)) {
 220			$url = preg_replace('/^\/'.Configure::read('BcAgent.smartphone.prefix').'\//', '/', $url);
 221		}
 222		return $url;
 223	}
 224/**
 225 * 最終登録IDを取得する
 226 *
 227 * @return	int
 228 * @access	public
 229 */
 230	function getInsertID(){
 231		
 232		if(!$this->__pageInsertID){
 233			$this->__pageInsertID = parent::getInsertID();
 234		}
 235		return $this->__pageInsertID;
 236		
 237	}
 238/**
 239 * ページテンプレートファイルが開けるかチェックする
 240 * 
 241 * @param	array	$data	ページデータ
 242 * @return	boolean
 243 * @access	public
 244 */
 245	function checkOpenPageFile($data){
 246		
 247		$path = $this->_getPageFilePath($data);
 248		$File = new File($path);
 249		if($File->open('w')) {
 250			$File->close();
 251			$File = null;
 252			return true;
 253		}else {
 254			return false;
 255		}
 256		
 257	}
 258/**
 259 * afterSave
 260 * 
 261 * @param array $created
 262 * @return boolean
 263 * @access public
 264 */
 265	function afterSave($created) {
 266
 267		if(isset($this->data['Page'])){
 268			$data = $this->data['Page'];
 269		} else {
 270			$data = $this->data;
 271		}
 272		// タイトルタグと説明文を追加
 273		if(empty($data['id'])) {
 274			$data['id'] = $this->id;
 275		}
 276		
 277		if($this->fileSave) {
 278			$this->createPageTemplate($data);
 279		}
 280
 281		// 検索用テーブルに登録
 282		if($this->contentSaving) {
 283			if(empty($data['exclude_search'])) {
 284				$this->saveContent($this->createContent($data));
 285			} else {
 286				$this->deleteContent($data['id']);
 287			}
 288		}
 289
 290		// モバイルデータの生成
 291		if(!empty($data['reflect_mobile'])) {
 292			$this->refrect('mobile', $data);
 293		}
 294		if(!empty($data['reflect_smartphone'])){
 295			$this->refrect('smartphone', $data);
 296		}
 297			
 298
 299	}
 300/**
 301 * 関連ページに反映する
 302 * 
 303 * @param string $type
 304 * @param array $data
 305 * @return boolean
 306 */
 307	function refrect($type, $data) {
 308		
 309		if(isset($this->data['Page'])){
 310			$data = $this->data['Page'];
 311		}
 312		
 313		// モバイルページへのコピーでスーパークラスのIDを上書きしてしまうので退避させておく
 314		$this->__pageInsertID = parent::getInsertID();
 315
 316		$agentId = $this->PageCategory->getAgentId($type);
 317		if(!$agentId){
 318			// カテゴリがない場合は trueを返して終了
 319			return true;
 320		}
 321
 322		$data['url'] = '/'.Configure::read('BcAgent.'.$type.'.prefix').$this->removeAgentPrefixFromUrl($data['url']);
 323		
 324		$agentPage = $this->find('first',array('conditions'=>array('Page.url'=>$data['url']),'recursive'=>-1));
 325
 326		unset($data['id']);
 327		unset($data['sort']);
 328		unset($data['status']);
 329
 330		if($agentPage){
 331			$agentPage['Page']['name'] = $data['name'];
 332			$agentPage['Page']['title'] = $data['title'];
 333			$agentPage['Page']['description'] = $data['description'];
 334			$agentPage['Page']['draft'] = $data['draft'];
 335			$agentPage['Page']['modified'] = $data['modified'];
 336			$agentPage['Page']['contents'] = $data['contents'];
 337			$agentPage['Page']['reflect_mobile'] = false;
 338			$agentPage['Page']['reflect_smartphone'] = false;
 339			$this->set($agentPage);
 340		}else{
 341			if($data['page_category_id']){
 342				$fields = array('parent_id','name','title');
 343				$pageCategoryTree = $this->PageCategory->getTreeList($fields,$data['page_category_id']);
 344				$path = getViewPath().'pages'.DS.Configure::read('BcAgent.'.$type.'.prefix');
 345				$parentId = $agentId;
 346				foreach($pageCategoryTree as $pageCategory) {
 347					$path .= '/'.$pageCategory['PageCategory']['name'];
 348					$categoryId = $this->PageCategory->getIdByPath($path);
 349					if(!$categoryId){
 350						$pageCategory['PageCategory']['parent_id'] = $parentId;
 351						$this->PageCategory->create($pageCategory);
 352						$ret = $this->PageCategory->save();
 353						$parentId = $categoryId = $this->PageCategory->getInsertID();
 354					}else{
 355						$parentId = $categoryId;
 356					}
 357				}
 358				$data['page_category_id'] = $categoryId;
 359			}else{
 360				$data['page_category_id'] = $agentId;
 361			}
 362			$data['author_id'] = $_SESSION['Auth']['User']['id'];
 363			$data['sort'] = $this->getMax('sort')+1;
 364			$data['status'] = false;	// 新規ページの場合は非公開とする
 365			unset($data['publish_begin']);
 366			unset($data['publish_end']);
 367			unset($data['created']);
 368			unset($data['modified']);
 369			$data['reflect_mobile'] = false;
 370			$data['reflect_smartphone'] = false;
 371			$this->create($data);
 372
 373		}
 374		return $this->save();
 375
 376	}
 377/**
 378 * 検索用データを生成する
 379 *
 380 * @param array $data
 381 * @return array
 382 * @access public
 383 */
 384	function createContent($data) {
 385
 386		if(isset($data['Page'])) {
 387			$data = $data['Page'];
 388		}
 389		if(!isset($data['publish_begin'])) {
 390			$data['publish_begin'] = '';
 391		}
 392		if(!isset($data['publish_end'])) {
 393			$data['publish_end'] = '';
 394		}
 395
 396		if(!$data['title']) {
 397			$data['title'] = Inflector::camelize($data['name']);
 398		}
 399		
 400		// モバイル未対応
 401		$PageCategory = ClassRegistry::init('PageCategory');
 402		$excludeIds = am($PageCategory->getAgentCategoryIds('mobile'), $PageCategory->getAgentCategoryIds('smartphone'));
 403		if(in_array($data['page_category_id'], $excludeIds)) {
 404			return array();
 405		}
 406
 407		$_data = array();
 408		$_data['Content']['type'] = 'ページ';
 409		// $this->idに値が入ってない場合もあるので
 410		if(!empty($data['id'])) {
 411			$_data['Content']['model_id'] = $data['id'];
 412		} else {
 413			$_data['Content']['model_id'] = $this->id;
 414		}
 415		$_data['Content']['category'] = '';
 416		if(!empty($data['page_category_id'])) {
 417			$categoryPath = $PageCategory->getPath($data['page_category_id'], array('title'));
 418			if($categoryPath) {
 419				$_data['Content']['category'] = $categoryPath[0]['PageCategory']['title'];
 420			}
 421		}
 422		$_data['Content']['title'] = $data['title'];
 423		$parameters = split('/', preg_replace("/^\//", '', $data['url']));
 424		$detail = $this->requestAction(array('controller' => 'pages', 'action' => 'display'), array('pass' => $parameters, 'return') );
 425		$detail = preg_replace('/<!-- BaserPageTagBegin -->.*?<!-- BaserPageTagEnd -->/is', '', $detail);
 426		$_data['Content']['detail'] = $data['description'].' '.$detail;
 427		$_data['Content']['url'] = $data['url'];
 428		$_data['Content']['status'] = $this->allowedPublish($data['status'], $data['publish_begin'], $data['publish_end']);
 429
 430		return $_data;
 431
 432	}
 433/**
 434 * beforeDelete
 435 * 
 436 * @return boolean
 437 * @access public
 438 */
 439	function beforeDelete() {
 440		
 441		return $this->deleteContent($this->id);
 442		
 443	}
 444/**
 445 * データが公開済みかどうかチェックする
 446 * 同様のメソッド checkPublish があり DB接続前提でURLでチェックする仕組みだが
 447 * こちらは、実データで直接チェックする
 448 * TODO メソッド名のリファクタリング要
 449 *
 450 * @param boolean $status
 451 * @param boolean $publishBegin
 452 * @param boolean $publishEnd
 453 * @return	array
 454 * @access public
 455 */
 456	function allowedPublish($status, $publishBegin, $publishEnd) {
 457
 458		if(!$status) {
 459			return false;
 460		}
 461
 462		if($publishBegin && $publishBegin != '0000-00-00 00:00:00') {
 463			if($publishBegin < date('Y-m-d H:i:s')) {
 464				return false;
 465			}
 466		}
 467
 468		if($publishEnd && $publishEnd != '0000-00-00 00:00:00') {
 469			if($publishEnd > date('Y-m-d H:i:s')) {
 470				return false;
 471			}
 472		}
 473
 474		return true;
 475
 476	}
 477/**
 478 * DBデータを元にページテンプレートを全て生成する
 479 * 
 480 * @return boolean
 481 * @access public
 482 */
 483	function createAllPageTemplate(){
 484		
 485		$pages = $this->find('all', array('recursive' => -1));
 486		$result = true;
 487		foreach($pages as $page){
 488			if(!$this->createPageTemplate($page)){
 489				$result = false;
 490			}
 491		}
 492		return $result;
 493		
 494	}
 495/**
 496 * ページテンプレートを生成する
 497 * 
 498 * @param array $data ページデータ
 499 * @return boolean
 500 * @access public
 501 */
 502	function createPageTemplate($data){
 503
 504		if(isset($data['Page'])){
 505			$data = $data['Page'];
 506		}
 507		$contents = $this->addBaserPageTag($data['id'], $data['contents'], $data['title'],$data['description']);
 508
 509		// 新しいページファイルのパスを取得する
 510		$newPath = $this->_getPageFilePath($data);
 511
 512		// ファイルに保存
 513		$newFile = new File($newPath, true);
 514		if($newFile->open('w')) {
 515			if($newFile->append($contents)) {
 516				// テーマやファイル名が変更された場合は元ファイルを削除する
 517				if($this->oldPath && ($newPath != $this->oldPath)) {
 518					$oldFile = new File($this->oldPath);
 519					$oldFile->delete();
 520					unset($oldFile);
 521				}
 522			}
 523			$newFile->close();
 524			unset($newFile);
 525			@chmod($newPath, 0666);
 526			return true;
 527		}else {
 528			return false;
 529		}
 530
 531	}
 532/**
 533 * ページファイルのディレクトリを取得する
 534 * 
 535 * @param array $data
 536 * @return string
 537 * @access protected
 538 */
 539	function _getPageFilePath($data) {
 540
 541		if(isset($data['Page'])){
 542			$data = $data['Page'];
 543		}
 544
 545		$file = $data['name'];
 546		$categoryId = $data['page_category_id'];
 547		$SiteConfig = ClassRegistry::getObject('SiteConfig');
 548		if(!$SiteConfig){
 549			$SiteConfig = ClassRegistry::init('SiteConfig');
 550		}
 551		$SiteConfig->cacheQueries = false;
 552		$siteConfig = $SiteConfig->findExpanded();
 553		$theme = $siteConfig['theme'];
 554
 555		// pagesディレクトリのパスを取得
 556		if($theme) {
 557			$path = WWW_ROOT.'themed'.DS.$theme.DS.'pages'.DS;
 558		}else {
 559			$path = VIEWS.'pages'.DS;
 560
 561		}
 562
 563		if(!is_dir($path)) {
 564			mkdir($path);
 565			chmod($path,0777);
 566		}
 567
 568		if($categoryId) {
 569			$this->PageCategory->cacheQueries = false;
 570			$categoryPath = $this->PageCategory->getPath($categoryId, null, null, -1);
 571			if($categoryPath) {
 572				foreach($categoryPath as $category) {
 573					$path .= $category['PageCategory']['name'].DS;
 574					if(!is_dir($path)) {
 575						mkdir($path,0777);
 576						chmod($path,0777);
 577					}
 578				}
 579			}
 580		}
 581		return $path.$file.Configure::read('BcApp.templateExt');
 582
 583	}
 584/**
 585 * ページファイルを削除する
 586 * 
 587 * @param array $data
 588 */
 589	function delFile($data) {
 590		
 591		$path = $this->_getPageFilePath($data);
 592		if($path) {
 593			return unlink($path);
 594		}
 595		return true;
 596		
 597	}
 598/**
 599 * ページのURLを取得する
 600 * 
 601 * @param array $data
 602 * @return string
 603 * @access public
 604 */
 605	function getPageUrl($data) {
 606
 607		if(isset($data['Page'])) {
 608			$data = $data['Page'];
 609		}
 610		$categoryId = $data['page_category_id'];
 611		$url = '/';
 612		if($categoryId) {
 613			$this->PageCategory->cacheQueries = false;
 614			$categoryPath = $this->PageCategory->getPath($categoryId);
 615			if($categoryPath) {
 616				foreach($categoryPath as $key => $category) {
 617					if($key == 0 && $category['PageCategory']['name'] == Configure::read('BcAgent.mobile.prefix')) {
 618						$url .= Configure::read('BcAgent.mobile.prefix').'/';
 619					} else {
 620						$url .= $category['PageCategory']['name'].'/';
 621					}
 622				}
 623			}
 624		}
 625		return $url.$data['name'];
 626		
 627	}
 628/**
 629 * Baserが管理するタグを追加する
 630 * 
 631 * @param string $id
 632 * @param string $contents
 633 * @param string $title
 634 * @param string $description
 635 * @return string
 636 * @access public
 637 */
 638	function addBaserPageTag($id,$contents,$title,$description) {
 639		
 640		$tag = '<!-- BaserPageTagBegin -->'."\n";
 641		$tag .= '<?php $bcBaser->setTitle(\''.$title.'\') ?>'."\n";
 642		$tag .= '<?php $bcBaser->setDescription(\''.$description.'\') ?>'."\n";
 643		if($id) {
 644			$tag .= '<?php $bcBaser->setPageEditLink('.$id.') ?>'."\n";
 645		}
 646		$tag .= '<!-- BaserPageTagEnd -->'."\n";
 647		return $tag . $contents;
 648		
 649	}
 650/**
 651 * ページ存在チェック
 652 *
 653 * @param string チェック対象文字列
 654 * @return boolean
 655 * @access public
 656 */
 657	function pageExists($check) {
 658		
 659		if($this->exists()) {
 660			return true;
 661		}else {
 662			$conditions['Page.name'] = $this->data['Page']['name'];
 663			if(empty($this->data['Page']['page_category_id'])) {
 664				if(isset($this->data['Page']['page_type']) && $this->data['Page']['page_type'] == 2) {
 665					$conditions['Page.page_category_id'] = $this->PageCategory->getAgentId('mobile');
 666				} elseif(isset($this->data['Page']['page_type']) && $this->data['Page']['page_type'] == 3) {
 667					$conditions['Page.page_category_id'] = $this->PageCategory->getAgentId('smartphone');
 668				} else {
 669					$conditions['Page.page_category_id'] = NULL;
 670				}
 671			}else {
 672				$conditions['Page.page_category_id'] = $this->data['Page']['page_category_id'];
 673			}
 674			if(!$this->find('first', array('conditions' => $conditions, 'recursive' => -1))) {
 675				return true;
 676			}else {
 677				return !file_exists($this->_getPageFilePath($this->data));
 678			}
 679		}
 680		
 681	}
 682/**
 683 * コントロールソースを取得する
 684 *
 685 * @param string $field フィールド名
 686 * @param array $options
 687 * @return mixed $controlSource コントロールソース
 688 * @access public
 689 */
 690	function getControlSource($field, $options = array()) {
 691
 692		switch ($field) {
 693			
 694			case 'page_category_id':
 695								
 696				$catOption = array();
 697				$isSuperAdmin = false;
 698				$agentRoot = true;
 699				
 700				extract($options);
 701
 702				if(!empty($userGroupId)) {
 703					
 704					if(!isset($pageCategoryId)) {
 705						$pageCategoryId = '';
 706					}
 707
 708					if($userGroupId == 1) {
 709						$isSuperAdmin = true;
 710					}
 711
 712					// 現在のページが編集不可の場合、現在表示しているカテゴリも取得する
 713					if(!$pageEditable && $pageCategoryId) {
 714						$catOption = array('conditions' => array('OR' => array('PageCategory.id' => $pageCategoryId)));
 715					}
 716
 717					// super admin でない場合は、管理許可のあるカテゴリのみ取得
 718					if(!$isSuperAdmin) {
 719						$catOption['ownerId'] = $userGroupId;
 720					}
 721				
 722					if($pageEditable && !$rootEditable && !$isSuperAdmin) {
 723						unset($empty);
 724						$agentRoot = false;
 725					}
 726				
 727				}
 728				
 729				$options = am($options, $catOption);
 730				$categories = $this->PageCategory->getControlSource('parent_id', $options);
 731				
 732				// 「指定しない」追加
 733				if(isset($empty)) {
 734					if($categories) {
 735						$categories = array('' => $empty) + $categories;
 736					} else {
 737						$categories = array('' => $empty);
 738					}
 739				}
 740				if(!$agentRoot) {
 741					// TODO 整理
 742					$agentId = $this->PageCategory->getAgentId('mobile');
 743					if(isset($categories[$agentId])) {
 744						unset($categories[$agentId]);
 745					}
 746					$agentId = $this->PageCategory->getAgentId('smartphone');
 747					if(isset($categories[$agentId])) {
 748						unset($categories[$agentId]);
 749					}
 750				}
 751				
 752				$controlSources['page_category_id'] = $categories;
 753				
 754				break;
 755				
 756			case 'user_id':
 757				
 758				$controlSources['user_id'] = $this->User->getUserList($options);
 759				break;
 760			
 761		}
 762		
 763		if(isset($controlSources[$field])) {
 764			return $controlSources[$field];
 765		}else {
 766			return false;
 767		}
 768
 769	}
 770/**
 771 * 非公開チェックを行う
 772 * 
 773 * @param	string	$url
 774 * @return	boolean
 775 * @access	public
 776 * @deprecated isPageUrl と組み合わせて checkPublish を利用してください。
 777 */
 778	function checkUnPublish($url) {
 779
 780		if($this->_unpublishes == -1) {
 781			
 782			$conditions['or']['Page.status'] = false;
 783			$conditions['or'][] = array(array('Page.publish_begin >' => date('Y-m-d H:i:s')),
 784												array('Page.publish_begin <>' => '0000-00-00 00:00:00'),
 785												array('Page.publish_begin <>' => NULL));
 786			$conditions['or'][] = array(array('Page.publish_end <' => date('Y-m-d H:i:s')),
 787												array('Page.publish_end <>' => '0000-00-00 00:00:00'),
 788												array('Page.publish_end <>' => NULL));
 789			$pages = $this->find('all',array('fields'=>'url','conditions'=>$conditions,'recursive'=>-1));
 790			
 791			if(!$pages) {
 792				$this->_unpublishes = array();
 793				return false;
 794			}
 795			
 796			$this->_unpublishes = Set::extract('/Page/url', $pages);
 797			
 798		}
 799
 800		if(preg_match('/\/$/', $url)) {
 801			$url .= 'index';
 802		}
 803		$url = preg_replace('/^\/'.Configure::read('BcRequest.agentAlias').'\//', '/'.Configure::read('BcRequest.agentPrefix').'/', $url);
 804		
 805		return in_array($url,$this->_unpublishes);
 806
 807	}
 808/**
 809 * キャッシュ時間を取得する
 810 * 
 811 * @param string $url
 812 * @return mixed int or false
 813 */
 814	function getCacheTime($url) {
 815		
 816		$url = preg_replace('/^\/'.Configure::read('BcRequest.agentAlias').'\//', '/'.Configure::read('BcRequest.agentPrefix').'/', $url);
 817		$page = $this->find('first', array('conditions' => array('Page.url' => $url), 'recursive' => -1));
 818		if(!$page) {
 819			return false;
 820		}
 821		if($page['Page']['status'] && $page['Page']['publish_end'] && $page['Page']['publish_end'] != '0000-00-00 00:00:00') {
 822			return strtotime($page['Page']['publish_end']) - time();
 823		} else {
 824			return Configure::read('BcCache.defaultCachetime');
 825		}
 826		
 827	}
 828/**
 829 * 公開チェックを行う
 830 * 
 831 * @param string $url
 832 * @return boolean
 833 * @access public
 834 */
 835	function checkPublish($url) {
 836
 837		if(preg_match('/\/$/', $url)) {
 838			$url .= 'index';
 839		}
 840		$url = preg_replace('/^\/'.Configure::read('BcRequest.agentAlias').'\//', '/'.Configure::read('BcRequest.agentPrefix').'/', $url);
 841		
 842		if($this->_publishes == -1) {
 843			$conditions = $this->getConditionAllowPublish();
 844			// 毎秒抽出条件が違うのでキャッシュしない
 845			$pages = $this->find('all', array(
 846				'fields'	=> 'url',
 847				'conditions'=> $conditions,
 848				'recursive'	=> -1,
 849				'cache'		=> false
 850			));
 851			if(!$pages) {
 852				$this->_publishes = array();
 853				return false;
 854			}
 855			$this->_publishes = Set::extract('/Page/url', $pages);
 856		}
 857		return in_array($url,$this->_publishes);
 858
 859	}
 860/**
 861 * 公開済の conditions を取得
 862 *
 863 * @return array
 864 * @access public
 865 */
 866	function getConditionAllowPublish() {
 867
 868		$conditions[$this->alias.'.status'] = true;
 869		$conditions[] = array('or'=> array(array($this->alias.'.publish_begin <=' => date('Y-m-d H:i:s')),
 870										array($this->alias.'.publish_begin' => NULL),
 871										array($this->alias.'.publish_begin' => '0000-00-00 00:00:00')));
 872		$conditions[] = array('or'=> array(array($this->alias.'.publish_end >=' => date('Y-m-d H:i:s')),
 873										array($this->alias.'.publish_end' => NULL),
 874										array($this->alias.'.publish_end' => '0000-00-00 00:00:00')));
 875		return $conditions;
 876
 877	}
 878/**
 879 * ページファイルを登録する
 880 * ※ 再帰処理
 881 *
 882 * @param string $pagePath
 883 * @param string $parentCategoryId
 884 * @return array 処理結果 all / success
 885 * @access protected
 886 */
 887	function entryPageFiles($targetPath,$parentCategoryId = '') {
 888
 889		if(function_exists('ini_set')) {
 890			ini_set('max_execution_time', 0);
 891			ini_set('max_input_time', 0);
 892			ini_set('memory_limit ', '256M');
 893		}
 894		
 895		$this->fileSave = false;
 896		$folder = new Folder($targetPath);
 897		$files = $folder->read(true,true,true);
 898		$insert = 0;
 899		$update = 0;
 900		$all = 0;
 901
 902		// カテゴリの取得・登録
 903		$categoryName = basename($targetPath);
 904		
 905		$pageCategoryId = '';
 906		$this->PageCategory->updateRelatedPage = false;
 907		if($categoryName != 'pages') {
 908			
 909			// カテゴリ名の取得
 910			// 標準では設定されてないので、利用する場合は、あらかじめ bootstrap 等で宣言しておく
 911			$categoryTitles = Configure::read('Baser.pageCategoryTitles');
 912			$categoryTitle = -1;
 913			if($categoryTitles) {
 914				$categoryNames = explode('/', str_replace(getViewPath().'pages'.DS, '', $targetPath));
 915				foreach($categoryNames as $key => $value) {
 916					if(isset($categoryTitles[$value])) {
 917						if(count($categoryNames) == ($key + 1)) {
 918							$categoryTitle = $categoryTitles[$value]['title'];
 919						}elseif(isset($categoryTitles[$value]['children'])) {
 920							$categoryTitles = $categoryTitles[$value]['children'];
 921						}
 922					}
 923				}
 924			}
 925			
 926			$categoryId = $this->PageCategory->getIdByPath($targetPath);
 927			if($categoryId) {
 928				$pageCategoryId = $categoryId;
 929				if($categoryTitle != -1) { 
 930					$pageCategory = $this->PageCategory->find('first', array('conditions' => array('PageCategory.id' => $pageCategoryId), 'recursive' => -1));
 931					$pageCategory['PageCategory']['title'] = $categoryTitle;
 932					$this->PageCategory->set($pageCategory);
 933					$this->PageCategory->save();
 934				}
 935			}else {
 936				$pageCategory['PageCategory']['parent_id'] = $parentCategoryId;
 937				$pageCategory['PageCategory']['name'] = $categoryName;
 938				if($categoryTitle == -1) { 
 939					$pageCategory['PageCategory']['title'] = $categoryName;
 940				} else {
 941					$pageCategory['PageCategory']['title'] = $categoryTitle;
 942				}
 943				$pageCategory['PageCategory']['sort'] = $this->PageCategory->getMax('sort')+1;
 944				$this->PageCategory->cacheQueries = false;
 945				$this->PageCategory->create($pageCategory);
 946				if($this->PageCategory->save()) {
 947					$pageCategoryId = $this->PageCategory->getInsertID();
 948				}
 949			}
 950		}else {
 951			$categoryName = '';
 952		}
 953
 954		// ファイル読み込み・ページ登録
 955		if(!$files[1]) $files[1] = array();
 956		foreach($files[1] as $path) {
 957
 958			if(preg_match('/'.preg_quote(Configure::read('BcApp.templateExt')).'$/is',$path) == false) {
 959				continue;
 960			}
 961
 962			$pageName = basename($path, Configure::read('BcApp.templateExt'));
 963			$file = new File($path);
 964			$contents = $file->read();
 965			$file->close();
 966			$file = null;
 967
 968			// タイトル取得・置換
 969			$titleReg = '/<\?php\s+?\$bcBaser->setTitle\(\'(.*?)\'\)\s+?\?>/is';
 970			if(preg_match($titleReg,$contents,$matches)) {
 971				$title = trim($matches[1]);
 972				$contents = preg_replace($titleReg,'',$contents);
 973			}else {
 974				$title = Inflector::camelize($pageName);
 975			}
 976
 977			// 説明文取得・置換
 978			$descriptionReg = '/<\?php\s+?\$bcBaser->setDescription\(\'(.*?)\'\)\s+?\?>/is';
 979			if(preg_match($descriptionReg,$contents,$matches)) {
 980				$description = trim($matches[1]);
 981				$contents = preg_replace($descriptionReg,'',$contents);
 982			}else {
 983				$description = '';
 984			}
 985
 986			// PageTagコメントの削除
 987			$pageTagReg = '/<\!\-\- BaserPageTagBegin \-\->.*?<\!\-\- BaserPageTagEnd \-\->/is';
 988			$contents = preg_replace($pageTagReg,'',$contents);
 989
 990			$conditions['Page.name'] = $pageName;
 991			if($pageCategoryId) {
 992				$conditions['Page.page_category_id'] = $pageCategoryId;
 993			}else{
 994				$conditions['Page.page_category_id'] = null;
 995			}
 996			$page = $this->find('first', array('conditions' => $conditions, 'recursive' => -1));
 997			if($page) {
 998				$chage = false;
 999				if($title != $page['Page']['title']) {
1000					$chage = true;
1001				}
1002				if($description != $page['Page']['description']) {
1003					$chage = true;
1004				}
1005				if(trim($contents) != trim($page['Page']['contents'])) {
1006					$chage = true;
1007				}
1008				if($chage) {
1009					$page['Page']['title'] = $title;
1010					$page['Page']['description'] = $description;
1011					$page['Page']['contents'] = $contents;
1012					$this->set($page);
1013					if($this->save()) {
1014						$update++;
1015					}
1016				}
1017			}else {
1018				$page = $this->getDefaultValue();
1019				$page['Page']['name'] = $pageName;
1020				$page['Page']['title'] = $title;
1021				$page['Page']['description'] = $description;
1022				$page['Page']['contents'] = $contents;
1023				$page['Page']['page_category_id'] = $pageCategoryId;
1024				$page['Page']['url'] = $this->getPageUrl($page);
1025				$this->create($page);
1026				if($this->save()) {
1027					$insert++;
1028				}
1029			}
1030			$all++;
1031		}
1032
1033		// フォルダー内の登録
1034		if(!$files[0]) $files[0] = array();
1035		foreach($files[0] as $file) {
1036			$folderName = basename($file);
1037			if($folderName != '_notes' && $folderName != 'admin') {
1038				$result = $this->entryPageFiles($file,$pageCategoryId);
1039				$insert += $result['insert'];
1040				$update += $result['update'];
1041				$all += $result['all'];
1042			}
1043		}
1044
1045		return array('all'=>$all,'insert'=>$insert,'update'=>$update);
1046
1047	}
1048/**
1049 * 関連ページの存在チェック
1050 * 存在する場合は、ページIDを返す
1051 * 
1052 * @param array $data ページデータ
1053 * @return mixed ページID / false
1054 * @access public
1055 */
1056	function agentExists ($type, $data) {
1057		
1058		if(isset($data['Page'])){
1059			$data = $data['Page'];
1060		}
1061		$url = $this->removeAgentPrefixFromUrl($data['url']);
1062		if(preg_match('/^\/'.Configure::read('BcAgent.'.$type.'.prefix').'\//is', $url)){
1063			// 対象ページがモバイルページの場合はfalseを返す
1064			return false;
1065		}
1066		return $this->field('id',array('Page.url'=>'/'.Configure::read('BcAgent.'.$type.'.prefix').$url));
1067		
1068	}
1069/**
1070 * ページで管理されているURLかチェックする
1071 * 
1072 * @param string $url
1073 * @return boolean
1074 * @access public
1075 */
1076	function isPageUrl($url) {
1077		
1078		if(preg_match('/\/$/', $url)) {
1079			$url .= 'index';
1080		}
1081		$url = preg_replace('/^\/'.Configure::read('BcRequest.agentAlias').'\//', '/'.Configure::read('BcRequest.agentPrefix').'/', $url);
1082		
1083		if($this->_pages == -1) {
1084			$pages = $this->find('all', array(
1085				'fields'	=> 'url',
1086				'recursive'	=> -1
1087			));
1088			if(!$pages) {
1089				$this->_pages = array();
1090				return false;
1091			}
1092			$this->_pages = Set::extract('/Page/url', $pages);
1093		}
1094		return in_array($url,$this->_pages);
1095		
1096	}
1097/**
1098 * Removes record for given ID. If no ID is given, the current ID is used. Returns true on success.
1099 *
1100 * @param mixed $id ID of record to delete
1101 * @param boolean $cascade Set to true to delete records that depend on this record
1102 * @return boolean True on success
1103 * @access public
1104 * @link http://book.cakephp.org/view/690/del
1105 */
1106	function del($id = null, $cascade = true) {
1107		
1108		// メッセージ用にデータを取得
1109		$page = $this->read(null, $id);
1110		
1111		/* 削除処理 */
1112		if(parent::del($id, $cascade)) {
1113			
1114			// ページテンプレートを削除
1115			$this->delFile($page);
1116			
1117			// 公開状態だった場合、サイトマップのキャッシュを削除
1118			// 公開期間のチェックは行わず確実に削除
1119			if($page['Page']['status']) {
1120				clearViewCache();
1121			}
1122			return true;
1123			
1124		} else {
1125			
1126			return false;
1127			
1128		}
1129		
1130	}
1131/**
1132 * ページデータをコピーする
1133 * 
1134 * @param int $id
1135 * @param array $data
1136 * @return mixed page Or false
1137 */
1138	function copy($id = null, $data = array()) {
1139		
1140		if($id) {
1141			$data = $this->find('first', array('conditions' => array('Page.id' => $id), 'recursive' => -1));
1142		}
1143		$data['Page']['name'] .= '_copy';
1144		$data['Page']['title'] .= '_copy';
1145		if(!empty($_SESSION['Auth']['User'])) {
1146			$data['Page']['author_id'] = $_SESSION['Auth']['User']['id'];
1147		}
1148		$data['Page']['sort'] = $this->getMax('sort')+1;
1149		$data['Page']['status'] = false;
1150		$data['Page']['url'] = $this->getPageUrl($data);
1151		unset($data['Page']['id']);
1152		unset($data['Page']['created']);
1153		unset($data['Page']['modified']);
1154		
1155		$this->create($data);
1156		$result = $this->save();
1157		if($result) {
1158			return $result;
1159		} else {
1160			if(isset($this->validationErrors['name']) && $this->validationErrors['name'] != 'ページ名は50文字以内で入力してください。') {
1161				return $this->copy(null, $data);
1162			} else {
1163				return false;
1164			}
1165		}
1166		
1167	}
1168	
1169}
1170?>