ブログ・エス技研

当ブログは引越しをしました。10秒後に自動で転送しますが、転送されない場合は、http://blog.s-giken.net/ をご覧ください。
ブログ・エス技研 TOP  >  CakePHP 2.x

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
[ --年--月--日 --:-- ] カテゴリ:スポンサー広告 | TB(-) | CM(-)

CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法

CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合」連携先のテーブルの項目をキーとして条件を抽出したい場合の記述方法について書きましたが、今回は、単純にテーブルの項目をキーとするのではなく、その項目に対して何かしらの演算を行ったうえで抽出条件として利用しよう、という場合の方法です。

例えば...
100円のリンゴ 10コ在庫があります。テーブルには、リンゴの単価 100円。在庫 10コ。という項目しか保存されていませんが、在庫が 800円以上の商品を抽出したいという場合などを想定しています。

この場合は、リンゴの単価と在庫数を書けた結果を抽出のキーにできたらいいなぁ、と考えるでしょう。そのやり方についての説明です。


各テーブルの構成などは、テーブルの連携の仕組みについて書いた http://ssgiken.blog.fc2.com/blog-entry-63.html を参照してください。


例えば、「Detail.id」と「Detail3.id」のそれぞれの IDの値を足して、ある一定の数未満のレコードを抽出する場合の記述方法です。
変更したのは 5行目だけです。
実に簡単です。

-----------------/Controllers/DetailsController.php
<?php
class DetailsController extends AppController {
  function index() {
    $datas = $this->Detail->find('all',
      array ( 'conditions' => array ( "( Detail.id + Detail3.id ) <" => 17 ) )
    );
    $this->set('datas', $datas);
  }
}
?>
-----------------

あくまでもこれはサンプルですので、単に四則演算ができる「int()」の項目として IDを例にとっていますが、同一テーブル内の計算もソートキーとしての利用も可能です。

(これまた baserCMSではこの方法が利用できず....)


【Cakephp 2.3・baserCMS テーブルの連携(アソシエーション)関連記事】
baserCMSでオリジナルのデータベースから情報を取得する場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合の詳細ページの注意点
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法
baserCMS ID以外のカラムでアソシエーション(連携)をさせる場合


スポンサーサイト
[ 2013年12月20日 23:11 ] カテゴリ:CakePHP 2.x | TB(0) | CM(0)

CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合

http://ssgiken.blog.fc2.com/blog-entry-63.html でテーブルの連携の仕組みについて書きましたが、連携先のテーブルの項目をキーとして条件を抽出したい場合の記述方法です。

上記のページで説明した内容は、複数のテーブルの連携(テーブルのアソシエーション)を行って、複数のテーブルをまたいでデータを取得する方法を記述しました。

だいたいの場合においては、自分のテーブル内にある項目を条件抽出のキーとして条件抽出をすると思いますが、場合によっては連携先のテーブルにある項目を条件抽出のキーとして条件抽出したい場合も出てくるでしょう。
そんな場合の記述方法です。


結構悩んでいろいろと妙な試行錯誤を行いましたが、分かってしまえば記述方法は簡単です。そして「そりゃそうだな」と思える記述方法です。

テーブルや、Model、Viewなどは上記の説明ページを参考にしてください。


変更する点は Controllerです。

例えば、通常「details.sec_code = "1234"」の値を取得する場合は、「conditions句」を使って下記の様に記述します。

-----------------/Controllers/DetailsController.php
<?php
class DetailsController extends AppController {
  function index() {
    $datas = $this->Detail->find('all',
      array ( 'conditions' => array ( 'Detail.sec_code' => '1234' ) )
    );
    $this->set('datas', $datas);
  }
}
?>
-----------------

そして、連携先のテーブルの項目で抽出したい場合は、5行目の「Detail2.sec_code」を連携先の情報にするだけです。
連携先のテーブル名は、Modelで連携の名前として記述したものを記述し、項目名はそのまま項目名を記述します。
下記の例は、いずれのテーブルも「sec_code」という項目がありますのでわかりにくいですが、「Detail2.name」などと条件を設定しても検索されます。

