• PATH_INFOを取得してhiddenに代入

    URLにパラメータをくっつけて、GETで送信する場合、

    http://www.example.com/?param0=aaa&param1=bbb
    

    という感じで渡して、受け取るときは

    $param0 = $_GET['param0'];
    $param1 = $_GET['param1'];
    

    または

    $param0 = $_REQUEST['param0'];
    $param1 = $_REQUEST['param1'];
    

    というようにするのが一般的ですが、以下のように、

    http://www.example.com/aaa/bbb/
    

    で値を渡して、受け取りは

    $param = split("[/\.]", $_SERVER["PATH_INFO"]);
    

    とすると、$param[0] に「aaa」が、$param[1] に「bbb」が代入されます。

    さて、これを WordPress でやろうとすると、「aaa」とか「bbb」をURLとして処理しようとしてしまい、当然パーマリンクや実体があるわけではないので、表示できません(実体があればそちらを表示しちゃう)。

    WordPress では PATH_INFO を使わない方がよさそうなのですが、使わざるを得ない場合、WordPress とは関係なく、一旦 PATH_INFO を受けるプログラムを作成し、そこから何かしらの方法で WordPress にパラメータを渡すようにします。

    受け方は上記の通りなので、あとは渡し方になるのですが、手軽なのは GET でリダイレクトする方法でしょう。

    $url = "遷移先URL?param0=" . $param0 . "&param1=" . $param1;
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: " . $url );
    

    GETではURLにパラメータが見えるということであれば、セッションを使う方法もある。

    ...
  • wp_insert_attachment() で新規 insert

    wp_insert_attachment() のリファレンスには、

    wp_insert_attachment( $attachment, $filename, $parent_post_id );
    

    と書かれており、$parent_post_id を指定する必要があります。つまり、事前に posts テーブルに何らか insert して、そのレコードの post_id を指定することとなります。

    でも、新規で画像情報を登録したくて、でも紐づく投稿がまだ無い場合、post_id が無いわけで、どうするべきか調べてみました。

    WPのソースを追ってみて、実際に試してみたところ、

    wp_insert_attachment( $attachment, $filename, 0 );
    

    というように、$parent_post_id = 0 とすることで、新規で insert されます。

    ちなみに、$attachment には、

    $wp_filetype = wp_check_filetype(basename($filename), null );
    $wp_upload_dir = wp_upload_dir();
    $attachment = array(
         'guid'  => $wp_upload_dir['url'] . '/' . basename( $filename ), 
         'post_mime_type' => $wp_filetype['type'],
         'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
         'post_content' => '',
         'post_status' => 'inherit'
    );
    

    という感じで事前にアップロードしておいた画像の画像情報を入れてやればOK。

    ...
  • スクリプトで WordPress の DB にアクセスしたい

    WordPress の DB にスクリプトからアクセスしたい場合、単純に MySQL にアクセスして処理すればいいのですが、何らかの理由で WordPress の関数を使いたい場合(画像の投稿をスクリプトで行う等)は、

    require_once('wp-blog-header.php');
    

    でOKなのですが、一部のメソッドは直接そのメソッドが記述されたソースをインクルードする必要があります。

    例えば、カテゴリ登録するための wp_insert_category() を使いたい場合、

    require_once('/wp-admin/includes/taxonomy.php');
    

    とする必要があります。/wp-admin/includes/にクラスがあるので必要なものを探しだして、インクルードします。

    また、wp-blog-header.phpをインクルードするということは、例えば、HTTPSで必ずアクセスさせたり、ログインユーザのみに見せるといったようなWebの制限をfunction.phpなどに入れて、サイト全体に制限かけた場合、影響を受けます。

    そこで、そういった制限を入れた場合は、その制限処理に、

    if ( ! preg_match( '/^(script.php|hogehoge.*.php)/', basename( $_SERVER['SCRIPT_NAME'] ) ) ){
     // 制限処理
    }
    

    のように除外したいスクリプト名(上記の場合、「script.php」か「hogehoge.*.php」にマッチするスクリプト)を指定して、処理から除外する必要があります。

    これをしない場合、スクリプトを実行すると、制限に引っかかり、処理が止まります。

    ...
  • 複数ファイルのアーカイブをダウンロードさせる時の方法

    例えば、複数個の画像ファイルをまとめてダウンロードさせたりする場合、サーバ上でテンポラリディレクトリに画像ファイルをコピーして、それらをアーカイブしてダウンロードさせたりします。 しかし、これだと画像ファイルをいちいちコピーすることになるので、ストレージを圧迫する可能性があるし、ファイル数が多いとコピーに時間がかかります。

    そこで、シンボリックリンクを作成し、そのディレクトリ毎アーカイブすることにします。

    まず、テンポラリディレクトリを作成します。

    $tmp_path = "/tmp/" . uniqid(rand());
    $archive_dir = "(指定したいディレクトリ名)";
    $tmp_dir = $tmp_path . "/" . $archive_dir;
    

    テンポラリディレクトリまでのパスと、テンポラリディレクトリ名を分けている理由は後述。

    次に、作成したテンポラリディレクトリに、画像ファイルのシンボリックリンクを作成します。

    // $filelists:画像ファイル名のリスト
    // $$image_dir:画像ファイルの格納ディレクトリ
    foreach( $filelists as $image_name ) :
        $target = $image_dir . "/" . $img_name;
        $link   = $tmp_dir . "/" . $img_name;
        symlink($target, $link);
    }
    

    あとは、このテンポラリディレクトリごとアーカイブします。特に画像ファイルの場合、圧縮してもサイズは余り変わらないので、tar でアーカイブすれば、圧縮処理が無い分、処理が早いです。 tarコマンドのオプションで「h」をつけることで、シンボリックリンクを実体としてアーカイブできます。これがキモですね。

    // アーカイブファイルパスを設定
    $tar_file = tempnam("/tmp", "DOWNLOAD");
    
    // tarコマンドでアーカイブ
    $command  = "tar chf $tar_file -C $tmp_path $archive_dir"; 
    system( $command );
    

    この時、tarコマンドのオプションで「-C」をつける。これで、指定したディレクトリに移動してから処理します。 こうすることで、テンポラリディレクトリのフルパスでアーカイブされずに済みます。

    ...
  • パスワード管理アプリ(Android版)

    パスワードは使い回してはいけない。パスワードは一定の文字数以上でなければならない。パスワードは定期的に変更しなければならない…そんなの覚えるの無理でしょ!

    というわけで、社内向けに作成したパスワード管理アプリを公開します。

    既に山ほどのパスワード管理アプリがgoogle playで絶賛公開中ですが、それらのアプリを採用しなかった理由は

    • (社内用としては)不要な権限を要求するアプリが多い
    • 必要な機能がない
    • マルウェアをつかんでしまう可能性がある

    といったためです。

    今回作成したアプリの特徴は

    • ランダムパスワード自動生成機能搭載
    • 要求する権限はSDカード読み書きのみ(バックアップのため)
    • 2ヶ月以上更新していないパスワードを警告
    • 充実したソート機能
    • マッシュルーム対応
    • マッシュルーム対応していないIME向けに、クリップボードコピーも対応
    • Android 4系のカッコイイUIを2.2以上にご提供
    • マルウェアではない(自己申告になりますが…)

    ぜひお試し下さい。

    インストール方法:

    1. [設定] > [アプリケーション] > [不明な提供元]チェックボックスをON
    2. 以下のリンクをクリックしてapkをダウンロード
    3. インストールする

    PassBox ver 0.9.5

    ...
  • jQuery 1.9 で変更された仕様によって動かなくなるプラグインが多い

    code { padding: 2px; background-color: #f4f4f4; color: #7f0055; font-weight: bold; border: solid 1px #ddd; } blockquote { margin-left: 1em; font-size: 12px; line-height: 17px; background-color: #fdfdfd; border: solid 1px #ccc; padding: 4px; font-style: normal; }

    現在開発しているあるシステムで、最新のjQuery 1.9.1を導入して開発を行っていたところ、先月開発していたシステムでは動いていて、同じように実装したはずなのに動かないjQueryプラグインがあってハマりました。それがWordPressのコアに同梱されている「thickbox」でして、管理パネルでは動いて、テーマ側で動かないのは何故だろうと思って調べてみたところ、読み込んでいるコアのjQueryが1.8系と1.9系と差があった。もしや・・・と思って、jQuery 1.9系の仕様変更内容を調べてみたら、おっと、今までかなり重宝していたメソッドがなくなっているではありませんか。
    将来的に削除されることは知っていたけど、使い勝手が良くて使っていた$.browser()と、何気に動的に生成されたDOMオブジェクトに対して適応性が低い$.bind()より汎用的に使えるため重宝していた$.live()などが削除されてしまったため、これらのメソッドを使っているjQueryプラグインではエラーが発生してしまうようになってしまいました。
    ・・・と言うことで、jQuery 1.9系での主な仕様変更をまとめてみた。

    1. $.browser()が廃止1.3からサポート外に指定されてましたが、ついにメソッドが削除されてしまった・・・何気にお手軽にブラウザ判定できるので使い勝手良かったんだが・・・致し方ないですね。これからは、$.support()を使って判定式を組まないといかんです。

    2. $.live()が廃止

      $.bind()の拡張版メソッドで、bindはjQueryやJavaScriptで動的に生成されたオブジェクトに対して処理をバインドできなかったのを可能にするメソッド。これも使い勝手が良くて重宝していたのだが・・・廃止されてしまった。今後は$.on()$.off()を使えってことです。まぁ、バインドイベントのオン・オフを判り易く制御できるのでこちらの方が確かにスマートだ。

    3. $.die()が廃止

      上記live関数を削除するメソッドです。liveがなければこちらも不要ということですね。

    4. $.sub()が廃止

      プロパティとメソッドが自由に変更可能なコアjQueryオブジェクトのコピーを作成するメソッドです。プラグイン開発などで、コアを変更せずに、独自にjQueryコアを拡張する時などに使われていましたが、結構巨大なjQueryコア自体をコピーしてメモリ食いまくってまで作るプラグインもないだろう・・・という判断があったのかも。まぁ、プラグイン開発者以外にはあまり使わないメソッドだし、1.8系からこのメソッド自体がプラグイン化されたらしいので、廃止によるインパクトは低いかな。

    5. $.toggle(fn1(),fn2(),[...fnN()])の廃止

      1.7系で非推奨化されてたメソッドです。指定のオブジェクトがクリックされる毎にfn1、fn2、・・・fnNと関数を実行して、fnN以降はfn1に戻るみたいな処理が書けるメソッドでした。まぁ、クリック毎にそこまで処理変えなきゃいかんUIってどうよ?って感じなので、廃止は妥当かな・・・と。あ、ちなみに、関数バインド型ではないイベントエフェクト型の$.toggle()は廃止されていません。

    6. 他に記述順や処理内容が変更されたメソッド

      $.add()$.before()$.after()$.addSelf()などなど細かいところが色々と変わっているようです。

    ...
  • AndroidのLogCatのTagにクラス名、メソッド名、行番号を表示するクラス

    たとえデバッカがあってステップ実行が出来ようとも、デバックログの手軽さは手放せません。Androidの場合、標準のLogクラスを使えば、その目的を達成できるのですが、できたらTagに、クラス名、メソッド名、行番号が出たら嬉しいと思う人が多いはず!

    と思ってぐぐってみたら、実現している方がいました。

    [

    AndroidのLogCatのTagで「クラス名.メソッド名:行番号」と表示するには?

    ](http://kinsentansa.blogspot.jp/2012/06/androidlogcattag.html)

    せっかくなんで、これを即使えるようにクラス化してみました。

    [code lang=“java” light=“true”] package jp.fuga.hoge.android.app;

    import java.util.regex.Pattern; import jp.fuga.hoge.android.app.BuildConfig; import android.util.Log;

    /** * ログ出力クラス。
    * ログを出力する場合には必ず本クラスを使用すること。
    * リリース時には、デバックログを出力しないよう設定される。 * */ public class L {

    /**
     * デバック用ログを出力する。 本番リリース時は出力されない。
     * 
     * @param msg 出力するメッセージ
     */
    public static void d(String msg) {
        if (!BuildConfig.DEBUG) return;
        Log.d(getTag(), msg);
    }
    
    /**
     * エラー用ログを出力する。 <br>
     * catchの中や想定外の動作でログを出力する場合に使用すること。<br>
     * 本番リリース時も、起きたエラーを解析するために本ログは出力される想定。
     * 
     * @param msg 出力するメッセージ
     */
    public static void e(String msg) {
        Log.e(getTag(), msg);
    }
    
    /**
     * 同上
     * 
     * @param msg
     * @param t
     */
    public static void e(String msg, Throwable t) {
        Log.e(getTag(), msg, t);
    }
    
    /**
     * タグを生成する
     * 
     * @return className#methodName:line
     */
    private static String getTag() {
    
        final StackTraceElement trace = Thread.currentThread().getStackTrace()[4];
        final String cla = trace.getClassName();
        Pattern pattern = Pattern.compile("[\\.]+");
        final String[] splitedStr = pattern.split(cla);
        final String simpleClass = splitedStr[splitedStr.length - 1];
    
        final String mthd = trace.getMethodName();
        final int line = trace.getLineNumber();
        final String tag = simpleClass + "#" + mthd + ":" + line;
    
        return tag;
    }
    

    }

    ...
  • Android(java)で電話番号にいい感じに'-'(ハイフン)を入れる方法

    電話番号って

    [市外局番] - [市内局番] - [顧客番号]

    みたいにハイフン2つで番号を区切る構造になっていますが

    0312345678

    みたいな、ハイフンが入っていない番号にハイフンを入れようと思うと、これが案外難しいです。

    市外局番は、2桁の時もあれば、3桁、4桁の時もあるし、携帯は3桁だし、ちょっと自分でなんとかするのは手に余ります。

    ウィキペディアの市外局番の項

    こんな時は長いものにまかれましょう、という事で信頼できそうなとこが提供しているライブラリを活用です。
    本家googleがライブラリを出してました。

    libphonenumber

    トップページ

    ダウンロード

    基本的には一番新しいものをダウンロードして、Android projectのlibsに放りこめば準備完了です。

    ※apkを作る時にエクスポートするライブラリにチェックを付けるのをお忘れなく。

    使い方は極めて簡単。

    [code lang=“java” light=“true”] /** * 数字が羅列された電話番号をハイフン付きの電話番号に変換する * @param incomingNumber * @return ハイフン付き電話番号 */ private String getFormattedPhoneNumber(String incomingNumber) { PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); try { PhoneNumber pn = phoneUtil.parse(incomingNumber, “JP”); incomingNumber = phoneUtil.format(pn, PhoneNumberFormat.NATIONAL); } catch (NumberParseException e) { Log.e(“app tag”,“電話番号をフォーマットできませんでした”, e); } return incomingNumber; }[/code]

    ...
  • iframeから新規ウィンドウを開いてリンクできない時の対処法

    完全な備忘録です。<br /> インラインフレーム内に読み込んだHTMLから新しいウィンドウにリンクを開きたい時、Aタグのtarget="_blank"やjQueryMobileのrel="external"、果てはJavaScriptのwindow.open()を使っても出来ない状態に陥った時は、IFRAME内の属性にsandbox="allow-scripts"がないかを疑ってみましょう。
    HTML5で追加されたIFRAMEタグの新属性「sandbox」で「allow-scripts」を指定してしまうと、インラインフレーム内に読み込まれたコンテンツのJavaScriptの機能をかなり制限してしまいます。特にwindowオブジェクトが受ける影響は大きく、ブラウザのポップアップを伴う処理を完全に抑止してしまいます。
    WEBセマンティック的にも、IFRAMEを使うときは内包されるコンテンツによって属性を正しく設定してあげる必要があるってことですね。

    ...
  • WordPressのデータベース仕様書を書いてみた

    以前から、 WordPressCodexのデータベース構造のページが見づらくて、仕様も古くなっていたのが、ちょっと気になっていたので、自分でデータベース仕様書を書き直してみようかと思っていたところ、WordPressでシステム開発する業務が急激に増えて来て、特にマルチサイト系の仕組みを把握する必要もあって、WordPressのデータベース仕様書をチートシート的に書き起こしておかないとシステム設計がしづらいという状況になってきた。そこで、自分なりのデータベース仕様書(テーブル定義書)を書いてみた次第。

    基本的には日本語版Codexと本家WordPress.orgのサイトを見ながら、実際のデータベース構造と見比べて書いてみたのだが、マルチサイト系のテーブル部分はまだちょっと不明なところが多いんだなこれが(特にwp_sitecategoriesテーブル…このテーブルってwp3.0以降ではドロップされてしまったのか?…みたいな)。

    まぁ、一通り書き切ったので、ここに共有化しておこうかと。

    バージョン:0.1

    さて話は変わる(…ようでそうでもないのだ)が、今月12/11に新安定バージョンのWordPress3.5がリリースされたので、さっそく本デベラボも3.5へアップグレードしてみた。
    管理パネルからの自動アップデートが上手く動作しなかった(パッケージデータを取得して展開している途中でタイムアウトしてしまう)ので、一旦アップグレードするのを躊躇したのだけど、PHP側の設定を見直すのは面倒だったので、最終的に手動でアップデートしてしまいました。アップデート後、今のところテーマやプラグインに不具合もなく動いているようだけど、管理パネルに常にWordPressの自動更新失敗のノーティフィケーションが出るようになってしまった…(大した影響はなさそうなので、そのうち直そうかと)。

    そんなわけで、WPも3.5になったので、書き上げたデータベース仕様書と構成の突合せをしてみようと、バージョン3.5のデータベースを覗いてみた。
    ざっと構造を見てみましたが、3.4.x → 3.5 でデータベースへの変更はなかった(マルチサイト側は突合せてませんが…)。

    本記事が今年最後のデベラボの投稿になりそうだ。
    それではみなさん、良いお年を。

    ...
  • 【WordPressを使う】WindowsPCで動かしてみる

    WordPressを仕事で扱うことになったので、試しにいつも使っているWindowsPCに入れてみることにしました。

    さてどうすれば動かせるのかと調べてみると、WordPressはPHPとMySQL、Apacheがあれば動くようで、WindowsPCではWebアプリを動かすのに必要なソフトウェアをひとまとめにした「XAMPP」というものをインストールして、それを利用してWordPressを実行できるようです。

    というわけで、まずはXAMPPをインストールすることに。

    ...
  • サイトをスマートフォンに最適化してくれる無料WEBサービス「GoMo」がスゴイ!

    そのサイト、いますぐスマホに最適化「GOMO」

    dudamobile

    DudaMobile(とGoogle)がスゴイサービスを作ってくれました。

    「GoMo」はスマートフォンに最適化されていないWEBサイトを自動でスマートフォンサイトへ最適化してくれるASP型のサービスだ。特筆すべきはなんと一年間は無料で使えるフリーウェア(二年目以降は1,180円)だということ。
    WEBサイトのURLを入力して、数分待つだけで、スマートフォンに最適化されたサイトが出来上がり、プレビューしながらレイアウトのテンプレートやカラーバリエーションなどが選べるうえに、ページ単位で個別にヘッダーやフッター、コンテンツ部分のスタイルシートやHTMLも修正できる。さらに新規コンテンツの追加やSEOの設定なども可能だ。ブログサイトの場合、ブログとして認識させるか一般サイトとして認識させるかによってテンプレートのバリエーションが変る。
    何気に、スマートフォンサイト作成用のCMSと言えるぐらい機能が充実していて、作成したサイトはアカウント登録すると保存できたり、そのまま公開できる。

    これでFlash→HTML5コンバート機能が付いていたらほぼ無敵のサービスだったかもしれないが、まだFlashをHTML5へコンバートする機能やECサイト等の高度な機能を持っているサイトには対応できていない。
    それでも十分スゴイWEBサービスなので、特殊なことをやっていないWEBサイトやブログならこのツールだけで最適化は事足りてしまうのではないだろうか。
    また、現行サイトのスマートフォン最適化を企図した時の、モックアップ開発や最適化後の外観プレビュー的なツールとしても重宝しそうなツールでもある。

    PCサイトやフィーチャーフォンサイトをスマートフォンサイト化するASPツールは数あれど、無償でここまでの機能を提供されてしまうと、既存デベロッパーは苦しいだろうなぁ…。

    ...
  • WordPressでHyperDBによるデータベース二重化を行う時の注意点

    商用サイトなどをWordPressで構築する場合、WEBアプリケーションサーバとデータベースサーバを切り離して、データベース側を二重化することが良くあります。単にデータベースへのアクセス負荷を分散させてサービスのパフォーマンスを向上させるためでもあり、もし障害が発生した場合にミラーリングしている副系ノードのデータベースから正系データベースを復旧させることができる意味でも、サービスとして最悪のケースである「データ消失」のリスクを軽減できるからです。
    WordPressにはそういう正副ノードのミラーリングデータベース構成にも対応できる「HyperDB」というドロップインがあります。これを使うことで、データベースの更新はマスターデータベースのみに集約し、データベース参照はマスターとセカンダリに分散させるということができます。
    (※ 「HyperDB」ドロップインによるデータベース二重化の方法は、QuickKnowLedge : MySQL HyperDB + Keepalivedを利用した、wordpress の負荷分散 などで詳しく説明されています。)

    さて、この「HyperDB」を利用しているWordPressサイトで、WordPressのコア処理に依存しない形で、データベースアクセスの処理を独自拡張している場合に、問題が発生することがあります。
    一体どういうケースかと言うと、WordPressのデータベース制御系のグローバル変数「$wpdb」をWordPressページ外で使う場合です。

    例えば、WordPressの投稿からAjaxなどで直接独自に作成したPHPをコールし、そのPHP内でWordPressのデータベースへのアクセスを行う処理があるような場合です。このようなWordPressのプログラム群から独立した外部プログラムでデータベースアクセス用のグローバル変数「$wpdb」を利用する場合に、
    [code lang=“php” light=“true”]require_once(’./wp-config.php’);[/code] …と、上記のように設定ファイルをインクルードしているケースだと「HyperDB」を有効化した途端に動かなくなります。

    この場合、インクルードするファイルを設定ファイルからブログヘッダーに変更することで、正常化します。
    [code lang=“php” light=“true”]require_once(’./wp-blog-header.php’);[/code]
    特にインクルードファイルを変更してもパフォーマンスに変化が見られなかったため、結論的には、外部プログラムで「$wpdb」を利用する場合は「wp-blog-header.php」をインクルードしておくのが無難なようです。

    ...
  • Encrypted Http Live Streaming

    自社サイトでiPhone向け動画を配信するにあたり、採用した手法です。

    • 参考

    HTTP Live Streaming(Encrypt)
    ここが詳しいですが、暗号化するとうまく再生できないのでアレンジしています。

    iPhone, iPad, iPod – HTTP Live Streaming (HLS) with free tools on Windows
    エンコードのオプション等が参考になります。

    • 方針

    元動画

    mpeg2ts

    分割

    暗号化

    再生

    • プラットフォーム

    Ubuntu 12.04

    ffmpeg は apt-get でインストール。

    ...