How to pass arguments to add_action() or retrieve return value of called function?

It’s possible to use functions in a way that allow for one action to pass variables to the next. In this case, I’ve waited till the wp_head event to add the_content filter. And it will be using the queried_object_id when appending content with showPostMetaInfo.

This makes your function a little more OOP friendly.

// Wait till the head
add_action( 'wp_head', function() {

    // Get the queried ID for use with `the_content`
    $queried_id = get_queried_object_id();

    add_filter( 'the_content', function( $content ) use ( $queried_id ) {

        // append post meta info to content
        return $content . showPostMetaInfo( $queried_id );
    } );
} );

function showPostMetaInfo( $id = null ) {

    if ( empty( $id ) ) {
        return '';
    }

    ob_start();

    ?>
    <table id='meta-info'>
    <thead>
    <tr>
        <th> Meta Type</th>
        <th> Value
    </tr>
    </thead>
    <tbody>
    <tr>
        <td> Title</td>
        <td><?php echo get_the_title( $id ); ?></td>
    </tr>
    <tr>
        <td> Author</td>
        <td><?php echo get_the_author( $id ); ?></td>
    </tr>
    <tr>
        <td> Published</td>
        <td><?php echo get_the_date( "", $id ); ?></td>
    </tr>
    <tr>
        <td> Last Modified</td>
        <td><?php echo get_the_modified_date( "", $id ); ?></td>
    </tr>
    <tr>
        <td> Categories</td>
        <td><?php echo listCategories( $id ); ?></td>
    </tr>
    <tr>
        <td> Tags</td>
        <td><?php echo listTags( $id ); ?></td>
    </tr>
    </tbody>
    </table><?php

    return ob_get_clean();
}

function listCategories( $id ) { return 'listCategories: ' . $id; };
function listTags( $id ) { return 'listTags: ' . $id; };

Note: This won’t work with all versions of PHP.


Option 2

Taking this a step further, you could create a class that allows for dynamic data (including methods) and route your functions through it using magic methods.

if ( ! class_exists( 'FunctionProxy' ) ):

    class FunctionProxy {

        private $s = array ();

        // properties
        function __set( $k, $c ) { $this->s[ $k ] = $c; }
        function __get( $k ) { return isset($this->s[ $k ]) ? $this->s[ $k ] : null; }

        // methods
        public function __call( $method, $args ) {
            if ( isset($this->s[ $method ]) && is_callable( $this->s[ $method ] ) ) {
                return call_user_func_array( $this->s[ $method ], func_get_args() );
            } else {
                echo "unknown method " . $method;
                return false;
            }
        }

        // backtrace caller
        static function get_backtrace_object( $depth = 3 ) {
            $trace  = debug_backtrace();
            return isset( $trace[ $depth ][ 'object' ] ) ? $trace[ $depth ][ 'object' ] : null;
        }
    }

endif;

Using the FunctionProxy dynamic object you can make methods and properties on the fly.

// Wait till the head
add_action( 'wp_head', function() {

    // create our dynamic object
    $func = new FunctionProxy();

    // Get the queried ID for use with `the_content`
    $func->queried_id = get_queried_object_id();

    // Create a method on the object
    $func->filter_the_content = function( $content ) {

        // Find the callee of this function
        $caller = FunctionProxy::get_backtrace_object();

        // Return content plus post meta from our caller object
        return $content . showPostMetaInfo( $caller->queried_id );
    };

    // add content filer
    add_filter( 'the_content', array ( $func, 'filter_the_content' ) );
} );

Reference