Git Product home page Git Product logo

codelapse's People

Contributors

thiry1 avatar ucym avatar

Watchers

 avatar  avatar  avatar

Forkers

hanakla

codelapse's Issues

Pager class

Benefit

ページネーションの実装にかかるコードが削減されます。

Feature

  • 全ページ数の自動計算
  • foreachイテレーションによるページリンクの生成
    • 簡易テンプレートエンジンによる foreachの削減
  • 範囲指定イテレータ(現在のページから前後nページ / 先頭からnページ / 後方から nページ)

Ideal code sample

<?php
require 'd5/bs.php';

define('ITEMS_PER_PAGE', 30);

$current_page = $_GET['page'];
$result = DB::query('SELECT COUNT(*) AS `count` FROM `users`')->fetch();
$all_count = $result['count'];

// Pager 初期化
Pager::init($current_page, $all_count, ITEMS_PER_PAGE);
?>

<!-- Example 1 -->
<ul class="pager">
<?php Pager::hasPrev('<li class="pager__page pager__page-prev"><a href="search.php?page=:page">&lt;&lt; 戻る</a></li>')  ?>
<?php Pager::relateRange(5, '<li class="pager__page"><a href="search.php?page=:page"></li>') ?>
<?php Pager::hasNext('<li class="pager__page pager__page-next"><a href="search.php?page=:page">次へ&gt;&gt;</a></li>')  ?>

<!--- Example 2 -->
あるいは以下の書き方もできる
<?php if (Pager::hasPrev()) : ?>
<li class="pager__page pager__page-prev">
    <a href="search.php?page=:page">&lt;&lt; 戻る</a>
</li>
<?php end if; ?>

<?php foreach (Pager::relateRange(5) as $page) : ?>
<li class="pager__page"><a href="search.php?page=<?php echo $page ?>"></li>
<?php end foreach; ?>

<?php if (Pager::hasNext()) : ?>
<li class="pager__page pager__page-next">
    <a href="search.php?page=:page">次へ&gt;&gt;</a>
</li>
<?php end if; ?>
-->

Description

Pager::init($currentPage, $allCount, $perPage) : void

ページャーを初期化します。
$currentPage は現在いるページ番号を"0から"の値で指定します。
$allCount は表示できるアイテムが全部で何件あるかを指定します。
$perPage は1ページに表示するアイテムの件数を指定します。
Pager::hasPrev($content = null) : bool

前のページが存在するかを true / false で表す。
$content が指定された時、 前のページが存在すれば $contentを表示します。
その際、$content内の":page"を前のページのページ番号に置き換えます。
Pager::hasNext($content = null) : bool

次のページが存在するかを true / falseで表します。
その他の動作は ::hasPrevに準じます。
Pager::relateRange($before_after, $content = null) : array

今いるページの前後 $before_after ページの範囲の配列を返します。
現在のページが 2、 $before_afterに 5を指定した時  array(0, 1, 2, 3, 4, 5, 6 ,7)を返します。
$content が指定された時、$content内の":page"を処理中のページ番号に置き換えながら表示します。

Introduction Sizzle like dom parser.

検討中のライブラリ

  • PHP Simple HTML DOM Parser
  • phpQuery

TODO

  • 各ライブラリが空のコレクションに対してどう動くか調べる
  • サンプルコードが正しいか検証

サンプル

ファイルからHTMLを読み込んで"ul#nav"を検索し、その中の"li"を検索、そのli要素の内部のテキストをechoする。

<?php // PHP Simple HTML DOM Parser
$html = file_get_html('http://www.google.com/');

foreach ($html->find('ul#nav')->find('li') as $element) {
       echo $element->plaintext;
}
<?php // phpQuery
// TODO

Support other template engines (View class)

Feature

他のテンプレートエンジンを使えるようにする

Benefit & Scene

  • より短くhtmlを記述できる言語(jade,slim)を利用したい
  • Smartyという既存資産を使いたい(新しい言語を学ぶ必要がない)

Ideal code sample

// lib/app-require.php
require "cl/bs.php";

// ユーザー情報を取得
$resultSet = DB::query('SELECT `name`, `icon` FROM `users` WHERE `id` = ?', [Session::get('user_id')]);
$user = $resultSet->fetch();

