Pictnotes メインイメージ

お仕事メモ

2014年10月

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

contentsName関数の挙動について

contentsNameの挙動を整理



contentsName関数は、
http://basercms.net/reference_3/archives/65
 

によれば、
[contentsName] コンテンツを特定するIDを出力する
と、cssとかの切り替えに便利なのですが、デフォルトがキャメルケースなので、それを小文字にしたいばあいは
<body id="<?php $this->BcBaser->contentsName(false, array('underscore'=>true)) ?>">
とすると、小文字で出力する事ができる。第2引数の「underscore」は通常アンダースコアつながりというオプションなのだが、こちらを指定することで、大文字にする事を回避する事ができます。

http://basercms.net/reference/archives
を例にとると、

<body id="<?php $this->BcBaser->contentsName() ?>">
引数をあたえない場合
<body id="Reference">
と出力される。

<body id="<?php $this->BcBaser->contentsName(true) ?>">
第一引数を trueに
<body id="ReferenceArchives">
と出力される。

<body id="<?php $this->BcBaser->contentsName(false, array('underscore'=>true)) ?>">
第一引数を falseに underscoreをtrueに
<body id="reference">
と出力される。

<body id="<?php $this->BcBaser->contentsName(true, array('underscore'=>true)) ?>">
第一引数を trueに underscoreをtrueに
<body id="reference_archives">
と出力される。

ちなみに、
http://basercms.net/reference_3/archives/65
のURLの場合、
<body id="<?php $this->BcBaser->contentsName() ?>">
引数をあたえない場合
<body id="Reference3
">
と、アンダースコアは削除され3は大文字がないのでそのままつながります。

<body id="<?php $this->BcBaser->contentsName(true) ?>">
第一引数を trueに
<body id="Reference3Archives65">
と、なります。

<body id="<?php $this->BcBaser->contentsName(false, array('underscore'=>true)) ?>">
第一引数を falseに underscoreをtrueに
<body id="reference_3">
と出力される。

<body id="<?php $this->BcBaser->contentsName(true, array('underscore'=>true)) ?>">
第一引数を trueに underscoreをtrueに
<body id="reference_3_archives_65">
と出力される。

URLの中にアンダースコアや数字が入っていると思った通りの挙動にならないかもしれないので注意が必要です。

とりあえず、僕のid指定とかは小文字だけで指定してるぜ!!
ってかたは、第2引数を「array('underscore'=>true)」にして対応してくださいませ。

 





 

 

≫ 続きを読む

baserCMS   2014/02/14   admin

プログラム一式をドキュメントルート以下におかない方法

baserCMSをインストールするときに、プログラム等の一式をドキュメントルート以下に展開しないで
運用する方法。



カスタマイズ前提とかで、サイトを構築するとき、セキュリティ上の事とかもろもろかんがえて、
baserCMSのプログラムフォルダ等をドキュメントルート以下に置きたく無い場合の運用方法。
(これを書く一ヶ月以上前にしたので、記憶みすで、間違いがあったらごめんなさい)

/var/www/html
がドキュメントルートとして、

/var/www/basercms
というフォルダにbaserCMSのパッケージを設置するとします。。

1) basercms/index.phpをドキュメントルート以下にコピー(移動でもいいよ)
2) コピーした、index.phpの中身を修正

38c38,39
< define('ROOT', dirname($_SERVER['SCRIPT_FILENAME']));
---
> //define('ROOT', dirname($_SERVER['SCRIPT_FILENAME']) . '/../basercms/');
> define('ROOT', realpath(dirname($_SERVER['SCRIPT_FILENAME']) . '/../basercms/'));
53c54,56
< require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
---
> //require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
> require ROOT . DS . APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
>


diffで書くと上記の様なかたち、やっていることは、ROOTの定数をbasercmsのパッケージがある絶対パスへ変更
と、上記にあわせて、appフォルダの場所を再指定。

3) webroot以下の files と theme フォルダをドキュメントルート以下にリンク
/var/www/basercms/app/webroot/files
/var/www/basercms/app/webroot/theme
の2つのフォルダは、ドキュメントルート以下に存在する必要があるのでこれに関しては、
1.シンボリックリンクをはる
2. ScriptAlias を設定する
のどちらかが必要です。
/var/www/basercms/app/webroot/files

/var/www/html/files
で、
/var/www/basercms/app/webroot/theme

/var/www/html/theme
と同じものになっている必要があるってことですね。これはコピーするだけではだめで、
プログラム的には、
/var/www/basercms/app/webroot/theme
のパスで見に行く事がほとんどなのですが、cssとかのファイルを閲覧者(ブラウザ)から見られる場合は
/var/www/html/theme
のドキュメントルートの方から見られるので、同じ物を参照してないと問題になってきます。

ln -s  /var/www/basercms/app/webroot/files files
ln -s  /var/www/basercms/app/webroot/theme theme
とかですね

