Index: api.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/api/api.info,v retrieving revision 1.4 diff -u -p -r1.4 api.info --- api.info 29 Jun 2007 05:44:25 -0000 1.4 +++ api.info 23 Jan 2008 08:47:25 -0000 @@ -2,3 +2,4 @@ name = API description = Generates and displays API documentation pages. package = Development +core = 6.x Index: api.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/api/api.install,v retrieving revision 1.5.2.5 diff -u -p -r1.5.2.5 api.install --- api.install 20 Oct 2007 01:39:16 -0000 1.5.2.5 +++ api.install 23 Jan 2008 08:47:25 -0000 @@ -1,63 +1,68 @@ array( + 'branch_name' => array('type' => 'varchar', 'length' => '31', 'not null' => 1, 'default' => ''), + 'title' => array('type' => 'varchar', 'length' => '255', 'not null' => 1, 'default' => ''), + 'directory' => array('type' => 'varchar', 'length' => '255', 'not null' => 1, 'default' => '')), + 'primary key' => array('branch_name'), +); +$schema['api_documentation'] = array( + 'fields' => array( + 'did' => array('type' => 'int', 'unsigned' => 1, 'not null' => 1, 'default' => 0, 'disp-width' => '10'), + 'object_name' => array('type' => 'varchar', 'length' => '127', 'not null' => 1, 'default' => ''), + 'branch_name' => array('type' => 'varchar', 'length' => '31', 'not null' => 1, 'default' => ''), + 'object_type' => array('type' => 'varchar', 'length' => '31', 'not null' => 1, 'default' => ''), + 'title' => array('type' => 'varchar', 'length' => '255', 'not null' => 1, 'default' => ''), + 'file_name' => array('type' => 'varchar', 'length' => '127', 'not null' => 1, 'default' => ''), + 'summary' => array('type' => 'text', 'size' => 'medium', 'not null' => 1), + 'documentation' => array('type' => 'text', 'size' => 'medium', 'not null' => 1), + 'code' => array('type' => 'text', 'size' => 'medium', 'not null' => 1)), + 'primary key' => array('did'), + 'unique keys' => array( + 'object_name' => array('object_name', 'branch_name', 'object_type')), + 'indexes' => array( + 'branch_name' => array('branch_name'), + 'title' => array('title')), +); + +$schema['api_file'] = array( + 'fields' => array( + 'did' => array('type' => 'int', 'unsigned' => 1, 'not null' => 1, 'default' => 0, 'disp-width' => '10'), + 'modified' => array('type' => 'int', 'not null' => 1, 'default' => 0, 'disp-width' => '11'), + 'version' => array('type' => 'varchar', 'length' => '255', 'not null' => 1, 'default' => ''), + 'found' => array('type' => 'int', 'unsigned' => 1, 'size' => 'tiny', 'not null' => 1, 'default' => 0, 'disp-width' => '1')), + 'primary key' => array('did'), +); + +$schema['api_function'] = array( + 'fields' => array( + 'did' => array('type' => 'int', 'unsigned' => 1, 'not null' => 1, 'default' => 0, 'disp-width' => '10'), + 'signature' => array('type' => 'varchar', 'length' => '255', 'not null' => 1, 'default' => ''), + 'start_line' => array('type' => 'int', 'not null' => 1, 'default' => 0, 'disp-width' => '10'), + 'parameters' => array('type' => 'text', 'size' => 'medium', 'not null' => 1), + 'return' => array('type' => 'text', 'size' => 'medium', 'not null' => 1)), + 'primary key' => array('did'), +); + +$schema['api_reference_storage'] = array( + 'fields' => array( + 'object_name' => array('type' => 'varchar', 'length' => '127', 'not null' => 1, 'default' => ''), + 'branch_name' => array('type' => 'varchar', 'length' => '31', 'not null' => 1, 'default' => ''), + 'object_type' => array('type' => 'varchar', 'length' => '31', 'not null' => 1, 'default' => ''), + 'from_did' => array('type' => 'int', 'not null' => 1, 'default' => 0, 'disp-width' => '11'), + 'to_did' => array('type' => 'int', 'not null' => 1, 'default' => 0, 'disp-width' => '11')), + 'indexes' => array( + 'object_ref' => array('object_name', 'branch_name', 'object_type')), +); - case 'pgsql': - break; - } + return $schema; +} + +function api_install() { + drupal_install_schema('api'); } function api_update_1() { @@ -66,17 +71,7 @@ function api_update_1() { function api_update_2() { $ret = array(); - - switch ($GLOBALS['db_type']) { - case 'pgsql': - db_add_column($ret, 'api_file', 'found', 'smallint', array('not null' => TRUE, 'default' => 0)); - break; - - case 'mysql': - case 'mysqli': - $ret[] = update_sql("ALTER TABLE {api_file} ADD COLUMN found tinyint(1) UNSIGNED NOT NULL DEFAULT 0"); - break; - } + db_add_column($ret, 'api_file', 'found', 'tinyint', array('not null' => TRUE, 'default' => 0, 'length' => 1, 'unsigned' => TRUE)); return $ret; } @@ -98,26 +93,13 @@ function api_update_3() { function api_update_4() { $return = array(); - - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $return[] = update_sql('ALTER TABLE {api_documentation} ADD INDEX (branch_name)'); - break; - } - + db_add_index($return, 'api_documentation', '', 'branch_name'); return $return; } function api_update_5() { $return = array(); - - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $return[] = update_sql('ALTER TABLE {api_documentation} ADD INDEX (title)'); - break; - } + db_add_index($return, 'api_documentation', '', 'title'); return $return; } @@ -128,34 +110,48 @@ function api_update_5() { */ function api_update_6() { $return = array(); + $schema['api_reference_storage'] = array( + 'fields' => array( + 'object_name' => array( + 'type' => 'varchar', + 'length' => '127', + 'not null' => TRUE, + 'default' => ''), + 'branch_name' => array( + 'type' => 'varchar', + 'length' => 31, + 'not null' => TRUE, + 'default' => ''), + 'object_type' => array( + 'type' => 'varchar', + 'length' => 31, + 'not null' => TRUE, + 'default' => ''), + 'from_did' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => '0'), + 'to_did' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => '0'), + ), + 'indexes' => array( + 'api_documentation_object_ref' => array('object_name', 'branch_name', 'object_type'), + ), + ); + + db_rename_table($return, 'api_reference_storage', 'api_reference_storage_old'); + db_create_table($return, 'api_reference_storage', $schema['api_reference_storage']); - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $return[] = update_sql('RENAME TABLE {api_reference_storage} TO {api_reference_storage_old}'); - $return[] = update_sql("CREATE TABLE {api_reference_storage} ( - object_name varchar(127) NOT NULL default '', - branch_name varchar(31) NOT NULL default '', - object_type varchar(31) NOT NULL default '', - from_did int NOT NULL default '0', - to_did int NOT NULL default '0', - INDEX object_ref (object_name,branch_name,object_type) - ) /*!40100 DEFAULT CHARACTER SET utf8 */"); - break; - } $result = db_query('SELECT * FROM {api_reference_storage}'); while ($row = db_fetch_object($result)) { list($branch_name, $to_type, $to_name) = unserialize($row->reference_key); db_query("INSERT INTO {api_reference_storage} (object_name, branch_name, object_type, from_did) VALUES ('%s', '%s', '%s', %d)", $to_name, $branch_name, $to_type, $row->from_did); } - - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - $return[] = update_sql('DROP TABLE {api_reference_storage_old}'); - break; - } + + db_drop_table($return, 'api_reference_storage_old'); return $return; } @@ -166,23 +162,24 @@ function api_update_6() { function api_update_7() { $return = array(); - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': + $return[] = update_sql("INSERT INTO {api_reference_storage} (object_name, branch_name, object_type, from_did, to_did) SELECT d.object_name, d.branch_name, d.object_type, r.from_did, r.to_did FROM {api_reference} r INNER JOIN {api_documentation} d ON d.did = r.to_did"); + db_drop_table($return, 'api_reference'); + return $return; +} + +/** + * Move data from {api_reference} to {api_reference_storage}. + +function api_update_7() { + $return = array(); $return[] = update_sql("INSERT INTO {api_reference_storage} (object_name, branch_name, object_type, from_did, to_did) SELECT d.object_name, d.branch_name, d.object_type, r.from_did, r.to_did FROM {api_reference} r INNER JOIN {api_documentation} d ON d.did = r.to_did"); $return[] = update_sql('DROP TABLE {api_reference}'); break; - } - return $return; } - +*/ function api_uninstall() { - db_query('DROP TABLE IF EXISTS {api_branch}'); - db_query('DROP TABLE IF EXISTS {api_documentation}'); - db_query('DROP TABLE IF EXISTS {api_file}'); - db_query('DROP TABLE IF EXISTS {api_function}'); - db_query('DROP TABLE IF EXISTS {api_reference_storage}'); + drupal_uninstall_schema('api'); variable_del('api_default_branch'); variable_del('api_php_funcsummary'); variable_del('api_php_funcpath'); Index: api.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/api/api.module,v retrieving revision 1.48.2.20 diff -u -p -r1.48.2.20 api.module --- api.module 23 Jan 2008 02:49:56 -0000 1.48.2.20 +++ api.module 23 Jan 2008 08:47:25 -0000 @@ -27,8 +27,8 @@ define('API_RE_FILENAME', '([a-zA-Z0-9_- /** * Implementation of hook_help() */ -function api_help($section) { - switch ($section) { +function api_help($path, $arg) { + switch ($path) { case 'admin/help#api': $output = t('

@@ -72,7 +72,7 @@ Indexing of PHP functions is also suppor

The module indexes code branches during cron runs, so make sure the site has cron functionality set up properly.

-', array('!api_site' => l('http://api.drupal.org', 'http://api.drupal.org', array(), NULL, NULL, TRUE), '!api_settings_page' => l(t('API settings page'), 'admin/settings/api'))); +', array('!api_site' => l('http://api.drupal.org', 'http://api.drupal.org', array('absolute' => TRUE)), '!api_settings_page' => l(t('API settings page'), 'admin/settings/api'))); return $output; } } @@ -93,340 +93,318 @@ function api_get_branches() { /** * Implementation of hook_menu(). + * Split into hook_menu() to exectute code on all pages and hook_init() to execute code on non-cached pages only. */ -function api_menu($may_cache) { +function api_menu() { $items = array(); - $access = user_access('access API reference'); + + $access_callback = 'user_access'; + $access_arguments = array('access API reference'); $branches = api_get_branches(); $default_branch = variable_get('api_default_branch', 'HEAD'); - if ($may_cache) { - $items[] = array( - 'path' => 'api', - 'title' => t('API reference'), - 'access' => $access, - 'callback' => 'api_page_branch', - 'callback arguments' => array($default_branch), - ); - $items[] = array( - 'path' => 'api/functions', - 'title' => t('Functions'), - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($default_branch, 'function'), - 'type' => MENU_CALLBACK, - ); - $items[] = array( - 'path' => 'api/constants', - 'title' => t('Constants'), - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($default_branch, 'constant'), - 'type' => MENU_CALLBACK, - ); - $items[] = array( - 'path' => 'api/globals', - 'title' => t('Globals'), - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($default_branch, 'global'), - 'type' => MENU_CALLBACK, - ); - $items[] = array( - 'path' => 'api/file', - 'title' => t('Files'), - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($default_branch, 'file'), - 'type' => MENU_CALLBACK, - ); - $items[] = array( - 'path' => 'api/files', - 'title' => t('Files'), - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($default_branch, 'file'), - 'type' => MENU_CALLBACK, - ); - $items[] = array( - 'path' => 'api/groups', - 'title' => t('Topics'), - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($default_branch, 'group'), - 'type' => MENU_CALLBACK, - ); - - foreach ($branches as $branch) { - $items[] = array( - 'path' => 'api/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_branch', - 'access' => $access, - 'callback arguments' => array($branch->branch_name), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'api/function_dump/'. $branch->branch_name, - 'title' => t('Functions'), - 'callback' => 'api_page_function_dump', - 'access' => $access, - 'callback arguments' => array($branch->branch_name), - 'type' => MENU_CALLBACK, - ); - $items[] = array( - 'path' => 'api/functions/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, 'function'), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'api/constants/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, 'constant'), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'api/globals/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, 'global'), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'api/files/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, 'file'), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'api/groups/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_listing', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, 'group'), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - } + // Part 1: No object, Default branch + $items['api'] = array( + 'title' => 'API reference', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page callback' => 'api_page_branch', + 'page arguments' => array($default_branch), + ); + $items['api/functions'] = array( + 'title' => 'Functions', + 'page callback' => 'api_page_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page arguments' => array($default_branch, 'function'), + 'type' => MENU_CALLBACK, + ); + $items['api/constants'] = array( + 'title' => 'Constants', + 'page callback' => 'api_page_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page arguments' => array($default_branch, 'constant'), + 'type' => MENU_CALLBACK, + ); + $items['api/globals'] = array( + 'title' => 'Globals', + 'page callback' => 'api_page_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page arguments' => array($default_branch, 'constant'), + 'type' => MENU_CALLBACK, + ); + $items['api/file'] = array( + 'title' => 'Files', + 'page callback' => 'api_page_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page arguments' => array($default_branch, 'file'), + 'type' => MENU_CALLBACK, + ); + $items['api/files'] = array( + 'title' => 'Files', + 'page callback' => 'api_page_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page arguments' => array($default_branch, 'file'), + 'type' => MENU_CALLBACK, + ); + $items['api/groups'] = array( + 'title' => 'Topics', + 'page callback' => 'api_page_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'page arguments' => array($default_branch, 'group'), + 'type' => MENU_CALLBACK, + ); - $items[] = array( - 'path' => 'apis', - 'title' => t('API search'), - 'callback' => 'api_search_listing', - 'access' => $access, - 'type' => MENU_CALLBACK, - ); - $items[] = array('path' => 'api/autocomplete', - 'callback' => 'api_autocomplete', 'access' => $access, - 'type' => MENU_CALLBACK); - $items[] = array('path' => 'admin/settings/api', - 'title' => t('API reference'), - 'description' => t('Configure Drupal branches for documentation.'), - 'access' => user_access('administer API reference'), - 'callback' => 'api_page_admin'); - } - else { - if (arg(0) == 'api') { - if (arg(1) == 'function' && is_string(arg(2))) { - $items[] = array( - 'path' => 'api/function/'. arg(2), - 'title' => t('Function'), - 'callback' => 'api_page_function', - 'access' => $access, - 'callback arguments' => array($default_branch, arg(2)), - 'type' => MENU_CALLBACK, - ); - foreach ($branches as $branch) { - if (db_result(db_query("SELECT did FROM {api_documentation} WHERE object_name = '%s' AND branch_name = '%s' AND object_type = 'function'", arg(2), $branch->branch_name))) { - $items[] = array( - 'path' => 'api/function/'. arg(2) .'/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_function', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, arg(2)), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - } - } - $version = is_null(arg(3)) ? $default_branch : arg(3); - $items[] = array( - 'path' => 'api/function/'. arg(2) .'/'. $version .'/documentation', - 'title' => t('View documentation'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10 - ); - $items[] = array( - 'path' => 'api/function/'. arg(2) .'/'. $version .'/references', - 'title' => t('List references'), - 'callback' => 'api_page_function_references', - 'access' => $access, - 'callback arguments' => array(arg(3), arg(2)), - 'type' => MENU_LOCAL_TASK, - ); - } + $items['apis'] = array( + 'title' => 'API search', + 'page callback' => 'api_search_listing', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'type' => MENU_CALLBACK, + ); + $items['api/autocomplete'] = array( + 'page callback' => 'api_autocomplete', + 'access callback' => $access_callback, + 'access arguments' => $access_arguments, + 'type' => MENU_CALLBACK, + ); + $items['admin/settings/api'] = array( + 'title' => 'API reference', + 'description' => 'Configure Drupal branches for documentation.', + 'access callback' => 'user_access', + 'access arguments' => array('administer API reference'), + 'page callback' => 'api_page_admin', + ); - if (arg(1) == 'constant' && is_string(arg(2))) { - $items[] = array( - 'path' => 'api/constant/'. arg(2), - 'title' => t('Constant'), - 'callback' => 'api_page_constant', - 'access' => $access, - 'callback arguments' => array($default_branch, arg(2)), - 'type' => MENU_CALLBACK, - ); - foreach ($branches as $branch) { - if (db_result(db_query("SELECT did FROM {api_documentation} WHERE object_name = '%s' AND branch_name = '%s' AND object_type = 'constant'", arg(2), $branch->branch_name))) { - $items[] = array( - 'path' => 'api/constant/'. arg(2) .'/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_constant', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, arg(2)), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - } - } - } + // Function dumps for IDEs and code editors. + $items['api/function_dump/%api_branch'] = array( + 'page callback' => 'api_page_function_dump', + 'callback arguments' => array(2), + 'type' => MENU_CALLBACK, + ); + // Search callback. + $items['api/search/%menu_tail'] = array( + 'title' => 'Search', + 'page callback' => 'api_search_listing', + 'type' => MENU_CALLBACK, + ); - if (arg(1) == 'global' && is_string(arg(2))) { - $items[] = array( - 'path' => 'api/global/'. arg(2), - 'title' => t('Global'), - 'callback' => 'api_page_global', - 'access' => $access, - 'callback arguments' => array($default_branch, arg(2)), - 'type' => MENU_CALLBACK, - ); - foreach ($branches as $branch) { - if (db_result(db_query("SELECT did FROM {api_documentation} WHERE object_name = '%s' AND branch_name = '%s' AND object_type = 'global'", arg(2), $branch->branch_name))) { - $items[] = array( - 'path' => 'api/global/'. arg(2) .'/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_global', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, arg(2)), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - } - } - } + // Part 2: Object provided, default branch. + $items['api/function/%'] = array( + 'title' => 'Function', + 'page callback' => 'api_page_function', + 'page arguments' => array($default_branch, 2), + 'type' => MENU_CALLBACK, + ); + // Note: We can't support Documentation / References for the "default" branch case. + // If we tried it, we'd suddenly get extra tabs in the branch list. + $items['api/constant/%'] = array( + 'title' => 'Constant', + 'page callback' => 'api_page_constant', + 'page arguments' => array($default_branch, 2), + 'type' => MENU_CALLBACK, + ); + $items['api/global/%'] = array( + 'title' => 'Global', + 'page callback' => 'api_page_global', + 'page arguments' => array($default_branch, 2), + 'type' => MENU_CALLBACK, + ); + $items['api/file/%api_filename'] = array( + 'title callback' => 'basename', + 'title arguments' => array(2), + 'page callback' => 'api_page_file', + 'page arguments' => array($default_branch, 2), + 'type' => MENU_CALLBACK, + ); + $items['api/group/%'] = array( + 'title' => 'Topic', + 'page callback' => 'api_page_group', + 'page arguments' => array($default_branch, 2), + 'type' => MENU_CALLBACK, + ); - if (arg(1) == 'file' && is_string(arg(2))) { - // The file path to the file makes determining the correct menu path a - // bit tricky. We have to break off the beginning section of the path, - // then test the last part to see if it's a branch name, then build the - // filename/branch name from there. - $parts = $parts2 = explode('/', substr($_GET['q'], strlen('api/file/'))); - $last = array_pop($parts2); - if ($last == 'source' || $last == 'documentation') { - $last = array_pop($parts2); - } - if (in_array($last, array_keys($branches))) { - $main_file_name = implode('/', $parts2); - $branch_name = $last; - } - else { - $main_file_name = implode('/', $parts); - $branch_name = $default_branch; - } + foreach ($branches as $branch) { + // Part 3: No object, specific branch + $items['api/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_branch', + 'page arguments' => array($branch->branch_name), + 'access callback' => $access_callback, // @@@ + 'access arguments' => $access_arguments, // @@@ + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/functions/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_listing', + 'page arguments' => array($branch->branch_name, 'function'), + 'access callback' => 'api_tabchk', + 'access arguments' => array('function', NULL, $branch->branch_name), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/constants/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_listing', + 'page arguments' => array($branch->branch_name, 'constant'), + 'access callback' => 'api_tabchk', + 'access arguments' => array('constant', NULL, $branch->branch_name), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/globals/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_listing', + 'page arguments' => array($branch->branch_name, 'global'), + 'access callback' => 'api_tabchk', + 'access arguments' => array('global', NULL, $branch->branch_name), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/files/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_listing', + 'page arguments' => array($branch->branch_name, 'file'), + 'access callback' => 'api_tabchk', + 'access arguments' => array('file', NULL, $branch->branch_name), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/groups/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_listing', + 'page arguments' => array($branch->branch_name, 'group'), + 'access callback' => 'api_tabchk', + 'access arguments' => array('group', NULL, 2), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); - foreach ($branches as $branch) { - if ($branch->branch_name == $branch_name) { - $items[] = array( - 'path' => 'api/file/'. $main_file_name, - 'title' => basename($main_file_name), - 'callback' => 'api_page_file', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, $main_file_name), - 'type' => MENU_CALLBACK, - ); - } - // Check if file path has changed in different branches. - if ($file_name = db_result(db_query("SELECT file_name FROM {api_documentation} WHERE title = '%s' AND branch_name = '%s' AND object_type = 'file'", basename($main_file_name), $branch->branch_name))) { - $items[] = array( - 'path' => 'api/file/'. $file_name .'/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_file', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, $file_name), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - } - } - $items[] = array( - 'path' => 'api/file/'. $main_file_name .'/'. $branch_name .'/documentation', - 'title' => t('View documentation'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, - ); - $items[] = array( - 'path' => 'api/file/'. $main_file_name .'/'. $branch_name .'/source', - 'title' => t('View source'), - 'callback' => 'api_page_file_source', - 'access' => $access, - 'callback arguments' => array($branch_name, $main_file_name), - 'type' => MENU_LOCAL_TASK, - ); - } + // Part 4: Object provided, specific branch. + $items['api/function/%/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_function', + 'page arguments' => array(3, 2), + 'access callback' => 'api_tabchk', + 'access arguments' => array(1, 2, 3), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + // Documentation / References sub-tabs + $version = ($branch->branch_name == $default_branch) ? '' : $branch->branch_name .'/'; + $items['api/function/%/'. $version .'documentation'] = array( + 'title' => 'View documentation', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['api/function/%/'. $version .'references'] = array( + 'title' => 'List references', + 'page callback' => 'api_page_function_references', + 'page arguments' => array(3, 2), + 'type' => MENU_LOCAL_TASK, + ); - if (arg(1) == 'group' && is_string(arg(2))) { - $items[] = array( - 'path' => 'api/group/'. arg(2), - 'title' => t('Topic'), - 'callback' => 'api_page_group', - 'access' => $access, - 'callback arguments' => array($default_branch, arg(2)), - 'type' => MENU_CALLBACK, - ); - foreach ($branches as $branch) { - if (db_result(db_query("SELECT did FROM {api_documentation} WHERE object_name = '%s' AND branch_name = '%s' AND object_type = 'group'", arg(2), $branch->branch_name))) { - $items[] = array( - 'path' => 'api/group/'. arg(2) .'/'. $branch->branch_name, - 'title' => $branch->title, - 'callback' => 'api_page_group', - 'access' => $access, - 'callback arguments' => array($branch->branch_name, arg(2)), - 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - ); - } - } - } - - if (arg(1) == 'search' && is_string(arg(3))) { - $items[] = array( - 'path' => 'api/search', - 'title' => t('Search'), - 'callback' => 'api_search_listing', - 'access' => $access, - 'type' => MENU_CALLBACK, - ); - foreach ($branches as $branch) { - $items[] = array( - 'path' => 'api/search/'. $branch->branch_name .'/'. arg(3), - 'title' => $branch->title, - 'callback' => 'api_search_listing', - 'callback arguments' => array($branch->branch_name, arg(3)), - 'access' => $access, - //'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - 'type' => MENU_LOCAL_TASK, - ); - } - } - } + $items['api/constant/%/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_constant', + 'page arguments' => array(3, 2), + 'access callback' => 'api_tabchk', + 'access arguments' => array(1, 2, 3), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/global/%/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_global', + 'page arguments' => array(3, 2), + 'access callback' => 'api_tabchk', + 'access arguments' => array(1, 2, 3), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + // Here's where it gets interesting. + $items['api/file/%api_filename/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_file', + 'page arguments' => array(3, 2), + 'access callback' => 'api_tabchk', + 'access arguments' => array(1, 2, 3), + 'tab_parent' => 'api/file/%api_filename', + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + // We are actually collapsing the entire filename into a single argument. + $items['api/file/%api_filename/'. $branch->branch_name .'/documentation'] = array( + 'title' => 'View documentation', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'tab_parent' => 'api/file/%api_filename/'. $branch->branch_name, + 'weight' => -10, + ); + // The tabs act as expected, even thought there are a variable number of slashes. + $items['api/file/%api_filename/'. $branch->branch_name .'/source'] = array( + 'title' => 'View source', + 'page callback' => 'api_page_file_source', + 'page arguments' => array(3, 2), + 'type' => MENU_LOCAL_TASK, + 'tab_parent' => 'api/file/%api_filename/'. $branch->branch_name, + ); + $items['api/group/%/'. $branch->branch_name] = array( + 'title' => $branch->title, + 'page callback' => 'api_page_group', + 'page arguments' => array(3, 2), + 'access callback' => 'api_tabchk', + 'access arguments' => array(1, 2, 3), + 'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + ); + $items['api/search/'. $branch->branch_name .'/%menu_tail'] = array( + 'title' => $branch->title, + 'page callback' => 'api_search_listing', + 'page arguments' => array($branch->branch_name, arg(3)), + 'access callback' => 'api_tabchk', + 'access arguments' => array(1, 2, 3), + //'type' => ($branch->branch_name == $default_branch) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, + 'type' => MENU_LOCAL_TASK, + ); } - return $items; } /** + * Determine a filename. + */ +function api_filename_to_arg($arg, $map, $index) { + $end = count($map) - 1; + // Search for a dot going backwards. When we find one, we know we're in the basename section. + while(strpos($map[$end], '.') === FALSE && $end > $index) { + $end--; + } +drupal_set_message(var_export(implode('/', array_slice($map, $index+3, $end - $index + 1)), true)); + return implode('/', array_slice($map, $index+3, $end - $index + 1)); +} + +/** + * Quote unquote "access" control function which is mainly used to hide inapplicable branch tabs. + */ +function api_tabchk($object_type = NULL, $object_name = NULL, $branch_name = NULL) { + // If the user isn't allowed in in the FIRST place, quit early. + if (!user_access('access API reference')) { + return FALSE; + } + + // NULL means we're using the default branch. + if ($branch_name == NULL) { + $branch_name = variable_get('api_default_branch', 'HEAD'); + } + + // Are we talking about a *group* of objects here? + if ($object_name == NULL) { + // OK, no object name, let's see if there's ANYTHING in this branch of this type... + return (db_result(db_query("SELECT COUNT(*) FROM {api_documentation} WHERE object_type = '%s' AND branch_name = '%s'", $object_type, $branch_name)) >= 1); + } + else { + // We have all three, see if this branch carries this object of this type. + return (db_result(db_query("SELECT COUNT(*) FROM {api_documentation} WHERE object_type = '%s' AND object_name = '%s' AND branch_name = '%s'", $object_type, $object_name, $branch_name)) >= 1); + } +} + +/** * Implementation of hook_perm(). */ function api_perm() { @@ -550,8 +528,8 @@ function api_search_form($branch) { return $form; } -function api_search_form_submit($form_id, $form_values) { - return 'api/search/'. $form_values['branch_name'] .'/'. $form_values['search']; +function api_search_form_submit($form, &$form_state) { + return 'api/search/'. $form_state['values']['branch_name'] .'/'. $form_state['values']['search']; } /** @@ -566,12 +544,12 @@ function api_search_listing($branch_name drupal_set_title(t('API Search for “%search” in %branch', array('%search' => $search_text, '%branch' => $branch_name))); // Exact match. - $result = db_query("SELECT * FROM {api_documentation} WHERE branch_name = '%s' AND title = '%s'", $branch_name, $search_text); - $count = db_num_rows($result); + $result = db_query("SELECT COUNT(*) FROM {api_documentation} WHERE branch_name = '%s' AND title = '%s'", $branch_name, $search_text); + $count = db_result($result); if ($count != 1) { // Wildcard search. $result = db_query("SELECT * FROM {api_documentation} WHERE branch_name = '%s' AND title LIKE '%%%s%%'", $branch_name, $search_text); - $count = db_num_rows($result); + $count = db_result($result); } switch ($count) { @@ -594,7 +572,7 @@ function api_search_listing($branch_name */ function api_autocomplete($branch_name, $search) { $matches = array(); - $result = db_query("SELECT title FROM {api_documentation} WHERE title LIKE '%%%s%%' AND branch_name = '%s' ORDER BY LENGTH(title) LIMIT 20", $search, $branch_name); + $result = db_query("SELECT title FROM {api_documentation} WHERE title LIKE '%%%s%%' AND branch_name = '%s' ORDER BY LENGTH(title)", 0, 20); while ($r = db_fetch_object($result)) { $matches[$r->title] = check_plain($r->title); } @@ -868,6 +846,12 @@ function api_page_global($branch_name, $ * Menu callback; displays documentation for a file. */ function api_page_file($branch_name, $object_name) { +// @@@ TODO: Figure out why $object_name is being split like this.... +$object_name = func_get_args(); +array_shift($object_name); +array_pop($object_name); +$object_name = implode('/', $object_name); + drupal_add_css(drupal_get_path('module', 'api') .'/api.css'); $result = db_query("SELECT d.did, d.title, d.documentation, f.version FROM {api_documentation} d INNER JOIN {api_file} f ON d.did = f.did WHERE object_name = '%s' AND branch_name = '%s' AND object_type = 'file'", $object_name, $branch_name); @@ -1038,6 +1022,7 @@ function api_page_admin() { function api_page_admin_form() { $form = array(); + $radios = array(); $result = db_query('SELECT branch_name, title, directory FROM {api_branch}'); $form['branches'] = array( @@ -1086,10 +1071,12 @@ function api_page_admin_form() { ); global $base_url; - + $first_key = ''; if ($radios) { if (!variable_get('api_default_branch', FALSE)) { - list($first_key) = array_keys($radios); + + $first_key = array_keys($radios); + list($first_key) = $first_key; variable_set('api_default_branch', $first_key); } @@ -1126,8 +1113,8 @@ function api_page_admin_form() { return $form; } -function api_page_admin_form_submit($form_id, $form_values) { - foreach ($form_values['branches'] as $branch_name => $branch) { +function api_page_admin_form_submit($form, &$form_state) { + foreach ($form_state['values']['branches'] as $branch_name => $branch) { if ($branch_name == 'new') { if ($branch['branch_name'] != '') { db_query("INSERT INTO {api_branch} (branch_name, title, directory) VALUES ('%s', '%s', '%s')", $branch['branch_name'], $branch['title'], $branch['directory']); @@ -1158,12 +1145,12 @@ function api_page_admin_form_submit($for } //save the variable for default branch - if ($form_values['default_branch']) { - variable_set('api_default_branch', $form_values['default_branch']); + if ($form_state['values']['default_branch']) { + variable_set('api_default_branch', $form_state['values']['default_branch']); } // Save the variable for max files per cron. - variable_set('api_files_per_cron', $form_values['api_files_per_cron']); + variable_set('api_files_per_cron', $form_state['values']['api_files_per_cron']); // We may have menu changes, so clear the menu cache for all users. cache_clear_all('*', 'cache_menu', TRUE); @@ -1190,12 +1177,12 @@ function api_php_manual_index_form() { return $form; } -function api_php_manual_index_form_submit($form_id, $form_values) { +function api_php_manual_index_form_submit($form, &$form_state) { include_once(drupal_get_path('module', 'api') .'/parser.inc'); - variable_set('api_php_funcsummary', $form_values['api_php_funcsummary']); - variable_set('api_php_funcpath', $form_values['api_php_funcpath']); + variable_set('api_php_funcsummary', $form_state['values']['api_php_funcsummary']); + variable_set('api_php_funcpath', $form_state['values']['api_php_funcpath']); db_query("DELETE FROM {api_documentation} WHERE branch_name = 'php'"); - api_parse_php_manual($form_values['api_php_funcsummary']); + api_parse_php_manual($form_state['values']['api_php_funcsummary']); drupal_set_message(t('Manual pages scanned.')); } @@ -1210,16 +1197,16 @@ function api_reindex_form() { return $form; } -function api_reindex_form_submit($form_id, $form_values) { +function api_reindex_form_submit($form, &$form_state) { db_query("UPDATE {api_file} SET modified = 52"); - drupal_set_message(t('All files have been tagged for reindexing. The index will be rebuilt during the next few runs of !cron.', array('!cron' => l('cron.php', 'admin/logs/status/run-cron')))); + drupal_set_message(t('All files have been tagged for reindexing. The index will be rebuilt during the next few runs of !cron.', array('!cron' => l('cron.php', 'admin/reports/status/run-cron')))); } /** * Implementation of hook_cron(). */ function api_cron() { - include_once(drupal_get_path('module', 'api') .'/parser.inc'); + require_once(drupal_get_path('module', 'api') .'/parser.inc'); $files_scanned = 0; $max_files = variable_get('api_files_per_cron', 10); @@ -1253,7 +1240,7 @@ function api_cron() { if ($files_scanned == 0) { $result = db_query("SELECT ad.file_name, ad.branch_name FROM {api_file} af LEFT JOIN {api_documentation} ad ON ad.did = af.did WHERE af.found = 0"); while ($file = db_fetch_object($result)) { - watchdog('api', t('Removing %file', array('%file' => $file->file_name))); + watchdog('api', 'Removing %file', array('%file' => $file->file_name)); $doc_result = db_query("SELECT ad.did FROM {api_documentation} ad WHERE ad.file_name = '%s' AND ad.branch_name = '%s'", $file->file_name, $file->branch_name); while ($doc = db_fetch_object($doc_result)) { db_query("DELETE FROM {api_documentation} WHERE did = %d", $doc->did); Index: parser.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/api/parser.inc,v retrieving revision 1.24.2.15 diff -u -p -r1.24.2.15 parser.inc --- parser.inc 23 Jan 2008 02:49:56 -0000 1.24.2.15 +++ parser.inc 23 Jan 2008 08:47:25 -0000 @@ -470,13 +470,12 @@ function api_parse_php_file($file_path, * The documentation ID of the inserted/updated construct. */ function api_save_documentation(&$docblock) { - $result = db_query("SELECT did FROM {api_documentation} WHERE object_name = '%s' AND branch_name = '%s' AND object_type = '%s'", $docblock['object_name'], $docblock['branch_name'], $docblock['object_type']); - if (db_num_rows($result) > 0) { - $did = db_result($result); + $did = db_result(db_query("SELECT did FROM {api_documentation} WHERE object_name = '%s' AND branch_name = '%s' AND object_type = '%s' AND file_name = '%s'", $docblock['object_name'], $docblock['branch_name'], $docblock['object_type'], $docblock['file_name'])); + if ($did > 0) { db_query("UPDATE {api_documentation} SET title = '%s', file_name = '%s', summary = '%s', documentation = '%s', code = '%s' WHERE did = %d", $docblock['title'], $docblock['file_name'], $docblock['summary'], $docblock['documentation'], $docblock['code'], $did); } else { - $did = db_next_id('{api_documentation}_did'); + $did = db_last_insert_id('api_documentation', 'did'); db_query("INSERT INTO {api_documentation} (did, object_name, branch_name, object_type, title, file_name, summary, documentation, code) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", $did, $docblock['object_name'], $docblock['branch_name'], $docblock['object_type'], $docblock['title'], $docblock['file_name'], $docblock['summary'], $docblock['documentation'], $docblock['code']); } @@ -734,7 +733,7 @@ function api_reference($branch_name, $to static $is_php_function = array(); if ($to_type == 'function' && !isset($is_php_function[$to_name])) { - $is_php_function[$to_name] = (db_num_rows(db_query("SELECT object_name FROM {api_documentation} WHERE object_name = '%s' AND branch_name = 'php'", $to_name)) == 1); + $is_php_function[$to_name] = (db_result(db_query("SELECT COUNT(*) FROM {api_documentation} WHERE object_name = '%s' AND branch_name = 'php'", $to_name)) == 1); } if ($to_type != 'function' || !$is_php_function[$to_name]) {