// ビューに設定
View::set([
  'user_name'  => $user['user.name'],
  'user_icon'  => $user['user.icon']
]);
``
`
``` php
// index.php
require 'lib/app-require.php';

// $news にお知らせ情報を取得

View::set('news', $news)->output('index.jade');
//- index.jade
doctype html
html
  head
    title #{user_name} | MyPage
 body
    #user-info
      img.userIcon(src=user_icon)
      span.userName= user_name

Public API Spec

class CodeLapse\View

View関連クラスの窓口となるクラス

  • set($name : String|Array, $value = null) : void
    Viewに変数を設定します。
    第1引数に割り当て名、第2引数に割り当てる値を指定します。
    第1引数が配列の場合、添字を第1引数、値を第2引数としてすべての要素に対してsetメソッドを実行します。
    設定された値はエスケープされます。
  • setRaw($name: String|Array, $value = null) :void
    Viewに変数を設定します。
    * 設定された値はエスケープされません。*
  • get($name : String|Array, $default = null) : mixed
  • out($filename : String) : String
    指定されたテンプレートをレンダリングし、表示します。
    ファイル名の拡張子によって使用するエンジンを切り替えます。
    • .jade - jade.php
    • .tpl - smarty
  • fetch($filename) : void
    指定されたテンプレートをレンダリングし、HTMLを返します。
  • setRoot($path) : void
    テンプレートの保存先パスを指定します。
    setRootによって値が設定されない場合はview.templateDir設定を利用します。
  • getDriver($extension: String) : CodeLapse\View\Driver
    指定された拡張子に対応するドライバ(Driverクラスの実装クラスインスタンス)を取得します。

interface CodeLapse\View\Driver

テンプレートエンジンの初期化などを行うクラスのインターフェース

  • __construct()
    テンプレートエンジンを初期化します。
  • getNativeDriver() : Object
    テンプレートエンジンのハンドラを取得します。
    たとえば、Smartyの場合は Smartyオブジェクト返します。
  • render($filePath, $variables) : String
    指定されたファイルをレンダリングして、文字列として返します。
    第1引数にはテンプレートファイルへのフルパス、
    第2引数には割り当てられた変数が渡されます。

class CodeLapse\View\Driver\Jade (implements CodeLapse\View\Driver)

class CodeLapse\View\Driver\Smarty (implements CodeLapse\View\Driver)

New feature proposal template

Feature

機能の概要

Benefit & Scene

想定する利用シーン+利用するメリット

Ideal code sample

実際の利用例サンプル(コード)

Spec

メソッド等仕様の解説

Profiler

Benefit

Profilerの利用で、実行中の変数の値のロギングやエラーの補足を行い。
より快適なデバッグ環境を提供する。
後に、DBクラスを利用したSQLの実行などを捕捉できるようにする。

Feature

  • PHPQuickProfiler(PQP)ベース
  • 1メソッドコールで有効・無効を切り替え
  • "var_dump"より短いログ用関数
  • 例外の捕捉
    • 通常のエラーよりも細かい情報(スタックトレースなど)を提供する
  • PQPより見やすいオブジェクト/配列出力

Ideal code sample

Deferred...

Description

class Profiler

  • ::activate()
    プロファイラを有効化します。
    プロファイラはactivateのコールをもって、例外の捕捉やパネルの表示を制御します。
  • ::time($label = null)
  • ::timeEnd($label = null) : int (nano-time)
    処理時間の計測を行います。
    ::timeで計測を開始、::timeStopで計測を終了し、処理時間をプロファイラに表示します。
    このとき第1引数を指定することで「なにについての計測か」を識別することが出来ます。
  • ::log($vars...)
  • ::info($vars...)
  • ::error($vars...)
    渡されたすべての変数の内容をプロファイラに表示します。

Validation

Feature

入力値検証を行い、パターンにマッチしない値の検出を行う

  • JavaScriptのリアルタイム検証用のコード出力を行う(希望)

Benefit & Scene

通常の値検証に加え、クライアントサイドのリアルタイム検証用のコード出力を行う。
バリデーションルールの鯖蔵間の二重定義を避け検証ルールの保守コストを下げたい。

また、クライアントサイドのリアルタイム検証を少ない時間で実装したい。

Ideal code sample

