Delphi for PHP でコンポーネントを作成する

Por: Tomohiro Takahashi

Resumen: この記事では、シンプルなVCL for PHPコンポーネントを作成する手順を解説します

Delphi for PHP は、VCL for PHP によって、ビジュアルなIDEに統合可能なPHPコンポーネントを作成するための標準規格を提供します。この標準規格は、既存のPHPのコードベースを再利用できるよう、可能な限りオープンであるかをチェックされています。

コンポーネントを作成することにより、次のようなメリットを得られます:

  • 動作済みの機能を抽象化およびラップし、プロパテイ、メソッドやイベントを通して簡単に利用可能なインターフェースを提供できる
  • 最高の再利用性を提供できる
  • 最良のビジュアル開発のエクスペリエンスを享受できる
  • さらに、サードパーティがコードを簡単に利用できる

以前ブログに掲載した記事では、僅かなHTMLとCSSで簡単にグラフを作成できることを見ました。それでは、それらのコードをコンポーネントにラップして、ツールパレットへのインストールや、フォームへのドラッグ&ドロップ、オブジェクトインスペクタでのプロパティ設定が行えるようにしましょう。

もし、Delphi for Windows のコンポーネントを作成したことがあれば、この手順がいかにそれと似ているかが分かるでしょう。

    フォルダ構成

コンポーネントは VCL for PHP フォルダ内の中に作らなければなりません。ですので、C:\Program Files\CodeGear\Delphi for PHP\2.0\vcl の中に csschart というフォルダを作成して、csscharts.inc.php という名前のユニットを作成しましょう。このユニットは、これから記述しようとしている新しいコンポーネント用のコードになります。

    クラスの派生

開発を始めるにあたり、ある既存のクラスから派生することが可能で、例えば、派生するのに最も適切なクラスは Control です。このControlクラスは、内部にコントロールをドラッグ&ドロップするのは許可しないものの、コンテナの中には配置可能であるビジュアルコントロールを作成したい場合には適切なクラスです。

以下は、コントロールの基本的なコードです:

<?php
use_unit("controls.inc.php");

class CSSChart extends Control
{
  function __construct($aowner = null)
  {
    parent::__construct($aowner);
  }
}
?>

このコンポーネントクラスは CSSChart という名前で、Controlから派生し、後に利用するためにコンストラクタをオーバーライドしています。

    プロパティの追加

チャートに表示するデータを格納するためのプロパティが必要になりますので、追加してみましょう。[Edit] - [Add published property] を選択すると、プロパティ名とデフォルト値の入力を促されます。以下が生成されたコードです:

protected $_data = array();
function getData() { return $this->_data; }
function setData($value) { $this->_data = $value; }
function defaultData() { return array(); }

情報を効率的に格納するprotectedなフィールドおよび、getter/setter/default関数が生成されました。このプロパティは'get'で始まるので、オブジェクトインスペクタに表示され、ユーザーによる値の変更も可能になります。

    初期化

次に初期化用のコードを追加する必要があります。例えば、コントロールのデフォルトのサイズを設定し、デフォルト値に合致するように配列データを初期化します。

コンストラクタは次のようになるはずです:

function __construct($aowner = null)
{
  parent::__construct($aowner);

  //Set the initial properties on the constructor
  $this->Width = 330;
  $this->Height = 145;
  $this->_data = array();
}

    コンポーネントはどのようにHTMLを出力するのか?

以前ブログに掲載した記事には異なる形式のチャートがありましたが、例として水平バーのチャートを取り上げます。そのチャートを描画するのに使用したHTMLコードを見てみると、次のようになっています:

<ul class="chartlist">
<li>
<a href="http://www.example.com/fruits/apples/">Apples</a>
<span class="count">420</span>
<span class="index" style="width: 42%">(42%)</span>

</li>
<li>
<a href="http://www.example.com/fruits/bananas/">Bananas</a>
<span class="count">280</span>
<span class="index" style="width: 28%">(28%)</span>
</li>
<li>

<a href="http://www.example.com/fruits/cherries/">Cherries</a>
<span class="count">200</span>

<span class="index" style="width: 20%">(20%)</span>
</li>
<li>
<a href="http://www.example.com/fruits/dates/">Dates</a>

<span class="count">100</span>
<span class="index" style="width: 10%">(10%)</span>
</li>
</ul>

