3c612b517f960526d436454f59294406ad9e5b34

Author: chawbacca

Date: 2009-02-06 16:53:05 -0600

Merge from api_generator.git

diff --git a/api_generator_app_controller.php b/api_generator_app_controller.php index fc3fec3..f7042ea 100644 --- a/api_generator_app_controller.php +++ b/api_generator_app_controller.php @@ -49,7 +49,10 @@ class ApiGeneratorAppController extends AppController { $path = APP; $this->ApiConfig->data['paths'][$path] = true; } - $this->path = Folder::slashTerm(realpath($path)); + $this->path = Folder::slashTerm(realpath($path)); + $localePaths = Configure::read('localePaths'); + $localePaths[] = dirname(__FILE__) . DS . 'locale'; + Configure::write('localePaths',$localePaths); } /** * Error Generating Page. diff --git a/controllers/api_generator_controller.php b/controllers/api_generator_controller.php index 2fafdae..a05dfd2 100644 --- a/controllers/api_generator_controller.php +++ b/controllers/api_generator_controller.php @@ -120,9 +120,8 @@ class ApiGeneratorController extends ApiGeneratorAppController { } catch(Exception $e) { $this->_notFound($e->getMessage()); } - $classIndex = $this->ApiClass->getClassIndex(); + $classIndex = $this->ApiClass->getClassIndex(true); list($dirs, $files) = $this->ApiFile->read($this->path . $previousPath); - if (!empty($docs)) { $this->set('showSidebar', true); $this->set('sidebarElement', 'sidebar/file_sidebar'); @@ -191,85 +190,14 @@ class ApiGeneratorController extends ApiGeneratorAppController { } $term = trim($term); $terms = explode(' ', $term); - $conditions = array(); - $match = false; foreach ($terms as $i => $j) { if (trim($j) === '') { unset ($terms[$i]); } } - foreach ($terms as $i => $class) { - $slug = str_replace('_', '-', Inflector::slug(Inflector::underscore($class))); - if ($this->ApiClass->find('count', array('conditions' => array('slug like' => $slug . '%')))) { - $match = $class; - break; - } - } - $fields = array('DISTINCT ApiClass.name', 'ApiClass.method_index', 'ApiClass.property_index', 'file_name'); - $order = 'ApiClass.name'; - if ($match) { - $conditions['ApiClass.slug like'] = $slug . '%'; - $results = $this->ApiClass->find('all', compact('conditions', 'order', 'fields')); - } else { - $results = array(); - } - $conditions = array(); - foreach ($terms as $term) { - $conditions['NOT']['ApiClass.id'] = Set::extract($results, '/ApiClass/id'); - $conditions['OR'][] = array('OR' => array( - 'ApiClass.method_index LIKE' => '% ' . $term . '%', - )); - } - $results = am($results, $this->ApiClass->find('all', compact('conditions', 'order', 'fields'))); - $conditions = array(); - foreach ($terms as $term) { - $conditions['NOT']['ApiClass.id'] = Set::extract($results, '/ApiClass/id'); - $conditions['OR'][] = array('OR' => array( - 'ApiClass.property_index LIKE' => '% ' . $term . '%', - )); - } - $results = am($results, $this->ApiClass->find('all', compact('conditions', 'order', 'fields'))); - $docs = array(); - foreach ($results as $i => $result) { - $docs[$i] = $this->ApiFile->loadFile($result['ApiClass']['file_name'], array('useIndex' => true)); - foreach ($docs[$i]['class'] as $name => &$obj) { - foreach ($obj->properties as $j => $prop) { - $delete = true; - foreach($terms as $term) { - if (strpos($prop['name'], $term) !== false) { - $delete = false; - break; - } - } - if ($delete) { - unset ($obj->properties[$j]); - } - } - foreach ($obj->methods as $j => $method) { - $delete = true; - foreach($terms as $term) { - if (strpos($method['name'], $term) !== false) { - $delete = false; - break; - } - } - if ($delete) { - unset ($obj->methods[$j]); - } - } - if (!$match && !$obj->methods && !$obj->properties) { - unset($docs[$i]['class']); - } - } - if (!$docs[$i]['function']) { - unset ($docs[$i]['function']); - } - if (!$docs[$i]) { - unset ($docs[$i]); - } - } + $docs = $this->ApiClass->search($terms); $classIndex = $this->ApiClass->getClassIndex(); - $this->set(compact('classIndex', 'terms', 'class', 'docs')); + $this->set(compact('classIndex', 'terms', 'docs')); } /** * Extract all the useful config info out of the ApiConfig. diff --git a/locale/default.pot b/locale/default.pot new file mode 100755 index 0000000..a95c97a --- /dev/null +++ b/locale/default.pot @@ -0,0 +1,193 @@ +# LANGUAGE translation of CakePHP Application +# Copyright YEAR NAME <EMAIL@ADDRESS> +# Generated from file: Revision: 7945 \webroot\test.php +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"POT-Creation-Date: 2009-02-05 08:28+0900\n" +"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" +"Last-Translator: NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: \plugins\api_generator\controllers\api_generator_controller.php:117 +msgid "No file exists with that name" +msgstr "" + +#: \plugins\api_generator\controllers\api_generator_controller.php:144 +msgid "No class name was given" +msgstr "" + +#: \plugins\api_generator\controllers\api_generator_controller.php:150;178 +msgid "No class exists in the index with that name" +msgstr "" + +#: \plugins\api_generator\controllers\api_generator_controller.php:165 +msgid "Oops, seems we couldn't get the documentation for that class." +msgstr "" + +#: \plugins\api_generator\vendors\shells\api_index.php:64 +msgid "Your database configuration was not found. Take a moment to create one." +msgstr "" + +#: \plugins\api_generator\vendors\shells\api_index.php:100 +msgid "Routes file updated" +msgstr "" + +#: \plugins\api_generator\vendors\shells\api_index.php:103 +msgid "Routes file NOT updated" +msgstr "" + +#: \plugins\api_generator\views\api_generator\classes.ctp:53 +msgid "Index" +msgstr "" + +#: \plugins\api_generator\views\api_generator\classes.ctp:75 +msgid "(cont.)" +msgstr "" + +#: \plugins\api_generator\views\api_generator\files.ctp:7 +msgid "All files" +msgstr "" + +#: \plugins\api_generator\views\api_generator\files.ctp:17 +#: \plugins\api_generator\views\api_generator\source.ctp:29 +#: \plugins\api_generator\views\elements\sidebar\file_sidebar.ctp:28 +msgid "No files" +msgstr "" + +#: \plugins\api_generator\views\api_generator\no_class.ctp:7 +msgid "No classes were found in the requested file" +msgstr "" + +#: \plugins\api_generator\views\api_generator\search.ctp:10 +msgid "Search Results" +msgstr "" + +#: \plugins\api_generator\views\api_generator\search.ctp:12 +msgid "Your search returned no results" +msgstr "" + +#: \plugins\api_generator\views\elements\api_menu.ctp:4 +msgid "Classes" +msgstr "" + +#: \plugins\api_generator\views\elements\api_menu.ctp:11 +msgid "Source" +msgstr "" + +#: \plugins\api_generator\views\elements\api_menu.ctp:18 +msgid "Files" +msgstr "" + +#: \plugins\api_generator\views\elements\class_info.ctp:12 +msgid "Class Declaration:" +msgstr "" + +#: \plugins\api_generator\views\elements\class_info.ctp:15 +msgid "File name:" +msgstr "" + +#: \plugins\api_generator\views\elements\class_info.ctp:18 +msgid "Summary:" +msgstr "" + +#: \plugins\api_generator\views\elements\class_info.ctp:22 +msgid "Class Inheritance" +msgstr "" + +#: \plugins\api_generator\views\elements\class_info.ctp:27 +msgid "Interfaces Implemented" +msgstr "" + +#: \plugins\api_generator\views\elements\element_toc.ctp:10 +msgid "Defined Classes" +msgstr "" + +#: \plugins\api_generator\views\elements\element_toc.ctp:22 +msgid "Declared Functions" +msgstr "" + +#: \plugins\api_generator\views\elements\function_summary.ctp:18 +#: \plugins\api_generator\views\elements\method_detail.ctp:24 +msgid "Parameters:" +msgstr "" + +#: \plugins\api_generator\views\elements\function_summary.ctp:29 +#: \plugins\api_generator\views\elements\method_detail.ctp:35 +msgid "(no default)" +msgstr "" + +#: \plugins\api_generator\views\elements\function_summary.ctp:38 +msgid "Function defined in file:" +msgstr "" + +#: \plugins\api_generator\views\elements\header_search.ctp:20 +msgid "Search" +msgstr "" + +#: \plugins\api_generator\views\elements\method_detail.ctp:44 +msgid "Method defined in class:" +msgstr "" + +#: \plugins\api_generator\views\elements\method_detail.ctp:47 +msgid "Method defined in file:" +msgstr "" + +#: \plugins\api_generator\views\elements\method_detail.ctp:52 +msgid " on line " +msgstr "" + +#: \plugins\api_generator\views\elements\method_summary.ctp:10 +msgid "Method Summary:" +msgstr "" + +#: \plugins\api_generator\views\elements\method_summary.ctp:13 +msgid "Show/Hide parent methods" +msgstr "" + +#: \plugins\api_generator\views\elements\paging.ctp:9 +msgid "previous" +msgstr "" + +#: \plugins\api_generator\views\elements\paging.ctp:17 +msgid "next" +msgstr "" + +#: \plugins\api_generator\views\elements\properties.ctp:9 +msgid "Properties:" +msgstr "" + +#: \plugins\api_generator\views\elements\properties.ctp:13 +msgid "Show/Hide parent properties" +msgstr "" + +#: \plugins\api_generator\views\elements\sidebar\class_sidebar.ctp:7 +msgid "Class Index" +msgstr "" + +#: \plugins\api_generator\views\elements\sidebar\file_sidebar.ctp:7 +msgid "File browser" +msgstr "" + +#: \plugins\api_generator\views\elements\sidebar\file_sidebar.ctp:10 +msgid "Up one folder" +msgstr "" + +#: \plugins\api_generator\views\layouts\default.ctp:29;51 +msgid "CakePHP: API Generator" +msgstr "" + +#: \plugins\api_generator\views\layouts\default.ctp:68 +msgid "CakePHP: the rapid development php framework" +msgstr "" + +#: \webroot\test.php:99 +msgid "Debug setting does not allow access to this url." +msgstr "" + diff --git a/locale/jpn/LC_MESSAGES/default.mo b/locale/jpn/LC_MESSAGES/default.mo new file mode 100755 index 0000000..025eec5 Binary files /dev/null and b/locale/jpn/LC_MESSAGES/default.mo differ diff --git a/locale/jpn/LC_MESSAGES/default.po b/locale/jpn/LC_MESSAGES/default.po new file mode 100755 index 0000000..1aa002f --- /dev/null +++ b/locale/jpn/LC_MESSAGES/default.po @@ -0,0 +1,189 @@ +msgid "" +msgstr "" +"Project-Id-Version: api_generator\n" +"POT-Creation-Date: 2009-02-05 08:28+0900\n" +"PO-Revision-Date: \n" +"Last-Translator: Yusuke Ando <yandod@gmail.com>\n" +"Language-Team: cakephp.jp <ando@rikezemi.com>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: japanese\n" +"X-Poedit-Country: japan\n" + +#: \plugins\api_generator\controllers\api_generator_controller.php:117 +msgid "No file exists with that name" +msgstr "指定された名前のファイルは存在しません" + +#: \plugins\api_generator\controllers\api_generator_controller.php:144 +msgid "No class name was given" +msgstr "クラス名ではないものが指定されました" + +#: \plugins\api_generator\controllers\api_generator_controller.php:150;178 +msgid "No class exists in the index with that name" +msgstr "インデックス上に指定された名前のクラスは存在しません" + +#: \plugins\api_generator\controllers\api_generator_controller.php:165 +msgid "Oops, seems we couldn't get the documentation for that class." +msgstr "おっと、指定されたクラスのドキュメントを取得するできなかったようです" + +#: \plugins\api_generator\vendors\shells\api_index.php:64 +msgid "Your database configuration was not found. Take a moment to create one." +msgstr "データベース設定が見つかりませんでした。設定を行ってください" + +#: \plugins\api_generator\vendors\shells\api_index.php:100 +msgid "Routes file updated" +msgstr "routesファイルが更新されました" + +#: \plugins\api_generator\vendors\shells\api_index.php:103 +msgid "Routes file NOT updated" +msgstr "routesファイルが更新されませんでした" + +#: \plugins\api_generator\views\api_generator\classes.ctp:53 +msgid "Index" +msgstr "一覧" + +#: \plugins\api_generator\views\api_generator\classes.ctp:75 +msgid "(cont.)" +msgstr "(続く)" + +#: \plugins\api_generator\views\api_generator\files.ctp:7 +msgid "All files" +msgstr "全てのファイル" + +#: \plugins\api_generator\views\api_generator\files.ctp:17 +#: \plugins\api_generator\views\api_generator\source.ctp:29 +#: \plugins\api_generator\views\elements\sidebar\file_sidebar.ctp:28 +msgid "No files" +msgstr "ファイルがありません" + +#: \plugins\api_generator\views\api_generator\no_class.ctp:7 +msgid "No classes were found in the requested file" +msgstr "指定されたファイルにはクラスが見つかりませんでした" + +#: \plugins\api_generator\views\api_generator\search.ctp:10 +msgid "Search Results" +msgstr "検索結果" + +#: \plugins\api_generator\views\api_generator\search.ctp:12 +msgid "Your search returned no results" +msgstr "検索結果はありませんでした" + +#: \plugins\api_generator\views\elements\api_menu.ctp:4 +msgid "Classes" +msgstr "クラス" + +#: \plugins\api_generator\views\elements\api_menu.ctp:11 +msgid "Source" +msgstr "ソース" + +#: \plugins\api_generator\views\elements\api_menu.ctp:18 +msgid "Files" +msgstr "ファイル" + +#: \plugins\api_generator\views\elements\class_info.ctp:12 +msgid "Class Declaration:" +msgstr "クラス宣言:" + +#: \plugins\api_generator\views\elements\class_info.ctp:15 +msgid "File name:" +msgstr "ファイル名:" + +#: \plugins\api_generator\views\elements\class_info.ctp:18 +msgid "Summary:" +msgstr "サマリー:" + +#: \plugins\api_generator\views\elements\class_info.ctp:22 +msgid "Class Inheritance" +msgstr "クラス継承" + +#: \plugins\api_generator\views\elements\class_info.ctp:27 +msgid "Interfaces Implemented" +msgstr "実装インターフェース" + +#: \plugins\api_generator\views\elements\element_toc.ctp:10 +msgid "Defined Classes" +msgstr "宣言されたクラス" + +#: \plugins\api_generator\views\elements\element_toc.ctp:22 +msgid "Declared Functions" +msgstr "宣言された関数" + +#: \plugins\api_generator\views\elements\function_summary.ctp:18 +#: \plugins\api_generator\views\elements\method_detail.ctp:24 +msgid "Parameters:" +msgstr "パラメータ:" + +#: \plugins\api_generator\views\elements\function_summary.ctp:29 +#: \plugins\api_generator\views\elements\method_detail.ctp:35 +msgid "(no default)" +msgstr "(デフォルト無し)" + +#: \plugins\api_generator\views\elements\function_summary.ctp:38 +msgid "Function defined in file:" +msgstr "関数が定義されたファイル:" + +#: \plugins\api_generator\views\elements\header_search.ctp:20 +msgid "Search" +msgstr "検索" + +#: \plugins\api_generator\views\elements\method_detail.ctp:44 +msgid "Method defined in class:" +msgstr "メソッドが定義されたクラス:" + +#: \plugins\api_generator\views\elements\method_detail.ctp:47 +msgid "Method defined in file:" +msgstr "メソッドが定義されたファイル:" + +#: \plugins\api_generator\views\elements\method_detail.ctp:52 +msgid " on line " +msgstr " の行" + +#: \plugins\api_generator\views\elements\method_summary.ctp:10 +msgid "Method Summary:" +msgstr "メソッド概要:" + +#: \plugins\api_generator\views\elements\method_summary.ctp:13 +msgid "Show/Hide parent methods" +msgstr "表示/非表示 基底のメソッド" + +#: \plugins\api_generator\views\elements\paging.ctp:9 +msgid "previous" +msgstr "前へ" + +#: \plugins\api_generator\views\elements\paging.ctp:17 +msgid "next" +msgstr "次へ" + +#: \plugins\api_generator\views\elements\properties.ctp:9 +msgid "Properties:" +msgstr "プロパティ:" + +#: \plugins\api_generator\views\elements\properties.ctp:13 +msgid "Show/Hide parent properties" +msgstr "表示/非表示 基底プロパティ" + +#: \plugins\api_generator\views\elements\sidebar\class_sidebar.ctp:7 +msgid "Class Index" +msgstr "クラス一覧" + +#: \plugins\api_generator\views\elements\sidebar\file_sidebar.ctp:7 +msgid "File browser" +msgstr "ファイルブラウザ" + +#: \plugins\api_generator\views\elements\sidebar\file_sidebar.ctp:10 +msgid "Up one folder" +msgstr "1つ上のフォルダへ" + +#: \plugins\api_generator\views\layouts\default.ctp:29;51 +msgid "CakePHP: API Generator" +msgstr "CakePHP: APIジェネレータ" + +#: \plugins\api_generator\views\layouts\default.ctp:68 +msgid "CakePHP: the rapid development php framework" +msgstr "CakePHP: 高速開発PHPフレームワーク" + +#: \webroot\test.php:99 +msgid "Debug setting does not allow access to this url." +msgstr "デバッグ設定はこのurlでは許可されていません" + diff --git a/models/api_class.php b/models/api_class.php index a318214..aaf0211 100644 --- a/models/api_class.php +++ b/models/api_class.php @@ -52,7 +52,19 @@ class ApiClass extends ApiGeneratorAppModel { ) ), ); - +/** + * Flag bitmask for Pseudo classes (files with global functions) + * get a pseudo class assigned to them + * + * @var int + **/ + const PSEUDO_CLASS = 1; +/** + * Concrete class bitmask; + * + * @var string + **/ + const CONCRETE_CLASS = 0; /** * Clears (truncates) the class index. * @@ -82,14 +94,78 @@ class ApiClass extends ApiGeneratorAppModel { $this->set($new); return $this->save(); } +/** + * Save a set of global functions to the ApiClass index. + * Will make one record with a 'class name' derived from the filename. + * + * @param array $functions Array of FunctionDocumentor objects to index. + * @param string $filename Name of file these things are found in. + * @return boolean + **/ + public function savePseudoClassDocs($functions, $filename) { + $methodList = array(); + $name = basename($filename); + $slug = str_replace('_', '-', Inflector::underscore($name)); + foreach ($functions as $func) { + if ($func instanceof FunctionDocumentor) { + $methodList[] = $func->getName(); + } + } + $data = array( + 'name' => $name, + 'slug' => $slug, + 'file_name' => $filename, + 'method_index' => implode($methodList, ' '), + 'flags' => ApiClass::PSEUDO_CLASS, + ); + $this->set($data); + return $this->save(); + } +/** + * search method + * + * Find matching records for the given term or terms + * Find results ordered by those matching in order: class names, method names, properties + * + * @param mixed $terms array of terms or search term + * @return array of matching ApiFile objects + * @access public + */ + function search($terms = array()) { + if (!$terms) { + return array(); + } + $terms = (array)$terms; + $fields = array('DISTINCT ApiClass.id', 'ApiClass.name', 'ApiClass.method_index', + 'ApiClass.property_index', 'file_name'); + $order = 'ApiClass.name'; + + $conditions = array(); + foreach ($terms as $term) { + $conditions['OR'][] = array('ApiClass.slug LIKE' => $term . '%'); + $conditions['OR'][] = array('ApiClass.method_index LIKE' => '%' . $term . '%'); + $conditions['OR'][] = array('ApiClass.property_index LIKE' => '%' . $term . '%'); + } + $results = $this->find('all', compact('conditions', 'order', 'fields')); + return $this->_queryFiles($results, $terms); + } /** * Get the class index listing - * + * + * @param boolean $includePseudoClass Whether you want to include 'pseudo' classes (no actual class) * @return array **/ - public function getClassIndex() { - return $this->find('list', array('fields' => array('slug', 'name'), 'order' => 'ApiClass.name ASC')); + public function getClassIndex($includePseudoClass = false) { + $conditions = array(); + if (!$includePseudoClass) { + $conditions['ApiClass.flags'] = ApiClass::CONCRETE_CLASS; + } + return $this->find('list', array( + 'fields' => array('slug', 'name'), + 'order' => 'ApiClass.name ASC', + 'conditions' => $conditions + )); } /** * Generate a search index of methods or properties for the ClassDocumentor Object @@ -109,5 +185,107 @@ class ApiClass extends ApiGeneratorAppModel { } return strtolower(implode($index, ' ')); } +/** + * filterSearchResults method + * + * Purge results that don't match the search terms + * + * @param array $results + * @param array $terms + * @return array filtered results + * @access protected + */ + protected function _queryFiles($results, $terms) { + $return = $_return = array(); + $ApiFile =& ClassRegistry::init('ApiGenerator.ApiFile'); + foreach ($results as $i => $result) { + $result = $ApiFile->loadFile($result['ApiClass']['file_name'], array('useIndex' => true)); + foreach ($result['class'] as $name => $obj) { + $relevance = 0; + $this->_unsetUnmatching($obj, $terms, 'properties'); + $this->_unsetUnmatching($obj, $terms, 'methods'); + foreach ($terms as $term) { + if (low($name) === $term) { + $relevance += 6; + } elseif (strpos(low($name), $term) === 0) { + $relevance += 3; + } + } + if ($obj->methods) { + foreach ($obj->methods as $method) { + $_name = $method['name']; + foreach ($terms as $term) { + if (low($_name) === $term) { + $relevance += 4; + } elseif (strpos(low($_name), $term) === 0) { + $relevance += 2; + } + } + } + } + if ($obj->properties) { + foreach ($obj->properties as $property) { + $_name = $property['name']; + foreach($terms as $term) { + if (low($_name) === $term) { + $relevance += 4; + } elseif (strpos(low($_name), $term) === 0) { + $relevance += 2; + } + } + } + } + if ($relevance > 0) { + $_return[$relevance][$name]['class'][$name] = $obj; + } + } + foreach ($result['function'] as $name => $obj) { + $relevance = 0; + foreach ($terms as $term) { + if (low($name) === $term) { + $relevance += 6; + } elseif (strpos(low($name), $term) === 0) { + $relevance += 3; + } + if ($relevance > 0) { + $_return[$relevance][$name]['function'][$name] = $obj; + } + } + } + } + ksort($_return); + $_return = array_reverse($_return); + foreach ($_return as $result) { + ksort($result); + $return = am($return, $result); + } + return $return; + } +/** + * unsetUnmatching method + * + * @param mixed $obj + * @param array $terms + * @param string $field + * @return void + * @access protected + */ + function _unsetUnmatching(&$obj, $terms = array(), $field = 'properties') { + if (empty($obj->$field)) { + return; + } + foreach ($obj->$field as $j => $prop) { + $delete = true; + foreach($terms as $term) { + if (strpos($prop['name'], $term) === 0) { + $delete = false; + break; + } + } + if ($delete) { + unset ($obj->{$field}[$j]); + } + } + } } ?> \ No newline at end of file diff --git a/models/api_file.php b/models/api_file.php index 7a4150a..290be10 100644 --- a/models/api_file.php +++ b/models/api_file.php @@ -259,6 +259,9 @@ class ApiFile extends Object { foreach ($newObjects as $type => $objects) { foreach ($objects as $element) { $this->loadExtractor($type, $element); + if ($type == 'function' && basename($this->_extractor->getFileName()) != basename($filePath)) { + continue; + } $docs[$type][$element] = $this->getDocs(); } } @@ -291,10 +294,11 @@ class ApiFile extends Object { * @param boolean $forceParse Force the manual read of a file. * @return array **/ - public function findObjectsInFile($filePath, $forceParse = false) { + public function findObjectsInFile($filePath) { $new = $tmp = array(); $tmp['class'] = $this->_parseClassNamesInFile($filePath); $tmp['function'] = $this->_parseFunctionNamesInFile($filePath); + $include = false; foreach ($tmp['class'] as $classInFile) { $include = false; @@ -302,7 +306,13 @@ class ApiFile extends Object { $include = true; } } - if (!$include || $forceParse) { + foreach ($tmp['function'] as $funcInFile) { + if (!function_exists($funcInFile)) { + $include = true; + } + } + + if (!$include) { $new = $tmp; } else { ob_start(); @@ -313,9 +323,6 @@ class ApiFile extends Object { $funcs = get_defined_functions(); $new['function'] = array_diff($funcs['user'], $this->_definedFunctions); } - if (empty($new['class']) && empty($new['function']) && $forceParse === false) { - $new = $this->findObjectsInFile($filePath, true); - } return $new; } /** @@ -356,7 +363,7 @@ class ApiFile extends Object { $foundFuncs = array(); $fileContent = file_get_contents($fileName); $funcNames = implode('|', $this->_definedFunctions); - preg_match_all('/^\s*function\s*(' . $funcNames . ')[\s|\(]+/mi', $fileContent, $matches, PREG_SET_ORDER); + preg_match_all('/^\tfunction\s*(' . $funcNames . ')[\s|\(]+/mi', $fileContent, $matches, PREG_SET_ORDER); foreach ($matches as $function) { $foundFuncs[] = $function[1]; } diff --git a/tests/cases/models/api_class.test.php b/tests/cases/models/api_class.test.php index 86cd4a2..95fedf8 100644 --- a/tests/cases/models/api_class.test.php +++ b/tests/cases/models/api_class.test.php @@ -137,8 +137,8 @@ class ApiFileTestCase extends CakeTestCase { 'name' => 'ApiClassSampleClass', 'slug' => 'api-class-sample-class', 'file_name' => __FILE__, - 'search_index' => 'apiclasssampleclass doc block foo property test function in sample class first parameter second parameter non-extended method', - + 'property_index' => 'foo', + 'method_index' => 'testfunct extended', 'flags' => 0, 'created' => $now, 'modified' => $now, @@ -157,7 +157,8 @@ class ApiFileTestCase extends CakeTestCase { 'name' => 'ApiClassSampleClassChild', 'slug' => 'api-class-sample-class-child', 'file_name' => __FILE__, - 'search_index' => 'apiclasssampleclass doc block onlyme primary function extended-method this time', + 'property_index' => 'onlyme', + 'method_index' => 'primary extended', 'flags' => 0, 'created' => $now, 'modified' => $now, @@ -165,4 +166,17 @@ class ApiFileTestCase extends CakeTestCase { ); $this->assertEqual($result, $expected); } +/** + * test Saving of pseudo classes + * + * @return void + **/ + function testSavePseudoClassDocs() { + $file = CAKE_CORE_INCLUDE_PATH . DS . CAKE . 'basics.php'; + $ApiFile = ClassRegistry::init('ApiGenerator.ApiFile'); + $docs = $ApiFile->loadFile($file); + + $result = $this->ApiClass->savePseudoClassDocs($docs['function'], $file); + $this->assertTrue($result); + } } \ No newline at end of file diff --git a/tests/cases/models/api_file.test.php b/tests/cases/models/api_file.test.php index 871862e..953bfc4 100644 --- a/tests/cases/models/api_file.test.php +++ b/tests/cases/models/api_file.test.php @@ -232,4 +232,15 @@ class ApiFileTestCase extends CakeTestCase { $this->assertTrue(true); } } +/** + * Test Loading files, that have method config() and having global config() from core included + * + * @return void + **/ + function testLoadingFileWithAmbiguousFunction() { + $cacheFile = CAKE_CORE_INCLUDE_PATH . DS . LIBS . 'cache.php'; + $this->assertTrue(function_exists('config')); + $results = $this->ApiFile->loadFile($cacheFile); + $this->assertEqual($results['function'], array()); + } } \ No newline at end of file diff --git a/tests/fixtures/api_class_fixture.php b/tests/fixtures/api_class_fixture.php index 1743e44..a643287 100644 --- a/tests/fixtures/api_class_fixture.php +++ b/tests/fixtures/api_class_fixture.php @@ -7,7 +7,8 @@ class ApiClassFixture extends CakeTestFixture { 'name' => array('type' => 'string', 'length' => 200, 'null' => false), 'slug' => array('type' => 'string', 'length' => 200, 'null' => false), 'file_name' => array('type' => 'text'), - 'search_index' => array('type' => 'text'), + 'method_index' => array('type' => 'text'), + 'property_index' => array('type' => 'text'), 'flags' => array('type' => 'integer', 'default' => 0, 'length' => 5), 'created' => array('type' => 'datetime'), 'modified' => array('type' => 'datetime'), diff --git a/vendors/shells/api_index.php b/vendors/shells/api_index.php index 66a3bd4..e2f7acc 100644 --- a/vendors/shells/api_index.php +++ b/vendors/shells/api_index.php @@ -143,6 +143,12 @@ class ApiIndexShell extends Shell { $this->out('Added docs for ' . $classDocs->name . ' to index'); } } + if (!empty($docsInFile['function'])) { + $this->ApiClass->create(); + if ($this->ApiClass->savePseudoClassDocs($docsInFile['function'], $file)) { + $this->out('Added docs for global functions in ' . basename($file)); + } + } } } diff --git a/views/api_generator/search.ctp b/views/api_generator/search.ctp index 89e3a83..fed353f 100644 --- a/views/api_generator/search.ctp +++ b/views/api_generator/search.ctp @@ -13,20 +13,47 @@ endif; ?> <ul id="search-results"> <?php foreach ($docs as $result): - foreach ($result['class'] as $name => $doc): ?> - <li class="doc-block class-info"> - <h2><?php echo $apiDoc->classLink($doc->name, array(), array('class' => false)); ?></h2><?php - if ($doc->properties): - echo $this->element('properties', array('doc' => $doc, 'isSearch' => true)); - endif; + if (isset($result['function'])): + foreach($result['function'] as $name => $doc): ?> + <li class="doc-block function-info"> + <h2><?php echo $apiDoc->fileLink($doc->info['declaredInFile']); ?></h2> + <div class="doc-body"> + <table class="summary"> + <tbody> + <tr class="even"> + <td class="access public"><span>public</span></td> + <td> + <?php + echo $html->link($doc->info['signature'], + array('action' => 'view_file', $apiDoc->trimFileName($doc->info['declaredInFile']), + '#' => 'function-' . $doc->name), + array('class' => 'scroll-link') + ); + ?> + </td> + </tr> + </tbody> + </table> + + </div> + </li> +<?php endforeach; + elseif (isset($result['class'])) : + foreach ($result['class'] as $name => $doc): ?> + <li class="doc-block class-info"> + <h2><?php echo $apiDoc->classLink($doc->name, array(), array('class' => false)); ?></h2><?php + if ($doc->properties): + echo $this->element('properties', array('doc' => $doc, 'isSearch' => true)); + endif; - if ($doc->methods): - echo $this->element('method_summary', array('doc' => $doc, 'isSearch' => true)); - endif; -?> - </li> -<?php - endforeach; + if ($doc->methods): + echo $this->element('method_summary', array('doc' => $doc, 'isSearch' => true)); + endif; + ?> + </li> + <?php + endforeach; + endif; endforeach; ?> </ul> \ No newline at end of file diff --git a/views/elements/function_summary.ctp b/views/elements/function_summary.ctp index f759078..edec9b7 100644 --- a/views/elements/function_summary.ctp +++ b/views/elements/function_summary.ctp @@ -36,7 +36,19 @@ <?php endif; ?> <dt><?php __('Function defined in file:'); ?></dt> - <dd><?php echo $apiDoc->fileLink($doc->info['declaredInFile']); ?></dd> + <dd><?php + echo $apiDoc->fileLink($doc->info['declaredInFile']); + $pseudoClass = basename($doc->info['declaredInFile']); + if ($apiDoc->inClassIndex($pseudoClass)): + __(' on line '); + echo $html->link($doc->info['startLine'], array( + 'controller' => 'api_generator', + 'action' => 'view_source', + $pseudoClass, + '#line-'. $doc->info['startLine'] + )); + endif; + ?> </dd> <dt> <?php foreach ($doc->info['comment']['tags'] as $name => $value): ?>