CakePHPで論理削除

6 月 20th, 2008

app_model.phpでModelクラスをオーバーライドする。

これで、del()を呼び出すだけで、論理削除されるようになる。子テーブルなどのデータも全て論理削除される。

ただし、ある部分は論理削除、ある部分は物理削除、のような場合、別の対応を取る必要がある。

コードは以下の通り

	function del($id = null, $cascade = true) {
		if (!empty($id)) {
			$this->id = $id;
		}
		$id = $this->id;

		if ($this->exists() && $this->beforeDelete($cascade)) {
			$db =& ConnectionManager::getDataSource($this->useDbConfig);

			if (!empty($this->behaviors)) {
				$behaviors = array_keys($this->behaviors);
				$ct = count($behaviors);
				for ($i = 0; $i < $ct; $i++) {
					if ($this->behaviors[$behaviors[$i]]->beforeDelete($this, $cascade) === false) {
						return false;
					}
				}
			}
			$this->_deleteDependent($id, $cascade);
			$this->_deleteLinks($id);
			$this->id = $id;

			if (!empty($this->belongsTo)) {
				$keys = $this->find('first', array('fields', $this->__collectForeignKeys()));
			}

			$this->saveField('deleted', date('Y-m-d H:i:s'));
			$this->saveField('deletedby', $this->delUser);
			return true;

			//if ($db->delete($this)) {
			//	if (!empty($this->belongsTo)) {
			//		$this->updateCounterCache($keys[$this->alias]);
			//	}
			//	if (!empty($this->behaviors)) {
			//		for ($i = 0; $i < $ct; $i++) {
			//			$this->behaviors[$behaviors[$i]]->afterDelete($this);
			//		}
			//	}
			//	$this->afterDelete();
			//	$this->_clearCache();
			//	$this->id = false;
			//	$this->__exists = null;
			//	return true;
			//}
		}
		return false;
	}

あとはcontroller内で


	$this->ParentModel->delUser = $delUser;
	$this->ParentModel->ChildModel->delUser = $delUser;
	if ($this->ParentModel->del($id)) {

のようにdelUserをセットして、普通にdel()を呼び出せばいい。

なお、対象テーブルにはdeletedとdeletedbyカラムを用意する必要がある。

ここはdel_flgやdelete_flgなどを用意して、それに対応したソースに修正しても良いと思う。

CakePHPのバージョンは、1.2.0.6311 betaです。


CakePHPでMySQLのログを出力する

5 月 18th, 2008

/app/models/datasources/dbo/dbo_mysql_log.php

を作成。内容は以下


<?php
uses ('model' . DS . 'datasources' . DS . 'dbo' . DS . 'dbo_mysql');
 
class DboMysqlLog extends DboMysql {
 function showLog($sorted = false) {
  if ($sorted) {
   $log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
  } else {
   $log = $this->_queriesLog;
  }

  if ($this->_queriesCnt > 1) {
   $text = 'queries';
  } else {
   $text = 'query';
  }

  if (LOG_SQL) {   
   foreach($log as $k => $i) {
    $this->log(($k + 1) . ". (affected:{$i['affected']}|rows:{$i['numRows']}) {$i['query']}", LOG_DEBUG);
    if ($i['error']) $this->log("   [ERROR] {$i['error']}", LOG_DEBUG);
   }
   $this->log("{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms", LOG_DEBUG);
   //$this->log('', LOG_DEBUG);
  //} elseif (php_sapi_name() != 'cli') {
  }

  if (php_sapi_name() != 'cli') {
   print ("<table class=\"cake-sql-log\" id=\"cakeSqlLog_" . preg_replace('/[^A-Za-z0-9_]/', '_', uniqid(time(), true)) . "\" summary=\"Cake SQL Log\" cellspacing=\"0\" border = \"0\">\n<caption>{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms</caption>\n");
   print ("<thead>\n<tr><th>Nr</th><th>Query</th><th>Error</th><th>Affected</th><th>Num. rows</th><th>Took (ms)</th></tr>\n</thead>\n<tbody>\n");

   foreach ($log as $k => $i) {
    print ("<tr><td>" . ($k + 1) . "</td><td>" . h($i['query']) . "</td><td>{$i['error']}</td><td style = \"text-align: right\">{$i['affected']}</td><td style = \"text-align: right\">{$i['numRows']}</td><td style = \"text-align: right\">{$i['took']}</td></tr>\n");
   }
   print ("</tbody></table>\n");
  } else {
   foreach ($log as $k => $i) {
    print (($k + 1) . ". {$i['query']} {$i['error']}\n");
   }
  }
 }

}
?>

/app/config/core.phpに以下を追加


define('LOG_SQL', true);

で、

/app/tmp/logs/debug.log

にログが出力されます。

https://trac.cakephp.org/ticket/2166

http://openpaste.org/en/6181/

http://www.1×1.jp/blog/2007/04/cakephp_sql_log.html

を参考にさせて頂きました。ありがとうございます。

CakePHPにアクセスしても真っ白になる。。。

5 月 15th, 2008

PHP Fatal error:  Class ‘Configure’ not found in /home/www/***/app/config/core.php

httpd.conf

AllowOverride All
で解決。。。半日悩んだ。。。

isAuthorizedのaction

5 月 14th, 2008

isAuthorized($user, $controller, $action)

で$actionは
read
create
del
update
みたい。

cssの変更のみでtable表示のように

5 月 10th, 2008

以下のようにcssを変更すると

labelが左、入力フィールドが右に来て、table表示のようになります。

$ svn diff cake.generic.css
Index: cake.generic.css
===================================================================
— cake.generic.css (revision 10)
+++ cake.generic.css (working copy)
@@ -241,12 +241,23 @@
clear: left;
margin: 0 20px;
}
+/*
form div {
clear: both;
margin-bottom: 1em;
padding: .5em;
vertical-align: text-top;
}
+ */
+form div {
+ clear: left;
+ display: block;
+ width: 600px;
+ zoom: 1;
+ margin: 5px 0 0 0;
+ padding: 1px 3px;
+}
+
form div.input {
color: #444;
}
@@ -265,6 +276,16 @@
font-size: 110%;
padding-right: 20px;
}
+form div label {
+ display: block;
+ float: left;
+ width: 130px;
+ padding: 3px 5px;
+ margin: 0 0 5px 0;
+ text-align: right;
+}
+
+/*
input, textarea {
clear: both;
display: block;
@@ -272,7 +293,9 @@
font-family: “frutiger linotype”, “lucida grande”, “verdana”, sans-serif
;
padding: 2px;
/* width: 100%; */
+/*
}
+*/
select {
clear: both;
font-size: 120%;