Skip to content

Commit 0828fcd

Browse files
committed
include hooks/actions called by scheduled functions
1 parent 6c7f173 commit 0828fcd

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

src/generate.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,29 @@ function hooks_parse_files( array $files, string $root, array $ignore_hooks ) :
126126
$file_hooks = array_merge( $file_hooks, export_hooks( $file->uses['hooks'], $path ) );
127127
}
128128

129+
if ( ! empty( $file->uses['functions'] ) ) {
130+
$file_hooks = array_merge( $file_hooks, export_scheduled_hooks( $file->uses['functions'], $path ) );
131+
}
132+
129133
foreach ( $file->getFunctions() as $function ) {
130134
if ( ! empty( $function->uses ) && ! empty( $function->uses['hooks'] ) ) {
131135
$file_hooks = array_merge( $file_hooks, export_hooks( $function->uses['hooks'], $path ) );
132136
}
137+
138+
if ( ! empty( $function->uses ) && ! empty( $function->uses['functions'] ) ) {
139+
$file_hooks = array_merge( $file_hooks, export_scheduled_hooks( $function->uses['functions'], $path ) );
140+
}
133141
}
134142

135143
foreach ( $file->getClasses() as $class ) {
136144
foreach ( $class->getMethods() as $method ) {
137145
if ( ! empty( $method->uses ) && ! empty( $method->uses['hooks'] ) ) {
138146
$file_hooks = array_merge( $file_hooks, export_hooks( $method->uses['hooks'], $path ) );
139147
}
148+
149+
if ( ! empty( $method->uses ) && ! empty( $method->uses['functions'] ) ) {
150+
$file_hooks = array_merge( $file_hooks, export_scheduled_hooks( $method->uses['functions'], $path ) );
151+
}
140152
}
141153
}
142154

@@ -167,6 +179,74 @@ function hooks_parse_files( array $files, string $root, array $ignore_hooks ) :
167179
return $output;
168180
}
169181

182+
/**
183+
* @param \WP_Parser\Function_Call_Reflector[] $nodes Array of hook references.
184+
* @param string $path The file path.
185+
* @return array<int,array<string,mixed>>
186+
*/
187+
function export_scheduled_hooks( array $nodes, string $path ) : array {
188+
$out = array();
189+
190+
$event_functions = [
191+
'wp_schedule_event',
192+
// WooCommerce action scheduler
193+
'as_schedule_recurring_action',
194+
'as_schedule_cron_action',
195+
];
196+
197+
$single_event_functions = [
198+
'wp_schedule_single_event',
199+
// WooCommerce action scheduler
200+
'as_schedule_single_action',
201+
'as_enqueue_async_action',
202+
];
203+
204+
foreach ( $nodes as $wp_node ) {
205+
if ( !$wp_node instanceof \WP_Parser\Function_Call_Reflector ) {
206+
continue;
207+
}
208+
209+
$origNode = $wp_node->getNode();
210+
211+
// same code used in psalm-plugin-wordpress
212+
if ( $origNode instanceof \PhpParser\Node\Expr\FuncCall && $origNode->name instanceof \PhpParser\Node\Name ) {
213+
if ( in_array( (string) $origNode->name, $event_functions, true ) ) {
214+
$hook_type = 'cron-action';
215+
// the 3rd arg (index key 2) is the hook name
216+
$hook_index = 2;
217+
} elseif ( in_array( (string) $origNode->name, $single_event_functions, true ) ) {
218+
$hook_type = 'cron-action';
219+
$hook_index = 1;
220+
221+
if ( (string) $origNode->name === 'as_enqueue_async_action' ) {
222+
$hook_index = 0;
223+
}
224+
} else {
225+
continue;
226+
}
227+
228+
if ( ! $origNode->args[ $hook_index ]->value instanceof \PhpParser\Node\Scalar\String_ ) {
229+
continue;
230+
}
231+
232+
$out[] = array(
233+
'name' => $origNode->args[ $hook_index ]->value->value,
234+
'file' => $path,
235+
'type' => 'action',
236+
'doc' => array(
237+
'description' =>'',
238+
'long_description' => '',
239+
'tags' => array(),
240+
'long_description_html' => '',
241+
),
242+
'args' => 0,
243+
);
244+
}
245+
}
246+
247+
return $out;
248+
}
249+
170250
/**
171251
* @param \WP_Parser\Hook_Reflector[] $hooks Array of hook references.
172252
* @param string $path The file path.

0 commit comments

Comments
 (0)