Pictnotes メインイメージ

お仕事メモ

2014年10月

baserCMSで😄を使いたい場合の最適解

baserCMSで、絵文字を使いたい場合の最適解を考える
 



いきなり正解書いておくと、「DatabaseでPostgreSQLを使う」です。

baserCMSは、SQLite,MySQL,PostgreSQLのDatabaseが選択できますが、(SQLiteは検証してないので今回パスで)
MySQLで絵文字を管理画面等から登録しようとすると上手くいきません。原因は文字コードの設定です。

MySQLで絵文字を取り扱うのであればutf8mb4という文字コードセットを利用する必要があります。

utf8mb4は、4バイトを扱えるutf8、つまりは絵文字が扱えるutf8になります。

現在多くのレンタルサーバ等では、MySQLのデフォルトの文字コードは utf8 であり utf8mb4ではありません。
また、utf8mb4の文字コードセットは、MySQL5.5.3以上での利用となります。

そのためそもそもレンタルサーバで利用する場合は、まずMySQLのバージョンの問題を乗り越え
さらに、utf8で作成されるテーブル等々をutf8mb4にしつつ(baserCMSだとインストーラの改修が必要)、
CakePHPのdatabase.php のDBへのアクセス設定で encoding をutf8mb4に設定してあげる必要があります。

上記でも上手くいくかは、Database自体の設定のからみもあり、確実なものではありません。
本来、きちんとしたいのであれば、「create database 」とか MySQLの設定ファイル my.conf 等から
あわせて見直してあげる必要がでてきます。

そこまでいくと、baserCMSの領域でどうのこうのするのは難しくなりMySQLで絵文字を使えるという
状態を提供するのが困難になっています。

さらに、それを乗り越えても、寿司ビール問題とかはらんでますしね。

という事で、baserCMSで、顔文字使いたければPostgreSQLをつかえという結論です。
PostgreSQLならデフォルトのインストールで、顔文字を使える状態です。これは、PostgreSQLの
UTF8が、デフォルトで4バイト対応だからになります。

ちなみに、「どうしてMySQLのutf8は3バイトなんだ」という事に突っ込みを入れる気はないのであしからず。

文字コードの問題等々は歴史的事情等も複雑にからんでおり、後方互換も考えるとその時々の判断にすごく
苦労したのだと思います。MySQLもPostgreSQLも素晴らしいRDBであり、両方とも愛してくれたらうれしいです。


というわけで、baserCMSも、下記のようなチケットが上がっておりまが、(自分が作ったのですが・・)
MySQLの utf8mb4に対応するか

こちらの実装は当面しない予定です。絵文字使いたい人は、PostgreSQLを使ってくださいね。

  😃 😀 😊 😉 😍 😘 😚 😗 😙
😜 😝 😛 😳 😁 😔 😌 😒 😞 😣 😢
😂 😭 😪 😥 😰 😅 😓 😩 😫 😨 😱
😠 😡 😤 😖 😆 😋 😷 😎 😴 😵 😲
😟 😦 😧 😈 👿 😮 😬 😐 😕 😯 😶
😇 😏 😑 👲 👳 👮 👷 💂 👶 👦 👧
👨 👩 👴 👵 👱 👼 👸 😺 😸 😻 😽
😼 🙀 😿 😹 😾 👹 👺 🙈 🙉 🙊 💀
👽 💩 🔥 🌟 💫 💥 💢 💦 💧 💤
💨 👂 👀 👃 👅 👄 👍 👎 👌 👊
👋 👐 👆 👇 👉 👈 🙌 🙏
👏 💪 🚶 🏃 💃 👫 👪 👬 👭 💏 💑
👯 🙆 🙅 💁 🙋 💆 💇 💅 👰 🙎 🙍
🙇 🎩 👑 👒 👟 👞 👡 👠 👢 👕 👔
👚 👗 🎽 👖 👘 👙 💼 👜 👝 👛 👓
🎀 🌂 💄 💛 💙 💜 💚 💔 💗 💓
💕 💖 💞 💘 💌 💋 💍 💎 👤 👥 💬
👣 💭

 

