console api を使ってみた & 不具合があったのでチケット投げた

I submitted the ticket about console api bug. Now, fixed and closed.
https://trac.cakephp.org/ticket/6474


CakePHPでコンソールアクセスするのはBakeぐらいしか使わなかったんですが、console apiというのがあるのを知りました。下記の動画の20分目ぐらいにGwooがconsole apiについて説明しています。
http://www.youtube.com/watch?v=nZcyul3-s0s


console apiはコアライブラリのapi説明をオフラインでも見ることができるものです。
具体的には、consoleでcake api Modelとやると、libs/model/model.phpのクラスの中のメソッド説明が出てきます(下記が出力結果)

Model
---------------------------------------------------------------
1. afterFind($results, $primary = false)
2. afterSave($created)
3. beforeDelete($cascade = true)
4. beforeFind($queryData)
5. beforeSave($options = array())
6. beforeValidate($options = array())
7. bind($model, $options = array(), $permanent = true)
8. bindModel($params, $reset = true)
9. create($data = array(), $filterKey = false)
10. deconstruct($field, $data)
11. del($id = null, $cascade = true)
12. delete($id = null, $cascade = true)
13. deleteAll($conditions, $cascade = true, $callbacks = false)
14. escapeField($field = null, $alias = null)
15. exists($reset = false)
16. field($name, $conditions = null, $order = null)
17. find($conditions = null, $fields = array(), $order = null, $recursive = null)
18. findAll($conditions = null, $fields = null, $order = null, $limit = null, $page = 1, $recu
19. findAllThreaded($conditions = null, $fields = null, $order = null)
20. findCount($conditions = null, $recursive = 0)
21. findNeighbours($conditions = null, $field, $value)
22. getAssociated($type = null)
23. getColumnType($column)
24. getID($list = 0)
25. hasAny($conditions = null)
26. hasField($name)
27. invalidFields($options = array())
28. invalidate($field, $value = true)
29. isForeignKey($field)
30. isUnique($fields, $or = true)
31. joinModel($assoc, $keys = array())
32. read($fields = null, $id = null)
33. remove($id = null, $cascade = true)
34. save($data = null, $validate = true, $fieldList = array())
35. saveAll($data = null, $options = array())
36. saveField($name, $value, $validate = false)
37. schema($field = false)
38. set($one, $two = null)
39. setDataSource($dataSource = null)
40. setInsertID($id)
41. setSource($tableName)
42. unbindModel($params, $reset = true)
43. updateAll($fields, $conditions = true)
44. updateCounterCache($keys = array(), $created = false)
45. validates($options = array())

Select a number to see the more information about a specific method. q to quit. l to list.
[q] >

この一覧から説明が見たいメソッド番号を入力すると下記の説明が表示されます(下記はModel::set()の例)

[q] > 38
---------------------------------------------------------------
Model::set($one, $two = null)
---------------------------------------------------------------

  This function does two things: 1) it scans the array $one for the primary key,
  and if that's found, it sets the current id to the value of $one[id].
  For all other keys than 'id' the keys and values of $one are copied to the 'data' property of this object.
  2) Returns an array with all of $one's keys and values.
  (Alternative indata: two strings, which are mangled to
  a one-item, two-dimensional array using $one for a key and $two as its value.)

  @param mixed $one Array or string of data
  @param string $two Value string for the alternative indata method
  @return array Data with all of $one's keys and values
  @access public

Select a number to see the more information about a specific method. q to quit. l to list.

結果として出力される説明は、メソッドの手前に記述されているコメントを抽出して出力しているだけですが、ネット環境がなくて簡単に調べたいときには使えるかも。


helperのformのやつがみたければ、下記のようにすれば見れます。

cake api helper form

自作のcontrollerやプラグインなどには対応してないみたいです。


このメソッド一覧とコメント欄の取得は、前に書いたようにリフレクションクラスを使っているのかと思ったんですが、PHP4も対応させるためにリフレクションは使わずに、正規表現で引っこ抜いてます。


具体的にはconsole/libs/api.phpの下記のメソッド(要点だけ抽出)

function __parseClass($path) {
    if (preg_match_all('%(/\\*\\*[\\s\\S]*?\\*/)(\\s+function\\s+\\w+)(\\(.+\\))%', $contents, $result, PREG_PATTERN_ORDER)) {
    
    }
}

preg_match_allの正規表現箇所の、最初の括弧でコメント欄を、次の括弧でメソッド名を、最後の括弧でメソッドのパラメータ情報を取得しています。


昨日IRCでconsole apiについて色々と話してて盛り上がってたら、どうも取得できないメソッドがあって、なんでかなぁと話してたら、miauさんの「パラメータ情報取得の正規表現が間違ってるんじゃない?」という発言を元に、不具合の原因が分かって、パッチつきでチケット投げました。
https://trac.cakephp.org/ticket/6474

パッチつきで投げたら、US時間の朝一で速攻でMarkさんが修正をコミットしてくれました。早い!
https://trac.cakephp.org/changeset/8203


具体的な修正は、正規表現の箇所の最後の(\\(.+\\))を(\\(.*\\))に変えただけです。