> For the complete documentation index, see [llms.txt](https://wplake.gitbook.io/advanced-views/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wplake.gitbook.io/advanced-views/display-content/php-controller.md).

# PHP Controller

{% hint style="info" %}
The page below describes the Custom Data feature for *Layout*. You can read about the PHP Controller feature for *Post Selections* [here](https://docs.advanced-views.com/query-content/custom-data-pro).
{% endhint %}

## About the feature

#### Custom variables for extra data

Advanced Views automatically loads data from the selected fields into the *Layout* template. In most general cases, this will be sufficient to generate the desired output. However, there may be specific cases where you need to include additional data that is not available in the plugin's list of fields.

To address this need, you can take advantage of the PHP Controller snippet. This feature allows you to retrieve any necessary data using PHP and then use these extra variables in your template.

You can find the 'PHP Controller' field under the **'Template' tab** in the *Layout* settings. In this field, you can insert any PHP code and use WordPress functions as needed.

## PHP Controller snippet

The field with the snippet can be found in the **Template tab** of your *Layout*.

The snippet is a PHP code, which must return an instance of the `Layout_Controller_Base` class.&#x20;

* using the `get_variables()` method you can pass custom variables to the *Layout* template&#x20;
* using the `get_ajax_response()` method you define the Ajax callback for the block. [Read more](/advanced-views/templates/custom-ajax-and-rest-api.md)&#x20;
* using the `get_rest_api_response()` method you define the Rest api callback
* using the `get_object_id()` method you can get the id of the displaying object
* using the `get_custom_arguments()` method you can access the [custom arguments passed to the shortcode](https://docs.advanced-views.com/shortcode-attributes/common-arguments#id-4.-custom-arguments). The field is available in the both methods above.
* using the `get_default_variables()` method you can access to the default twig variables (that filled out automatically by the plugin)
* using the `get_container()` method you can access the PHP-DI Container (see the related chapter of this page)&#x20;

{% code overflow="wrap" %}

```php
<?php

declare(strict_types=1);

use Org\Wplake\Advanced_Views\Bridge\Controllers\Layout\Layout_Controller_Base;

return new class extends Layout_Controller_Base {
    /**
     * @return array<string,mixed>
     */
    public function get_variables(): array
    {
        return [
            // "custom_variable" => get_post_meta($this->get_object_id(), "your_field", true),
            // "another_var" => $this->get_custom_arguments()["another"] ?? "",
        ];
    }
    /**
     * @return array<string,mixed>
     */
    public function get_variables_for_validation(): array
    {
        // it's better to return dummy data here [ "custom_variable" => "dummy string", ]
        return $this->get_variables();
    }
    /**
     * @return array<string,mixed>
     */
    public function get_ajax_response(): array
	{
	    // $message = $this->get_container()->get(MyClass::class)->myMethod();
		return [
			// "message" => $message,
		];
	}
	/**
     * @return array<string,mixed>
     */
    public function get_rest_api_response(WP_REST_Request $request): array
	{
	    // $input = $request->get_json_params();
	    // $message = $this->get_container()->get(MyClass::class)->myMethod();
		return [
			// "message" => $message,
		];
	}
};

```

{% endcode %}

{% hint style="info" %}
Tip: if you pass custom variables using the `get_variables()` method, we recommend to change the `get_variables_for_validation()` method and return dummy data there.

Advanced Views has the built-in automatic template validation, which is called on the Publish or Update action. There is no sense to return real data in this case, and it's better to return dummy data, to avoid potential issues with missing functions.

For example, if you use WP functions inside, they may be front-end only, and aren't available in the wp-admin area, which will lead to the failed validation.&#x20;
{% endhint %}

## PHP-DI support

[PHP-DI](https://php-di.org/) is a well-known dependency injection container. If you haven't used it, we recommend checking it out and harnessing its capabilities.

Advanced Views supports PHP-DI out-of-the-box. To simplify access to your theme's PHP class instances inside the Custom\_Data instances, you can employ the PHP-DI container. To do this, you need to define the container in your theme using the [`advanced_views/container`](/advanced-views/customization/filters-and-hooks.md#container-pro) hook. Then, you can access it using the `get_container()` method in any method of the Custom\_Data class.

### Example

A simple example is below:

#### 1. Define a container in your theme:&#x20;

```php
<?php

use DI\Container;

$container = new Container();

add_filter( 'acf_views/container', function () use ( $container ) {
	return $container;
} );
```

#### 3. Request Container inside the Custom\_Data:

```php
<?php

declare(strict_types=1);

use Org\Wplake\Advanced_Views\Bridge\Controllers\Layout\Layout_Controller_Base;
use MyTheme\MyClass;

return new class() extends Layout_Controller_Base {
    /**
     * @return array<string,mixed>
     */
    public function get_variables(): array {
       $container = $this->get_container();

       if ( null === $container ) {
          return array();
       }

       $my_class = $container->get( MyClass::class );

       return array(
          'my_var_with_complex_calculation' => $my_class->get_var(),
       );
    }
};
```

If you're unfamiliar with [PHP-DI concepts](https://php-di.org/doc/understanding-di.html), the benefits of the code above may be unclear to you. We could replace `$container->get` with `new MyClass()` and it would work perfectly. However, the container is a powerful tool, especially for more complex cases.&#x20;

You won't see a significant benefit if your `MyClass` has no dependencies. But let's say the class has 2-3 constructor arguments (e.g., a logger and a theme object). To get the `MyClass` instance, you would need to create those instances initially. Furthermore, one of those arguments may have its own arguments, and your creation code will turn into a multi-line creation.

{% hint style="info" %}
With PHP-DI, you don't need to worry about the constructor, as PHP-DI will use [PHP's reflection feature](https://www.php.net/manual/en/intro.reflection.php) to get the necessary instances and pass them to the constructor on the fly.
{% endhint %}

An additional benefit is that the `->get` method, [unlike](https://php-di.org/doc/container.html) `->make`, creates the instance only once, reusing it for other calls. This way, you get a smart 'global' variables pool, allowing you to handle dependencies easily and efficiently.&#x20;

{% hint style="info" %}
Unlike the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern), which is [considered an anti-pattern](https://medium.com/@razu.dev/singleton-the-anti-pattern-18fb2bd102c2), it doesn't turn your code into single-instance classes. You still define constructors, clearly specifying class dependencies, while avoiding the hassle of manual creation.
{% endhint %}

Additionally, PHP-DI supports and encourages the use of interfaces, so you can call&#x20;

`->get(MapInterface::class)->calculate()` in your code, while defining which exact class should be used for each interface in the container configuration.

## How to use it

Go to **Edit** your *Layout*.

Switch to the *Template* tab.

Scroll down until you see the *PHP Controller* field.

Add your PHP code.

Click on the **Update** button to save your *Layout*.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wplake.gitbook.io/advanced-views/display-content/php-controller.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