≫ 続きを読む

baserCMS   2016/12/02   admin

pg_basebackupからのstandbyサーバの復旧

primary と standbyで差分ができてしまったとき(WALファイルの紛失などで)pg_basebackupからの復旧手順
滅多にしないのでメモ。



standby側での作業

su - postgres
mkdir /usr/local/pgsql/basebackup
pg_basebackup -x -h primary.server.ip -D /usr/local/pgsql/basebackup
chmod 700 basebackup
cp -a ./data/recovery.conf ./basebackup
mv ./basebackup/postgresql.conf ./basebackup/postgresql.conf.master
cp -a ./data/postgresql.conf ./basebackup/
diff ./basebackup/postgresql.conf ./basebackup/postgresql.conf.master
mv ./basebackup/pg_hba.conf ./basebackup/pg_hba.conf.master
cp -a ./data/pg_hba.conf ./basebackup/pg_hba.conf
diff ./basebackup/pg_hba.conf ./basebackup/pg_hba.conf.master


#下記の4つのコマンドはrootにて
/etc/init.d/postgresql stop
mv /usr/local/pgsql/data /usr/local/pgsql/data20160623
mv /usr/local/pgsql/basebackup /usr/local/pgsql/data
/etc/init.d/postgresql start


su - postgres
psql -p 5432 -c "SELECT pg_last_xact_replay_timestamp()"
 pg_last_xact_replay_timestamp
-------------------------------
 2016-06-23 16:27:45.726323+09
(1 row)

基本的には
作業フォルダを作成
プライマリーのホストから、スタンバイの指定のフォルダにデータをコピー
basebackupのパーミッションを変更しておかないと起動時にエラーになるのでDBのユーザ(postgres等)のみのパーミッションへ変更
masterとの差分ファイル、pg_hba.conf, postgresql.conf, recovery.conf を元フォルダからコピー
もし、*.pid ファイルとかあれば削除しておく。pg_log のフォルダの中のログもマスタのログなので必要に応じて削除
PostgreSQLを停止
ディレクトリをリネーム
PostgreSQLを起動
起動が成功したら、コマンドから動作を確認
といったながれです。
ちなみに、起動が失敗したときは

#切り戻し
mv /usr/local/pgsql/data /usr/local/pgsql/basebackup
mv /usr/local/pgsql/data20160623 /usr/local/pgsql/data
/etc/init.d/postgresql start

とかで、切り戻して、起動ログを確認して対応します。

 

≫ 続きを読む

PostgreSQL   2016/06/23   admin

Vagarntで、vagrantのマウントに失敗するときの対処メモ

/vagrantのmountに失敗するときの対処方法の一つ



根本的に
# /etc/init.d/vboxadd
がこけてる場合は、使っているカーネルの開発ツールをいれて setupしなおす必要がある
yumとかで自動で取ってこれない場合にこけることがあるみたいなのでWEBで該当のものをさがしだして手動でいれてしまう。

# uname -r
2.6.32-431.3.1.el6.x86_64
# rpm -qa | grep kernel
kernel-2.6.32-431.3.1.el6.x86_64



とかで、今のkernelのバージョンをみつけて上記なら
kernel-devel-2.6.32-431.3.1.el6.centos.x86_64
とかを探していれる、今回同様のものがみつからなかったので
kernel-devel-2.6.32-431.3.1.el6.centos.plus.x86_64
で代用した。そのためシンボリックリンクを張る作業が追加されている


