Techracho

cakephp paginator 引数を保った状態でsort

このエントリーをはてなブックマーク Share
2009.06.26    CakePHP, PHP, 渡辺      peter   

小一時間ほどハマったのでメモ程度に。

cakephpでpaginateするために専用helperを使っている方は多いと思います。

適当に他サイトからコピペしても動くことと、コード事態が汚いことが相まって、

細部まであまり見ておりませんでした。

絞り込んだ結果をpaginateやらsortする機会する場合は、

大抵コピペしたコードだは動作しないので

その場合の処置を共有します。

$paginator->options(array(’url’ => $this->passedArgs));

urlできたパラメータを引き継げよ、って指示します。

Windows x64でgemsからrails入れるとき

このエントリーをはてなブックマーク Share
    Ruby, Ruby on Rails, Windows, 馬場      baba   

Railsを入れるために、まずはrubyをインストールして、次にgemsを入れるのですが、
OSが64bitなので、rubyもx64(x64_mswin64 が含まれるファイル名のやつ)にしておきました。

そうすると、gem install rails をやったときにエラーが出ました。
zlib.dllもx64にしないとダメみたいです。
ZLIB DLL Home Pageから for AMD64/Intel EM64T のやつをダウンロードして、gemsのフォルダに上書きしたら、無事インストールできました。

IE7でmarginが消える

このエントリーをはてなブックマーク Share
2009.06.25    CSS, HTML, 馬場   タグ: , —    baba   

たぶん既出ネタですが、ふと見つけたので一応。
IE7で、marginが消える場合があります。

再現条件は、
・paddingが0以外のブロック要素Aに囲まれている
・Aの最初の子要素(空白・TAB・改行以外)がブロック要素Bである
・Bにheightとmarginが指定してある(たぶんhasLayoutがtrueになるならheight以外でも該当)
こんな感じみたいです。

これらを満たすと、Bのmarginが無視されます。
シンプルな再現HTMLは以下の通りです。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>test</title>
</head>
<body>

<div style="padding:1px;">
<div style="margin:100px; height:20px;">こんにちは</div>
<div style="margin:100px; height:20px;">ハロー</div>
</div>

</body>
</html>

これを開くと、IE7以外では「こんにちは」と「ハロー」の左端はそろいますが、IE7では「こんにちは」が左に寄ってしまいます。

解決するには、Bを先頭子要素でなくせばいいので、適当なコメントを入れます。

<div style="padding:1px;">
<!– bugfix for IE7 –>
<div style="margin:60px; height:20px;">こんにちは</div>
<div style="margin:60px; height:20px;">ハロー</div>
</div>

やっぱりIE7は地雷ですね。
自動更新でIE8が入るようになったのがせめてもの救いです。

ネットワークプレイスの件続き

このエントリーをはてなブックマーク Share
2009.06.23    Windows, 馬場   タグ: —    baba   

ネットワークプレイスの件の続きです。

前回紹介した方法でアイコンを正しくしても、たまにショートカットに戻ってしまうようなので、解決を目指します。

「コンピュータ」の「ネットワークの場所」の実体は、
C:\Users\(ユーザ名)\AppData\Roaming\Microsoft\Windows\Network Shortcuts
の中にありました。

ここにあるのはショートカットではありません(「種類」が「ファイル フォルダ」になっている)。
しかし、コマンドプロンプトで dir /all しても表示されないため、ジャンクションやシンボリックリンクでも無いみたいです。何者?

しかし、ここにショートカットやシンボリックリンクを置けば、名前もリンクも正常に動作しました。
シンボリックリンクは、mklink /d で作ります。
アイコンは手動で変えれば良いみたいです(?)。

それにしてもWindowsのファイルシステムは複雑です。

Windowsのネットワークプレイスで謎のバグ

このエントリーをはてなブックマーク Share
2009.06.19    Windows, 馬場   タグ: , —    baba   