まだ、構築中で本格運用はしてないですが、これで大丈夫なはず。

-- 2015.01.15 追記
css,js 等の呼び込みが上手く行ってないときは、
basercms/app/Config/install.php

Configure::write('App.baseUrl', '');
を追記する、特にスマートURL(mod_rewrite on)の状況において改善される場合有

 

≫ 続きを読む

baserCMS   2014/02/04   admin

RPM(yum)でinitdbをするときの注意点 CentOS6.x

PostgreSQLをインストールするときに、コミュニティーのリポジトリを登録してから
インストールするのですが、その時の注意点



コミュニティのリポジトリを使う初期の導入については、
http://lets.postgresql.jp/documents/tutorial/yum/
を参考にしてください。

ここでは、上記の導入を終了していざ、initdb を行う時の注意点として、
9.1 以上から、引数で、localeを指定出来る様になったので、

service postgresql-9.2 initdb C
といったかたちで、ロケールを C (なぜCなのかは、適当にググってください)
としておくと、環境変数の $LANG あたりに影響されずに幸せになります。

あと、一緒に default の encoding を設定したいのですが、これは引数では対応してないので
(対応自体は難しくなさそうでしたが)基本一回しかinitdbしないので、

$SU -l postgres -c "$PGENGINE/initdb --pgdata='$PGDATA' --auth='ident' $LOCALESTRING" >> "$PGLOG" 2>&1 < /dev/null
の行に
$SU -l postgres -c "$PGENGINE/initdb --pgdata='$PGDATA' --encoding=UTF8 --auth='ident' $LOCALESTRING" >> "$PGLOG" 2>&1 < /dev/null
と「--encoding=UTF8」あたりを直接書き込んでしまいます。


ここは、createdb するときにencodingを指定してあげれば回避もできるのですが、初期設定文字コード
とDBで利用したい文字コードが違うとtemplate0が使えなり、都度都度、template1等を指定してあげる
必要があるので、最初に合わせておきます。

以上の2点を忘れずに設定しておくこと。俺。

≫ 続きを読む

PostgreSQL   2013/07/03   admin

baserCMSのライセンスのステキな関係

baserCMSの Advent Calendar があったので、
http://www.adventar.org/calendars/54
参加させていただきました。

 



あらためてbaserCMSのライセンスについてです。
baerCMSは、現在 version1(1系) と version2(2系) の 2バージョン存在します。
version1の方は開発も(実質的に)終了している事もあり、今更触ることもないと思います。

1系と2系の大きな違いは、細かい機能面の違いはるけど、

  1. 管理画面のインターフェイス
  2. ライセンスの変更

の2点です。(ちがってたら、@ryuringから指摘がはいると思います。)

で、今回は、ライセンスのお話。

baserCMSは、1系で、GPLライセンス (GPL version2)を採用しておりましたが、2系では、MIT ライセンスとなっております。

これは、小さな事の様で大きな違いです。

ライセンスの問題は複雑なので、間違いがあれば指摘してほしいのですが、GPLライセンスとMITライセンスの一番の違いと僕が思うところは、コピーレフトであるか無いかです。

GPLライセンスは、コピーレフト。MITライセンスはそうでない。

http://www.gnu.org/copyleft/copyleft.ja.html
に判りやすい、コピーレフトの一文があったので引用いたします。

コピーレフト(Copyleft)とは、プログラム(もしくはその他の著作物)を自由とし、加えてそのプログラムの改変ないし拡張されたバージョンもすべて自由であることを要求するための、一般的な手法の一つです

GPLライセンスで配布されている物をカスタマイズする時は、その成果物(カスタマイズされたもの)も自由でなくてはいけない。逆に書くと、ブラックボックス化してはいけない。という事になります。

これ、オープンソースである限りはいいのですが、商用利用しようとするといきなり困ったりします。
例えば、GPLライセンスのCMSをカスタマイズして、別名で○○CMSと名付けて売り出すと、GPLライセンス違反になってしまいます。

なので、世の中には、GPLと商用ライセンスのデュアルライセンスとかで配布している物も存在致します。
また、プラグインフォルダに関しては、GPLの対象外とするとかの付加条項をつけているものもあります。
(その場合、プラグインフォルダには,LGPLとかMITライセンスのパッケージを入れられたりする)

オープン(自由)であることを保証するには、いいライセンスではあるのですが、商用利用しようと考え出すと
すこしだけグレーゾーンが発生しているのが昨今の現状ではないでしょうか?

そういう事情も踏まえて、baserCMSは2系から、ライセンス形態をMITライセンスとしました。
@ryuringの英断ですね。

MITライセンスは、軽く書くと、その著作権表示の部分を削除しなければ好きにつかっていいよ。という物になります。

なので、上記の例と同じ感じに説明すると、baserCMSをそのまま名前をかえて、pictnotesCSMとかで有料配布しだしても問題ないのですね。

