{"id":18637970,"url":"https://github.com/imponeer/smarty-db-resource","last_synced_at":"2026-01-04T07:14:57.366Z","repository":{"id":38012056,"uuid":"336754051","full_name":"imponeer/smarty-db-resource","owner":"imponeer","description":"Smarty plugin that adds DB resource type","archived":false,"fork":false,"pushed_at":"2024-07-08T20:13:06.000Z","size":68,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-09T13:43:35.519Z","etag":null,"topics":["hacktoberfest","resource","smarty","smarty-plugins"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/imponeer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-07T09:59:03.000Z","updated_at":"2024-07-08T20:13:08.000Z","dependencies_parsed_at":"2024-05-21T22:31:58.700Z","dependency_job_id":"98207312-b5a0-473c-bb75-1eea16483514","html_url":"https://github.com/imponeer/smarty-db-resource","commit_stats":{"total_commits":31,"total_committers":4,"mean_commits":7.75,"dds":0.3870967741935484,"last_synced_commit":"b2e24571a4b9b3a967dc5ad0997567331abc7989"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imponeer%2Fsmarty-db-resource","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imponeer%2Fsmarty-db-resource/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imponeer%2Fsmarty-db-resource/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/imponeer%2Fsmarty-db-resource/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/imponeer","download_url":"https://codeload.github.com/imponeer/smarty-db-resource/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223466133,"owners_count":17149768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","resource","smarty","smarty-plugins"],"created_at":"2024-11-07T05:38:30.469Z","updated_at":"2026-01-04T07:14:57.360Z","avatar_url":"https://github.com/imponeer.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/github/license/imponeer/smarty-db-resource.svg)](LICENSE) [![GitHub release](https://img.shields.io/github/release/imponeer/smarty-db-resource.svg)](https://github.com/imponeer/smarty-db-resource/releases) [![PHP](https://img.shields.io/packagist/php-v/imponeer/smarty-db-resource.svg)](http://php.net) [![Packagist](https://img.shields.io/packagist/dm/imponeer/smarty-db-resource.svg)](https://packagist.org/packages/imponeer/smarty-db-resource) [![Smarty version requirement](https://img.shields.io/packagist/dependency-v/imponeer/smarty-db-resource/smarty%2Fsmarty)](https://smarty-php.github.io)\n\n# Smarty DB Resource\n\n\u003e Database-driven template resource for Smarty\n\n[Smarty](https://smarty.net) resource plugin that enables reading templates directly from a database. This powerful extension allows you to store and manage your Smarty templates in a database instead of the filesystem, providing dynamic template management capabilities.\n\nThis plugin is inspired by and similar to [Xoops](https://xoops.org) - [resource.db](https://github.com/XOOPS/XoopsCore25/blob/v2.5.8/htdocs/class/smarty/xoops_plugins/resource.db.php).\n\n## Installation\n\nTo install and use this package, we recommend to use [Composer](https://getcomposer.org):\n\n```bash\ncomposer require imponeer/smarty-db-resource\n```\n\nOtherwise, you need to include manually files from `src/` directory.\n\n\n\n## Database Structure\n\nThis plugin requires a specific database table structure to store template information. The table should contain the following columns:\n\n### Required Columns\n\n| Column Name | Type | Description |\n|-------------|------|-------------|\n| Template ID | `MEDIUMINT UNSIGNED AUTO_INCREMENT` | Primary key for the template record |\n| Template Set | `VARCHAR(50)` | Template set identifier (e.g., 'default', 'theme1') |\n| Template File | `VARCHAR(50)` | Template filename (e.g., 'header.tpl', 'footer.tpl') |\n| Template Source | `TEXT` | The actual template source code (optional if using file-based templates) |\n| Last Modified | `INT UNSIGNED` | Unix timestamp of last modification |\n| Template Description | `VARCHAR(255)` | Human-readable description of the template |\n| Last Imported | `INT UNSIGNED` | Unix timestamp of last import |\n| Template Type | `VARCHAR(20)` | Template type identifier |\n\n### Example Table Schema\n\n```sql\nCREATE TABLE `tplfile` (\n    `tpl_id` MEDIUMINT UNSIGNED AUTO_INCREMENT,\n    `tpl_refid` SMALLINT UNSIGNED NOT NULL DEFAULT '0',\n    `tpl_tplset` VARCHAR(50) NOT NULL DEFAULT 'default',\n    `tpl_file` VARCHAR(50) NOT NULL DEFAULT '',\n    `tpl_desc` VARCHAR(255) NOT NULL DEFAULT '',\n    `tpl_lastmodified` INT UNSIGNED NOT NULL DEFAULT '0',\n    `tpl_lastimported` INT UNSIGNED NOT NULL DEFAULT '0',\n    `tpl_type` VARCHAR(20) NOT NULL DEFAULT '',\n    `tpl_source` TEXT,\n    PRIMARY KEY (`tpl_id`),\n    KEY `tpl_tplset_file` (`tpl_tplset`, `tpl_file`)\n);\n```\n\n**Note:** Column names are configurable when initializing the plugin, so you can adapt the plugin to your existing database schema.\n\n## PDO Driver Support\n\nThis plugin supports multiple database systems through PDO drivers. The plugin automatically selects the appropriate driver based on your PDO connection:\n\n- **SQLite**: Uses optimized SQLite-specific queries\n- **All others**: Uses MySQL-compatible queries (works with most SQL databases)\n\n## Setup\n\nTo register the database resource with Smarty, use the [`registerResource` function](https://www.smarty.net/docs/en/api.register.resource.tpl):\n\n```php\nuse Imponeer\\Smarty\\Extensions\\DatabaseResource\\DatabaseResource;\n\n// Create a Smarty instance\n$smarty = new \\Smarty\\Smarty();\n\n// Create PDO connection\n$pdo = new PDO('mysql:host=localhost;dbname=your_database', $username, $password);\n\n// Create and register the database resource\n$plugin = new DatabaseResource(\n    pdo: $pdo,                                    // PDO database connection\n    tplSetName: 'default',                        // Current template set name\n    templatesTableName: 'tplfile',                // Table name containing templates\n    templateSourceColumnName: 'tpl_source',      // Column containing template source\n    templateModificationColumnName: 'tpl_lastmodified', // Column with modification timestamp\n    tplSetColumnName: 'tpl_tplset',              // Column identifying template set\n    templateNameColumnName: 'tpl_file',          // Column containing template filename\n    templatePathGetter: function (array $row): ?string { // Function to get file path from DB row\n        return __DIR__ . '/templates/' . $row['tpl_file'];\n    },\n    defaultTplSetName: 'default'                  // Default template set fallback\n);\n\n$smarty-\u003eregisterResource('db', $plugin);\n```\n\n### Custom Database Schema\n\nYou can adapt the plugin to your existing database schema by configuring the column names:\n\n```php\n$plugin = new DatabaseResource(\n    pdo: $pdo,\n    tplSetName: 'my_theme',\n    templatesTableName: 'custom_templates',       // Your table name\n    templateSourceColumnName: 'template_content', // Your source column\n    templateModificationColumnName: 'modified_at', // Your timestamp column\n    tplSetColumnName: 'theme_name',               // Your template set column\n    templateNameColumnName: 'filename',          // Your filename column\n    templatePathGetter: function (array $row): ?string {\n        // Custom logic for file path resolution\n        return '/path/to/templates/' . $row['filename'];\n    },\n    defaultTplSetName: 'default_theme'\n);\n```\n\n### Template Path Resolution Examples\n\nThe `templatePathGetter` function allows you to customize how database records are converted to file paths:\n\n```php\n// Simple file path concatenation\n$templatePathGetter = function (array $row): ?string {\n    return __DIR__ . '/templates/' . $row['tpl_file'];\n};\n\n// Subdirectory organization by template type\n$templatePathGetter = function (array $row): ?string {\n    $subdir = $row['tpl_type'] ?? 'default';\n    return __DIR__ . '/templates/' . $subdir . '/' . $row['tpl_file'];\n};\n\n// Conditional file resolution with validation\n$templatePathGetter = function (array $row): ?string {\n    if (empty($row['tpl_file'])) {\n        return null; // No file path available\n    }\n\n    $basePath = __DIR__ . '/templates/';\n    $filePath = $basePath . $row['tpl_file'];\n\n    return is_file($filePath) ? $filePath : null;\n};\n```\n\n### Using the Built-in TemplatePathResolver\n\nThe package includes a built-in `TemplatePathResolver` class that provides a clean, object-oriented alternative to closures for template path resolution:\n\n```php\nuse Imponeer\\Smarty\\Extensions\\DatabaseResource\\Resolver\\TemplatePathResolver;\n\n// Create the resolver with your template base path\n$templatePathResolver = new TemplatePathResolver('/path/to/templates');\n\n// Use it in DatabaseResource\n$plugin = new DatabaseResource(\n    pdo: $pdo,\n    tplSetName: 'default',\n    templatesTableName: 'tplfile',\n    templateSourceColumnName: 'tpl_source',\n    templateModificationColumnName: 'tpl_lastmodified',\n    tplSetColumnName: 'tpl_tplset',\n    templateNameColumnName: 'tpl_file',\n    templatePathGetter: $templatePathResolver,\n    defaultTplSetName: 'default'\n);\n```\n\n#### Custom Template File Column\n\nYou can also specify a custom column name for the template filename:\n\n```php\n// Use a custom column name for template files\n$templatePathResolver = new TemplatePathResolver(\n    templateBasePath: '/path/to/templates',\n    templateFileColumn: 'custom_filename_column'\n);\n```\n\n### Using with Symfony Container\n\nTo integrate with Symfony, you can leverage autowiring, which is the recommended approach for modern Symfony applications:\n\n```yaml\n# config/services.yaml\nservices:\n    # Enable autowiring and autoconfiguration\n    _defaults:\n        autowire: true\n        autoconfigure: true\n\n    # Register your application's services\n    App\\:\n        resource: '../src/*'\n        exclude: '../src/{DependencyInjection,Entity,Tests,Kernel.php}'\n\n    # Configure PDO connection\n    PDO:\n        arguments:\n            $dsn: '%env(DATABASE_URL)%'\n            $username: '%env(DB_USERNAME)%'\n            $password: '%env(DB_PASSWORD)%'\n\n    # Configure template path resolver\n    Imponeer\\Smarty\\Extensions\\DatabaseResource\\Resolver\\TemplatePathResolver:\n        arguments:\n            $templateBasePath: '%kernel.project_dir%/templates'\n\n    # Configure DatabaseResource\n    Imponeer\\Smarty\\Extensions\\DatabaseResource\\DatabaseResource:\n        arguments:\n            $pdo: '@PDO'\n            $tplSetName: 'default'\n            $templatesTableName: 'tplfile'\n            $templateSourceColumnName: 'tpl_source'\n            $templateModificationColumnName: 'tpl_lastmodified'\n            $tplSetColumnName: 'tpl_tplset'\n            $templateNameColumnName: 'tpl_file'\n            $templatePathGetter: '@Imponeer\\Smarty\\Extensions\\DatabaseResource\\Resolver\\TemplatePathResolver'\n            $defaultTplSetName: 'default'\n\n    # Configure Smarty with the extension\n    Smarty\\Smarty:\n        calls:\n            - [registerResource, ['db', '@Imponeer\\Smarty\\Extensions\\DatabaseResource\\DatabaseResource']]\n```\n\n\n\nThen in your application code:\n\n```php\n// Get the Smarty instance with the database resource already registered\n$smarty = $container-\u003eget(\\Smarty\\Smarty::class);\n```\n\n### Using with PHP-DI\n\nWith PHP-DI container, you can take advantage of autowiring for a clean configuration:\n\n```php\nuse function DI\\create;\nuse function DI\\get;\nuse function DI\\factory;\nuse Imponeer\\Smarty\\Extensions\\DatabaseResource\\Resolver\\TemplatePathResolver;\n\nreturn [\n    // Configure PDO\n    PDO::class =\u003e factory(function () {\n        return new PDO('mysql:host=localhost;dbname=your_database', $username, $password);\n    }),\n\n    // Configure TemplatePathResolver\n    TemplatePathResolver::class =\u003e create()\n        -\u003econstructor(__DIR__ . '/templates'),\n\n    // Configure DatabaseResource\n    \\Imponeer\\Smarty\\Extensions\\DatabaseResource\\DatabaseResource::class =\u003e create()\n        -\u003econstructor(\n            get(PDO::class),\n            'default',                    // tplSetName\n            'tplfile',                   // templatesTableName\n            'tpl_source',                // templateSourceColumnName\n            'tpl_lastmodified',          // templateModificationColumnName\n            'tpl_tplset',                // tplSetColumnName\n            'tpl_file',                  // templateNameColumnName\n            get(TemplatePathResolver::class), // templatePathGetter\n            'default'                    // defaultTplSetName\n        ),\n\n    // Configure Smarty with the database resource\n    \\Smarty\\Smarty::class =\u003e create()\n        -\u003emethod('registerResource', 'db', get(\\Imponeer\\Smarty\\Extensions\\DatabaseResource\\DatabaseResource::class))\n];\n```\n\nThen in your application code:\n\n```php\n// Get the configured Smarty instance\n$smarty = $container-\u003eget(\\Smarty\\Smarty::class);\n```\n\n### Using with League Container\n\nIf you're using League Container, you can register the extension like this:\n\n```php\nuse League\\Container\\Container;\nuse Imponeer\\Smarty\\Extensions\\DatabaseResource\\DatabaseResource;\nuse Imponeer\\Smarty\\Extensions\\DatabaseResource\\Resolver\\TemplatePathResolver;\n\n// Create the container\n$container = new Container();\n\n// Register PDO\n$container-\u003eadd(PDO::class, function() {\n    return new PDO('mysql:host=localhost;dbname=your_database', $username, $password);\n});\n\n// Register TemplatePathResolver\n$container-\u003eadd(TemplatePathResolver::class, function() {\n    return new TemplatePathResolver(__DIR__ . '/templates');\n});\n\n// Register DatabaseResource\n$container-\u003eadd(DatabaseResource::class, function() use ($container) {\n    return new DatabaseResource(\n        pdo: $container-\u003eget(PDO::class),\n        tplSetName: 'default',\n        templatesTableName: 'tplfile',\n        templateSourceColumnName: 'tpl_source',\n        templateModificationColumnName: 'tpl_lastmodified',\n        tplSetColumnName: 'tpl_tplset',\n        templateNameColumnName: 'tpl_file',\n        templatePathGetter: $container-\u003eget(TemplatePathResolver::class),\n        defaultTplSetName: 'default'\n    );\n});\n\n// Register Smarty with the database resource\n$container-\u003eadd(\\Smarty\\Smarty::class, function() use ($container) {\n    $smarty = new \\Smarty\\Smarty();\n    // Configure Smarty...\n\n    // Register the database resource\n    $smarty-\u003eregisterResource('db', $container-\u003eget(DatabaseResource::class));\n\n    return $smarty;\n});\n```\n\nThen in your application code:\n\n```php\n// Get the configured Smarty instance\n$smarty = $container-\u003eget(\\Smarty\\Smarty::class);\n```\n\n## Usage\n\n### Basic Template Inclusion\n\nTo use database-stored templates in your Smarty templates, use the `db:` prefix when referencing template files:\n\n```smarty\n{* Include a template from the database *}\n{include file=\"db:header.tpl\"}\n\n{* Include with subdirectory structure *}\n{include file=\"db:layouts/main.tpl\"}\n\n{* Include with variables *}\n{include file=\"db:user/profile.tpl\" user=$currentUser}\n```\n\n### Template Examples\n\n#### Main Layout Template\n```smarty\n{* File: db:layout.tpl *}\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003ctitle\u003e{$pageTitle|default:\"My Website\"}\u003c/title\u003e\n    {include file=\"db:includes/head.tpl\"}\n\u003c/head\u003e\n\u003cbody\u003e\n    {include file=\"db:includes/header.tpl\"}\n\n    \u003cmain\u003e\n        {$content}\n    \u003c/main\u003e\n\n    {include file=\"db:includes/footer.tpl\"}\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### Dynamic Content Loading\n```smarty\n{* Load different templates based on conditions *}\n{if $userType == 'admin'}\n    {include file=\"db:admin/dashboard.tpl\"}\n{else}\n    {include file=\"db:user/dashboard.tpl\"}\n{/if}\n\n{* Loop through template sections *}\n{foreach $sections as $section}\n    {include file=\"db:sections/{$section.template}\" data=$section.data}\n{/foreach}\n```\n\n### Template Set Management\n\nThe plugin supports multiple template sets, allowing you to have different themes or versions:\n\n```php\n// Switch to a different template set\n$plugin = new DBResource(\n    pdo: $pdo,\n    tplSetName: 'mobile_theme',  // Use mobile-specific templates\n    // ... other parameters\n);\n```\n\nTemplates are resolved with fallback logic:\n1. First, look for templates in the specified template set\n2. If not found, fall back to the default template set\n3. If still not found, attempt to load from filesystem (if `templatePathGetter` is configured)\n\n## Development\n\n### Code Quality Tools\n\nThis project uses several tools to ensure code quality:\n\n- **PHPUnit** - For unit testing\n  ```bash\n  composer test\n  ```\n\n- **PHP CodeSniffer** - For coding standards (PSR-12)\n  ```bash\n  composer phpcs    # Check code style\n  composer phpcbf   # Fix code style issues automatically\n  ```\n\n- **PHPStan** - For static analysis\n  ```bash\n  composer phpstan\n  ```\n\n### Running Tests\n\nThe test suite includes comprehensive tests for database operations and template resolution:\n\n```bash\n# Run all tests\ncomposer test\n\n# Run tests with coverage\nvendor/bin/phpunit --coverage-html coverage/\n```\n\n## Documentation\n\nAPI documentation is automatically generated and available in the project's wiki. For more detailed information about the classes and methods, please refer to the [project wiki](https://github.com/imponeer/smarty-db-resource/wiki).\n\n## Contributing\n\nContributions are welcome! Here's how you can contribute:\n\n1. **Fork the repository**\n2. **Create a feature branch**: `git checkout -b feature-name`\n3. **Commit your changes**: `git commit -am 'Add some feature'`\n4. **Push to the branch**: `git push origin feature-name`\n5. **Submit a pull request**\n\n### Contribution Guidelines\n\n- **Follow PSR-12 coding standards** - Use `composer phpcs` to check your code\n- **Write tests** - Include unit tests for any new features or bug fixes\n- **Update documentation** - Update README.md and inline documentation as needed\n- **Test thoroughly** - Ensure your changes work with all supported database systems\n\n### Reporting Issues\n\nIf you find a bug or have a feature request, please create an issue in the [issue tracker](https://github.com/imponeer/smarty-db-resource/issues).\n\nWhen reporting bugs, please include:\n- PHP version\n- Database system and version\n- Smarty version\n- Steps to reproduce the issue\n- Expected vs actual behavior\n\n### Development Setup\n\n1. Clone the repository\n2. Install dependencies: `composer install`\n3. Run tests: `composer test`\n4. Check code style: `composer phpcs`\n5. Run static analysis: `composer phpstan`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimponeer%2Fsmarty-db-resource","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fimponeer%2Fsmarty-db-resource","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fimponeer%2Fsmarty-db-resource/lists"}