これらは基本的なリストであり、それぞれの項目にはテキストと2つのspanタグがあります。VCL for PHPのコンポーネント開発の基本は、コンポーネントのプロパティによって提供される情報を使用して、動的なコードでそれらのHTMLデータを出力することです。

ブラウザに何か表示するようコンポーネントに指示するには、dumpContents()メソッドをオーバーライドします。このメソッドは、コンポーネントのコンテンツを生成するために呼び出されます。では、HTMLデータを生成するために、以前追加したDataプロパティを使ってみましょう。

function dumpContents()
{
  //Get the data to use
  $data = $this->_data;

  //Echoes the start of the list
  echo '<ul class="chartlist">';

  //Iterates through the data and dump each <li> tag
  reset($data);
  while(list($key, $val) = each($data))
  {
    echo '<li>';
    echo '<A href="">';
    echo $key;
    echo '</a>';
    echo '<span class="count">' . $val . '</span>';
    echo '<span class="index" style="width: ' . ($val / 10) . '%">(' . ($val / 10) . '%)</span>';
    echo '</li>';
  }

  //Echoes the end of the list
  echo '</ul>';
}

このコードは、表示するデータを繰り返し処理して、配列データの項目それぞれに応じて必要なコードを出力します。

    デフォルトデータ

もし今すぐコンポーネントをインストールして、ページに配置した場合、Dataプロパティは空ですから何も表示されません。ですので、設計時には何らかの処理が必要です。

dumpContents()メソッドを書き直して、表示すべきデータがあるかどうかチェックしましょう。もし何も情報が無く、且つIDE内で実行される場合には、サンプルデータを追加して、コントロールがどのように見えるのかをユーザーがチェックできるようにします。

function dumpContents()
{
  //Get the data to use
  $data = $this->_data;

  //If there is no information to show
  if(count($data) == 0)
  {
    //And we are in design-time
    if(($this->ControlState & csDesigning) == csDesigning)
    {
      //Let's use some sample data
      $data = array();
      $data['PHP'] = 800;
      $data['Delphi'] = 700;
      $data['Java'] = 500;
      $data['C#'] = 400;
    }
  }

  //Echoes the start of the list
  echo '<ul class="chartlist">';

  //Iterates through the data and dump each <li> tag
  reset($data);
  while(list($key, $val) = each($data))
  {
    echo '<li>';
    echo '<A href="">';
    echo $key;
    echo '</a>';
    echo '<span class="count">' . $val . '</span>';
    echo '<span class="index" style="width: ' . ($val / 10) . '%">(' . ($val / 10) . '%)</span>';
    echo '</li>';
  }

  //Echoes the end of the list
  echo '</ul>';
}

IDEの中かどうかは、ControlStateプロパティとcsDesigning形式を使って判定することができます。csDesigningは、コンポーネントがIDEの中で動作している時にだけ設定されます。

    リストにスタイルシートを適用する

もしコンポーネントを実行すればその情報が見えますが、見た目はあまり良くありません。少なくもと元の記事と同じように見えるためには、何が足りないのでしょうか?チャートはスタイルシートを使用して描画されていますので、コンポーネントにスタイル情報を出力させる必要があります。

最初の手順は、必要なスタイル全てが含まれた.cssファイルを作成することです。では、csscharts.css と名前を付けて、csscharts.inc.php のあるフォルダと同じ場所に配置しましょう。

次のコードを追加します:

/* CHART LISTS */
.chartlist {
font-family: Helvetica, Arial, sans-serif;
color: #333;

float: left;
border-top: 1px solid #EEE;
width: 15em;
}
.chartlist li {
position: relative;
display: block;
border-bottom: 1px solid #EEE;
_zoom: 1;
}
.chartlist li a {

color: #2D7BB2;
text-decoration: none;
font-weight: bold;

display: block;
padding: 0.4em 4.5em 0.4em 0.5em;
position: relative;
z-index: 2;
}

.chartlist li a:hover {
color: #333;
}

.chartlist .count {
display: block;
position: absolute;
top: 0;
right: 0;
margin: 0 0.3em;
text-align: right;
color: #999;
font-weight: bold;
font-size: 0.875em;
line-height: 2em;
}
.chartlist .index {
display: block;
position: absolute;
top: 0;
left: 0;
height: 100%;
background: #B8E4F5;
text-indent: -9999px;
overflow: hidden;
line-height: 2em;
}
.chartlist li:hover {
background: #EFEFEF;
}

