//コントローラクラス内の処理 $errors = $this->TestHasManyA->validationErrors;$errorsはバリデーション情報。
if(empty($this->Animal)){ App::uses('Animal','Model'); $this->Animal=ClassRegistry::init('Animal'); //$this->Animal=new Animal(); } //SELECT情報 $fields=array( 'id', 'xxx', 'name', ); //WHERE情報 $conditions=array( "id = {$id}", "xxx = '{$xxx}'", "delete_flg = 0", ); //ORDER情報 $order=array('sort'); //オプション $option=array( 'fields'=>$fields, 'conditions'=>$conditions, 'order'=>$order, 'recursive' => -1, ); //DBから取得 $data=$this->Animal->find('all',$option); //2次元配列に構造変換する。 if(!empty($data)){ $data=Hash::extract($data, '{n}.Animal'); } return $data;
if(empty($this->Animal)){ App::uses('Animal','Model'); $this->Animal=new Animal(); } //SELECT情報 $fields=array( 'Animal.id', 'Animal.xxx', 'Animal.name', 'Food.name', ); //WHERE情報 $conditions=array( "Animal.xxx = '{$xxx}'", "Animal.name like '%{$name}%'", ); //ORDER情報 $order=array('Animal.sort'); //JOIN情報 $joins = array( array( 'type' => 'left',//innerも指定可能 'table' => 'foods', 'alias' => 'Food', 'conditions' => array( 'Animal.food_id = Food.id', ), ), //他に連結するテーブルがあれば上記のような配列を連結 ); //オプション $option=array( 'fields'=>$fields, 'conditions'=>$conditions, 'joins'=>$joins, 'order'=>$order, 'recursive' => -1, ); //DBから取得 $data=$this->Animal->find('all',$option); //データ構造を変換(2次元配列化) $data2=array(); foreach($data as $i=>$tbl){ foreach($tbl as $ent){ foreach($ent as $key => $v){ $data2[$i][$key]=$v; } } } return $data2; //データを構造変換してエンティティを取得 //$ent=array(); //if(!empty($data)){ // foreach($data as $i=>$tbl){ // foreach($tbl as $key=>$v){ // $ent[$key]=$v; // } // } //} //return $ent;
//DBからエンティティを取得 $ent = $this->find('first', array( 'conditions' => "id={$ent['Neko']['id']}" )); $ent=$ent['Neko'];
//SELECT情報 $fields=array( 'id', 'xxx', 'name', ); //WHERE情報 $conditions=array( "id = {$id}", "xxx = '{$xxx}'", "delete_flg = 0", ); $dbo = $this->Neko->getDataSource(); //オプション $option=array( 'table' => $dbo->fullTableName($this->Neko), 'alias' => 'Neko', 'fields'=>$fields, 'conditions'=>$conditions, ); $sql = $dbo->buildStatement($option,$this->Neko); //$sql → SELECT ... FROM nekos AS Neko WHERE ...
/**
* カテゴリIDに紐づくアニマルリストを取得する
* @param int $category_id カテゴリID
* @return アニマルリスト
*/
public function getAnimalList($category_id){
if(empty($this->Animal)){
App::uses('Animal','Model');
$this->Animal=ClassRegistry::init('Animal');
}
//SELECT情報
$fields=array(
'id',
'animal_name',
);
//WHERE情報
$conditions=array(
"category_id = {$category_id}",
"delete_flg != 1",
);
//ORDER情報
$order=array('animal_name');
//オプション
$option=array(
'fields'=>$fields,
'conditions'=>$conditions,
'order'=>$order,
);
//DBから取得
$data=$this->Animal->find('all',$option);
//構造変換
$list = array();
if(!empty($data)){
$list=Hash::combine($data, '{n}.Animal.id','{n}.Animal.animal_name');
}
return $list;
}
認証状態と未認証状態を判定
認証状態と未認証状態を判定することもできる。特定のメソッドだけ未認証を許可する
特定のアクションだけ未認証を許可する場合、引数に許可するアクション名(メソッド名)を指定する。$this->Auth->allow('test_action');
class NoAuthController extends AppController { public $name = 'NoAuth'; public function beforeFilter() { $this->Auth->allow(); // 認証と未認証の両方に対応したページする。 parent::beforeFilter();//基本クラスのメソッドを呼び出し。 } public function index() { $msg="認証されていません。"; if(!empty($this->Auth->user('id'))){ $msg = "認証中です。"; } $this->set(array('msg'=>$msg)); } }
<a href="users/login">ログイン</a><br> <a href="users/logout">ログアウト</a><br> <br> <?php echo $msg?>
<a href="users/login">ログイン</a> <a href="users/logout">ログアウト</a>
class DemoController extends AppController {
public $name = 'Demo';
public $components=null;//ログイン認証不要
public function index(){
}
}
Controller/NoAuthController.php
class NoAuthController extends AppController { public $name = 'NoAuth'; public function beforeFilter() { $this->Auth->allow(); // 認証と未認証の両方に対応したページする。 parent::beforeFilter();//基本クラスのメソッドを呼び出し。 } public function ajax_auth(){ } // AJAXで呼び出されるアクション public function ajax_auth_test1(){ $this->autoRender = false;//ビュー(ctp)を使わない。 // ★認証状態の確認 if(empty($this->Auth->user('id'))){ return '認証されていません'; } $json_param=$_POST['key1']; return $json_param; } }
View/NoAuth/ajax_auth.ctp
<input type="button" value="test1" onclick="test1()" /> <div id="xxx"></div>
JavaScript
function test1(){ var data={'neko':'ネコ','same':{'hojiro':'ホオジロザメ','shumoku':'シュモクザメ'},'xxx':111}; var json_str = JSON.stringify(data); $.ajax({ type: "POST", url: "/cake_demo/no_auth/ajax_auth_test1", data: "key1="+json_str, cache: false, dataType: "text", success: function(str_json, type) { $("#xxx").html(str_json); }, error: function(xmlHttpRequest, textStatus, errorThrown){ $('#xxx').html(xmlHttpRequest.responseText);//詳細エラーの出力 } }); }
test1ボタンを押した時の出力
認証中のとき{"neko":"ネコ","same":{"hojiro":"ホオジロザメ","shumoku":"シュモクザメ"},"xxx":111}
認証されていません
echo $this->Form->input('animal', array( 'legend' => false, 'type' => 'radio', 'value'=>'usi',//初期選択値 'options' => array('neko'=>'猫','nezumi'=>'ネズミ','usi'=>'牛','tora'=>'虎',) ));value属性を省略したり、nullを指定すると、未選択状態になる。
/** * カテゴリ名をマッピング * データの指定IDに紐づく名称をカテゴリテーブルからとってきて、データにセットする。 * @param $data データ * @return データ */ public function mapping($data){ //引数データの紐づけ情報 $id_key='category_id1'; $name_key='category_name1'; $model_name1="RecCrud1"; //結合先テーブルの紐づけ情報 $id_key2='id'; $name_key2='name'; $model_name2="Category"; // データからIDリストを取得 $ids=array(); foreach($data as $ent){ $id=$ent[$model_name1][$id_key]; if(!empty($ent[$model_name1][$id_key])){ $ids[]=$ent[$model_name1][$id_key]; }elseif($ent[$model_name1][$id_key]===0 || $ent[$model_name1][$id_key]==='0'){ $ids[]=$ent[$model_name1][$id_key]; } } // IDリストから重複するIDリストを削除 $ids=array_unique($ids); if(empty($ids)){ foreach($data as &$ent){ $ent[$model_name1][$name_key]=null; } unset($ent); return $data; } // IN句をIDリストから作成する。 $str_ids=join($ids,','); //元データをDBから取得 $fields=array($id_key2,$name_key2); $conditions=array("id IN ({$str_ids})"); $option=array( 'fields'=>$fields, 'conditions'=>$conditions, 'recursive' => -1, ); $mapData=$this->find('all',$option); //マッピングデータを作成 $map=array(); //マッピングデータを作成。ついでにサニタイズ if(!empty($mapData)){ foreach($mapData as &$map_ent){ $map[$map_ent[$model_name2][$id_key2]]=Sanitize::html($map_ent[$model_name2][$name_key2]); } unset($ent); } // データ件数分ループして、IDに紐づくマッピングのデータをセット foreach($data as &$ent){ if(!empty($map[$ent[$model_name1][$id_key]])){ $ent[$model_name1][$name_key]=$map[$ent[$model_name1][$id_key]]; }else{ $ent[$model_name1][$name_key]=null; } } unset($ent); return $data; }
$str1="→テスト<a href='#' onclick='alert(\"XSS攻撃のテスト\");' > Hello</a>"; echo h($str1);
class AppHelper extends Helper { //オリジナルヘルパーとなるメソッド public function test($v){ $v='大きい'; return $v; } }
echo $this->Html->test('ネコ'); //出力例 → 大きいネコ
class IrukaHelper extends AppHelper {
public function test(){
echo 'イルカ';
}
}
class SampleController extends AppController {
public $helpers = array('Iruka');
~略~
$this->Iruka->test();
//出力例 → イルカ
$this->FrontA = $this->Helpers->load('FrontA');
$this->FrontA->test();
App::uses('Helper', 'View/Helper');
class FrontAHelper extends Helper {
public function test(){
echo 'テストでござい';
}
}
public function uhtml_entity_decode_ex($v){ $v=html_entity_decode($v);//エスケープされた記号を元に戻す。 $v=str_replace('<','<',$v);//「 < 」記号のみサニタイズ $v=nl2br($v);//改行コードをbrタグに変換 return $v; }アスキーアートなど記号をふんだんに使った文字列を表示させたいが、XSS対策は施したいといった場合の時に使うと便利です。
$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
?>
<!DOCTYPE html>
<html>
<head>
<?php echo $this->Html->charset(); ?>
<title>
<?php echo $cakeDescription ?>:
<?php echo $title_for_layout; ?>
</title>
<?php
echo $this->Html->meta('icon');
echo $this->Html->css(array(
'cake.generic', //←これは、bootstrap.min.cssに置き換わる
'http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/ui-lightness/jquery-ui.css'
));
echo $this->fetch('meta');
echo $this->fetch('css');
//echo $this->fetch('script');
echo $this->Html->script(array(
'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js',
));
?>
~ 以下略 ~
修正後 app/View/Layouts/default.ctp$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework'); ?> <!DOCTYPE html> <html> <head> <?php echo $this->Html->charset(); ?> <title> <?php echo $cakeDescription ?>: <?php echo $title_for_layout; ?> </title> <?php echo $this->Html->meta('icon'); echo $this->Html->css(array( 'bootstrap.min.css', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/ui-lightness/jquery-ui.css' )); echo $this->fetch('meta'); echo $this->fetch('css'); //echo $this->fetch('script'); echo $this->Html->script(array( 'jquery-1.11.1.min.js', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js', 'bootstrap.min.js', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js', )); ?> <script> $(function() { $("#datepicker").datepicker({ dateFormat:'yy-mm-dd' }); //2つ目の日付入力用 $("#datepicker2").datepicker({ dateFormat:'yy-mm-dd' }); }); </script> ~ 以下略 ~
$ret=$this->モデル->delete(削除するID);
//モデルクラス内で削除する場合。 $ret=$this->delete(削除するID);
// モデル生成 if(empty($this->TestModel)){ App::uses('TestModel','Model'); $this->TestModel=new TestModel(); } // トランザクション開始 $dataSource = $this->TestModel->getDataSource (); $dataSource->begin(); // ★削除処理 id=10000を削除 $ret=$this->TestModel->delete(10000); if($ret==true){ $dataSource->commit();//コミット }else{ $dataSource->rollback();//ロールバック }
$this->Neko->begin();//トランザクション開始 $this->Neko->deleteAll(array('text1'=>'wani'));//複数行をまとめて削除 $this->Neko->commit();
SELECT `Neko`.`id` FROM `cake_smp`.`nekos` AS `Neko` WHERE `text1` = 'wani' GROUP BY `Neko`.`id` DELETE `Neko` FROM `cake_smp`.`nekos` AS `Neko` WHERE `Neko`.`id` IN (16, 17)
id | val1 | text1 | test_date | test_dt |
---|---|---|---|---|
15 | 3 | yagi | 2014/4/3 | 2014/12/12 0:00 |
18 | 3 | wani | 2014/4/3 | 2014/12/12 0:00 |
19 | 3 | wani | 2014/4/3 | 2014/12/12 0:00 |