2015-02-23 14:40:16 +00:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Generate documentation for hooks in WC
|
|
|
|
*/
|
|
|
|
class WC_HookFinder {
|
|
|
|
private static $current_file = '';
|
|
|
|
private static $files_to_scan = array();
|
|
|
|
private static $pattern_custom_actions = '/do_action(.*?);/i';
|
|
|
|
private static $pattern_custom_filters = '/apply_filters(.*?);/i';
|
|
|
|
private static $found_files = array();
|
|
|
|
private static $custom_hooks_found = '';
|
|
|
|
|
|
|
|
private static function get_files( $pattern, $flags = 0, $path = '' ) {
|
|
|
|
|
2016-09-07 22:32:24 +00:00
|
|
|
if ( ! $path && ( $dir = dirname( $pattern ) ) != '.' ) {
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2016-09-07 22:32:24 +00:00
|
|
|
if ( '\\' == $dir || '/' == $dir ) {
|
|
|
|
$dir = '';
|
|
|
|
}
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2017-03-07 18:31:47 +00:00
|
|
|
return self::get_files( basename( $pattern ), $flags, $dir . '/' );
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2017-03-07 18:31:47 +00:00
|
|
|
} // End IF Statement
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2017-03-07 18:31:47 +00:00
|
|
|
$paths = glob( $path . '*', GLOB_ONLYDIR | GLOB_NOSORT );
|
|
|
|
$files = glob( $path . $pattern, $flags );
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2017-03-07 18:31:47 +00:00
|
|
|
if ( is_array( $paths ) ) {
|
|
|
|
foreach ( $paths as $p ) {
|
|
|
|
$found_files = array();
|
|
|
|
$retrieved_files = (array) self::get_files( $pattern, $flags, $p . '/' );
|
|
|
|
foreach ( $retrieved_files as $file ) {
|
2017-03-07 20:24:24 +00:00
|
|
|
if ( ! in_array( $file, self::$found_files ) ) {
|
2017-03-07 18:31:47 +00:00
|
|
|
$found_files[] = $file;
|
2017-03-07 20:24:24 +00:00
|
|
|
}
|
2017-03-07 18:31:47 +00:00
|
|
|
}
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2017-03-07 18:31:47 +00:00
|
|
|
self::$found_files = array_merge( self::$found_files, $found_files );
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2017-03-07 18:31:47 +00:00
|
|
|
if ( is_array( $files ) && is_array( $found_files ) ) {
|
|
|
|
$files = array_merge( $files, $found_files );
|
|
|
|
}
|
|
|
|
} // End FOREACH Loop
|
|
|
|
}
|
|
|
|
return $files;
|
|
|
|
}
|
2015-02-23 14:40:16 +00:00
|
|
|
|
|
|
|
private static function get_hook_link( $hook, $details = array() ) {
|
|
|
|
if ( ! empty( $details['class'] ) ) {
|
2016-07-25 13:39:54 +00:00
|
|
|
$link = 'http://docs.woocommerce.com/wc-apidocs/source-class-' . $details['class'] . '.html#' . $details['line'];
|
2015-02-23 14:40:16 +00:00
|
|
|
} elseif ( ! empty( $details['function'] ) ) {
|
2016-07-25 13:39:54 +00:00
|
|
|
$link = 'http://docs.woocommerce.com/wc-apidocs/source-function-' . $details['function'] . '.html#' . $details['line'];
|
2015-02-23 14:40:16 +00:00
|
|
|
} else {
|
2016-09-28 10:17:40 +00:00
|
|
|
$link = 'https://github.com/woocommerce/woocommerce/search?utf8=%E2%9C%93&q=' . $hook;
|
2015-02-23 14:40:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return '<a href="' . $link . '">' . $hook . '</a>';
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function process_hooks() {
|
2018-05-02 13:28:53 +00:00
|
|
|
self::$files_to_scan = array();
|
|
|
|
|
|
|
|
self::$files_to_scan['Template Files'] = self::get_files( '*.php', GLOB_MARK, '../templates/' );
|
|
|
|
self::$files_to_scan['Template Functions'] = array( '../includes/wc-template-functions.php', '../includes/wc-template-hooks.php' );
|
|
|
|
self::$files_to_scan['Shortcodes'] = self::get_files( '*.php', GLOB_MARK, '../includes/shortcodes/' );
|
|
|
|
self::$files_to_scan['Widgets'] = self::get_files( '*.php', GLOB_MARK, '../includes/widgets/' );
|
|
|
|
self::$files_to_scan['Data Stores'] = self::get_files( '*.php', GLOB_MARK, '../includes/data-stores' );
|
|
|
|
self::$files_to_scan['Core Classes'] = array_merge(
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/abstracts/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/customizer/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/emails/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/export/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/gateways/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/import/' ),
|
|
|
|
self::get_files( '*.php', GLOB_MARK, '../includes/shipping/' )
|
2015-02-23 14:40:16 +00:00
|
|
|
);
|
|
|
|
|
2018-05-02 13:28:53 +00:00
|
|
|
self::$files_to_scan = array_filter( self::$files_to_scan );
|
2015-02-23 14:40:16 +00:00
|
|
|
|
|
|
|
$scanned = array();
|
|
|
|
|
|
|
|
ob_start();
|
|
|
|
|
2018-05-02 13:28:53 +00:00
|
|
|
$index = array();
|
|
|
|
|
|
|
|
foreach ( self::$files_to_scan as $heading => $files ) {
|
|
|
|
$index[] = '<a href="#hooks-' . str_replace( ' ', '-', strtolower( $heading ) ) . '">' . $heading . '</a>';
|
|
|
|
}
|
|
|
|
|
2015-02-23 14:40:16 +00:00
|
|
|
echo '<div id="content">';
|
|
|
|
echo '<h1>Action and Filter Hook Reference</h1>';
|
2018-05-02 13:28:53 +00:00
|
|
|
echo '<div class="description">
|
|
|
|
<p>This is simply a list of action and filter hooks found within WooCommerce files. View the source to see supported params and usage.</p>
|
|
|
|
<p>' . implode( ', ', $index ) . '</p>
|
|
|
|
</div>';
|
2015-02-23 14:40:16 +00:00
|
|
|
|
|
|
|
foreach ( self::$files_to_scan as $heading => $files ) {
|
|
|
|
self::$custom_hooks_found = array();
|
|
|
|
|
|
|
|
foreach ( $files as $f ) {
|
|
|
|
self::$current_file = basename( $f );
|
|
|
|
$tokens = token_get_all( file_get_contents( $f ) );
|
|
|
|
$token_type = false;
|
|
|
|
$current_class = '';
|
|
|
|
$current_function = '';
|
|
|
|
|
|
|
|
if ( in_array( self::$current_file, $scanned ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$scanned[] = self::$current_file;
|
|
|
|
|
|
|
|
foreach ( $tokens as $index => $token ) {
|
|
|
|
if ( is_array( $token ) ) {
|
2016-09-09 12:13:35 +00:00
|
|
|
$trimmed_token_1 = trim( $token[1] );
|
2016-09-07 22:32:24 +00:00
|
|
|
if ( T_CLASS == $token[0] ) {
|
2015-02-23 14:40:16 +00:00
|
|
|
$token_type = 'class';
|
2016-09-07 22:32:24 +00:00
|
|
|
} elseif ( T_FUNCTION == $token[0] ) {
|
2015-02-23 14:40:16 +00:00
|
|
|
$token_type = 'function';
|
2016-09-07 22:32:24 +00:00
|
|
|
} elseif ( 'do_action' === $token[1] ) {
|
2015-02-23 14:40:16 +00:00
|
|
|
$token_type = 'action';
|
2016-09-07 22:32:24 +00:00
|
|
|
} elseif ( 'apply_filters' === $token[1] ) {
|
2015-02-23 14:40:16 +00:00
|
|
|
$token_type = 'filter';
|
2016-09-09 11:49:14 +00:00
|
|
|
} elseif ( $token_type && ! empty( $trimmed_token_1 ) ) {
|
2015-02-23 14:40:16 +00:00
|
|
|
switch ( $token_type ) {
|
|
|
|
case 'class' :
|
|
|
|
$current_class = $token[1];
|
|
|
|
break;
|
|
|
|
case 'function' :
|
|
|
|
$current_function = $token[1];
|
|
|
|
break;
|
|
|
|
case 'filter' :
|
|
|
|
case 'action' :
|
|
|
|
$hook = trim( $token[1], "'" );
|
2018-05-02 13:28:53 +00:00
|
|
|
$hook = str_replace( '_FUNCTION_', strtoupper( $current_function ), $hook );
|
|
|
|
$hook = str_replace( '_CLASS_', strtoupper( $current_class ), $hook );
|
|
|
|
$hook = str_replace( '$this', strtoupper( $current_class ), $hook );
|
|
|
|
$hook = str_replace( array( '.', '{', '}', '"', "'", ' ', ')', '(' ), '', $hook );
|
2016-02-22 14:41:14 +00:00
|
|
|
$loop = 0;
|
|
|
|
|
2018-05-02 13:28:53 +00:00
|
|
|
// Keep adding to hook until we find a comma or colon
|
|
|
|
while ( 1 ) {
|
|
|
|
$loop ++;
|
|
|
|
$prev_hook = is_string( $tokens[ $index + $loop - 1 ] ) ? $tokens[ $index + $loop - 1 ] : $tokens[ $index + $loop - 1 ][1];
|
|
|
|
$next_hook = is_string( $tokens[ $index + $loop ] ) ? $tokens[ $index + $loop ] : $tokens[ $index + $loop ][1];
|
|
|
|
|
|
|
|
if ( in_array( $next_hook, array( '.', '{', '}', '"', "'", ' ', ')', '(' ) ) ) {
|
|
|
|
continue;
|
2016-02-22 14:41:14 +00:00
|
|
|
}
|
2018-05-02 13:28:53 +00:00
|
|
|
|
|
|
|
if ( in_array( $next_hook, array( ',', ';' ) ) ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$hook_first = substr( $next_hook, 0, 1 );
|
|
|
|
$hook_last = substr( $next_hook, -1, 1 );
|
|
|
|
|
|
|
|
if ( '{' === $hook_first || '}' === $hook_last || '$' === $hook_first || ')' === $hook_last || '>' === substr( $prev_hook, -1, 1 ) ) {
|
|
|
|
$next_hook = strtoupper( $next_hook );
|
|
|
|
}
|
|
|
|
|
|
|
|
$next_hook = str_replace( array( '.', '{', '}', '"', "'", ' ', ')', '(' ), '', $next_hook );
|
|
|
|
|
|
|
|
$hook .= $next_hook;
|
2016-02-22 14:41:14 +00:00
|
|
|
}
|
|
|
|
|
2015-02-23 14:40:16 +00:00
|
|
|
if ( isset( self::$custom_hooks_found[ $hook ] ) ) {
|
|
|
|
self::$custom_hooks_found[ $hook ]['file'][] = self::$current_file;
|
|
|
|
} else {
|
2017-03-07 18:31:47 +00:00
|
|
|
self::$custom_hooks_found[ $hook ] = array(
|
2015-02-23 14:40:16 +00:00
|
|
|
'line' => $token[2],
|
|
|
|
'class' => $current_class,
|
|
|
|
'function' => $current_function,
|
|
|
|
'file' => array( self::$current_file ),
|
2016-08-27 01:46:45 +00:00
|
|
|
'type' => $token_type,
|
2015-02-23 14:40:16 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$token_type = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ( self::$custom_hooks_found as $hook => $details ) {
|
|
|
|
if ( ! strstr( $hook, 'woocommerce' ) && ! strstr( $hook, 'product' ) && ! strstr( $hook, 'wc_' ) ) {
|
2018-05-02 13:28:53 +00:00
|
|
|
//unset( self::$custom_hooks_found[ $hook ] );
|
2015-02-23 14:40:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ksort( self::$custom_hooks_found );
|
|
|
|
|
|
|
|
if ( ! empty( self::$custom_hooks_found ) ) {
|
2018-05-02 13:28:53 +00:00
|
|
|
echo '<div class="panel panel-default"><div class="panel-heading"><h2 id="hooks-' . str_replace( ' ', '-', strtolower( $heading ) ) . '">' . $heading . '</h2></div>';
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2015-11-20 10:05:33 +00:00
|
|
|
echo '<table class="summary table table-bordered table-striped"><thead><tr><th>Hook</th><th>Type</th><th>File(s)</th></tr></thead><tbody>';
|
2015-02-23 14:40:16 +00:00
|
|
|
|
|
|
|
foreach ( self::$custom_hooks_found as $hook => $details ) {
|
|
|
|
echo '<tr>
|
|
|
|
<td>' . self::get_hook_link( $hook, $details ) . '</td>
|
|
|
|
<td>' . $details['type'] . '</td>
|
|
|
|
<td>' . implode( ', ', array_unique( $details['file'] ) ) . '</td>
|
|
|
|
</tr>' . "\n";
|
|
|
|
}
|
|
|
|
|
2015-11-20 10:05:33 +00:00
|
|
|
echo '</tbody></table></div>';
|
2015-02-23 14:40:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
echo '</div><div id="footer">';
|
|
|
|
|
2015-11-20 10:05:33 +00:00
|
|
|
$html = file_get_contents( '../wc-apidocs/tree.html' );
|
2016-02-23 05:52:10 +00:00
|
|
|
$header = explode( '<div id="content">', $html );
|
|
|
|
$header = str_replace( '<li class="active">', '<li>', current( $header ) );
|
2015-02-23 14:40:16 +00:00
|
|
|
$header = str_replace( '<li class="hooks">', '<li class="active">', $header );
|
2015-11-20 10:05:33 +00:00
|
|
|
$header = str_replace( 'Tree | ', 'Hook Reference | ', $header );
|
2016-02-23 05:52:10 +00:00
|
|
|
$footer = explode( '<div id="footer">', $html );
|
2015-02-23 14:40:16 +00:00
|
|
|
|
2016-02-23 05:52:10 +00:00
|
|
|
file_put_contents( '../wc-apidocs/hook-docs.html', $header . ob_get_clean() . end( $footer ) );
|
2015-02-23 14:40:16 +00:00
|
|
|
echo "Hook docs generated :)\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-20 10:05:33 +00:00
|
|
|
WC_HookFinder::process_hooks();
|