• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CPS-IT / handlebars-forms / 23788866234

31 Mar 2026 08:52AM UTC coverage: 0.659% (-0.06%) from 0.72%
23788866234

push

github

web-flow
Merge pull request #18 from CPS-IT/feature/view-models

0 of 163 new or added lines in 33 files covered. (0.0%)

7 of 1062 relevant lines covered (0.66%)

0.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/Classes/ContentObject/NavigationContentObject.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "handlebars_forms".
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17

18
namespace CPSIT\Typo3HandlebarsForms\ContentObject;
19

20
use CPSIT\Typo3HandlebarsForms\Domain;
21
use CPSIT\Typo3HandlebarsForms\Fluid\ViewHelperInvoker;
22
use Symfony\Component\DependencyInjection;
23
use TYPO3\CMS\Fluid;
24
use TYPO3\CMS\Form;
25

26
/**
27
 * NavigationContentObject
28
 *
29
 * @author Elias Häußler <e.haeussler@familie-redlich.de>
30
 * @license GPL-2.0-or-later
31
 */
32
#[DependencyInjection\Attribute\AutoconfigureTag('frontend.contentobject', ['identifier' => 'HBS_NAVIGATION'])]
33
final class NavigationContentObject extends AbstractHandlebarsFormsContentObject
34
{
35
    private const PREVIOUS_PAGE = 'previousPage';
36
    private const NEXT_PAGE = 'nextPage';
37
    private const SUBMIT = 'submit';
38

39
    public function __construct(
×
40
        private readonly ViewHelperInvoker $viewHelperInvoker,
41
    ) {}
×
42

43
    /**
44
     * @return list<mixed>
45
     */
46
    protected function resolve(array $configuration, Context\ValueResolutionContext $context): array
×
47
    {
48
        $renderable = $context->renderable;
×
49
        $elements = [];
×
50

51
        // We cannot process navigation within a concrete form element
52
        if (!($renderable instanceof Form\Domain\Runtime\FormRuntime)) {
×
53
            return [];
×
54
        }
55

56
        // Add previous page button
57
        if ($renderable->getPreviousEnabledPage() !== null) {
×
58
            $elements[self::PREVIOUS_PAGE] = $renderable->getPreviousEnabledPage();
×
59
        }
60

61
        // Add next page OR submit button
62
        if ($renderable->getNextEnabledPage() !== null) {
×
63
            $elements[self::NEXT_PAGE] = $renderable->getNextEnabledPage();
×
64
        } else {
65
            $elements[self::SUBMIT] = $renderable;
×
66
        }
67

68
        return $this->processElements($elements, $configuration, $context, $renderable);
×
69
    }
70

71
    /**
72
     * @param array<self::*, Form\Domain\Model\FormElements\Page|Form\Domain\Runtime\FormRuntime> $renderables
73
     * @param array<string|int, mixed> $configuration
74
     * @return list<mixed>
75
     */
76
    private function processElements(
×
77
        array $renderables,
78
        array $configuration,
79
        Context\ValueResolutionContext $context,
80
        Form\Domain\Runtime\FormRuntime $formRuntime,
81
    ): array {
NEW
82
        $renderingContext = $context->renderingContext;
×
83
        $processedElements = [];
×
84

85
        foreach ($renderables as $step => $stepRenderable) {
×
86
            $stepConfiguration = $configuration[$step . '.'] ?? null;
×
87

88
            if (is_array($stepConfiguration)) {
×
NEW
89
                $stepViewModel = $this->processButton($renderingContext, $stepRenderable, $formRuntime, $step);
×
90
            } else {
91
                $stepConfiguration = [];
×
NEW
92
                $stepViewModel = new Domain\ViewModel\SimpleViewModel($stepRenderable);
×
93
            }
94

95
            $processedElement = $context->process($stepConfiguration, $stepRenderable, $stepViewModel);
×
96

97
            if ($processedElement !== null) {
×
98
                $processedElements[] = $processedElement;
×
99
            }
100
        }
101

102
        return $processedElements;
×
103
    }
104

105
    /**
106
     * @param self::* $step
107
     */
108
    private function processButton(
×
109
        Fluid\Core\Rendering\RenderingContext $renderingContext,
110
        Form\Domain\Model\FormElements\Page|Form\Domain\Runtime\FormRuntime $pageOrForm,
111
        Form\Domain\Runtime\FormRuntime $formRuntime,
112
        string $step,
113
    ): Domain\ViewModel\ViewModel {
114
        $isPage = $pageOrForm instanceof Form\Domain\Model\FormElements\Page;
×
115
        $labelRenderable = $isPage ? $formRuntime->getCurrentPage() : $formRuntime;
×
116

117
        $buttonResult = $this->viewHelperInvoker->invoke(
×
118
            $renderingContext,
×
119
            Fluid\ViewHelpers\Form\ButtonViewHelper::class,
×
120
            [
×
121
                'property' => '__currentPage',
×
122
                'value' => $isPage ? $pageOrForm->getIndex() : count($pageOrForm->getPages()),
×
123
            ],
×
124
        );
×
NEW
125
        $buttonViewModel = new Domain\ViewModel\ViewHelperContainedViewModel($pageOrForm, $buttonResult);
×
126

NEW
127
        if ($labelRenderable === null) {
×
NEW
128
            return $buttonViewModel;
×
129
        }
130

NEW
131
        $labelResult = $this->viewHelperInvoker->translateElementProperty(
×
NEW
132
            $renderingContext,
×
NEW
133
            $labelRenderable,
×
NEW
134
            match ($step) {
×
NEW
135
                self::PREVIOUS_PAGE => 'previousButtonLabel',
×
NEW
136
                self::NEXT_PAGE => 'nextButtonLabel',
×
NEW
137
                self::SUBMIT => 'submitButtonLabel',
×
NEW
138
            },
×
NEW
139
            'renderingOptionProperty',
×
NEW
140
        );
×
141

NEW
142
        if (!is_string($labelResult)) {
×
NEW
143
            return $buttonViewModel;
×
144
        }
145

NEW
146
        return Domain\ViewModel\FormFieldViewModel::forLabelAndElement($labelResult, $buttonViewModel);
×
147
    }
148
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc