# ivyforms/0.8/backend/src/Services/Template/TemplateService.php

The Innovative Form Builder – IvyForms, version 0.8. 141 lines.

- Page: https://pluginprobe.com/plugins/ivyforms/0.8/code/backend/src/Services/Template/TemplateService.php
- Raw: https://pluginprobe.com/plugins/ivyforms/0.8/raw/backend/src/Services/Template/TemplateService.php
- Modified: 2026-01-13T11:11:38+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/ivyforms/0.8/code/backend/src/Services/Template/TemplateService.php#L10-L20`.

```php
<?php

/**
 * @copyright © Melograno Venture Studio. All rights reserved.
 * @licence   See COPYING.md for license details.
 */

namespace IvyForms\Services\Template;

// phpcs:disable PSR1.Files.SideEffects
if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

use IvyForms\Common\Exceptions\InvalidArgumentException;
use IvyForms\Services\Translations\BackendStrings;

/**
 * Class TemplateService
 *
 * @package IvyForms\Services\Template
 */
class TemplateService
{
    /**
     * Get all predefined form templates
     *
     * @return array<string, array<string, mixed>>
     */
    public function getAllTemplates(): array
    {
        return TemplateMapper::getAllTemplates();
    }

    /**
     * Get predefined form template by ID
     *
     * @param string $templateId
     * @return array<string, mixed>|null
     */
    public function getTemplateById(string $templateId): ?array
    {
        return TemplateMapper::getTemplate($templateId);
    }

    /**
     * Get form data from template by ID
     *
     * @param string $templateId
     * @return array<string, mixed>
     * @throws InvalidArgumentException
     */
    public function getFormDataFromTemplate(string $templateId): array
    {
        $template = $this->getTemplateById($templateId);

        if (!$template) {
            throw new InvalidArgumentException(
                BackendStrings::getTemplateStrings()['template_not_found']
            );
        }

        $formData = $template['form_data'];

        // Assign sequential rowIndex to each field ONLY if not already specified
        // This ensures templates without layout get single-column, but templates with
        // custom multi-column layouts are preserved
        if (isset($formData['fields']) && is_array($formData['fields'])) {
            $formData['fields'] = $this->assignFieldLayout($formData['fields']);
        }

        return $formData;
    }

    /**
     * Assign layout properties to fields
     *
     * @param array<int, array<string, mixed>> $fields
     * @return array<int, array<string, mixed>>
     */
    private function assignFieldLayout(array $fields): array
    {
        $rowCounter = 0;
        foreach ($fields as &$field) {
            if ($this->shouldAssignLayout($field)) {
                $field['rowIndex'] = $rowCounter;
                $field['columnIndex'] = 0;
                $field['width'] = 100;
                $rowCounter++;
                continue;
            }

            if ($this->hasCustomLayout($field)) {
                $rowCounter = max($rowCounter, $field['rowIndex'] + 1);
            }
        }
        unset($field);
        return $fields;
    }

    /**
     * Check if field should get default layout
     *
     * @param array<string, mixed> $field
     * @return bool
     */
    private function shouldAssignLayout(array $field): bool
    {
        return !isset($field['parentId'])
            && !isset($field['rowIndex'])
            && !isset($field['columnIndex'])
            && !isset($field['width']);
    }

    /**
     * Check if field has custom layout
     *
     * @param array<string, mixed> $field
     * @return bool
     */
    private function hasCustomLayout(array $field): bool
    {
        return !isset($field['parentId']) && isset($field['rowIndex']);
    }

    /**
     * Get template categories
     *
     * @return array<string, array<string, string>>
     */
    public function getTemplateCategories(): array
    {
        return [
//            'basic' => [
//                'name' => '',
//                'description' => ''
//            ]
        ];
    }
}

```