#wget http://vault.centos.org/6.5/centosplus/x86_64/Packages/kernel-devel-2.6.32-431.3.1.el6.centos.plus.x86_64.rpm
#rpm -ivh kernel-devel-2.6.32-431.3.1.el6.centos.plus.x86_64.rpm
#cd /usr/src/kernels/
#ln -s /usr/src/kernels/2.6.32-431.3.1.el6.centos.plus.x86_64 2.6.32-431.3.1.el6.x86_64
#/etc/init.d/vboxadd setup

とかして、再起動すればOK


 

≫ 続きを読む

  2015/10/22   admin

さくらインターネットのVPSでWEBサーバ、レンタルサーバでメールサーバとする場合の設定

さくらインターネットでドメイン管理をしつつ

VPS(もしくはクラウド)をWEBサーバとして

レンタルサーバをメールサーバとして利用する場合の設定

 



上記の事が、可能なのかサポートに問い合わせたら「弊社にて独自ドメインをご利用いただく場合、1つのサーバにてウェブ・メールをするのが前提だけどできるよん。ゾーン設定はレクチャー出来ないけど自力でやってみてね」(本当はもっと丁寧)な返事がやってきたのでやってみた。

上記ができるか不思議だったのは、さくらのドメインで設定するときに
「レンタルサーバで利用する場合は、レンタルサーバのコンパネで設定する必要がある」と注意書きがあったので、そちらのコンパネをみるとAレコードを別に割り振る事ができなさそうなインターフェイスだったので疑問におもえたのと、かといって、会員ログイン後のドメイン管理から別途ゾーン設定してMXに、example.sakura.ne.jp と記載したとしても(さくらのレンタルサーバは初期に、sakura.ne.jpのサブドメインを設定してそれを初期ドメインとする必要がある)レンタルサーバ側の設定ができてないので、@example.com のメール(example.comを取得したと仮定)が配送できないと思ったからです。

そんな理由で問い合わせると、上記の解答がきたので、とりあえず設定メモ。手順が大事。

とりあえず、契約

  • ドメイン契約 (example.com)
  • レンタルサーバ契約 - 初期ドメインをexample.sakura.ne.jpとする
  • vps契約

をすませる。(ここはどれからしてもOK, ドメイン名と、sakura.ne.jpのサブドメイン名は合わせた方がわかりやすいかとおもう)
次に、レンタルサーバ側のコンパネで「ドメイン設定」から「新しいドメインの追加」を選択してレンタルサーバにドメインを紐付ける。
紐付け後「ドメイン詳細設定」の「5. SPFレコードの利用を選んでください」の「SPFレコードを利用する」にチェックをいれて保存。

これで、レンタルサーバ側の設定は終了

次に、会員メニューから「ドメイン管理」で確認すると、上記の事をするとexample.comのゾーン設定が行われている事が確認できると思います。
結果的に、直接ゾーン設定をするのでなくて、コンパネ経由でゾーン設定してた事だったみたいです。
じゃあ、最初からゾーン設定すれば同じではと思いますが、どの共用サーバに収容されているかなどしれべるのが面倒だとおもいますので一端、レンタルサーバ側から設定してそれらの値を取得後書き換えてあげるのが良さそうです。
初期だと

エントリ名 タイプ データ 補足
@ NS ns1.dns.ne.jp.  
NS ns2.dns.ne.jp.  
A xxx.xxx.xxx.xx (IPアドレス)  
MX 10 @  
TXT "v=spf1 a:www111.sakura.ne.jp mx ~all" 111の部分は適当な数字
www CNAME @  
mail CNAME @  
ftp CNAME @  

とかなので不必要な部分等を削除して、下記のように調整

エントリ名 タイプ データ 補足
@ NS ns1.dns.ne.jp.  
  NS ns2.dns.ne.jp.  
  A xxx.xxx.xxx.xx VPSのIPアドレスに書き換え
  MX 10 example.sakura.ne.jp. レンタルサーバの初期ドメインに書き換え
  TXT  "v=spf1 a:www111.sakura.ne.jp +ip4:xx.x.x.x +ip6:x:xx:xx:xx:x:x:x:x ~all" 必要に応じて、VPSのIPを追加
