| 1 |
<?php |
<?php |
| 2 |
// $Id: parser.inc,v 1.31 2008/07/21 02:18:08 drumm Exp $ |
// $Id: parser.inc,v 1.32 2008/07/21 05:33:22 drumm Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 35 |
} |
} |
| 36 |
|
|
| 37 |
/** |
/** |
|
* Read in the file at the given path and pass it off to the appropriate handler |
|
|
* for parsing. |
|
|
*/ |
|
|
function api_parse_file($file_path, $branch_name, $file_name) { |
|
|
if (preg_match('!\.(php|module|inc|install|engine|theme)$!', $file_name)) { |
|
|
watchdog('api', 'Parsing %branch %path.', array('%branch' => $branch_name, '%path' => $file_name)); |
|
|
api_parse_php_file($file_path, $branch_name, $file_name); |
|
|
return TRUE; |
|
|
} |
|
|
if (preg_match('!\.(txt)$!', $file_name)) { |
|
|
watchdog('api', 'Parsing %branch %path.', array('%branch' => $branch_name, '%path' => $file_name)); |
|
|
api_parse_text_file($file_path, $branch_name, $file_name); |
|
|
return TRUE; |
|
|
} |
|
|
if (preg_match('!\.(htm|html)$!', $file_name)) { |
|
|
watchdog('api', 'Parsing %branch %path.', array('%branch' => $branch_name, '%path' => $file_name)); |
|
|
api_parse_html_file($file_path, $branch_name, $file_name); |
|
|
return TRUE; |
|
|
} |
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
/** |
|
| 38 |
* Read in the file at the given path and parse it as if it consisted entirely of |
* Read in the file at the given path and parse it as if it consisted entirely of |
| 39 |
* documentation. |
* documentation. |
| 40 |
*/ |
*/ |
| 492 |
} |
} |
| 493 |
} |
} |
| 494 |
|
|
| 495 |
|
api_schedule_update_references(); |
| 496 |
|
api_schedule_cache_clear(); |
| 497 |
|
|
| 498 |
return $did; |
return $did; |
| 499 |
} |
} |
| 500 |
|
|
| 732 |
} |
} |
| 733 |
|
|
| 734 |
/** |
/** |
| 735 |
|
* References do not need to be repeatedly updated, just at the end of a |
| 736 |
|
* request that involved parsing. |
| 737 |
|
*/ |
| 738 |
|
function api_schedule_update_references() { |
| 739 |
|
static $scheduled = FALSE; |
| 740 |
|
|
| 741 |
|
if (!$scheduled) { |
| 742 |
|
register_shutdown_function('api_update_references'); |
| 743 |
|
$scheduled = TRUE; |
| 744 |
|
} |
| 745 |
|
} |
| 746 |
|
|
| 747 |
|
/** |
| 748 |
* Update the references that were collected. |
* Update the references that were collected. |
| 749 |
*/ |
*/ |
| 750 |
function api_update_references() { |
function api_update_references() { |
| 751 |
// First, figure out all the dids of the object/branch/types. |
// Figure out all the dids of the object/branch/types. |
| 752 |
db_query('UPDATE {api_reference_storage} r, {api_documentation} d SET r.to_did = d.did WHERE r.object_name = d.object_name AND r.branch_name = d.branch_name AND r.object_type = d.object_type'); |
db_query('UPDATE {api_reference_storage} r, {api_documentation} d SET r.to_did = d.did WHERE r.object_name = d.object_name AND r.branch_name = d.branch_name AND r.object_type = d.object_type'); |
| 753 |
} |
} |
| 754 |
|
|
| 755 |
|
function api_schedule_cache_clear() { |
| 756 |
|
register_shutdown_function('cache_clear_all'); |
| 757 |
|
} |
| 758 |
|
|
| 759 |
|
function api_update_all_branches() { |
| 760 |
|
foreach (api_get_branches() as $branch) { |
| 761 |
|
api_update_branch($branch); |
| 762 |
|
} |
| 763 |
|
} |
| 764 |
|
|
| 765 |
|
function api_update_branch($branch) { |
| 766 |
|
static $parse_functions = array( |
| 767 |
|
'php' => 'api_parse_php_file', |
| 768 |
|
'module' => 'api_parse_php_file', |
| 769 |
|
'inc' => 'api_parse_php_file', |
| 770 |
|
'install' => 'api_parse_php_file', |
| 771 |
|
'engine' => 'api_parse_php_file', |
| 772 |
|
'theme' => 'api_parse_php_file', |
| 773 |
|
|
| 774 |
|
'txt' => 'api_parse_text_file', |
| 775 |
|
|
| 776 |
|
'htm' => 'api_parse_html_file', |
| 777 |
|
'html' => 'api_parse_html_file', |
| 778 |
|
); |
| 779 |
|
|
| 780 |
|
// List all documented files for the branch. |
| 781 |
|
$files = array(); |
| 782 |
|
$result = db_query("SELECT f.did, f.modified, d.object_name FROM {api_documentation} d INNER JOIN {api_file} f ON d.did = f.did WHERE d.branch_name = '%s' AND d.object_type = 'file'", $branch->branch_name); |
| 783 |
|
while ($file = db_fetch_object($result)) { |
| 784 |
|
$files[$file->object_name] = $file; |
| 785 |
|
} |
| 786 |
|
|
| 787 |
|
foreach (api_scan_directories($branch->directory) as $path => $file_name) { |
| 788 |
|
preg_match('!\.([a-z]*)$!', $file_name, $matches); |
| 789 |
|
if (isset($parse_functions[$matches[1]])) { |
| 790 |
|
if (isset($files[$file_name])) { |
| 791 |
|
$parse = (filemtime($path) > $files[$file_name]->modified); |
| 792 |
|
unset($files[$file_name]); // All remaining files will be removed. |
| 793 |
|
} |
| 794 |
|
else { // New file. |
| 795 |
|
$parse = TRUE; |
| 796 |
|
} |
| 797 |
|
if ($parse) { |
| 798 |
|
job_queue_add($parse_functions[$matches[1]], t('API parse %branch %file'), array($path, '%branch' => $branch->branch_name, '%file' => $file_name), drupal_get_path('module', 'api') .'/parser.inc', TRUE); |
| 799 |
|
} |
| 800 |
|
} |
| 801 |
|
} |
| 802 |
|
|
| 803 |
|
// Remove outdated files. |
| 804 |
|
foreach (array_keys($files) as $file_name) { |
| 805 |
|
watchdog('api', 'Removing %file.', array('%file' => $file_name)); |
| 806 |
|
$result = db_query("SELECT ad.did FROM {api_documentation} ad WHERE ad.file_name = '%s' AND ad.branch_name = '%s'", $file_name, $branch->branch_name); |
| 807 |
|
while ($doc = db_fetch_object($result)) { |
| 808 |
|
db_query("DELETE FROM {api_documentation} WHERE did = %d", $doc->did); |
| 809 |
|
db_query("DELETE FROM {api_file} WHERE did = %d", $doc->did); |
| 810 |
|
db_query("DELETE FROM {api_function} WHERE did = %d", $doc->did); |
| 811 |
|
db_query("DELETE FROM {api_reference_storage} WHERE from_did = %d OR to_did = %d", $doc->did, $doc->did); |
| 812 |
|
} |
| 813 |
|
api_schedule_cache_clear(); |
| 814 |
|
} |
| 815 |
|
} |
| 816 |
|
|
| 817 |
|
/** |
| 818 |
|
* Find all the files in the directories specified for a branch. |
| 819 |
|
*/ |
| 820 |
|
function api_scan_directories($directories) { |
| 821 |
|
$directory_array = explode(':', $directories); |
| 822 |
|
|
| 823 |
|
if (count($directory_array) > 1) { |
| 824 |
|
$directories_components = array(); |
| 825 |
|
foreach ($directory_array as $directory) { |
| 826 |
|
$directory_components = array(); |
| 827 |
|
$parts = explode('/', $directory); |
| 828 |
|
foreach ($parts as $part) { |
| 829 |
|
if (strlen($part)) { |
| 830 |
|
array_unshift($directory_components, reset($directory_components) .'/'. $part); |
| 831 |
|
} |
| 832 |
|
} |
| 833 |
|
$directories_components[] = $directory_components; |
| 834 |
|
} |
| 835 |
|
|
| 836 |
|
$common_ancestor_components = call_user_func_array('array_intersect', $directories_components); |
| 837 |
|
$common_ancestor = reset($common_ancestor_components); |
| 838 |
|
} |
| 839 |
|
else { |
| 840 |
|
$common_ancestor = $directories; |
| 841 |
|
} |
| 842 |
|
|
| 843 |
|
$source_files = array(); |
| 844 |
|
foreach ($directory_array as $directory) { |
| 845 |
|
$files = file_scan_directory($directory, '.*'); |
| 846 |
|
foreach ($files as $path => $file) { |
| 847 |
|
if (strpos($path, '/.') !== FALSE) { |
| 848 |
|
continue; |
| 849 |
|
} |
| 850 |
|
$file_name = substr($path, strlen($common_ancestor) + 1); |
| 851 |
|
|
| 852 |
|
$source_files[$path] = $file_name; |
| 853 |
|
} |
| 854 |
|
} |
| 855 |
|
return $source_files; |
| 856 |
|
} |