CSSスタイルシートの準備ができました。コンポーネントにそれを使用するよう指示する必要がありますが、dumpHeaderCode()メソッドをオーバーライドすることで可能です。このメソッドは、Pageコンポーネントがドキュメントの<head>セクションを生成する際に呼び出されますので、スタイルシートを出力するのに適切な場所です。

function dumpHeaderCode()
{
  parent::dumpHeaderCode();
  echo '<link type="text/css" rel="StyleSheet" href="'. VCL_HTTP_PATH .'/csschart/csscharts.css" />';
}

ここでは、親クラスのdumpHeaderCode()メソッドを呼び出して、先ほど記述したばかりの.cssファイルを取り込むための1行を出力しています。

    VCL_HTTP_PATH とは?

VCL_HTTP_PATH は、VCL for PHP によって動的に定義される定数で、ブラウザで見た際に確実にVCLフォルダを参照出来るようにするためのものです。ですので、そのようなことを心配せずに簡単にコンポーネント内にリソース(画像, JavaScript, CSS)を取り込めるのです。

    複数のコンポーネント

しかし、ページ内に5個のチャートコンポーネントを取り込んだ場合はどうなるでしょう? .cssスタイルシートが5回も取り込まれることになるでしょう。これを防ぐ簡単な方法は、既に追加したかどうかをチェックすることです。

function dumpHeaderCode()
{
parent::dumpHeaderCode();

//If we have not dump the style sheet for charts yet, let's do it
if(!defined('CSSCHARTS'))
{
define('CSSCHARTS', 1);
//Note the VCL_HTTP_PATH constant
echo '<link type="text/css" rel="StyleSheet" href="'. VCL_HTTP_PATH .'/csschart/csscharts.css" />';
}
}

これでコンポーネントをIDEに追加する準備が整いました。これまででも追加することは出来たのですが、サンプルプロジェクト上で動作させ、そこで実行時にそのコンポーネントを生成するのがベターですし、開発しながらテストすることができます。コンポーネントの準備がほぼ整ったら、安全にIDEに追加することができます。

    IDEにコンポーネントを追加する

IDEにコンポーネントを追加するには、パッケージが必要となります。新規ユニットを作成して、作業しているフォルダと同じ場所に csscharts.package.php という名前で保存します。

以下は、今回のコンポーネントをインストールするパッケージ用のコードです:

<?php
require_once("vcl/vcl.inc.php");
use_unit("designide.inc.php");

setPackageTitle("CSS Charts sample component");
//Change this setting to the path where the icons for the components reside
setIconPath("./icons");

//Change yourunit.inc.php to the php file which contains the component code
registerComponents("CSSChart", array("CSSChart"), "csschart/csscharts.inc.php");

registerPropertyEditor("CSSChart","Data","TValueListPropertyEditor","native");
?>

ユニット designide.inc.php は、使用する以下の関数を含んでいます:

  • setPackageTitleは、表示されるパッケージタイトルをIDEに指示します
  • setIconPathは、このパッケージ内のコンポーネントアイコンを検索する場所をIDEに指示します
  • registerComponentsは、csschart/csscharts.inc.phpユニットに格納されたCSSChartという名前のコンポーネントを、ツールパレットのCSSChartカテゴリにインストールするようIDEに指示します。そのパスは、VCL for PHPのパスからの相対パスでなければなりません。
  • registerPropertyEditorは、CSSChartコンポーネントのDataプロパティを編集するのに、TValueListPropertyEditorという名前のプロパティエディタを使用するようIDEに指示します

ここで、[Component] - [Install Packages] を選択してコンポーネントをインストールすると、ツールパレットの最下部に追加されます。それをページに配置すると、次のようになります:

Hide image
Click to see full-sized image

Dataプロパティを選択すると、[...]ボタンが表示されクリックできるようになります。クリックするとダイアログを使ってDataプロパティの配列をカスタマイズすることができます。設計時にこのプロパティを変更すると、以下のような表示になります。

Hide image
Click to see full-sized image

これまで見てきたように、VCL for PHPのコンポーネントの作成はとても簡単で、Delphi for Windowsのコンポーネントの作成と多くの類似点があります。


今後の記事では、今回のコンポーネントにDataSourceプロパティを追加する方法を紹介します。そのデータはデータベースのテーブルから取得し、今回のコンポーネントをますます便利なものにしてくれるでしょう。

今回のコンポーネントをダウンロードする

Respuesta del Servidor desde: ETNASC01