上記が可能なら、企業の資金力をバックに、cloneであるpictnotesCSMが爆発的な人気がでて、大元のbaserCMSが衰退しちゃう事もかんがえられなくはないです。その他、企業てきな営利で考えるのであれば、MITライセンスへ踏み切る事はかなり勇気がいる決断でした。
ですが、それよりまずbaserCMSが皆様に使われる用になることが重要だという決断でライセンスの変更はきまりました。

まぁ、格好いいこと書いてますが、baesrCMSで少なからず食べさて頂いてる僕としては、そうなると困ると言えば困るのですが、そこは、コミュニティーの活動をより活発にすれば自ずと防げる事であり、baserCSMが名実共に、コミュニティー主体の物になるという意思表示でもあります。

と言うことで、小難しい事を書いてきましたが、つまりはbaserCMSだと何も考えないで使えるよ!!って事です。
さらに書くならば、

Database - PostgreSQL - BSD派生ライセンス
Framework - CakePHP - MITライセンス
CMS - baserCMS - MITライセンス

あたりで、構築してパッケージにすれば、なにも問題無く商用販売できちゃうというステキなパッケージがつくれます。
OSで、FreeBSD - BSDライセンス を選択すればさらに拡がるのかな?


さて、話は少しだけかわって、baserCMS3系の開発状態。

僕自身最近忙しくてあまりさわれなかったのですが、またちらほら作業を開始して、どちらかといえば、僕は表示側のバグをフィックスしていってます。年内公開は現段階で不可能と言うことになりますが間違えなく進んでいってますので、期待して待っておいてくださいませ。

ということで、福岡で飲んでいる僕をみつけたら、飲まずに開発しろ!!ってはっぱかけて下さいませ。

以上、baserCMSをよろしくお願い致します。

 

≫ 続きを読む

baserCMS   2012/12/23   admin

baserCMSで、googleMapを全てのページで表示したい。

facebookの雑談ページのスレから。

全ページのフッターに、システム設定で入力した住所のGoogleMapを表示させたいのですが、コアのソースをコピーしただけだと、固定ページにしか表示できず、ブログとメールフォームではエラーが出てしまいます。

どうすればいいでしょうか?
 



これは、プラグインの方に、Helperが呼ばれていないのが原因なので暫定対応として
/baser/controllers/app_controller.php を /app/controllers/app_controller.php としてコピーします。
コピーしたファイルのクラス内に次のコードを追加します。

class AppController extends BaserAppController {
}
?>

class AppController extends BaserAppController {
    var $helpers = array(
                    'Session', 'BcPluginHook', BC_HTML_HELPER, BC_HTML_HELPER, 'Form', BC_FORM_HELPER,
                    'Javascript', BC_BASER_HELPER, BC_XML_HELPER, BC_ARRAY_HELPER, BC_BASER_ADMIN_HELPER, BC_GOOGLEMAPS_HELPER
    );
}

管理システムよりサーバーキャッシュを削除します。

おわり。(このファイル閉じタグが残ってた・・・)

チケットきるべきかな?

≫ 続きを読む

baserCMS   2012/10/27   admin

お問い合せフォームの確認画面に入力画面に戻るボタンを追加する

baserCMSのお問い合せフォーム(メールプラグイン)ってすごく便利なのですが、
入力画面に戻るボタンがないので、実装してみました。



baserCMS 2.0.3で確認しています。

とりあえず、変更点
baser/plugins/mail/views/elements/mail_form.php
の50行目あたりの

<?php if($freezed): ?>
    <?php echo $mailform->submit(' 送信する ', array('div' => false, 'class' => 'btn-red button', 'id' => 'MessageSubmit'))  ?>
<?php elseif($this->action != 'submit'): ?>

の部分に1行追加&1行修正して

<?php if($freezed): ?>
    <?php echo $mailform->submit(' 書き直す ', array('div' => false, 'class' => 'btn-red button', 'id' => 'MessageBack', 'name' => 'data[mode][back]'))  ?>
    <?php echo $mailform->submit(' 送信する ', array('div' => false, 'class' => 'btn-red button', 'id' => 'MessageSubmit', 'name' => 'data[mode][submit]'))  ?>
<?php elseif($this->action != 'submit'): ?>

と、戻るボタンの追加とsubmitボタンに名前をつけます。

でもって、次は baser/plugins/mail/controllers/mail_controller.php の324行目あたり function submit($id = null) のメソッドのなかの

        if(!$this->data) {
            $this->redirect(array('action' => 'index', $id));
        }else {

        if(!$this->data) {
            $this->redirect(array('action' => 'index', $id));
        } elseif( isset($this->data['mode']) && key($this->data['mode']) == 'back' ) {
            $this->_back($id);
        } else {

とします。

あわせて、元ファイルだと、352行目あたりの

	        }
	
	        $this->set('mailContent',$this->dbDatas['mailContent']);
	        $this->render($this->dbDatas['mailContent']['MailContent']['form_template'].DS.'submit');

を、

	            $this->set('mailContent',$this->dbDatas['mailContent']);
	            $this->render($this->dbDatas['mailContent']['MailContent']['form_template'].DS.'submit');
	        }