-----------------/Controllers/DetailsController.php
<?php
class DetailsController extends AppController {
  function index() {
    $datas = $this->Detail->find('all',
      array ( 'conditions' => array ( 'Detail2.sec_code' => '1234' ) )
    );
    $this->set('datas', $datas);
  }
}
?>
-----------------

また、「Detail2」「Detail3」のどちらも検索できますので、「$hasOne」「$belongsTo」のいずれも対応できることが分かります。


何事も分かってしまえば簡単なのですが、今回も結構試行錯誤してしまいましたね。
(ちなみに、baserCMSのプラグインとして試行錯誤をしていましたので、うまく動いていないだけでした。この辺も CakePHPと baserCMSとで動作が違うようですね。)


【Cakephp 2.3・baserCMS テーブルの連携(アソシエーション)関連記事】
baserCMSでオリジナルのデータベースから情報を取得する場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合の詳細ページの注意点
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法
baserCMS ID以外のカラムでアソシエーション(連携)をさせる場合


[ 2013年12月19日 23:05 ] カテゴリ:CakePHP 2.x | TB(0) | CM(0)

CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合の詳細ページの注意点

CakePHPにおいて、Modelで「$primaryKey」を指定すると、個別の詳細ページを表示させる際のキーになるカラムが「$primaryKey」で指定したになりますので注意が必要、という記事になります。


また、下記の ID以外のカラムでテーブルのアソシエーション(テーブルの連携)をさせる場合の説明を下記のページで行いましたが、今回の記事は、下記の記事の続きとして書いています。
CakePHPの場合
 http://ssgiken.blog.fc2.com/blog-entry-63.html
baserCMSの場合
 http://ssgiken.blog.fc2.com/blog-entry-67.html

※baserCMSは、CakePHP上で動いている CMSですので、基本的には CakePHPの仕様に則って動いているのですが、テーブルの連携の部分は若干処理が違うようでした。そのため、別々に記事を書いていますが、今回の処理はどちらでも同じ結果でしたので、記事を分けていません。
また、ソース自体は、CakePHPのものとして書いています。


通常、一覧ページには詳細ページへのリンクがあり、詳細ページへのリンクは「ID」を設定します。

具体的なリンクの記述は以下のようになります。
----------------------
foreach ( $datas as $data ):
   echo ($this->html->link('詳細', array('controller' => 'details', 'action' => 'view', $data['Detail']['id'])));
endforeach;
----------------------

そして、受ける側の処理は、下記の様になります。

----------------------
function view($id) {
  if ($id) {
    $data = $this->Detail->read(null, $id);
    $this->set('data', $data);
  }
}
----------------------

ですが、Modelで「$primaryKey = 'sec_code'」を指定しているため、引数として IDの情報を渡しても何も表示されません。
(この場合だと「id」と「sec_code」が同じレコードは表示されますが。)

なぜなら、Modelで「$primaryKey = 'sec_code'」と指定しているため、すべての処理の PrimaryKeyが「sec_code」になってしまっているからです。

そのため、リンクの設定の部分で下記の様に「id」の部分を「sec_code」に変えることで正しくリンクがされるようになります。
----------------------
   echo ($this->html->link('詳細', array('controller' => 'details', 'action' => 'view', $data['Detail']['sec_code'])));
----------------------



私はこのことには比較的早く気付いたものの、これまで使っていた処理をそのまま使って、エラーが表示されるでもなく、値が取得できないというのは結構焦りますね。
悩む原因の一つになるでしょう。

同じように悩む方の悩みが早く解消されることを祈りつつ...


【Cakephp 2.3・baserCMS テーブルの連携(アソシエーション)関連記事】
baserCMSでオリジナルのデータベースから情報を取得する場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合の詳細ページの注意点
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法
baserCMS ID以外のカラムでアソシエーション(連携)をさせる場合


[ 2013年12月18日 23:02 ] カテゴリ:CakePHP 2.x | TB(0) | CM(0)

CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合

