# Local action traits

There are a few traits offered for your convenience. Every single action interface comes with a basic trait that provides the following implementation:

* Stores the action result as a nullable exception property.
* Stores the action state as a nullable boolean property with the following interpretation:
  * `null` means that the action has not been attempted yet and accessing the action result will throw a PHP runtime error.
  * `true` means that the action was performed successfully and accessing the action result will return `null`.
  * `false` means that the action failed and accessing the action result will return the `Exception` which caused the failure.
* Provides getters for both the action result and state.
* Implements the respective action method. The action method set the action state and result, and will return an exception is called more than once (but will maintain the original state and result).

The most confusing part must be the last point. If the action method is already implemented, then where do you put your class' action logic? Short answer: in a protected action method that ends with `_local`. Long answer: either there, or in a protected method defined by an [action extension trait](/foundations-module/actions/extension-action-traits.md). But we'll look into that on the next page.

It might be best to look at an example. Open the default trait for the `OutputtableInterface` by clicking [here](https://github.com/deep-web-solutions/wordpress-framework-foundations/blob/master/src/includes/Actions/Outputtable/OutputtableTrait.php) and then look at the method `output`. The first `if` statement basically checks for the existence of the trait `OutputLocalTrait` (see [here](https://github.com/deep-web-solutions/wordpress-framework-foundations/blob/master/src/includes/Actions/Outputtable/OutputLocalTrait.php)) on the current object and, if present, calls the method `output_local` which has the same return type as the original `output` method.

Ignoring the second `elseif` statement for now, if `output_local` returns `null`, the output action is considered successful. Otherwise it fails with the result of the local output action.

In practice you wouldn't use the `OutputtableTrait` directly, but you'd use the `OutputLocalTrait` only since it already "imports" the `OutputtableTrait`:

```php
<?php

namespace DeepWebSolutions\Plugins\MyTestPlugin\Actions;

use DeepWebSolutions\Framework\Foundations\Actions\OutputtableInterface;
use DeepWebSolutions\Framework\Foundations\Actions\Outputtable\OutputFailureException;
use DeepWebSolutions\Framework\Foundations\Actions\Outputtable\OutputLocalTrait;

class MyOutput implements OutputtableInterface {
    use OutputLocalTrait; // USE THIS
    
    protected bool $success;
    
    public function __construct( bool $success ) {
        $this->success = $success;
    }
    
    protected function output_local(): ?OutputFailureException {
        if ( true === $this->success ) {
            return null;
        } else {
            return new OutputFailureException( 'Local output failed for some reason' ); 
        }
    }
}

$my_output = new MyOutput( true );
$my_output->output(); // equals null

$my_output = new MyOutput( false );
$my_output->output()->getMessage(); // equals 'Local output failed for some reason'

```

{% hint style="info" %}
The page uses the output action as an example but all the concepts carry over to all the other actions as well.
{% endhint %}

{% hint style="warning" %}
The article mentions that the traits will return an error if the action method is called twice. That is true, but there exists **one exception**: if an object is both runnable and resettable and uses both default traits, then it is possible to call the `run` method again after calling the `reset` method and the `reset` method again after calling the `run` method indefinitely.
{% endhint %}


---

# Agent Instructions: 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:

```
GET https://framework.deep-web-solutions.com/foundations-module/actions/local-action-traits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