<?php
//
//-- 基本的な使い方
//
Validator::addRule('noDuplicatedEmail', function ($value, $fieldName, array $options) {
    $resutSet = DB::query('SELECT "" FROM `users` WHERE `email` = ?', [$value]);
    return $resultSet->fetch() === false;
}, function ($fieldName, $param) {
    return <<<JS
    // function (value, fieldName) {
        // trueを返すか resolveで trueを返されれば検証を通過
        // falseを返すか rejectすれば検証エラーを発生
        return new Promise(function (res, rej) {
            $.ajax({url: "/api/checkConflict", data:{email: value}, dataType: "json"})
                .done(function (res) {
                    res(res.conflict);  // res.conflict: Boolean
                })
                .fail(rej);
        });
    // }email_confirm
JS;
});

Validator::define(/* nullable -> */ 'register')
    ->rule('name',          ['required', 'minLength' => 4, 'maxLength' => 5])
    // ラベルを指定するときはフィールド名を "フィールド名:ラベル"形式で指定
    // ->rule('name:名前',   ['required', 'minLength' => 4, 'maxLength' => 5])
    // ->rule('email:メールアドレス',         ['required', 'email', 'noDuplicatedEmail'])
    ->rule('email',         ['required', 'email', 'noDuplicatedEmail'])
    ->rule('email_confirm', ['required', 'equals' => 'email'])
    ->rule('password',      ['required', 'minLength' => 6, 'maxLength' => 20])
    ->rule('password_confirm', ['required', 'equals' => 'password'])
    ->rule('credit_card',   ['required', 'credit_card' => ['visa', 'master']])
    ->rule('agree',         ['required', 'accepted']);

if (Validator::check($_POST, /* nullable -> */ 'register')) {
    echo 'Hello';
} else {
    echo 'Invalid!';
}

//
//-- 複数の設定を読み込む
//
$rules = [
    'name'              => ['required', 'minLength' => 4, 'maxLength' => 5],
    'email'             => ['required', 'email', 'noDuplicatedEmail'],
    'email_confirm'     => ['required', 'equals' => 'email'],
    'password'          => ['required', 'minLength' => 6, 'maxLength' => 20],
    'password_confirm'  => ['required', 'equals' => 'password'],
    'credit_card'       => ['required', 'credit_card' => ['visa', 'mastercard']],
    'agree'             => ['required', 'accepted']
];

// あるいはConfigクラスを用いて読み込む
// $rules = Config::get('validators.register');
if (Validator::check($_POST, $rules)) {
    echo 'Hello';
} else {
    echo 'Invalid!';
}

//
//-- 設定の再利用
//
Validator::addRule('validTwitterId', function ($value, $fieldName, array $options) {
    return preg_match('/^@[a-zA-Z0-9_]+$/', $value) === 1;
}, function ($fieldName, $param) {
    return 'return /^@[a-zA-Z0-9_]+$/.test(value);';
});

$rules = Config::get('validators.register');
Validator::define($rules, /* nullable -> */ 'regist with twitter')
    // email, email_confirm を検査項目から除外
    ->remove('email', 'email_confirm')
    // 新しい検査項目を追加
    ->rule('twitter_id', ['required', 'validTwitterId']);

if (Validator::check($_POST, 'regist with twitter')) {
    echo 'Hello';
} else {
    echo 'Invalid!';
}

Spec

  • Validator::define(string $fieldSetName = null) : Validator
  • Validator::define(array $rules, string $fieldSetName = null) : Validator
  • Validator::addRule(string $ruleName, callable($value, $fieldName, array $options) $validater, callable($fieldName, array $options) $jsValidatorGenerator = null) : void
  • Validator::check(array $data, string $fieldSetName) : bool
  • Validator::check(array $data, array $rules) : bool
  • Validator::js(string $fieldSet) : void
  • Validator::js(array $fieldSet) : void
  • Validator#rule(string $fieldName, array $rules) : Validator

[Restored issue] Add new feture "Form"

Feature

  • PHPでHTMLのInput要素を生成する
  • 入力値の割り当て・ポピュレーションを容易にする
    (text, checkbox, radio, textarea, select....)

Benefit

このクラスにより、単純な"登録と編集"ページの再利用性が向上します。

Form::bind()によりデータの入力元を選ばなくなるため、登録内容の復元はもちろん、
フォームのname属性に対応するように変換されたデータベース上のデータをフォームに展開することが可能となります。

Ideal code sample

<?php
require 'bs.php';