CakePHPで ID以外のカラム同士でテーブルをアソシエーション(連携)させたい場合の方法について書いておきます。


そもそもは baserCMSでプラグインを作っているとき、いずれの項目もユニークではありつつ、IDにはしたくない項目同士を連携させたい、と思ったことがきっかけでした。
ただ、baserCMSのテーブル連携は、CakePHPとは少し仕様が違うようですので、baserCMSで悩んでいる方は、http://ssgiken.blog.fc2.com/blog-entry-67.html を参照してください。
(baserCMSは、CakePHPをベースに作られている CMSですので、本来はプラグインを作る際も CakePHPのルールに則って作っていきます。)


下記の「details.post_id」と「posts.id」の項目を連携させることは、CakePHPのルールに命名規約に則っていますので、「$hasOne」でも「$belongsTo」でもどちらでも簡単に連携させることができます。

ですが、「details.sec_code」と「posts.sec_code」を連携させたい場合にはどうすればいいの?という場合の対応が今回の主題です。


まず、下記 2つのテーブルを生成します。
データは、適当に登録してください。その際、それぞれのテーブルの「sec_code」の項目で連携をさせますので、いくつかのレコードは連携できるよう同じ情報を編集してください。

-----------------テーブル「posts」
CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(8) NOT NULL AUTO_INCREMENT,
  `sec_code` char(4) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
-----------------