www CNAME @  

という風に変更しました。AレコードをレンタルサーバのIPからVPSのIPに書き換えて、MXレコードは、レンタルサーバの初期ドメインに変更(初期に記載されていたAレコードのIPでも問題ないかとおもうのですが、万が一変更があったときのためにFQDNの方がいいかとおもう)。必要に応じてSPFレコードにVPS(WEBサーバ側のIPを追加、)の設定です。

メンテナンスやコストを考えて今後この設定での運用は増えそうなのでメモ

≫ 続きを読む

その他   2015/10/21   admin

FormHelper 複数checkboxの出力を調整する

CakePHP 2.x の FormHelperで、関連するチェックボックスのタグを出力するときのタグの調整



CakePHP2.xで、関連するチェックボックスをFormHelperを利用して出力しようとすると かならず、devタグで囲まれてしまいます。これをどうにかしたくてFormHelperに手を入れました。 FormHelperの、_selectOptions メソッドのほぼ最後のあたりで

$label = $this->label(null, $title, $label);
$item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions);
$select[] = $this->Html->div($attributes['class'], $item . $label);

のぶぶんで、強制的に devタグをつけられています。
classの設定をdevタグの部分で実装しているので、そうなっているみたいです。class => false にしていても
強制的に class=>'checkbox' をつけられる鬼仕様でした。
なので、
<li><input type="checkbox" name="hoge" value="1" id="hoge" class="checkbox_area" /><label for="hoge">アジア</label></li>
とかの状態のHTMLが生成できないので無理矢理修正

'multiple'=> 'checkbox',で、 'class'=> 'checkbox_area'の場合のみ挙動が代わるようにしました。

 

$label = $this->label(null, $title, $label);
if( $attributes['class'] == 'checkbox_area' ){
    $htmlOptions['class'] = $attributes['class'];// add customize
    $item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions);
    $select[] = $this->Html->tag('li', $item . $label);
} else {
    $item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions);
    $select[] = $this->Html->div($attributes['class'], $item . $label);
}

とclass名で条件分岐を作成、checkbox_areaの場合は、最初のinput tagを生成する時に、classのoptionを追加してそちらにclassが入るように設定、で、liでかこみたいので、 html->dev でなく、 html->tag で li を設定に変更です。

無理矢理感はありますが、これでなんとか思った通りの出力に変更できました。

≫ 続きを読む

CakePHP   2015/03/13   admin

CakePHPの変数の命名規則はDBとの関係で考えると非常に悩ましい

個人的に、変数はスネークケース(アンダースコアつなぎ)で書くことが多いのだけどCakePHPのコーディング規則をみると命名規約で変数はキャメルバック(先頭小文字のキャメルケース)で書くようにと書いてある

 



http://book.cakephp.org/2.0/ja/contributing/cakephp-coding-conventions.html
変 数名はできる限り説明的に、しかしできる限り短くもしてください。 通常の変数は小文字で始まり、複数の単語の場合はキャメルバックで書く必要があります。 オブジェクトを参照する変数は大文字で始まり、何らかの方法で変数がオブジェクトとなっているクラスに関連したものになるべきです。

基本的に長いものに巻かれるタイプですのでこれ自体を受け入れられないという事はないのですが、プロジェクトで扱う変数は最初から最後までできるだけ同じ命 名規則で書きたいという欲望もあり(その方がミスが少なくなりますよね)その場合、PHPの変数がキャメルケースだとデータベースとの関係ではあまり好ましくないと思う。

CakePHPに限らずPHPのフレームワークを使う上でDBの操作がラクという事は大きなメリットなのですが、その一環として、
$this->save($this->request->data);
などで、関連づけられているテーブルにinsert等の処理が簡単にできることだと思う。 これが出来る条件として、PHPの配列のkey名とdatabaseのカラム名が同じである必要があるのですが、変数名にキャメルケースを採用するとここが上手く行かない時がでてきます。
たとえば、PostgreSQLで

	cake=# create table test ( id serial primary key, last_name text, firstName text);
