diff -upr ../../api/api.module ./api.module --- ../../api/api.module 2010-04-30 01:08:26.000000000 +0200 +++ ./api.module 2010-05-03 01:27:09.000000000 +0200 @@ -367,6 +367,22 @@ function api_menu() { 'type' => $is_default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, ); if ($is_default) { + $items['api/' . $branch->project . '/classes'] = array( + 'title' => 'Classes', + 'page callback' => 'api_page_listing', + 'access arguments' => array('access API reference'), + 'page arguments' => array($branch, 'class'), + 'type' => MENU_CALLBACK, + ); + } + $items['api/' . $branch->project . '/classes/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_listing', + 'page arguments' => array($branch, 'class'), + 'access arguments' => array('access API reference'), + 'type' => $is_default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + if ($is_default) { $items['api/' . $branch->project . '/groups'] = array( 'title' => 'Topics', 'page callback' => 'api_page_listing', @@ -830,6 +846,7 @@ function api_block($op, $delta = NULL, $ $links = array(); $links[] = l($branch->title, 'api/' . $branch->project . '/' . $branch->branch_name); $links[] = l(t('Constants'), 'api/' . $branch->project . '/constants/' . $branch->branch_name); + $links[] = l(t('Classes'), 'api/' . $branch->project . '/classes/' . $branch->branch_name); $links[] = l(t('Files'), 'api/' . $branch->project . '/files/' . $branch->branch_name); $links[] = l(t('Functions'), 'api/' . $branch->project . '/functions/' . $branch->branch_name); $links[] = l(t('Globals'), 'api/' . $branch->project . '/globals/' . $branch->branch_name); @@ -1439,17 +1456,19 @@ function api_page_class($branch, $class) $see = api_link_documentation($class->see, $branch); // builds up class hierarchy - $children = api_class_children($class); - $self = theme('item_list', array('' . $class->title . '' . $children)); - $hierarchy = api_class_parents($class, $self); + $class = api_class_children($class); + $parents = api_class_parents($class); + if (count($class->children) || count($parents->children) || count($class->interface)) { + $hierarchy = theme('item_list', array(api_render_class_hierarchy($parents, $class->did))); + } // builds up methods and constants lists $rows = array( - 'constant' => array(), + 'const' => array(), 'function' => array(), ); - $result = db_query("SELECT branch_id, title, object_name, summary, object_type, file_name FROM {api_documentation} WHERE class_did = %d AND branch_id = %d AND object_type IN ('constant', 'function') ORDER BY title", $class->did, $class->branch_id); + $result = db_query("SELECT branch_id, title, object_name, summary, object_type, file_name FROM {api_documentation} WHERE class_did = %d AND branch_id = %d AND object_type IN ('const', 'function') ORDER BY title", $class->did, $class->branch_id); while ($object = db_fetch_object($result)) { $rows[$object->object_type][] = array( l($object->title, api_url($object)), @@ -1462,15 +1481,9 @@ function api_page_class($branch, $class) t('Description'), ); - if (count($rows)) { - foreach ($rows as $type => $row) { - if (count($row) > 0) { - $list[$type] = theme('table', $header, $row); - } - } - } + $list = api_render_tables($rows, $header); - $output = theme('api_class_page', $branch, $class, $documentation, $hierarchy, $list['function'], $list['constant'], $code, $related_topics, $see); + $output = theme('api_class_page', $branch, $class, $documentation, $hierarchy, $list['function'], $list['const'], $code, $related_topics, $see); $output .= _api_add_comments($class); return $output; @@ -1501,25 +1514,11 @@ function api_page_file($branch, $file) { t('Name'), t('Description'), ); - $classes = ''; - if (count($rows['class']) > 0) { - $classes = theme('table', $header, $rows['class']); - } - $constants = ''; - if (count($rows['constant']) > 0) { - $constants = theme('table', $header, $rows['constant']); - } - $globals = ''; - if (count($rows['global']) > 0) { - $globals = theme('table', $header, $rows['global']); - } - $functions = ''; - if (count($rows['function']) > 0) { - $functions = theme('table', $header, $rows['function']); - } + + $list = api_render_tables($rows, $header); $related_topics = api_related_topics($file->did, $branch); - $output = theme('api_file_page', $file, $documentation, $classes, $constants, $globals, $functions, $see, $related_topics); + $output = theme('api_file_page', $file, $documentation, $list['class'], $list['constant'], $list['global'], $list['function'], $see, $related_topics); $output .= _api_add_comments($file); return $output; } @@ -1596,24 +1595,10 @@ function api_page_group($branch, $group) t('Location'), t('Description'), ); - $constants = ''; - if (count($rows['constant']) > 0) { - $constants = theme('table', $header, $rows['constant']); - } - $globals = ''; - if (count($rows['global']) > 0) { - $globals = theme('table', $header, $rows['global']); - } - $functions = ''; - if (count($rows['function']) > 0) { - $functions = theme('table', $header, $rows['function']); - } - $files = ''; - if (count($rows['file']) > 0) { - $files = theme('table', $header, $rows['file']); - } + + $list = api_render_tables($rows, $header); - $output = theme('api_group_page', $branch, $group, $documentation, $constants, $globals, $functions, $files, $see); + $output = theme('api_group_page', $branch, $group, $documentation, $list['constant'], $list['global'], $list['function'], $list['file'], $see); $output .= _api_add_comments($group); return $output; } @@ -1947,40 +1932,97 @@ function api_link_link($name, $branch, $ } /** - * Returns class parents (recursive) + * Returns class parents and interfaces (recursive) + * + * Get all interfaces first so we can return the recursive call after if needed * * @param $class * The class to look for parents. - * @param $text - * sub classes text. * * @return - * The list as html. + * object class with + * children = array(object class) + * interfaces = array(object interface). */ -function api_class_parents($class, $text = '') { - $tree = array(); - $result = db_query("SELECT DISTINCT rs.to_did as did, rs.branch_id as branch_id, d.title as title, d.object_type as object_type, d.file_name as file_name, d.object_name as object_name FROM {api_reference_storage} rs INNER JOIN {api_documentation} d ON d.did = rs.to_did WHERE rs.from_did = %d AND rs.branch_id = %d AND rs.object_type IN ('class', 'interface')", $class->did, $class->branch_id); - $object = db_fetch_object($result); - if (isset($object->did)) { - return api_class_parents($object, theme('item_list', array(l($object->title, api_url($object)) . $text))); +function api_class_parents($class, $recursive = true) { + $result = db_query("SELECT DISTINCT d.did as did, d.branch_id as branch_id, d.title as title, d.object_type as object_type, d.file_name as file_name, d.object_name as object_name FROM {api_reference_storage} rs INNER JOIN {api_documentation} d ON d.did = rs.to_did WHERE rs.from_did = %d AND rs.branch_id = %d AND rs.object_type IN ('interface'" . ($recursive ? ", 'class'" : '') . ") ORDER BY d.object_type DESC", $class->did, $class->branch_id); + while ($object = db_fetch_object($result)) { + if ($object->object_type == 'interface') { + $class->interfaces[] = $object; + } + else { + $object->children[] = $class; + return api_class_parents($object); + } } - return $text; + return $class; } /** - * Returns class children (recursive) + * Returns class children with interfaces (recursive) * * @param $class * The class to look for children. * * @return - * The list as html. + * object class with + * children = array(object class) + * interfaces = array(object interface). */ function api_class_children($class) { - $rows = array(); - $result = db_query("SELECT DISTINCT rs.from_did as did, rs.branch_id as branch_id, d.title as title, d.object_type as object_type, d.file_name as file_name, d.object_name as object_name FROM {api_reference_storage} rs INNER JOIN {api_documentation} d ON d.did = rs.from_did WHERE rs.to_did = %d AND rs.branch_id = %d AND rs.object_type IN ('class', 'interface')", $class->did, $class->branch_id); + $result = db_query("SELECT DISTINCT d.did as did, d.branch_id as branch_id, d.title as title, d.object_type as object_type, d.file_name as file_name, d.object_name as object_name FROM {api_documentation} d INNER JOIN {api_reference_storage} rs ON d.did = rs.from_did WHERE rs.to_did = %d AND d.branch_id = %d AND d.object_type = 'class'", $class->did, $class->branch_id); while ($object = db_fetch_object($result)) { - $rows[] = l($object->title, api_url($object)) . api_class_children($object); + // found a child : gather its interfaces, builds its possible children list, and adds it to the children list + $class->children[] = api_class_children(api_class_parents($object, false)); } - return theme('item_list', $rows); + return $class; } + +/** + * Render class hierarchy (recursive) + * + * @param $object + * Object hierarchy. + * @param $selected_did + * Selected class did. + * + * @return + * Themed hierarchy in html unordered list. + */ +function api_render_class_hierarchy($object, $selected_did = '') { + if (count($object->interfaces)) { + foreach ($object->interfaces as $interface) { + $interface_text = (empty($interface_text) ? '' : ',') . ' ' . l($interface->title, api_url($interface)); + } + $interface_text = ' implements' . $interface_text; + } + if (count($object->children)) { + foreach ($object->children as $child) { + $children[] .= api_render_class_hierarchy($child, $selected_did); + } + } + $object_text = ( $object->did == $selected_did ? '' . $object->title . '' : l($object->title, api_url($object)) ); + return $object_text . $interface_text . theme('item_list', $children); +} + +/** + * Render lists of tables with the same header + * + * @param $rows + * An array of data to render with theme_table. + * + * @return + * List of themed html tables. + */ +function api_render_tables($tables, $header) { + $list = array(); + if (count($tables)) { + foreach ($tables as $type => $row) { + if (count($row)) { + $list[$type] = theme('table', $header, $row); + } + } + } + return $list; +} + diff -upr ../../api/tests/sample/classes.php ./tests/sample/classes.php --- ../../api/tests/sample/classes.php 2010-04-10 07:38:26.000000000 +0200 +++ ./tests/sample/classes.php 2010-05-03 01:21:44.000000000 +0200 @@ -37,6 +37,23 @@ interface SampleInterface { /** * Subclass. + * + * @see Sample::foo() should be link */ -class SubSample extends Sample { +class SubSample extends Sample implements SampleInterfaceTwo { + /** + * Metasyntatic member function. + */ + public function bar() { + } +} + +/** + * Sample interface. + */ +interface SampleInterfaceTwo { + /** + * Implement this API. + */ + public function bar(); }