-----------------テーブル「details」
CREATE TABLE IF NOT EXISTS `details` (
  `id` int(8) NOT NULL AUTO_INCREMENT,
  `post_id` int(8) NOT NULL,
  `sec_code` char(4) DEFAULT NULL,
  `list` varchar(255) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
-----------------

続いて、Modelの設定です。
今回の件においては、この Modelの設定が一番大事な処理になります。

「$primaryKey」は、「/model/Detail.php」「/model/Post.php」の両方に書いてありますが、「Detail2」の「$belongsTo」で連携させる場合は、連携先の「/model/Post.php」の方に記述します。
「$hasOne」で連携させる場合は、自身の「/model/Detail.php」の中に記述をします。

その動きを確認するために、どちらかの「$primaryKey」の行を消してみると、消した方の変数が表示されなくなりますので、動きの内容が理解できるでしょう。

-----------------(/Model/Detail.php)
<?php
class Detail extends AppModel {

  var $primaryKey = 'sec_code';

  var $belongsTo = array(
    "Detail2" => array(
      "className" => "Post",
      "foreignKey" => "sec_code",
    ),
  );

  var $hasOne = array(
    "Detail3" => array(
      "className" => "Post",
      "foreignKey" => "sec_code",
    ),
  );
}
?>
-----------------

-----------------(/model/Post.php)
<?php
class Post extends AppModel {

  var $primaryKey = 'sec_code';

}
?>
-----------------

続いて、Controllerです。
こちらは、単にテーブルの値を表示させる処理とするため、簡単に記述しています。

-----------------/Controllers/DetailsController.php
<?php
class DetailsController extends AppController {
  function index() {
    $datas = $this->Detail->find('all');
    $this->set('datas', $datas);
  }
}
?>
-----------------

最後に View。
こちらも受け取った値を表示させるだけですので、「print_r」コマンドで簡単に表示しています。

-----------------/Views/Details/index.ctp
<?php
  echo "
\n";
  print_r($datas);
  echo "
\n"; ?>
-----------------


また、今回の記事を書くのに参考にしたのは下記のサイトですが、下記のサイトには Model内に記述する方法の他に、Controllerで記述する方法も書かれています。
http://labo.tsuchinokopro.com/2010/02/287/

※この方法で「$primaryKey = 'sec_code'」を指定すると、個別の詳細ページを表示させる際のキーになるカラムが「sec_code」になりますので注意が必要です。
 詳しくは http://ssgiken.blog.fc2.com/blog-entry-64.html を参照ください。


【Cakephp 2.3・baserCMS テーブルの連携(アソシエーション)関連記事】
baserCMSでオリジナルのデータベースから情報を取得する場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合の詳細ページの注意点
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
CakePHP 2.3 テーブルの項目を演算した結果を条件として抽出する方法
baserCMS ID以外のカラムでアソシエーション(連携)をさせる場合


[ 2013年12月17日 23:58 ] カテゴリ:CakePHP 2.x | TB(0) | CM(0)

CakePHP 2.3で PDFを作成する方法を調査「mpdf」「TCPDF」「FPDF」

CakePHPから PDFを出力する方法を調べてみましたので、そのレポートをお送りします。

CakePHPに限るわけではありませんが、CakePHP2.Xから PDF出力する方法は、「mpdf」「TCPDF」「FPDF」といったいくつかのライブラリがあるようでしたが、「http://cakephpmemo.blogspot.jp/2013/02/cakephppdf.html」この記事を読んで、TCPDFで実装をしてみることにしました。

とはいえ、上記のサイトでは初心者の私では何を言っているのかわからなかったため、実際に参考にしたサイトは、下記のサイトです。

http://prg.pro-mame.com/index.php?php%2F%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%2FCakePHP2.X%2FTCPDF

このサイトを上から順番に確認してそのまま対応していくと、たぶん問題なく PDFの出力について理解できると思います。
フォントを変える方法なども解説されていますので、実運用に向けてもかなりの参考になるでしょう。

また、インスタンスを生成する(クラスに初期値を設定する)際に設定する各項目と、その値は下記の様になっているようです。

PDF_PAGE_ORIENTATION:用紙の向き[P=縦方向、L=横方向] デフォルトはP
PDF_UNIT:処理単位[pt=ポイント、mm=ミリメートル、
     cm=センチメートル、in=インチ] デフォルトはmm
PDF_PAGE_FORMAT :ページフォーマット ( デフォルトは A4 )
※上記は /tcpdf/config/tcpdf_config.php ファイルで定義されています。


また、最初の 2つのサンプルでは、PDFの情報として、「Cell」「text」でテキストの位置と情報を与えています。
いずれも、最初の数値が横軸の座標値を表し、2個目の数字が縦軸の座標を表しています。「Cell」「text」の違いは、「text」が座標の絶対値で設定されるのに対し、「Cell」は相対値(??)で設定されるようです....

--------------
$pdf->Cell(10, 10, '日本語テスト');
$pdf->Cell(30, 30, 'Hello World' );
--------------
--------------
$pdf->text(10, 10, '日本語テスト');
$pdf->text(30, 30, 'Hello World' );
--------------


また、PDFのページデザインに関しては、Cell、textといった方法ではなく、HTMLで情報を渡す方法もあります。
実際は、こちらの HTML形式で整形していく方法を取られるのだと思いますが、実際に PDF出力をさせるページを作るとなると、しっかりした HTML(css)のコーディングが必要になりますので、結構骨が折れるでしょうね。


mpdf
http://d.hatena.ne.jp/okinaka/20111103/1320287622
http://blog.syuhari.jp/archives/1992

また、mpdfで作成する場合は、上記のサイトが参考になるのではないかと思います。

また、TCPDF、FPDFに関しては、下記のページも参考になるかと思います。
http://bakery.cakephp-users.jp/2011/02/05/creating-pdf-files-with-cakephp-and-tcpdf/
[ 2013年10月28日 08:03 ] カテゴリ:CakePHP 2.x | TB(0) | CM(0)
プロフィール

エス技研

Author:エス技研
性別:男性
職業:Web系エンジニア
エンジニアになって 15年ほど経ちますが、その途中で 5年ほどディレクタ、マネジメントを中心とした業務を行っていたためにやや現場を離れていましたが、転職をきっかけに 2012年に現場に復帰し、新たな技術を楽しみながら勉強しています。
メインの環境は LAMP環境です。

FC2ブログランキング
FC2カウンター
FC2拍手ランキング
GoogleAdWords
カレンダー
04 | 2017/05 | 06
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -
検索フォーム
ブロとも申請フォーム
QRコード
QR
フリーエリア


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。