として、326行目(元ファイルは324行目)あたりの else 句の中に入れ込みます。


最後に、同じmail_controller.phpにメソッドをまるっと追加。

    /**
     * [private] 確認画面から戻る
     *
     * @param mixed mail_content_id
     * @return void
     * @access public
     */
    function _back($id)
    {
        $this->set('freezed',false);
        $this->set('error',false);

        if($this->dbDatas['mailFields']){
            $this->set('mailFields',$this->dbDatas['mailFields']);
        }

        //mailの重複チェックがある場合は、チェック用のデータを復帰
        $sendVal = array();
        $noSendVal = array();
        foreach($this->dbDatas['mailContent']['MailField'] as $val){
            if($val['valid_ex'] == 'VALID_EMAIL_CONFIRM'){
                if(! $val['no_send'] ){
                    $sendVal[$val['group_valid']] = $val['field_name'];
                } else {
                    $noSendVal[$val['group_valid']][] = $val['field_name'] ;
                }
            }
        }
        if(! empty($noSendVal) ){
            foreach( $noSendVal as $key => $val){
                foreach( $val as $v){
                    if( isset($this->data['Message'][$sendVal[$key]]) ){
                        $this->data['Message'][$v] = $this->data['Message'][$sendVal[$key]];
                    }
                }
            }
        }

        $this->action = 'index'; //viewのボタンの表示の切り替えに必要なため変更

        $this->set('mailContent',$this->dbDatas['mailContent']);
        $this->render($this->dbDatas['mailContent']['MailContent']['form_template'].DS.'index');
    }

とすれば、完成です。

で、スマホは基本PCと同じなので一応チェックして動作確認しておりますが、ケータイはview自体が別物なので baser/plugins/mail/views/elements/mobile/mail_form.php の

    <?php echo $mailform->submit(' 送信する ', array('class' => 'btn-red button'))  ?>

    <?php echo $mailform->submit(' 書き直す ', array('class' => 'btn-red button', 'name' => 'data[mode][back]'))  ?>
    <?php echo $mailform->submit(' 送信する ', array('class' => 'btn-red button', 'name' => 'data[mode][submit]'))  ?>

とすれば大丈夫です。

とりあえず、本体の方には、マージしてもらえるように(関連する細かいバグを含めて)リクエストしておりますが
現状のバージョンにくみこみたい場合はお試しください。

あと、完了画面で、リロードすると2回送信なるので、全部の処理が終わったあとに、
入力データの 初期化を組み込むべきだろうなぁ。取りあえずチケットは上げたのでそのうち修正されると思います。

≫ 続きを読む

baserCMS   2012/10/24   admin

baserCMSのCKEditorをカスタマイズしてみる

SyntaxHighlighter というコード表示のJSを組み込んだのはいいけど、いちいち <pre class="brush: php">と書くのは面倒なので、CKEditorのメニューに組み込んでみた。



今回は、3パータンのカスタマイズをしてみました。

1)直接コードに書いちゃえ。その1
/baser/view/helpers/bc_ckeditor.php
をカスタマイズします。
300行目辺りの

$jscode .= "editor_" . $field ." = CKEDITOR.replace('" . $this->domId($fieldName) ."',". $this->Javascript->object($ckoptions) .");";

の前あたりに

$jscode .= "CKEDITOR.config.format_pre = { element : 'pre', attributes : { 'class' : 'brush: php' } };";

とかくと、「フォーマット」「書式付き」の部分が <pre> から <pre class="brush:php">と変更されます。 ただし、これだと他にJSやSQLに対応できないので、お奨めはできません。


2)直接コードに書いちゃえ。その2
今回のお奨め。
/baser/view/helpers/bc_ckeditor.php の51行目あたりから

    var $style = array(
                    array(    'name' => '青見出し(h3)',
                            'element' => 'h3',
                            'styles' => array('color'=>'Blue')),
                    array(    'name' => '赤見出し(h3)',
                            'element' => 'h3',
                            'styles' => array('color' => 'Red')),
                    array(    'name' => '黄マーカー(span)',
                            'element' => 'span',
                            'styles' => array('background-color' => 'Yellow')),
                    array(    'name' => '緑マーカー(span)',
                            'element' => 'span',
                            'styles' => array('background-color' => 'Lime')),
                    array(    'name' => '大文字(big)',
                            'element' => 'big'),
                    array(    'name' => '小文字(small)',
                            'element' => 'small'),
                    array(     'name' => 'コード(code)',
                            'element' => 'code'),
                    array(     'name' => '削除文(del)',
                            'element' => 'del'),
                    array(     'name' => '挿入文(ins)',
                            'element' => 'ins'),
                    array(    'name' => '引用(cite)',
                            'element' => 'cite'),
                    array(     'name' => 'インライン(q)',
                            'element' => 'q')
            );