といったテーブルを作ると
cake=# \d test
                           Table "public.test"
  Column   |  Type   |                     Modifiers                     
-----------+---------+---------------------------------------------------
 id        | integer | not null default nextval('test_id_seq'::regclass)
 last_name | text    |
 firstname | text    |

といったテーブルができます。

cake=# drop table test;
DROP TABLE
cake=# create table test ( id serial primary key, last_name text, "firstName" text);
CREATE TABLE
cake=# \d test
                           Table "public.test"
  Column   |  Type   |                     Modifiers                     
-----------+---------+---------------------------------------------------
 id        | integer | not null default nextval('test_id_seq'::regclass)
 last_name | text    |
 firstName | text    |

上記の2つの違いがわかりますでしょうか? firstNameを、ダブルコーテーションで囲んでいるかどうかです。 http://www.postgresql.jp/document/9.3/html/sql-syntax-lexical.html

4.1.1. 識別子とキーワード
で、
引用符が付かない名前は常に小文字に解釈されますが、識別子を引用符で囲むことによって大文字と小文字が区別されるようになります。 例えば、識別子FOO、foo、"foo"はPostgreSQLによれば同じものとして解釈されますが、"Foo"と"FOO"は、これら3つとも、またお互いに違ったものとして解釈されます (PostgreSQLが引用符の付かない名前を小文字として解釈することは標準SQLと互換性がありません。標準SQLでは引用符の付かない名前は大文字に解釈されるべきだとされています。 したがって標準SQLによれば、fooは"FOO"と同じであるべきで、"foo"とは異なるはずなのです。 もし移植可能なアプリケーションを書きたいならば、特定の名前は常に引用符で囲むか、あるいはまったく囲まないかのいずれかに統一することをお勧めします)。

とあります、MySQLの方は省きますが、こちらも基本的には区別しないみたいです。(オプション等で区別できるみたいですが)

なぜ、区別しないんだ!と言われても僕にはわかりませんが(たぶんファイルシステムとの兼ね合いかなぁという気はしますが)現状そうなので、DBのカラム名はスネークケースを採用する方がなにかと問題がないと思います。

で、最初の話題にもどると、CakePHP上で、連想配列のkeyが、firstNameとして扱っている変数をDBに入れたい場合、keyをfirst_name代入してsaveする必要とかがでてくるかと思います。

なんか、一手間かかってメリット消してる気がするのは僕だけなのですかね。

世の中のみんなはどうしてるのかなぁ。
個人的には、apiやhtmlのフォームタグ名から、dbのカラム名まで、変数に関してはスネークケースで行きたい所です。(上記の問題があるので)
 

≫ 続きを読む

CakePHP   2014/10/28   admin

Mailプラグインで戻るボタンが効かない場合の対処法

デザインを入れ替えたら、メール(フォーム)プラグインの戻るボタンが効かなくなった原因をさぐる。



結論から書くと
Elements/mail_form.php

        <?php echo $this->Mailform->submit(' 書き直す ', array('div' => false, 'class' => 'btn-red button form-submit', 'id' => 'BtnMessageBack')) ?>
あたりの
'class' => 'btn-red button form-submit'

form-submitを削除したから。
別のデザインにのせかえたので、classは必要なくなったため削除したのですがこのform-submitのクラスで判別して
submitする前にmodeをJSで切り替えているため、こちらの指定がなくなると戻れなくなります。
なので、消さないこと。

あわせて、
 


も及び
'id' => 'BtnMessageBack'
の指定も残しておかないと動きません。

≫ 続きを読む

baserCMS   2014/03/04   admin

pagination(ページ送り)をカスタマイズする