Windows Vista以降で(XP以前は知りません)、「コンピュータ」で右クリックして「ネットワークの場所を追加」すると、ネットワークフォルダをドライブ文字を消費せずに割り当てられて、お手軽です。

しかし、その名前をある程度長い(5文字以上くらい)日本語にすると、アイコンがドライブではなくフォルダになり、動作もショートカットになってしまうことがあります(開くとtargetというリンクがあり、それを開くとようやくネットワークフォルダにアクセスできる)。
これでは、見た目も悪いし、毎回1クリック増えるのは我慢できません。

もちろん英語名にしても良いのですが、簡単に直ったので紹介します。

日本語名のフォルダが、ネットワークドライブではなくリンクになってしまう

日本語名のフォルダが、ネットワークドライブではなくリンクになってしまう

3文字くらいまでの短い日本語名にすると、直る

3文字くらいまでの短い日本語名にすると、直る

一度直れば、1~2文字追加しても大丈夫

一度直れば、1~2文字追加しても大丈夫

さらに1文字ずつ追加しても大丈夫

さらに1文字ずつ追加しても大丈夫

さらに1文字追加しても大丈夫

さらに1文字追加しても大丈夫

以上のように、「1文字ずつ追加していく」と、なぜか長い日本語名でも大丈夫です。
また、1文字ずつ入れなくても、「ほげほげほげほげほげ」などは平気だったりしました。

どう考えてもバグなのですが、いったい何でこんなことに??
ネットワークの場所自体は、
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\PublishingWizard\AddNetworkPlace\AddNetPlace\LocationMRU
にあるみたいなんですが、表示名はどこに保存されているのか見つからなかったんですよね。。

他の環境での再現する・しない情報などもらえたら嬉しいです。

【再現環境】
Windows 7 Ultimate 64bit RC1
Windows Vista Ultimate SP2 32bit
サーバ: Windows Server 2008 R2 Standard 64bit RC

Windowsのアクセス権を初期化

このエントリーをはてなブックマーク Share
2009.06.16    Windows, セキュリティ, 馬場   タグ: , —    baba   

Windowsのフォルダアクセス制限は複雑です。

サーバの共有フォルダにユーザごとのフォルダを作成し、それぞれに排他的なアクセス権を与える、という運用はよくあると思います。
その場合、サーバのHDD交換などの事情で全フォルダを丸ごとコピーする場合などに、サーバ管理者でさえもアクセスできないという問題があります。

Linuxならrootで全部アクセスできるのですが、Windowsでは、Administratorsグループでも、アクセス許可を取得していないとアクセスできません。
アクセス許可を取得するには、所有者の操作が必要ですが、管理者権限で一括でやりたいものです。

このような場合、多少強引ですが、所有者を強引に変更してしまいましょう。
以下、Vista / 7 / Server 2008 / Server 2008 R2 などのOSで、管理者権限でログインしている人が、自マシン内のフォルダの所有権を変更する手順です。

プロパティを開く

プロパティを開く

セキュリティタブの詳細設定を開く

セキュリティタブの詳細設定を開く

所有者の編集

所有者の編集

所有者の編集を開く

所有者の編集を開く

所有者の編集

所有者の編集

新しい所有者を入力

新しい所有者を入力

完了

完了

以上の操作で、アクセス権をリセットに近いことができます。
本当はこんなことやらずに運用をしっかりすれば良いのですが・・・

XAMPPのPHPログ出力

このエントリーをはてなブックマーク Share
2009.06.12    PHP, 馬場   タグ: —    baba   

PHPを使ってXML_RPCなどのAPIを作る場合、エラーが画面に表示されないので、単純なタイプミスが原因で長くはまることがあります。
エラーログをきちんと出せば良いのですが、XAMPPのデフォルト設定ではPHPログがオフになっているので、

C:\xampp\php\php.ini
log_errors = On
error_log = “\xampp\apache\logs\phperror.log”