// POST内容をフォームに割り当て
Form::bind(Input::post());
// また、第二引数にフォーム名をつけられる: Form::bind(Input::post(), 'regist');
//  -> ページ内に複数のフォームが存在することを想定。
// フォーム名が指定されない時は "default"をフォーム名とする

// 職業の一覧を $work_typesに取得します
$work_types = get_worktypes();
?>
<body>
    <form method="post">
        <!-- 各フォーム生成メソッドは 自動でHTMLをprintする。 -->
        <!--
            textメソッド
                第1引数はフォームのname属性を指定
                もし割り当てられた値があれば、value属性を復元する
                    アイデア: IDとクラスを第1引数で指定可能にする?
                        ex : Form::text('user#id.class.class2')

                第2引数は、"属性名" => "値"で属性を指定できる
                連想配列が渡された時、値は自動でHTMLエスケープされる
                コード短縮のため、文字列でも指定可能にする
                    ex : Form::text('user', 'attr="value" attr2="value"')

                第3引数にインスタンス名を指定できる
                    ex: Form::text('user', array('class' => "form-control"), 'regist')
        -->
        <label>ユーザー名: <?php Form::text('user', array('class' => "form-control")) ?></label>
        <label>メールアドレス: <?php Form::email('mail') ?></label>

        性別
        <p>
            <!--
                radio, input は 値が一致すればchecked属性を付加する

                第1引数にname属性の値、第2引数にvalueの値をうけつけ、
                第3引数以降はtextメソッドの第2引数以降と同じとする
            -->
            <label><?php Form::radio('sex', 'male') ?></label>
            <label><?php Form::radio('sex', 'female') ?></label>
        </p>

        職業
        <!--
            selectも 値が一致した要素にselected属性を付加する
            第2引数に、選択項目の配列を受け取る。
            この配列は以下の形式とする
                array(
                    '表示名' => "value属性の値",
                    // あるいは
                    // '表示名' => array("value属性の値", '属性名' => '値'),

                    '表示名2' => "value属性の値2",
                );
            値に配列が渡された時、0番目の要素となるものをvalue属性の値として使う。
            もし0番目の要素がなければ 添字"value"を参照する。
            それでも値がなければ例外をスローする。

            この配列は以下のように展開される
                <option value="value属性の値">表示名</option>
                (値に配列を受け取った時)
                    <option value="value属性の値" '属性名'='値'>
                <option value="value属性の値2">表示名2</option>

            第3引数は、渡された配列に該当する値がないときの挙動を指定する。
            標準は IGNORE。
                CREATE : 選択肢を生成する
                IGNORE : 値がないものとして扱う
                STRICT : 例外をスローする

            第4引数以降はtextメソッドの第2引数以降と同じとする。
        -->
        <label>職業: <?php Form::select('work_type', $work_types) ?> </label>
    </form>
</body>

Mail wrapper

Feature

  • Multiple server support (sendmail & SMTP)
  • Mail
    • TO, CC, BCC (Multiple)
    • Attach File (Multiple)
      • From filepath, D5_File
    • Plain text / HTML message
    • Support Multibyte (for header / body)

Interface

class D5_Mail
{
  public __construct([array $config = array()])

  // Setting mail from
  public from(string $address) : D5_Mail

  // #to(), #cc(), #bcc() is push email address to interal list.
  //   join in before mail sending.

  // $to is valid mail address or array of valid email addresses.
  public to(array | string $to) : D5_Mail
  // $cc is valid mail address or array of valid email addresses. 
  public cc(array | string $cc) : D5_Mail
  // $bcc is valid mail address or array of valid email addresses.
  public bcc(array | string $bcc) : D5_Mail

  // Set subject
  // $subject is must be no contain EOL string.
  // if EOL contain, throw D5_Mail_InvalidSubjectException
  public subject(string $subject) : D5_Mail

  // Set mail body
  public body(string $body) : D5_Mail

  // Set mail body as HTML
  public htmlBody(string $body) : D5_Mail

  // add filepath to internal attaches list.
  // array is allowed contain valid file path or D5_File instance
  public attachFile(string | D5_File | array $file) : D5_Mail

  // send the mail.
  // if address list contains invalid address, or No exists file attached, throw D5_Mail_Exception
  // if mail submit failed, throw D5_Mail_Exception
  public send() : void
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.