cakephpでviewテンプレートをDBに保存する

もうちょい改造して

  • $this->render('db:layout_index');のときだけdbを見に行くようにしたい
  • 先にdbを見に行って該当がなければファイルを参照したい
  • elementsもdb保存したい

改造

  • d4-1977氏のは1.2用で1.3では$this->Html->が動かんかった
  • 1.3のviewをオーバーライドする方法で改造する

app/views/dbtemplate.php

  • とりあえずうごくようにしただけで根本的に理解してない
    • //parent::__construct();
    • //$name = $this->viewPath . DS . $subDir . Inflector::underscore($name);
  • cakephpの動作の仕組みやらオブジェクトの扱い方など勉強しなきゃ
  • eval使ってるのでセキュリティに注意
<?php
class DbtemplateView extends View{
	
	function __construct(&$controller, $register = true) {
		if (is_object($controller)) {
			$count = count($this->__passedVars);
			for ($j = 0; $j < $count; $j++) {
				$var = $this->__passedVars[$j];
				$this->{$var} = $controller->{$var};
			}
		}
		//parent::__construct();
		
		if ($register) {
			ClassRegistry::addObject('view', $this);
		}
		
		$this->subDir    = null;
		$this->ext       = null;    // 拡張子は使わない
		$this->_template = ClassRegistry::init('Template');
		$this->template  = array();
		
	}
	
	
	
	function _getViewFileName($name = null) {
		$subDir = null;
		
		if (!is_null($this->subDir)) {
			$subDir = $this->subDir . DS;
		}
		
		if ($name === null) {
			$name = $this->action;
		}
		$name = str_replace('/', DS, $name);
		$template = $this->__read_template($name);
		
		if (strpos($name, DS) === false && $name[0] !== '.') {
			//$name = $this->viewPath . DS . $subDir . Inflector::underscore($name);
		} elseif (strpos($name, DS) !== false) {
			if ($name{0} === DS || $name{1} === ':') {
				if (is_file($name)) {
					return $name;
				}
				$name = trim($name, DS);
			} else if ($name[0] === '.') {
				$name = substr($name, 3);
			} else {
				$name = $this->viewPath . DS . $subDir . $name;
			}
		}
		$paths = $this->_paths(Inflector::underscore($this->plugin));
		
		$exts = array($this->ext);
		if ($this->ext !== '.ctp') {
			array_push($exts, '.ctp');
		}
		
		if($template !== false){
			return $name;
		}
		
		/*
		foreach ($exts as $ext) {
			foreach ($paths as $path) {
				if (file_exists($path . $name . $ext)) {
					return $path . $name . $ext;
				}
			}
		}
		*/
		
		$defaultPath = $paths[0];
		
		if ($this->plugin) {
			$pluginPaths = App::path('plugins');
			foreach ($paths as $path) {
				if (strpos($path, $pluginPaths[0]) === 0) {
					$defaultPath = $path;
					break;
				}
			}
		}
		//return $this->_missingView($defaultPath . $name . $this->ext, 'missingView');
		return $this->_missingView($name, 'missingView');
	}
	
	
	function _getLayoutFileName($name = null) {
		if ($name === null) {
			$name = $this->layout;
		}
		$subDir = null;
		
		if (!is_null($this->layoutPath)) {
			$subDir = $this->layoutPath . DS;
		}
		$paths = $this->_paths(Inflector::underscore($this->plugin));
		//$file = 'layouts' . DS . $subDir . $name;
		$name = str_replace('/', DS, $name);
		$template = $this->__read_template($name);
		
		$exts = array($this->ext);
		if ($this->ext !== '.ctp') {
			array_push($exts, '.ctp');
		}
		
		if($template !== false){
			return $name;
		}
		
		/*
		foreach ($exts as $ext) {
			foreach ($paths as $path) {
				if (file_exists($path . $file . $ext)) {
					return $path . $file . $ext;
				}
			}
		}
		return $this->_missingView($paths[0] . $file . $this->ext, 'missingLayout');
		*/
		return $this->_missingView($name, 'missingLayout');
		
	}
	
	
	function __read_template($name){
		if(!array_key_exists($name, $this->template)){
			$template = $this->_template->findByName($name);
			if(!$template){
				return false;
			}else{
				$this->template[$name] = $template;
			}
		}
		return $this->template[$name];
	}
	
	

	function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = false) {
		$loadedHelpers = array();
		
		if ($this->helpers != false && $loadHelpers === true) {
			$loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
			$helpers = array_keys($loadedHelpers);
			$helperNames = array_map(array('Inflector', 'variable'), $helpers);
			
			for ($i = count($helpers) - 1; $i >= 0; $i--) {
				$name = $helperNames[$i];
				$helper =& $loadedHelpers[$helpers[$i]];
				
				if (!isset($___dataForView[$name])) {
					${$name} =& $helper;
				}
				$this->loaded[$helperNames[$i]] =& $helper;
				$this->{$helpers[$i]} =& $helper;
			}
			$this->_triggerHelpers('beforeRender');
			unset($name, $loadedHelpers, $helpers, $i, $helperNames, $helper);
		}
		
		$__dbtemplate = $this->__read_template($___viewFn);
		extract($___dataForView, EXTR_SKIP);
		ob_start();
		
		eval('?>' . $__dbtemplate['Template']['data'] . '<?');
		/*
		if (Configure::read() > 0) {
			include ($___viewFn);
		} else {
			@include ($___viewFn);
		}
		*/
		if ($loadHelpers === true) {
			$this->_triggerHelpers('afterRender');
		}
		
		$out = ob_get_clean();
		$caching = (
			isset($this->loaded['cache']) &&
			(($this->cacheAction != false)) && (Configure::read('Cache.check') === true)
		);
		
		if ($caching) {
			if (is_a($this->loaded['cache'], 'CacheHelper')) {
				$cache =& $this->loaded['cache'];
				$cache->base = $this->base;
				$cache->here = $this->here;
				$cache->helpers = $this->helpers;
				$cache->action = $this->action;
				$cache->controllerName = $this->name;
				$cache->layout = $this->layout;
				$cache->cacheAction = $this->cacheAction;
				$cache->cache($___viewFn, $out, $cached);
			}
		}
		return $out;
	}
	
	
}
?>

コントローラーは

<?php
class LayoutsController extends AppController {
	
	var $name = 'Layouts';
	
	var $scaffold = 'dev';
	
	var $helpers = array('Html', 'Form');
	
	var $layout  = 'default';
	
	var $view = 'dbtemplate';
	
	
	function index(){
		$this->pageTitle = 'DBからのテンプレートテスト';
		$this->set('content', 'DBからのテンプレートテスト');
		$this->render('layout_index') ;
	}
	
	
	
	
}
?>

SQL

CREATE TABLE `templates` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `data` text NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

--
-- テーブルのデータをダンプしています `templates`
--

INSERT INTO `templates` VALUES(2, 'layout_index', '<?php echo $content ?>\r\n', '2011-01-26 14:47:00', '2011-03-31 16:51:20');
INSERT INTO `templates` VALUES(1, 'default', '<html xmlns="http://www.w3.org/1999/xhtml">\r\n<head>\r\n	<?php echo $this->Html->charset(); ?>\r\n	<title>\r\n		<?php echo $title_for_layout; ?>\r\n	</title>\r\n</head>\r\n<body>\r\n			<?php echo $content_for_layout; ?>\r\n</body>\r\n</html>', '2011-01-01 00:00:00', '2011-03-31 17:44:13');