となっている所に、コードを追加して

    var $style = array(
                    array(    'name' => '青見出し(h3)',
                            'element' => 'h3',
                            'styles' => array('color'=>'Blue')),
                    array(    'name' => '赤見出し(h3)',
                            'element' => 'h3',
                            'styles' => array('color' => 'Red')),
                    array(    'name' => '黄マーカー(span)',
                            'element' => 'span',
                            'styles' => array('background-color' => 'Yellow')),
                    array(    'name' => '緑マーカー(span)',
                            'element' => 'span',
                            'styles' => array('background-color' => 'Lime')),
                    array(    'name' => '大文字(big)',
                            'element' => 'big'),
                    array(    'name' => '小文字(small)',
                            'element' => 'small'),
                    array(     'name' => 'コード(code)',
                            'element' => 'code'),
                    array(     'name' => '削除文(del)',
                            'element' => 'del'),
                    array(     'name' => '挿入文(ins)',
                            'element' => 'ins'),
                    array(    'name' => '引用(cite)',
                            'element' => 'cite'),
                    array(     'name' => 'インライン(q)',
                            'element' => 'q'),
                    array(     'name' => 'php code(pre)',
                            'element' => 'pre',
                            'attributes' => array('class'=>'brush: php')),
                    array(     'name' => 'sql code(pre)',
                            'element' => 'pre',
                            'attributes' => array('class'=>'brush: sql'))
            );

と「スタイル」のリストに新しいリストを追加してあげます。 たぶんこれが一番簡単です。

3)きちんとviewのテンプレートから引数でもってくる。 正統派のカスタマイズですが、ややめんどい。 /baser/plagins/blog/views/blog_posts/admin/form.php の167行目あたりから

<?php
    $styles = array('mystyle'=>
           array(
                    array(    'name' => '青見出し(h3)',
                            'element' => 'h3',
                            'styles' => array('color'=>'Blue')),
                    array(    'name' => '赤見出し(h3)',
                            'element' => 'h3',
                            'styles' => array('color' => 'Red')),
                    array(    'name' => '黄マーカー(span)',
                            'element' => 'span',
                            'styles' => array('background-color' => 'Yellow')),
                    array(    'name' => '緑マーカー(span)',
                            'element' => 'span',
                            'styles' => array('background-color' => 'Lime')),
                    array(    'name' => '大文字(big)',
                            'element' => 'big'),
                    array(    'name' => '小文字(small)',
                            'element' => 'small'),
                    array(     'name' => 'コード(code)',
                            'element' => 'code'),
                    array(     'name' => '削除文(del)',
                            'element' => 'del'),
                    array(     'name' => '挿入文(ins)',
                            'element' => 'ins'),
                    array(    'name' => '引用(cite)',
                            'element' => 'cite'),
                    array(     'name' => 'インライン(q)',
                            'element' => 'q'),
                    array(     'name' => 'php3 code(pre)',
                            'element' => 'pre',
                            'attributes' => array('class'=>'brush: php')),
                    array(     'name' => 'sql3 code(pre)',
                            'element' => 'pre',
                            'attributes' => array('class'=>'brush: sql'))
        )
      );
?>

と入れ替えるスタイルを記載します。ここで「mystyle」は好きに置き換えてもらって大丈夫ですが、あとで同じ文字列を設定する必要があるので忘れないでください。
次に、

<?php echo $bcForm->ckeditor('BlogPost.content',
    array('cols' => 60, 'rows' => 20),
    $ckEditorOptions1) ?>

となっているところを

<?php echo $bcForm->ckeditor('BlogPost.content',
    array('cols' => 60, 'rows' => 20),
    array_merge($ckEditorOptions1,array('stylesSet'=>'mystyle')),$styles) ?>

といれかえます。
このあと、$ckEditorOptions1が$ckEditorOptions2となっているところが直ぐしたにあるのですがそこも同じ様に

<?php echo $bcForm->ckeditor('BlogPost.content',
    array('cols' => 60, 'rows' => 20),
    $ckEditorOptions2) ?>

となっているところを

<?php echo $bcForm->ckeditor('BlogPost.content',
    array('cols' => 60, 'rows' => 20),
    array_merge($ckEditorOptions2,array('stylesSet'=>'mystyle')),$styles) ?>

