t3/extbase-session-entities

Extends TYPO3's Extbase framework by possibility to work with session entities over several actions without persisting, including partial model validation.

Installs: 989

Dependents: 0

Suggesters: 0

Security: 0

Type:typo3-cms-extension

1.0.0 2018-04-01 15:50 UTC

This package is auto-updated.

Last update: 2024-10-20 22:55:57 UTC


README

This extension extends TYPO3's Extbase framework by possibility

  • to work with session entities
  • over several actions without persisting
  • including partial model validation.

Installation

Just download the extension using TER or require it using composer:

$ composer require t3/extbase-session-entities

Check in Extension Manager of TYPO3 if the extension is installed.

Example & Dev Package

There is a parent git repository existing, which includes this one using git submodule. It provides a full dev environment, ready to work/test/play and it's super easy to install.

Also it contains an example extension which implements and demonstrates the features of this extension.

Checkout: https://bitbucket.org/t--3/extbase_session_entities-dev

Usage

The ability to work with session entities comes in three parts:

  1. Your models need to extend from \T3\ExtbaseSessionEntities\Mvc\AbstractSessionEntity

  2. Your controller must extend from \T3\ExtbaseSessionEntities\Mvc\AbstractSessionEntityController

  3. The fluid templates containing the <f:form> view helper must use the shipped form view helper:

     {namespace e=T3\ExtbaseSessionEntities\ViewHelpers}
     <e:form name="order" action="step2" object="{order}"> ... </e:form>
    

Now you can pass entities over actions without loosing their data (stored in fe_user session).

Create session entities

In the first action of your process, you need to create a new instance of your model.

Also you need to call the prepare() method before passing the object to the form view helper! Otherwise the session entity will not get properly passed to next action. Example:

/**
 * @param \T3\Example\Domain\Model\Order $order
 * @return void
 *
 * @ignorevalidation $order
 */
public function step1Action(\T3\Example\Domain\Model\Order $order = null)
{
    if (null === $order) {
        /** @var \T3\Example\Domain\Model\Order $order */
        $order = $this->objectManager->get(\T3\Example\Domain\Model\Order::class);
        $order->prepare();
    }
    $this->view->assign('order', $order);
}

Notice: You don't need to use the objectManager here. A new \T3\Example\Domain\Model\Order() would also work.

Save session entities

Like working with regular models in Extbase, you need to tell when to persist, by adding the entity to the persistence manager (e.g. $this->orderRepository->add($order);).

For session entities you need to do the same, but with a sessionRepository which is provided by AbstractSessionController. Example:

/**
 * @param \T3\Example\Domain\Model\Order $order
 * @validate $order \T3\ExtbaseSessionEntities\Mvc\PartialObjectValidator(validate="firstName,name")
 */
public function step2Action(\T3\Example\Domain\Model\Order $order)
{
    $this->sessionRepository->set($order);
    // $this->updateSessionEntity($order, $this->orderRepository); // see next chapter
    $this->view->assign('order', $order);
}

"Update session entity" helper function

The controller also provides a helper function to update entities in session or in database, depending on their status (has numeric uid). So you can reuse the same actions for both: session or database entities.

Just replace the call of sessionRepository with:

$this->updateSessionEntity($order, $this->orderRepository);

Move entity from session to database

Once you want to persist the session entity to database, you just need to add the entity to your regular extbase repository:

/**
 * @param \T3\Example\Domain\Model\Order $order
 * @validate $order \T3\ExtbaseSessionEntities\Mvc\PartialObjectValidator()
 */
public function saveAction(\T3\Example\Domain\Model\Order $order)
{
    $this->orderRepository->add($order);
    $this->persistAll();
    $this->redirect('thanks', null, null, ['order' => $order]);
}

The persistence manager is x-classed and converts the session entity automatically to a database one.

Notice: You don't need to perform $this->persistAll(); when you don't pass the entity to UriBuilder (like we did, by redirecting).

Session entities explained

When session entities are created and prepare() has been called, they get a new uid which not numeric. This string is the sessionIdentifier which is later used to store the object in user's session.

We fake persisted entities here. Also this extension provides a SessionObjectConverter, which loads entities from session, when mapping next action's arguments.

Session entities also got the method __finalize(). It's public, but the underscore and the @internal annotation implies to not to use it by your self. You don't need, because it is automatically called by a small x-class for the PersistenceManager of extbase.

Each time you add session entity to your repository, it is finalized. This means that the uid is reset to null, so persistence manager handles it as a regular new object.

Partial entity validation

Session entities are not validated by default!

Because Extbase validates always the whole object with all properties. So when you split your properties to several actions, you will always get validation errors for fields you don't want to check at this action.

To validate your models partially (or full) you can use this shipped validator at your action:

/**
 * @param \T3\Example\Domain\Model\Order $order
 * @validate $order \T3\ExtbaseSessionEntities\Mvc\PartialObjectValidator(validate="firstName,name")
 */
public function step2Action(\T3\Example\Domain\Model\Order $order)
{
}

The validate option is optional. When you leave it empty it validates all attributes of given entity.

You can work with sub entities, but you can not validate their attributes partially, yet.

Roadmap / To do

  • Provide ability to bind model instances to fe_user (currently the step1 action will always create a new instance when entity is not passed from previous action)
  • Test it in production