PHPackages                             corneltek/actionkit - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. corneltek/actionkit

ActiveLibrary

corneltek/actionkit
===================

3.1.1(9y ago)181.5k2[30 issues](https://github.com/corneltek/ActionKit/issues)MITPHP

Since Mar 24Pushed 8y ago3 watchersCompare

[ Source](https://github.com/corneltek/ActionKit)[ Packagist](https://packagist.org/packages/corneltek/actionkit)[ RSS](/packages/corneltek-actionkit/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (13)Versions (57)Used By (0)

ActionKit
=========

[](#actionkit)

[![Coverage Status](https://camo.githubusercontent.com/285410af7adf76d5195426ea3f3c9b86882b90ec4d03e553bab16bdbc2f6f343/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f636f726e656c74656b2f416374696f6e4b69742f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/r/corneltek/ActionKit?branch=master)[![Build Status](https://camo.githubusercontent.com/ad8a6f5bcf78c0389d76130f2402b65ef5da9f3ec2561168aa6a38889f586e5d/68747470733a2f2f7472617669732d63692e6f72672f636f726e656c74656b2f416374696f6e4b69742e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/corneltek/ActionKit)[![Latest Stable Version](https://camo.githubusercontent.com/e14e35e8e2f24243876b82817d516c47a23c04eed13529f29f5d675090ab06bb/68747470733a2f2f706f7365722e707567782e6f72672f636f726e656c74656b2f616374696f6e6b69742f762f737461626c65)](https://packagist.org/packages/corneltek/actionkit) [![Total Downloads](https://camo.githubusercontent.com/6bf0b282a4e8ebb301e31fab3663d92a8473d39fb4b18a92290c49cc4d44c5cf/68747470733a2f2f706f7365722e707567782e6f72672f636f726e656c74656b2f616374696f6e6b69742f646f776e6c6f616473)](https://packagist.org/packages/corneltek/actionkit) [![Latest Unstable Version](https://camo.githubusercontent.com/5b08da5d2bb889146a26f9be0ab1f5bc4fd0f28f008c5ffba02b6cb4d51e1617/68747470733a2f2f706f7365722e707567782e6f72672f636f726e656c74656b2f616374696f6e6b69742f762f756e737461626c65)](https://packagist.org/packages/corneltek/actionkit) [![License](https://camo.githubusercontent.com/4528040a8aa712d309e314f9d7e182ed363ac336868879dc992feb5631e8b23d/68747470733a2f2f706f7365722e707567782e6f72672f636f726e656c74656b2f616374696f6e6b69742f6c6963656e7365)](https://packagist.org/packages/corneltek/actionkit)

ActionKit is a library that let you share the business logics across controllers, pages, ajax requests.

Sometimes, you need to reuse code across your controllers, pages, ajax requests, you might sit down and write a shared controller class to share the common code for reuse. This approach might work well for small applications, , however, when your application is getting bigger and bigger, it will be very complex to share the common code, and hard to maintain.

ActionKit provides a way to wrap your common code up, and make these common code reuseable in everywhere in the application.

Besides of sharing the logics across your controllers, you may also define the parameters with types, validators, form widget type and a lot of parameter options, and render your Action as a web form.

```
[Web Form] => [Input: paramters] => [ Parameter Validation ]
        => [Execute the logic in Action]
            => [Return result: Success or Failure, Data: processed data]
                => [Render result on the web page]

```

Hence, you don't need to handle the ajax mechanisums, controller handlers, parameter validations, ActionKit\\Action does all the jobs for you automatically, so you can focus on the core logics that you only need to handle.

Action is just like API (application programming interface), which can be triggered from HTTP requests, Ajax requests, or from backend, here is the work flow:

[![ActionKit - PHP](https://camo.githubusercontent.com/577ae9cfdfea04363888b0d7dcd81bea03c2d78de84c0484d1e1dad75006b860/687474703a2f2f692e696d6775722e636f6d2f4774413350727a2e706e67)](https://camo.githubusercontent.com/577ae9cfdfea04363888b0d7dcd81bea03c2d78de84c0484d1e1dad75006b860/687474703a2f2f692e696d6775722e636f6d2f4774413350727a2e706e67)

A Basic Action
--------------

[](#a-basic-action)

A minimal action skeleton:

```
use ActionKit\Action;
class YourAction extends Action
{
    public function run() {
    }
}
```

To use Action, you should define a `run` method at least, in this `run` method, you write your logics, operations, then return the result at the end.

To report success result, you can simple use `success`method:

```
function run() {
    return $this->success('Success!!');
}
```

You can also pass data to the action result, by appending another argument in array:

```
function run() {
    return $this->success('Success', ['user_id' => 1]);
}
```

To report error:

```
function run() {
    return $this->error('Error', ['user_id' => 1]);
}
```

Action Signature
----------------

[](#action-signature)

To trigger an action from front-end, you can define an action signature in your HTML form.

When submitting this form, ActionRunner uses this signature to dispatch your action to the right place.

The convention rule is like below:

- A class with namespace like `App\Action\CreateUser`will be converted to signature `App::Action::CreateUser`.

A Simple Action Skeleton
------------------------

[](#a-simple-action-skeleton)

```
class YourAction extends \ActionKit\Action
{

    function schema() {
        $this->param('id')
            ->renderAs('HiddenInput');

        $this->param('password')
            ->renderAs('PasswordInput');

        $this->filterOut('hack','hack2','role');
    }

    function beforeRun() {
        // do something
    }

    function run()
    {
        return $this->success( 'Success Helper (point to action result object)' );
        return $this->error( 'Error Helper (point to action result object)' );
    }

    function afterRun()
    {
        // do something
    }
}
```

Then the caller:

```
$act = new Action( $_REQUEST );
$act->invoke();
$rs = $a->getResult();
```

To take an action, simply call `invoke` method to trigger the action.

the `invoke` method trigger `runPreinit`, `runInit`, `beforeRun`, `run`, `afterRun` in order.

Action Schema
-------------

[](#action-schema)

### run method

[](#run-method)

#### methods

[](#methods)

methods that you will use in `run`:

- `$this->arg(string $key)`: get argument from action by key.
- `$this->setArgs(array $arguments)`set action arguments.
- `$this->success(string $message, $data = array())`

    Report success message.

    You can also pass data to the action result object.

    By using this method, action object creates an action result object, and register the result object into the Action Result Pool by using the action signature as a key.

    @see ActionKit\\Runner

    - In Ajax mode, the action result will be converted into JSON format, and the front-end `Action.js` will get the action result data, then display the result message (or dispatch to jGrowl plugin)
    - In HTTP POST/GET mode, the action result is also saved in the Action Result Pool, and by calling a simple twig macro, you can render these action result objects into HTML format string.

        @see bundles/CoreBundle/Templates/phifty/action\_result.html
- `$this->error(string $message)`

    Report error message.

#### properties

[](#properties)

properties that you will need in Action `run` method:

- request: HttpRequest object, you can retrieve POST, GET, SESSION, SERVER through a simple API.

    ```
      $this->request->param('user')
      // is equal to isset($_REQUEST['user']) ? $_REQUEST['user'] : null

      $this->request->server->HTTP_HOST
      // is equal to isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null

    ```

### Action param methods

[](#action-param-methods)

Action Result
-------------

[](#action-result)

After executing an action, the action creates an action result object inside itself, you can retrieve the action result object through the `getResult()` method of action object to see if it's successfully executed or encountered an error.

Every action result object is saved in the ActionRunner instance. (the action result pool, which is a singleton object)

You can also fetch action result objects from ActionRunner.

An `ActionResult` object contains a flag (success or error), a message string, a data stash.

Here is a simple example to check the result error:

```
if( $result->success ) {

} else {
    // error here

}
```

To get an action result from an action object.

```
$rs = $action->getResult();
if( $rs->success ) {
    $msg = $rs->getMessage();
    $data = $rs->getData();
}
```

To get an action result from ActionRunner:

```
$runner = ActionKit\Runner::getInstance();
if( $result = $runner->getResult( 'Login::...' ) ) {
    // check the action result

}
```

RecordAction
------------

[](#recordaction)

Record Action is very useful for connecting ORM with front-end form, Record Action passes arguments to model object and validates the arguments from HTTP request.

If all validation passed, and no PDOExcetion was catched, the action result will be generated and ready to send back to front-end.

There are 3 type record actions, which is mapped to CRUD operations:

1. Create
2. Update
3. Delete

The mapped action classes are:

1. CreateRecordAction
2. UpdateRecordAction
3. DeleteRecordAction

Those 3 record action classes inherits BaseRecordAction class.

BaseRecordAction class provides most methods for glueing ORM interface methods and the result data conversion.

RecordAction Synopsis
---------------------

[](#recordaction-synopsis)

```
namespace User\Action\UpdateAction;
use ActionKit\RecordAction\UpdateRecordAction;

class UpdateAction extends UpdateRecordAction {

    function schema()
    {
        // For record actions, we can convert the record columns
        $this->useRecordSchema();

        $this->param( 'username' )
            ->label( _('Username') )
            ->useSuggestion();

        $this->param( 'password' )
            ->validator(function($value) {
                if ($value) {
                    return [false, "reason"];
                }
                return [true, "success!!"];
            });

        $this->filterOut(array('auth_token'));
    }

    function validatePassword( $value , $args )
    {
        return $this->valid( $message );

        # or
        return $this->invalid( $message );
    }

    function suggestUsername( $value , $args ) {
        return;  # not to suggest
        return $this->suggest( "$value is used. use: " , array( ... ) );
    }

    function completeCountry( $value , $args ) {

        ...
    }
}
```

### Messages

[](#messages)

The `BaseRecordAction` provides the default message interface, to override these messages (for both success and error message) you can simply override the methods:

```
function successMessage(OperationResult $ret) {
    return _('Your Success Message');
}

function errorMessage(OperationResult $ret) {
    return _('Your Error Message');
}
```

### RecordAction Examples

[](#recordaction-examples)

CreateNews

```
namespace News\Action;
use ActionKit\RecordAction\CreateRecordAction;

class CreateNews extends CreateRecordAction
{
    public $recordClass = 'News\Model\News';
}
```

UpdateNews

```
namespace News\Action;
use ActionKit\RecordAction\UpdateRecordAction;

class UpdateNews extends UpdateRecordAction
{
    public $recordClass = 'News\Model\News';
}
```

### Record Action API

[](#record-action-api)

```
$record = new User\Model\User( 3 ); // primary key = 3
$a = new User\Action\UpdateUser(array( 'nickname' => 'New Name' ) , $record );
$a->invoke();   // which calls $record->update(array( 'nickname' => 'New Name' ) );
```

### RecordAction schema methods

[](#recordaction-schema-methods)

- useRecordSchema

### Record Action Generator

[](#record-action-generator)

CRUD Actions could be automatically generated, or be manully created by hands.

To generate CreateRecordAction from a model class name

```
$g = new ActionKit\ActionGenerator;
$code = $g->generateClassCode( 'App\Model\User' , 'Create' )->code;
```

To generate UpdateRecordAction from a model class name

```
$g = new ActionKit\ActionGenerator;
$code = $g->generateClassCode( 'App\Model\User' , 'Update' )->code;
```

To generate custom action:

```
$g = new ActionKit\ActionGenerator;

$g->register('template name','...template path...');

$g->generate('SortImage', 'template name', array(
    "base_class" => "SortRecordAction",
    "record_class" => "ProductBundle\\Model\\ProductImage",
    ... template variable...
));
```

Or even shorter (???):

```
use ActionKit\RecordAction\BaseRecordAction;
$class = BaseRecordAction::createCRUDClass( 'App\Model\Post' , 'Create' );
```

Or create record actions from record object:

```
$post = new Post;
$update = $post->asUpdateAction();
$create = $post->asCreateAction();
$delete = $post->asDeleteAction();
```

Action Widget
-------------

[](#action-widget)

Action widgets depends on the parameter definition, the default widget type is TextInput.

```
$post = new Post;
$update = $post->asUpdateAction();
$html = $update->widget('title')->render();
$html = $update->widget('title')->render( array( 'class' => '....' ));

$html = $update->render('title',array( /* attributes.... */ ));
$html = $update->render( null, array( /* attributes */ )  );
```

In action schema, the parameters you defined can generate form widgets (with FormKit) automatically.

What you only to do is to define a `renderAs` attribute for your parameters in your action schema.

For example:

```
class YourAction extends Action {
    function schema() {
        $this->param('name')
            ->renderAs('TextInput');
    }
}
```

And then, to get the form widget through Action object, you can do:

```
$action = new YourAction;
$widget = $a->widget('name');
```

And to render it:

```
$html = $widget->render(array(
    'class' => 'extra-class'
    'id' => 'field-id'
));
```

For other type widgets, like SelectInput you can specify `options`:

```
$a->widget('user_type')->render(array(
    'options' => array(
        'Option 1' => '1'
        'Option 2' => '2'
        'Group Option' => array(
            'Suboption 1' => '2.1'
            'Suboption 2' => '2.2'
        )
    )
));
```

You can also force a form widget type for widget method, which will override the widget type that you defined previously:

```
$a->widget('confirmed','RadioInput')->render(array(
    'false', 'true'
));
```

Action View
-----------

[](#action-view)

An action view may contains a formkit layout builder, but an action view build everything for you.

to create an action view, you can simple calls the `createView` method

```
$view = $action->createView('+AdminUI\Action\StackView');
$view->render(array( ... render options ... ));
```

### Action rendering throught built-in StackView

[](#action-rendering-throught-built-in-stackview)

By using ActionKit StackView, you don't need to write HTML, the form elements are automatically generated.

Here is a StackView synopsis:

```
$action = new SomeWhatAction;
$view = new ActionKit\View\StackView($action, array( ... options ... ));
$view->render();
```

Use case:

```
$action = new User\Action\ChangePassword;
$view = new ActionKit\View\StackView( $action );
echo $view->render();
```

And you can render action view via Action's `asView` method:

```
    echo $action->asView('ActionKit\View\StackView')->render();
    echo $action->asView()->render();  // implies view class ActionKit\View\StackView
```

So that if you're in Twig template, you can do:

```
{{ action.asView('ActionKit\\View\\StackView').render()|raw}}
```

You can also pass extra options to View class:

```
echo $action->asView('ActionKit\View\StackView', array( ... view options ... ))->render();
```

Action Rendering (render by pure HTML elements)
-----------------------------------------------

[](#action-rendering-render-by-pure-html-elements)

You can simply render a HTML form to trigger corresponding action class, in this example we trigger the `User\Action\UpdateUser` action, which is generated automatically through the Dynamic Action Generator.

```

```

Action Rendering and Action.js integration
------------------------------------------

[](#action-rendering-and-actionjs-integration)

```

    $(function() {
        Action.form( $('#profile')).setup({
            validation: "msgbox",
            status: true
        });
    });

{{ Web.render_result( update.signature ) |raw}}

{{ update.asView('ActionKit\\View\\StackView',{
        'form_id': 'profile'
    }).render() |raw }}

```

Action Rendering (render field by field)
----------------------------------------

[](#action-rendering-render-field-by-field)

In controller, you can initialize a action object:

```
function updateAction() {
    $changePasswordAction = new User\Action\ChangePassword( array(
        ... values to override field values ... ) , $record );

    return $this->render('some_path.html',array(
        'changePasswordAction' => $changePasswordAction
    ));
}
```

Then in template, you can call action API to render these fields by these methods, eg `renderSignatureWidget` , `renderWidget` , `renderLabel` , `renderSubmitWidget`..etc:

```

    # This renders a field named "action" with action signature "User::Action::ChangePassword"
    {{ changePasswordAction.renderSignatureWidget |raw}}

    {% if CRUD.Record.id %}
        {{ forms.hidden('id', CRUD.Record.id) }}
    {% endif %}

    Change/Setup password

        {% trans 'Password' %}

            {{ changePasswordAction.widget('password1').render() |raw }}

        {% trans 'Password' %}

            {{ changePasswordAction.widget('password1').render() |raw }}

        {% trans 'Password Confirm' %}

            {{ changePasswordAction.widget('password2').render() |raw }}

        {% if CRUD.Record.id %}
            {{ changePasswordAction.renderSubmitWidget({ class: 'create button', value: _('Save') }) |raw }}
        {% else %}
            {{ changePasswordAction.renderSubmitWidget({ class: 'create button', value: _('Create') }) |raw }}
        {% endif %}
        {{ changePasswordAction.renderButtonWidget({ class: 'button', value: _('Close'), onclick: 'Region.of(this).fadeRemove();' }) |raw}}

```

Front-end Action API
--------------------

[](#front-end-action-api)

You can execute Actions from front-end, it's more like an API. to send action to execute, you need to include action.js from action assets.

action.js provides a short helper named `runAction` that helps you to execute Action, you can call runAction function in following forms:

```
runAction( {Action Signature}, {Arguments});
runAction( {Action Signature}, {Arguments} , {Options});
runAction( {Action Signature}, {Arguments} , {Options}, {Callback} );
runAction( {Action Signature}, {Arguments} , {Callback} );
runAction( {Action Signature}, {Callback} );
runAction( {Action Signature} );

```

And in the below example, we send `Stock::Action::DeleteTransaction` to backend with a record id to delete a transaction record, if it's successful, then fade remove the elements from HTML.

```

    {{ txn.display('status') }}

```

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 95.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~6 days

Total

53

Last Release

3594d ago

Major Versions

0.0.1 → 1.0.02013-03-24

1.5.2 → 2.0.x-dev2015-07-08

2.1.0 → 3.0.12016-06-10

### Community

Maintainers

![](https://www.gravatar.com/avatar/3cc34cde233b660869ff329ed8e20df611f75dfb61aab3e30889ac153d3e5e61?d=identicon)[c9s](/maintainers/c9s)

---

Top Contributors

[![c9s](https://avatars.githubusercontent.com/u/50894?v=4)](https://github.com/c9s "c9s (2193 commits)")[![azole](https://avatars.githubusercontent.com/u/2560515?v=4)](https://github.com/azole "azole (82 commits)")[![EragonJ](https://avatars.githubusercontent.com/u/68322?v=4)](https://github.com/EragonJ "EragonJ (20 commits)")[![CindyLinz](https://avatars.githubusercontent.com/u/285660?v=4)](https://github.com/CindyLinz "CindyLinz (5 commits)")

### Embed Badge

![Health badge](/badges/corneltek-actionkit/health.svg)

```
[![Health](https://phpackages.com/badges/corneltek-actionkit/health.svg)](https://phpackages.com/packages/corneltek-actionkit)
```

###  Alternatives

[abydahana/aksara

Aksara is a CodeIgniter based CRUD Toolkit you can use to build complex applications become shorter, secure and more reliable just in a few lines of code. Serving both CMS or Framework, produce both HEADLESS (RESTful API) or TRADITIONAL (Browser Based), just by writing single controller. Yet it's reusable, scalable and ready to use!

1101.2k](/packages/abydahana-aksara)[corneltek/lazyrecord

The Fast PHP ORM

103.6k2](/packages/corneltek-lazyrecord)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