といれかえます。(1つだけだと反映できません。) とすると、ここで設定したスタイルで上書きができます。
'stylesSet'=>'mystyle'の部分のmystyleは先のスタイルの設定の配列の部分のkeyと同じ文字列です。
ただ、今回設定した preですが、思った通りの囲みが出来ないことが多いのでやっぱりソースビューで綺麗にしてあげる必要がありそうです。 とりあえず、オリジナルのstyleとかをボタン一つで当て込みたい時とかに使えるテクニックでした。

 

≫ 続きを読む

baserCMS   2012/09/19   admin

PostgreSQLに興味がある人向けにまとめてみた。

PostgreSQL9.2がでたのと、一部で?またPostgreSQLを使いたいと思ってる人が多くなったとかあるみたいなので
4〜5年触ってなかったか、全然知らない人向けとおさらいとしてまとめてみた。
 



ざっくり書いてるので、詳しい人からみるとおかしい点もあるかと思いますが、気になった点はより詳しい記事が
あると思うので、調べてみてください。

明らかな間違え等々は、修正加筆したいので、コメントか twitterの @itm_kiyoまで、御願いします。
 

  • Q. なんて読むの?書くの?
  • A. PostgreSQL(ぽすとぐれすきゅーえる)、PとSQLは大文字。ちなみにMySQL(y以外は大文字)なんで、小文字と大文字の区別をきちんとするとその界隈の人がよろこびます。
    でも、「postgres」 とか 、「Postgres」や「ポスグレ」とか書かれてることも多いです。

 

  • Q. どのバージョンを使うのが良いの?
  • A. 最新版。とりあえず、最新版。基本的に最新版が一番機能が豊富で速い。
    ただ、その版で取り込まれた新機能については、当然バグも多くあると思うので、マイナーバージョンがすこし上がるのを待つのが良いかと思う。

 

  • Q. 最新版が、早いといいますがベンチマークとっても早くなってなさそうなんですが。
  • A. 単純なSQLだと見た目に差が出づらいです。内部のオプティマイザが苦悶するようなSQLだと差が出やすいと思います。

 

  • Q. どのぐらいのサイクルでリリースしてるの
  • A. 大体、1年か1年半ぐらいでバージョンアップしてる。2桁目までは、メジャーバージョンで、3桁目がマイナーバージョン(セキュリティパッチ等)にあたるので。
    9.1.3 は、version9.1 の3番目のバージョンという事になる。

 

  • Q. もっと具体的におしえて
  • A. 1997/01 6.0
    1998/03 6.3
    1998/01 6.4
    1999/11 6.5
    2000/05 7.0
    2001/04 7.1
    2002/02 7.2
    2002/11 7.3
    2003/11 7.4
    2005/01 8.0
    2005/11 8.1
    2006/12 8.2
    2008/02 8.3
    2009/07 8.4
    2010/09 9.0
    2011/09 9.1
    2012/09 9.2
    って感じらしいよ。

 

  • Q. サポートあるの?
  • A. サポート事業をしてる企業様があるので、そちらでお願いします。バグ報告とかは、本家の方に直接だしてもいいのだけどJPUGのMLへ投稿しても良い感じになるかも。
    あと、4世代前までしかメンテしない方針なので、今回9.2がでたので8.2のメンテナンスは打ち切られると思います。
    そう言う意味でも、できるだけ新しいのを使う方が吉。

 

  • Q. JPUGってなによ?
  • A. 日本PostgreSQLユーザ会(ユーザーと伸ばさない)。僕も所属してるけど、PostgreSQLの普及・促進を目指すNPO法人です。
    各支部とかもあるので、参加してくれると嬉しいです。

 

  • Q. バージョンはどうやってきまるの?
  • A. たぶん気分。8.xになったときは、Windows対応したので、9.xになったときは、レプリケーション対応したので、という理由だったはず。これは、1桁目のメジャーバージョンをかえるインパクトがある機能追加があった場合に変わるみたいだ。
    一説によれば、PostgreSQLは、4までしか数字を数えられないので、x.4 のあとは1桁目が上がるという説もある。この説がただしければ9.4の次は10.0という事になります。

 

  • Q. Windows版がないんじゃ??
  • A. 8.0で、windowsも対応しました。9.0からは、64bit Windowsも対応。

 

  • Q.ライセンスはどうなってるの?
  • A. The PostgreSQL Licence (PostgreSQL) になるのですが、BSDタイプ(準拠した)のライセンスです。簡単に書くと、元のライセンス条件の記述さえ消さなければ好きに使って大丈夫ってやつ。
    もっと簡単に書くと、好きに使って問題無い!

 

  • Q. FDWってなによ?
  • A. FDW(Foreign Data Wrappe),外部データラッパっていうやつで、SQL/MED(Management of External Data)の規格の一つで簡単にいうと、PostgreSQLにQUERYを発行したら、あら不思議、外部の(たとえばMySQLとかCSV)データが取得できるという変態機能。
    twitterAPIに変更あるらしいから今後はわからにけど、twitterのデータを取ってくるとかもできる。というかラッパーが用意されてる。(ちなみに使ってみたら楽しかったw)

 

  • Q. なぜその様な機能を実装したの。
  • A. はい、ここ大切。標準SQLに規格の記載があったから。PostgreSQLは標準SQLに準拠する事に重きをおいてます。なんで実装されました。

 

  • Q. 使って見ようとおもって9.1をいれたら、エスケープでwaningだでるのですが。
  • A. postgresql.confの、standard_conforming_strings が on になっているとおもわれます。今すぐ、offにしてreloadするか、おそらく、「where name = 'i\'tm_kiyo'」 とかなっている所を「where name = E'i''tm_kiyo'」か、「where name = E'\'tm_kiyo'」とかに書き直してください。
    この動作は、標準SQLで規程されてるので採用されました。PostgreSQLが標準SQLに準拠する姿勢の本気度が見えました・・・

 

  • Q. 日本語のソートがおかしいのですが。
  • A. ロケール(locale)をみなおす、 「psql -l」とかで、localeをチェック。
    「C」となっていたら、あなたのプログラムがおかしいです。「ja_JP.UTF-8」とかなってたら仕様です。今すぐPostgreSQLが、8.3より古ければ「initdb --no-locale」8.4以降であれば「createdb dbname --locale=C」とかしてください。
    詳しくは、http://lets.postgresql.jp/documents/technical/text-processing/2

 

  • Q. 昔つかってたけど、vacuumするのが面倒だよね?
  • A. autovacuum を使ってください。自動でやっくれます。仕組み的には、8.1から組み込まれてるのですが、8.3からデフォルトでONになりました。
    これは、開発者達の「自動でさせても性能が劣化しないからデフォルトONにしたよ」というメッセージだとおもって、素直に使ってください。
    ちなみに、8.4からは、vaccumに関係する設置値の max_fsm_pages も自動になったので、特になにかをする事はありません。

 

  • Q. でも、PostgreSQLって追記型なんで速度的に遅いんでしょ?
  • A. MySQLは、UPDATEが行われた時に、元のデータがあった場所へデータを上書きする。
    PostgreSQLは、UPDATEが行われた時に、元のデータに削除フラグを立てて、データの最後に追記する。
    簡単に書くとこういうイメージだと思われますが、PostgreSQLの中の人たちがこの部分にメスを入れないハズはなく。
    8.2に、FILLFACTORと言う機能。(データを追加するときに、すこし空き領域をもたせる事によって、更新されたときに元のデータの近くに配置する事ができ、余計なディスクスキャンをへらす)
    8.3で、Hot(Heap Only Tuple)と言う機能(データが更新されると、必ずインデックスも更新されてた、それをスキップしちゃう)
    などの機能で、更新処理が早くなってたりします。

    おまけですが追記型故にDBサイズが肥大化しがちだったのですが、Hotの機能の副産物で、ガベージ(ゴミデータ)を回収(再利用)するのはVACUUMの役割だったのですが、VACUUMが動かなくても回収出来る様になりDBサイズが大きく肥大する事などがなくなりました。
    つまりは、DBの肥大化という問題も同時に解消されていっていると言うこと。
    これは、 8.4で、Visibility map(ゴミデータの監視)の機能追加とかもあるのですがVisibility mapは、9.2で実装された、「index only scan」に繋がってきてるというのは話が大きくそれるのでまた今度。

 

  • Q. わかったけど、じゃあ、どのぐらいスケーラビリティする?
  • A. 8.1で、CPUの8コア。8.2で、16コア。今度の9.2で、64コアまでスケーラビリティ。
    サーバ1台で足りなければ、9.0からはレプリケーションもあるし、pgpool-II ,Slony-I とか他にも色々あるので用途によって使い分けてください。
    (09/13:17:40 追記:CPUのスケールは、TPC-Wの様な、ほぼreadなら望めるけど、TPC-Cの様なもでるだと9.1でも8コア程度という事をご指摘頂きました、ということは9.2の64コアもread中心って事かもしれませんね。要調査。)

 

  • Q. レプリケーションってどこまできるの?
  • A. 9.0で非同期、9.1で同期、9.2でカスケーディングができます。PostgreSQLの非同期と同期は、
    スタンバイにデータを送りつけるだけが非同期。
    スタンバイにデータが送られた事を確認までできたのが同期。(MySQLでいう準同期にあたるらしい)
    なので、どちらもスタンバイ側のPostgreSQLにきちんとデータが登録されたという点までは確認してませんのでお間違えの無いように。
    ちなみに、PostgreSQLのレプリケーションはWALファイルの転送で実装しています。
    あと、業務でレプリケーションを使うなら9.1以降がお奨めです。9.1で実装された管理コマンド等があるためです。

 

  • Q. 可用性を高めるために、2台構成で1台をウォームスタンバイしておきたけどお奨めある?
  • A. 大規模なのは、やったことないのでわかりませんが、最小限のスタンバイあわせて2台構成とかなら9.1以降を利用して、同期レプリケーションをとりつつ、HAクラスタはPacemakerを使うのを個人的にお奨め。
    Pacemakerには、PostgreSQL用の設定ファイルがあるはずなんで、それを利用します。Heartbeat+DRBDでもいいのですけどね。

    付属の利点として、Pacemakerの萌えキャラ「かなちゃん」「かよちゃんは」を見て、(*´∀`*)萌え~としてても業務だと言い張れます。
    一応JPUGにも「かめさん」というマスコットがいるので応援してあげてください。。(改めてみたら、名前が無い様だったので記載通り「かめさん」が名称だと勝手に解釈しています)

 

  • Q. GUIのツールとかないの?
  • A. pgadmin,phpPgAdmin とかがあります。

 

  • Q.情報はどこからしいれるの?
  • A. とりあえず、JPUGのセミナーを聞いてもらうとか、仕組み分科会の勉強会でコアな話をするとか、let's.postgres とか、postgres でググるとか、本(PostgreSQL徹底入門 第3版 あたりか?)買うとか

 

  • Q. おいら英語が苦手でさー。
  • A. PostgreSQLのドキュメントは全て日本語化されてます。これはJPUGの文書・書籍関連分科会がボランティアで行っています。
    9.2のドキュメントも2週間もあれば日本語化されると思いますが、その裏には分科会の方々のがんばりがある事を頭の片隅においておいて頂けると嬉しいです。
    分科会はMLを中心に活動してるので、可能な方は参加して頂けるともっと嬉しいです。(僕も参加してるぉ!幽霊部員だけどな!!)

 

  • Q. どのような方々が開発してるの?
  • A. PostgreSQL Global Development Group が開発しています。というと偉そうですが、世界各地の技術者がそれぞれの機能を開発して、コアメンバが取り込むかどうかを決定(先に開発の指針も)を行っています。
    マルチバイト対応をおこなった石井さんを初め、レプリケーションを実装した藤井さん等々多くの日本の開発者も開発に携わっています。

 

  • Q. 本体に入ってない機能を使いたいのですが?
  • A. 追加モジュールのcontribの事だと思います。ソースからインストールした場合は、「cd ./contrib | make | make install 」とかで組み込めるのですが9.1からは EXTENSION という管理単位が導入されたので、「CREATE EXTENSION hogehoge」とかでも組み込めます。(というかできるならこっちで)

 

  • Q. はやりのNoSQL(Not Only SQL)の方がいいんじゃね?
  • A. ひとえに、databaseといってもその目指す方向性で大きく利用形態等々が異なってきます、多くのNoSQLのアプリが、Partition Tolerance(ネットワーク分断への耐性)とAvailability(可用性)に重きを置いているのに対して、PostgreSQLをはじめとする、RDBMSは Consistency(一貫性、整合性)とAvailability(可用性)に重きを置いてます。
    誰かのツイートは、少々表示の時差があっても困りませんが、振込をして、銀行口座の残金が減ってるはずなのに、表示が変わらなかったら困りますよね(それはそれで嬉しいかもしれませんが)
    どちらが優れてるというのではなく、プロジェクト每にどのDBが最適か?で選んだ方が幸せになれると思います。

    とはいえ、PostgreSQLにも、XML型、JSON型等あり、それぞれの構造自体を保存して、XMLならXPath経由で必要な情報を取得できたり、contrib(追加モジュール)になりますが、hstoreという(キー、値)の組み合わせの集合を単一のPostgreSQLデータフィールドに格納するためのhstoreデータ型、つまりは 「Key Value Store」を実装していたりするので、NoSQLの側面ももっているという手前味噌な自慢をさせてくださいませ。

 

  • Q. 良いことばかり行ってるけど弱点も教えてよ
  • A. なんでしょうね。組込にむいてなとか? 不得手はあるとは思いますが、致命的な弱点というのはあまりないんじゃないかなー?ちょっと書くの(考えるの)に疲れてきました。。。

 

  • Q. てか機能面を教えてよ、どのような事ができるとか。
  • A. 色々できるので、またこんどで。というか書いてたらきりがない。PostGISとか特徴的なことはあるけど。なんか色々できます。だいぶ書くの(考えるの)に疲れてきました。。。。。。

 

  • Q. よし、今○○使ってるけど、乗り換えてみるか!マイグレーションは簡単?
  • A. 簡単でないと思うけど事例はあります、JPUGのセミナーでマイグレーションの話とかもやってます。当然、マイグレーションのサービスをしてくれる企業様もあるので興味がある方は調べてみるといいと思います。



ということで、なんかツッコミとかされたた、加筆修正します。

--
なんかたったこれだけ書くのに4時間かかったぉ(>_<)
 

≫ 続きを読む

PostgreSQL   2012/09/13   admin