ブログプラグインとかの、ページネーションのデザインをカスタマイズする。



まず、デフォルトで存在する
/lib/Baser/View/Elements/paginations/
フォルダを
/app/webroot/theme/default(利用しているテーマ名)/Elements/
にコピーします。
paginationsフォルダの中には、
default.php とsimple.php があるとおもうので、どちらかを削除してどちらかを
blog.php とかにリネーム
<?php $this->BcBaser->pagination('blog'); ?>
といった形で、呼び出しをblogにしてあげれば、こちらのthemeの方のpaginationファイルが優先的によばれます。
blog以外でも、適当な名前でOK,要は呼び出し元と呼び出すファイル名があってればOK

/lib/Baser/View/Elements/paginations/test.php
/app/webroot/theme/default(利用しているテーマ名)/Elements/paginations/test.php

<?php $this->BcBaser->pagination('test'); ?>
でよびだすと、後者の
/app/webroot/theme/default(利用しているテーマ名)/Elements/paginations/test.php
が優先的によびだされるので、カスタマイズするときは基本的に、利用テーマのエレメンツフォルダに別名(simple.php, default.php以外)でファイルを作成するのがいいと思う。

あとは、これをガスガスカスタマイズするのですが、spanタグとかが入って上手く行かない場合少々強引な方法ですが、
$blog_paginate = $this->Html->tag('dd', $this->Paginator->numbers(〜〜〜〜〜〜);
$blog_paginate = str_replace('</span>','',$blog_paginate);
$blog_paginate = str_replace('<span>','',$blog_paginate);
echo $blog_paginate ;
とかの形で出力されたものにたいして、文字列置換をかけるのが美しくないけど手っ取り早いと思います。


 

≫ 続きを読む

baserCMS   2014/02/26   admin

contentsName関数の挙動について その2

contentsNameの挙動をちょっとカスタマイズしたので、メモ



http://www.pictnotes.jp/hoge

とかの固定ページ(第一階層しかないページ)で、contentsName 関数をつかうと、返値は Defaultになる。
これを、「hoge」にしたい場合がある。
たとえば、
 

<body id="<?php $baser->contentsName() ?>"> としてると、 <body id="Default">

となるけど、hogeページは、

<body id="hoge">
となって欲しい場合などの時のカスタマイズ。(baserCMS3系)
まず、変えたいbodyタグがあるlayoutファイルで該当のbodyタグ周りを下記のように修正

<?php
$contentsNameDefault = 'Default';
if( isset( $this->request->pass[0] ) ){
    $contentsNameDefault = $this->request->pass[0] ;
}
?>
<body id="<?php $this->BcBaser->contentsName(false, array('underscore'=>true,'default'=>$contentsNameDefault)) ?>">

と書き換える、contentsNameメソッドの引数で、defaultの値を強制的に書き換えてる挙動です。
内部的には、

lib/Baser/View/Helper/BcBaserHelper.php の1351行目あたり、getContentsNameメソッドの

    public function getContentsName($detail = false, $options = array()) {

        $options = array_merge(array(
            'home' => 'Home',
            'default' => 'Default' ,
            'error' => 'Error',
            'underscore' => false), $options);

の'default' => 'Default'の部分を上書きして上げている状態になります。

これでだいたいの挙動は網羅できると思います。
 

≫ 続きを読む

baserCMS   2014/02/26   admin

パンくずリストのカスタマイズ

<ul><li>とかのタグで構成されているパンくずリストを作成する場合
ただし、検証が甘い。



baserCMSで用意されている、$this->BcBaser->crumbs だと、<ul><li>とかのタグで構成されているパンくずリストには対応できません。
でもってちょっとカスタマイズというか改造。

<dl id="breadList">
  <dt><a href="/">HOME</a></dt>
  <dd><a href="/shop/">直営店</a></dd>
  <dd>本店</dd>
</dl>
といったケースのパンくずリストのタグを作りたい場合、 ベースとしては、デフォルトのnada-iconsにのElementsフォルダにある、crumbs.phpを利用してください。

crumbs.phpの
$this->BcBaser->crumbs(' &gt; ', 'ホーム');

$crumb = $this->BcHtml->getCrumbList(array('separator'=>'','firstClass'=> false,'lastClass'=> false), array('text'=> '<dt>HOME</dt>','escape'=> false));
echo $crumb ;
と変更
getCrumbListは、baserCMSの機能でなく、HtmlHelperのメソッドとなります。
http://book.cakephp.org/2.0/ja/core-libraries/helpers/html.html#HtmlHelper::getCrumbList
こちらを使うと、ul,liとかのタグで囲んでくれます。
ただ、これul,liしか対応してないので、今回の dl, dd(dt)は非対応、なのでちょっとカスタマイズ。
BcHtmlHelper.php にgetCrumbListのメソッドをまるっとコピーして、そちらを見るようにしてしまいます。

/**
 * Returns breadcrumbs as a (x)html list
 *
 * This method uses HtmlHelper::tag() to generate list and its elements. Works
 * similar to HtmlHelper::getCrumbs(), so it uses options which every
 * crumb was added with.
 *
 * ### Options
 * - `separator` Separator content to insert in between breadcrumbs, defaults to ''
 * - `firstClass` Class for wrapper tag on the first breadcrumb, defaults to 'first'
 * - `lastClass` Class for wrapper tag on current active page, defaults to 'last'
 * - `firstTag` use tag, defaults to 'ul'
 * - `secondTag` use tag, defaults to 'li'
 *
 * @param array $options Array of html attributes to apply to the generated list elements.
 * @param string|array|boolean $startText This will be the first crumb, if false it defaults to first crumb in array. Can
 *   also be an array, see `HtmlHelper::getCrumbs` for details.
 * @return string breadcrumbs html list
 * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
 */
	public function getCrumbList($options = array(), $startText = false) {
		$defaults = array('firstClass' => 'first', 'lastClass' => 'last', 'separator' => '', 'firstTag' => 'ul', 'secondTag' => 'li');
		$options = array_merge($defaults, (array)$options);
		$firstClass = $options['firstClass'];
		$lastClass = $options['lastClass'];
		$separator = $options['separator'];
		$firstTag = $options['firstTag'];
		$secondTag = $options['secondTag'];
		unset($options['firstClass'], $options['lastClass'], $options['separator'], $options['firstTag'], $options['secondTag']);

		$crumbs = $this->_prepareCrumbs($startText);
		if (empty($crumbs)) {
			return null;
		}

		$result = '';
		$crumbCount = count($crumbs);
		$ulOptions = $options;
		foreach ($crumbs as $which => $crumb) {
			$options = array();
			if (empty($crumb[1])) {
				$elementContent = $crumb[0];
			} else {
				$elementContent = $this->link($crumb[0], $crumb[1], $crumb[2]);
			}
			if (!$which && $firstClass !== false) {
				$options['class'] = $firstClass;
			} elseif ($which == $crumbCount - 1 && $lastClass !== false) {
				$options['class'] = $lastClass;
			}
			if (!empty($separator) && ($crumbCount - $which >= 2)) {
				$elementContent .= $separator;
			}
			$result .= $this->tag($secondTag, $elementContent, $options);
		}
		return $this->tag($firstTag, $result, $ulOptions);
	}

オプションに、firstTag' と 'secondTag を追加してタグを自由に設定出来るようにしただけです。これで、dl,ddのタグで出力出来るようになります。

が、やはりこれだけでもいまいちで
<dl id="breadList">
の id="breadList" の部分や
  <dt><a href="/">HOME</a></dt>
の dtのタグが再現できません。

なので、ちょっと強引ですが
echo $crumb ;
する前に
$crumb = str_replace('<dd><a href="/"><dt>HOME</dt></a></dd>', '<dt><a href="/">HOME</a></dt>', $crumb);
$crumb = str_replace('<dl>', '<dl id="breadList">', $crumb);
とかで文字列変換をかけてあげれば、とりあえず思い通りにできたりします。

でもまだまだこれだけだと、もともとbaserCMSのcrumbsメソッドは、404 not found になるようなURLとかはリンクを張らない仕様になっているのでそこの機能も追加

BcBaserHelper.phpに

 

/**
 * 表示していいURLかを判別
 *
 * @param string $url
 * @param string $options
 * @return boolean
 * @access public
 * @manual
 */
	public function isViewLink($url = null, $options = array()) {

		if (!is_array($options)) {
			$options = array($options);
		}

		$options = array_merge(array(
			'escape' => false,
			'prefix' => false,
			'forceTitle' => false,
			'ssl' => false
			), $options);

		/*		 * * beforeIsViewLink ** */
		$event = $this->dispatchEvent('beforeIsViewLink', array(
			'url' => $url,
			'options' => $options
			), array('class' => 'Html'));
		if ($event !== false) {
			$options = $event->result === true ? $event->data['options'] : $event->result;
		}

		if ($options['prefix']) {
			if (!empty($this->request->params['prefix']) && is_array($url)) {
				$url[$this->request->params['prefix']] = true;
			}
		}
		$forceTitle = $options['forceTitle'];
		$ssl = $options['ssl'];

		unset($options['prefix']);
		unset($options['forceTitle']);
		unset($options['ssl']);

		// 管理システムメニュー対策
		// プレフィックスが変更された場合も正常動作させる為
		// TODO メニューが廃止になったら削除
		if (!is_array($url)) {
			$prefixes = Configure::read('Routing.prefixes');
			$url = preg_replace('/^\/admin\//', '/' . $prefixes[0] . '/', $url);
		}

		$_url = $this->getUrl($url);
		$_url = preg_replace('/^' . preg_quote($this->request->base, '/') . '\//', '/', $_url);
		$enabled = true;

		if ($options == false) {
			$enabled = false;
		}

		// 認証チェック
		if (isset($this->Permission) && !empty($this->_View->viewVars['user']['user_group_id'])) {
			$userGroupId = $this->_View->viewVars['user']['user_group_id'];
			if (!$this->Permission->check($_url, $userGroupId)) {
				$enabled = false;
			}
		}

		// ページ公開チェック
		if (isset($this->Page) && empty($this->request->params['admin'])) {
			$adminPrefix = Configure::read('Routing.prefixes.0');
			if (isset($this->Page) && !preg_match('/^\/' . $adminPrefix . '/', $_url)) {
				if ($this->Page->isPageUrl($_url) && !$this->Page->checkPublish($_url)) {
					$enabled = false;
				}
			}
		}

		if (!$enabled) {
			//$forceTitleの値に問わず、false
			return false;
		}else{
			return true;
		}

	}


とそのリンク先が表示していいのかのメソッドを追加、ちなみにこのソースは、getLink メソッドの一部を抜粋したソースなので、可能なら getLinkメソッドからこちらを参照するように変更かけるのがただしいのだけど、検証があまいので今回はそのまま、いつか確認ができたら、本体にマージしたいところ。

あとは、crumbs.php (エレメントのファイル)を少し書き直してあげる。
43行目あたりの
                $this->BcBaser->addCrumb($crumb['name'], $crumb['url'], array());
の所を、
                if( $this->BcBaser->isViewLink($crumb['url'])){
                    $this->BcBaser->addCrumb($crumb['name'], $crumb['url'], array());
                } else {
                    $this->BcBaser->addCrumb($crumb['name'], '', array());
                }
として、利用可能なリンク先かどうかのチェックを追加しておわり。
 

≫ 続きを読む

baserCMS   2014/02/15   admin