というように、コメントアウトを外してあげましょう。(パスは適宜読み変えて下さい)

当たり前のことですがいつも忘れるので。。

getObjectListの罠

このエントリーをはてなブックマーク Share
2009.06.05    Ethna, PHP, 馬場      baba   

昨日に引き続きEthnaネタです。今回は当たり前のことですが。。

AppManagerのgetObjectListを使う場合に、

$filter = array(’number’ => ‘0123′);

などと、省略記法を使う場合が多いと思います。
デフォルトではstring型はLIKE扱いになるので、

WHERE number LIKE ‘%0123%’

というSQLが生成されてしまいます。これでは、郵便番号や会員番号などで検索する場合などに困ります。

もちろん、

$filter = array(’number’ => new Ethna_AppSearchObject(’0123′, OBJECT_CONDITION_EQ);

とすれば良いのですが、たぶんEQの方がよく使うので、めんどくさいです。

なので、getObjectListをオーバーライドして、省略時はEQになるようにしました。

function getObjectList($class, $filter=null, $order=null, $offset=null, $count=null)
{
if (is_array($filter)) {
foreach ($filter as $key => $value) {
if (is_string($value)) {
$filter[$key] = new Ethna_AppSearchObject($value, OBJECT_CONDITION_EQ);
}
}
}
return parent::getObjectList($class, $filter, $order, $offset, $count);
}

AppObjectのupdateを改良

このエントリーをはてなブックマーク Share
2009.06.04    Ethna, PHP, 馬場      baba   

EthnaのAppObjectネタです。

add()したあと、auto_incrementで決定されたIDに応じて会員番号を生成する、といったときに、AppObjectのadd()をオーバーライドして、

class Appid_UserAppObject extends Appid_AppObject
{
//オーバーライド
function add()
{
parent::add();

//会員番号numberは、t+6桁の連番とする
$this->set(’number’, sprintf(’t%06d’, $this->get(’id’)));
$this->update();
}
}

としたいものですが、これだとupdateの時にSQLエラーが出ることがあります。
このエラーは、プロパティにNULLが含まれているときに、中途半端なSQLが生成されているのが原因です。

これに対処するには、Appid_AppObjectで、以下の関数をオーバーライドします。

/**
* オブジェクトプロパティを更新するSQL文を構築する
*
* @access private
* @return オブジェクトプロパティを更新するためのUPDATE文
*/
function _getSQL_Update()
{
$tables = implode(’,',
$this->my_db_rw->quoteIdentifier(array_keys($this->table_def)));

// SET句構築
$set_list = “”;
$prop_arg_list = $this->prop;
Ethna_AppSQL::escapeSQL($prop_arg_list, $this->my_db_type);
foreach ($this->prop_def as $k => $v) {
//この下のif文を追加
if (isset($prop_arg_list[$k]) && $prop_arg_list[$k] !== null && $prop_arg_list[$k] !== ”) {
if ($set_list != “”) {
$set_list .= “,”;
}
$set_list .= sprintf(”%s=%s”,
$this->my_db_rw->quoteIdentifier($k),
$prop_arg_list[$k]);
}
}

// 検索条件(primary key)
$condition = null;
foreach (to_array($this->id_def) as $k) {
if (is_null($condition)) {
$condition = “WHERE “;
} else {
$condition .= ” AND “;
}
$v = $this->prop_backup[$k]; // equals to $this->id
Ethna_AppSQL::escapeSQL($v, $this->my_db_type);
$condition .= Ethna_AppSQL::getCondition(
$this->my_db_rw->quoteIdentifier($k), $v);
}

$sql = “UPDATE $tables SET $set_list $condition”;

return $sql;
}

UPDATE文を生成するときに、値がセットされていないものをSETしないようにif文を追加しただけです。

COPYRIGHT [C] 2009 BEYOND PERSPECTIVE SOLUTIONS LTD. ALL RIGHTS RESERVED.