diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..7115125
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+/benchmark export-ignore
+/code-quality export-ignore
+/tests export-ignore
+/.github export-ignore
+.gitattributes export-ignore
+/.gitignore export-ignore
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 331c58f..8925195 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.idea
-vendor
\ No newline at end of file
+vendor
+composer.lock
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/readme.md b/README.md
similarity index 69%
rename from readme.md
rename to README.md
index e381e90..a6d2c0c 100644
--- a/readme.md
+++ b/README.md
@@ -1,17 +1,17 @@
# PHP Views
Blazing fast PHP Views with model-driven approach, multi-namespace support and
-built-in [Blade](https://laravel.com/docs/11.x/blade) implementation as a default template engine.
+custom [Blade](https://laravel.com/docs/11.x/blade) implementation as a default template engine.
### Benefits
-* Zero Dependencies: Lightweight and easy to integrate into any project.
-* Wide Compatibility: PHP 7.4+, 8.0+
-* Adherence to the [SOLID principles](https://en.wikipedia.org/wiki/SOLID): The architecture allows you to easily
+* **Blazing fast:** Outperforms the original Laravel Blade (see the [Benchmark section](#4-benchmark)).
+* **Zero Dependencies:** Lightweight and easy to integrate into any project.
+* **Wide Compatibility:** PHP 7.4+, 8.0+
+* **Adherence to the [SOLID principles](https://en.wikipedia.org/wiki/SOLID):** The architecture allows you to easily
override any module to meet specific requirements.
-* Namespace Support: Manage different templates seamlessly under a unified structure.
-* Test Coverage: Covered by [Pest](https://pestphp.com/) Unit and Feature tests.
-* Static Analysis: Checked by [PHPStan](https://phpstan.org/).
+* **Namespace Support**: Manage different templates seamlessly under a unified structure.
+* **Reliable**: Covered by [Pest](https://pestphp.com/) tests and checked by [PHPStan](https://phpstan.org/).
### Flexible Usage
@@ -25,13 +25,23 @@ You're free to use the package in your own way:
## Table of Contents
-- [1. Model-driven approach](#1-model-driven-approach)
-- [2. Views](#2-views)
-- [3. View Renderer](#3-view-renderer)
-- [4. Contribution](#4-contribution)
-- [5. Credits](#5-credits)
+- [1. Installation](#1-installation)
+- [2. Model-driven approach](#2-model-driven-approach)
+- [3. Views Manager](#3-views-manager)
+- [4. View Renderer](#4-view-renderer)
+- [5. Benchmark](#5-benchmark)
+- [6. Contribution](#6-contribution)
+- [7. Credits](#7-credits)
-## 1. Model-driven approach
+## 1. Installation
+
+`composer require prosopo/views`
+
+Don't forget to include the composer autoloader in your app:
+
+`require __DIR__ . '/vendor/autoload.php';`
+
+## 2. Model-driven approach
Similar to many frameworks, such as Laravel, this package embraces a model-driven approach to templates. Each template
is paired with its own Model, where the Model's public properties and methods act as arguments available within the
@@ -42,10 +52,10 @@ Model class:
```php
namespace MyPackage\Views;
+use Prosopo\Views\BaseTemplateModel;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-use Prosopo\Views\TemplateModel;
-class EmployeeTemplateModel extends TemplateModel
+class EmployeeTemplateModel extends BaseTemplateModel
{
public int $salary;
public int $bonus;
@@ -67,6 +77,7 @@ Model template (Blade is used in this example):
Your month income is {{ $total() }},
from which {{ $salary }} is a salary, and {{ $bonus }} is a bonus.
+Est. taxes: {{ $innerModel->taxes($salary) }}
{!! $innerModel !!}
@@ -76,7 +87,7 @@ from which {{ $salary }} is a salary, and {{ $bonus }} is a bonus.
{!! $company !!}
```
-### 1.2) Benefits of the model-driven approach
+### 2.1) Benefits of the model-driven approach
1. Typed variables: Eliminate the hassle of type matching and renaming associated with array-driven variables.
2. Reduced Routine: During object creation, public fields of the model without default values are automatically
@@ -86,11 +97,20 @@ from which {{ $salary }} is a salary, and {{ $bonus }} is a bonus.
maintain
flexibility and avoid specifying the exact component.
-The `TemplateModel` class implements the `TemplateModelInterface`. During rendering, any inner objects that also
-implement
-`TemplateModelInterface` will be automatically rendered and passed into the template as strings.
+By default, inner models are passed to templates as objects, enabling you to call their public methods directly. For
+example:
+
+`{{ $$innerModel->calc($localVar) }}`.
+
+The `BaseTemplateModel` class overrides the `__toString()` method, allowing inner models to be rendered as strings using
+echo statements, which supports HTML output. For instance:
+
+`{!! $innerModel !!}`
-### 1.3) Custom property defaults
+If you prefer, you can configure the `ViewsManager` to pass models as strings instead of objects. Refer to the `
+ViewsManager` section for details.
+
+### 2.2) Custom property defaults
Note: In the `TemplateModel` class, in order to satisfy the Model factory, the constructor is marked as final. If you
need to
@@ -99,15 +119,16 @@ set custom default values, consider using one of the following approaches:
```php
namespace MyPackage\Views;
-use Prosopo\Views\TemplateModel;
+use Prosopo\Views\BaseTemplateModel;
-class EmployeeTemplateModel extends TemplateModel
+class EmployeeTemplateModel extends BaseTemplateModel
{
// approach for plain field types.
public int $varWithCustomDefaultValue = 'custom default value';
public Company $company;
- protected function setCustomDefaults(){
+ protected function setCustomDefaults(): void
+ {
// approach for object field types.
$this->company = new Company();
}
@@ -120,7 +141,7 @@ class EmployeeTemplateModel extends TemplateModel
> automatically resolved
> while object creation by your application's DI system.
-### 1.4) Custom Model implementation (advanced usage)
+### 2.3) Custom Model implementation (advanced usage)
The only requirement for a Model is to implement the `TemplateModelInterface`. This means you can transform any class
into a Model without needing to extend a specific base class, or even define public properties:
@@ -130,31 +151,44 @@ namespace MyPackage\Views;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-class AnyClass implements TemplateModelInterface {
- public function getTemplateArguments(): array {
+class AnyClass implements TemplateModelInterface
+{
+ public function getTemplateArguments(): array
+ {
// you can fill out arguments from any source or define manually.
return [
- 'name' => 'value',
+ 'name' => 'value',
];
- }
+ }
}
```
-## 2. Views
+Note: If you plan to define inner models, remember that the default `__toString()` implementation is not provided. You
+will need to either implement it yourself or enable the option to pass models as strings in the `ViewsManager`
+configuration:
+
+```php
+$namespaceConfig->setModelsAsStringsInTemplates(true);
+```
+
+When this option is enabled, the renderer will automatically convert objects implementing `TemplateModelInterface` into
+strings before passing them to the template.
-The `Views` class provides the `addNamespace`, `makeModel` and `renderModel` methods. It acts as a
+## 3. Views Manager
+
+The `ViewsManager` class provides the `registerNamespace`, `createModel` and `renderModel` methods. It acts as a
namespace manager and brings together different namespace configurations.
Each `ViewNamespace` has its own independent setup and set of modules. E.g. among these modules is the
`ModelTemplateProvider`, which automates the process of linking models to their
corresponding templates.
-### 2.1) Setup
+### 3.1) Setup
```php
use Prosopo\Views\View\ViewNamespaceConfig;
use Prosopo\Views\View\ViewTemplateRenderer;
-use Prosopo\Views\Views;
+use Prosopo\Views\ViewsManager;
// 1. Make the Template Renderer.
// (By default it uses the built-in Blade, but you can connect any)
@@ -170,7 +204,9 @@ $namespaceConfig = (new ViewNamespaceConfig($viewTemplateRenderer))
// optional setting:
->setTemplateErrorHandler(function (array $eventDetails) {
// logging, notifying, whatever.
- });
+ })
+ // this option enables inner models rendering before passing them into the template
+ ->setModelsAsStringsInTemplates(true);
// (This line is necessary only if you defined the templateErrorHandler)
$namespaceConfig->getModules()
@@ -178,40 +214,38 @@ $namespaceConfig->getModules()
// 3. Make the Views instance:
-$views = new Views();
+$viewsManager = new ViewsManager();
// 4. Add the root namespace of your Template Models
-$views->addNamespace('MyPackage\Views', $namespaceConfig);
+$viewsManager->registerNamespace('MyPackage\Views', $namespaceConfig);
// Tip: you can have multiple namespaces, and mix their Models.
```
-### 2.2) Single-step Model creation and rendering
+### 3.2) Single-step Model creation and rendering
You can create, set values, and render a Model in a single step using the callback argument of the `renderView` method,
as shown below:
```php
-echo $views->renderModel(
+echo $viewsManager->renderModel(
EmployeeModel::class,
function (EmployeeModel $employee) use ($salary, $bonus) {
$employee->salary = $salary;
$employee->bonus = $bonus;
}
);
-
-// Tip: pass true to the third renderModel() argument to print it without echo.
```
This approach enables a functional programming style when working with Models.
-### 2.3) Multi-step creation and rendering
+### 3.3) Multi-step creation and rendering
When you need split creation, use the factory to create the model, and then render later when you need it.
```php
-$employee = $views->makeModel(EmployeeModel::class);
+$employee = $viewsManager->createModel(EmployeeModel::class);
// ...
@@ -226,19 +260,18 @@ echo $views->renderModel($employee);
// to customize the Model properties before rendering.
```
-Advice: The `Views` class implements three interfaces: `ViewNamespaceManagerInterface` (for `addNamespace`),
-`ModelFactoryInterface` (for
-`makeModel`), and `ModelRendererInterface` (for `renderModel`).
+Advice: The `ViewsManager` class implements three interfaces: `ViewNamespaceManagerInterface` (for `registerNamespace`),
+`ModelFactoryInterface` (for `createModel`), and `ModelRendererInterface` (for `renderModel`).
-When passing the `Views` instance to your methods, use
-one of these interfaces as the argument type instead of the `Views` class itself.
+When passing the `ViewsManager` instance to your methods, use one of these interfaces as the argument type instead of
+the `ViewsManager` class itself.
-This approach ensures that only the specific actions
-you expect are accessible, promoting cleaner and more maintainable code.
+This approach ensures that only the specific actions you expect are accessible, promoting cleaner and more maintainable
+code.
-### 2.4) Automated templates matching
+### 3.4) Automated templates matching
-The built-in `ModelTemplateProvider` automatically matches templates based on the Model names and their relative
+The built-in `ModelTemplateResolver` automatically matches templates based on the Model names and their relative
namespaces. This automates the process of associating templates with their corresponding Models.
Example:
@@ -256,13 +289,14 @@ Example:
**Naming Note:** Use dashes in template names, as camelCase in Model names is automatically converted to dash-separated
names.
-> Tip: In case this approach doesn't work for your setup, you can override the `ModelTemplateProvider` module to
-> implement your own logic. In case the reason is the name-specific only, consider overriding the `ModelNameProvider`
+> Tip: In case this approach doesn't work for your setup, you can override the `ModelTemplateResolver` module to
+> implement your own logic. In case the reason is the name-specific only, consider overriding the `ModelNameResolver`
> module instead.
-### 2.5) Custom modules
+### 3.5) Custom modules
-By default, the `addNamespace` class creates module instances for the namespace using classes from the current package.
+By default, the `registerNamespace` class creates module instances for the namespace using classes from the current
+package.
If you need to override the default module behavior, you can define a custom implementation in the
configuration and the package will use the specified implementation.
@@ -276,7 +310,7 @@ configuration and the package will use the specified implementation.
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
use Prosopo\Views\View\ViewNamespaceConfig;
-use Prosopo\Views\Views;
+use Prosopo\Views\ViewsManager;
class TwigDecorator implements TemplateRendererInterface
{
@@ -287,9 +321,9 @@ class TwigDecorator implements TemplateRendererInterface
// todo init Twig or another engine.
}
- public function renderTemplate(string $template, array $variables, bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
- return $this->twig->render($template, $variables, $doPrint);
+ return $this->twig->render($template, $variables);
}
}
@@ -303,11 +337,11 @@ $namespaceConfig = (new ViewNamespaceConfig($twigDecorator))
// 3. Make the Views:
-$views = new Views();
+$viewsManager = new ViewsManager();
// 4. Add the namespace (you can have multiple namespaces)
-$views->addNamespace('MyPackage\Views', $namespaceConfig);
+$viewsManager->registerNamespace('MyPackage\Views', $namespaceConfig);
```
You can override any namespace module in the following way:
@@ -321,9 +355,10 @@ $namespaceConfig->getModules()
> Note: The package includes only the Blade implementation. If you wish to use a different template engine,
> like Twig, you need to install its Composer package and create a facade object, as demonstrated above.
-### 2.6) Namespace mixing
+### 3.6) Namespace mixing
-> Fun Fact: The `Views` class not only supporting multiple namespaces, but also enabling you to use Models from one
+> Fun Fact: The `ViewsManager` class not only supporting multiple namespaces, but also enabling you to use Models from
+> one
> namespace within another, preserving their individual setup.
Example of multi-namespace usage:
@@ -335,13 +370,13 @@ Additionally, you have a namespace for Twig templates, with a `Popup` model and
Here’s the cool part: you can safely use `Button` as a property of the `Popup` model. The package will first render the
`Button` using Twig, converting it to a string, and then pass it seamlessly into the Blade template of the `Popup`.
-## 3. View Renderer
+## 4. View Renderer
`ViewTemplateRenderer` is the class responsible for rendering templates in this package. By default, it integrates the
Blade compiler, but it is fully customizable. You can replace the Blade compiler with your own implementation or use a
simple stub to enable support for plain PHP template files.
-### 3.1) Built-in Blade integration
+### 4.1) Built-in Blade integration
[Blade](https://laravel.com/docs/11.x/blade) is an elegant and powerful template engine originally designed
for [Laravel](https://laravel.com/).
@@ -378,7 +413,7 @@ However, we chose not to adopt this approach for several reasons:
Thanks to great Blade's conceptual design, our compiler implementation required fewer than 200 lines of code.
-### 3.2) View Renderer setup
+### 4.2) View Renderer setup
```php
use Prosopo\Views\View\ViewTemplateRenderer;
@@ -398,7 +433,7 @@ use Prosopo\Views\View\ViewTemplateRenderer;
use Prosopo\Views\View\ViewTemplateRendererConfig;
$viewRendererConfig = new ViewTemplateRendererConfig();
-$viewRendererConfig->setIsFileBasedTemplate(false);
+$viewRendererConfig->setFileBasedTemplates(false);
$viewTemplateRenderer = new ViewTemplateRenderer($viewRendererConfig);
@@ -412,11 +447,10 @@ echo $viewTemplateRenderer->renderTemplate('@if($var)The variable is set.@endif'
> means that even if you can't or don't want to use the model-driven approach, you can still utilize it as an
> independent Blade compiler.
-### 3.3) Available View Renderer settings
+### 4.3) Available View Renderer settings
The `ViewTemplateRenderer` supports a variety of settings that let you customize features such as
-escaping,
-error handling, and more:
+escaping, error handling, and more:
```php
use Prosopo\Views\View\ViewTemplateRenderer;
@@ -425,7 +459,7 @@ use Prosopo\Views\View\ViewTemplateRendererConfig;
$viewRendererConfig = (new ViewTemplateRendererConfig())
// By default, the Renderer expect a file name.
// Set to false if to work with strings
- ->setIsFileBasedTemplate(true)
+ ->setFileBasedTemplates(true)
->setTemplateErrorHandler(function (array $eventDetails): void {
// Can be used for logging, notifying, etc.
})
@@ -455,7 +489,7 @@ $viewRendererConfig = (new ViewTemplateRendererConfig())
$viewTemplateRenderer = new ViewTemplateRenderer($viewRendererConfig);
```
-### 3.4) Custom View Renderer modules
+### 4.4) Custom View Renderer modules
By default, the `ViewTemplateRenderer` creates module instances using classes from the current package, including the
Blade compiler.
@@ -472,7 +506,7 @@ use Prosopo\Views\Interfaces\Template\TemplateCompilerInterface;
use Prosopo\Views\View\ViewNamespaceConfig;
use Prosopo\Views\View\ViewTemplateRenderer;
use Prosopo\Views\View\ViewTemplateRendererConfig;
-use Prosopo\Views\Views;
+use Prosopo\Views\ViewsManager;
class CompilerStubForPlainPhpSupport implements TemplateCompilerInterface
{
@@ -490,26 +524,55 @@ $viewTemplateRendererConfig->getModules()
$viewTemplateRenderer = new ViewTemplateRenderer($viewTemplateRendererConfig);
-$views = new Views();
+$views = new ViewsManager();
$viewNamespaceConfig = new ViewNamespaceConfig($viewTemplateRenderer);
$viewNamespaceConfig
->setTemplatesRootPath(__DIR__ . './templates')
->setTemplateFileExtension('.php');
-$views->addNamespace('MyApp\Models', $viewNamespaceConfig);
+$views->registerNamespace('MyApp\Models', $viewNamespaceConfig);
```
Now this namespace is configured to deal with plain PHP template files, while having all the package features, including
model-driven approach and template error handling.
-## 4. Contribution
+## 5. Benchmark
+
+We conducted a [PHP performance benchmark](https://github.com/prosopo/php-views/blob/main/benchmark/src/Benchmark.php)
+to compare this package with the Laravel's Blade (mocked using [jenssegers/blade](https://github.com/jenssegers/blade))
+and [Twig](https://twig.symfony.com/). Here are the results for 1000x renders:
+
+| Contestant | First Rendering, MS | Cached Rendering, MS |
+|----------------------------------------|---------------------|----------------------|
+| `prosopo/views` (without models) | 19.75 | 19.75 (no cache atm) |
+| `prosopo/views` (with models) | 43.78 | 43.78 (no cache atm) |
+| `illuminate/view` (Blade from Laravel) | 181.24 | 56.77 ms |
+| `twig/twig` | 441.13 | 9.47 ms |
+
+We used the following package versions:
+
+* [illuminate/view](https://packagist.org/packages/illuminate/view) `11.7.0`
+* [twig/twig](https://packagist.org/packages/twig/twig) `3.17.1`
+* [jenssegers/blade](https://packagist.org/packages/jenssegers/blade) `2.0.1`
+
+Since the [benchmark](https://github.com/prosopo/php-views/blob/main/benchmark/src/Benchmark.php) is included in this
+repository, you can easily run it locally to verify the results.
+
+1. `git clone https://github.com/prosopo/php-views.git`
+2. `composer install; cd benchmark; composer install`
+3. `php benchmark {1000}` - pass your renders count
+
+We encourage you to enhance the benchmark further - feel free to make it more advanced and submit a pull request. We're
+happy to review and accept contributions! 🚀
+
+## 6. Contribution
We would be excited if you decide to contribute! Please read
the [for-devs.md](https://github.com/prosopo/php-views/blob/main/for-devs.md) file for project guidelines and
agreements.
-## 5. Credits
+## 7. Credits
This package was created by [Maxim Akimov](https://github.com/light-source/) during the development of
the [WordPress integration for Prosopo Procaptcha](https://wordpress.org/plugins/prosopo-procaptcha/).
diff --git a/benchmark/.gitignore b/benchmark/.gitignore
new file mode 100644
index 0000000..adc675c
--- /dev/null
+++ b/benchmark/.gitignore
@@ -0,0 +1,3 @@
+vendor
+composer.lock
+tmp
\ No newline at end of file
diff --git a/benchmark/benchmark.php b/benchmark/benchmark.php
new file mode 100644
index 0000000..4e4bb2e
--- /dev/null
+++ b/benchmark/benchmark.php
@@ -0,0 +1,9 @@
+run();
diff --git a/benchmark/composer.json b/benchmark/composer.json
new file mode 100644
index 0000000..2c5a68c
--- /dev/null
+++ b/benchmark/composer.json
@@ -0,0 +1,12 @@
+{
+ "require": {
+ "illuminate/view": "~11.7.0",
+ "twig/twig": "^3.17",
+ "jenssegers/blade": "^2.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Benchmark\\": "./src"
+ }
+ }
+}
diff --git a/benchmark/src/Benchmark.php b/benchmark/src/Benchmark.php
new file mode 100644
index 0000000..3026d4a
--- /dev/null
+++ b/benchmark/src/Benchmark.php
@@ -0,0 +1,382 @@
+ 1 ?
+ (int)$_SERVER['argv'][1] :
+ 1000;
+ $templateNameLength = 10;
+ $itemsInTemplateCount = 100;
+ $templateArguments = [
+ 'items' => array_fill(0, $itemsInTemplateCount, 'item'),
+ ];
+ $validationString = sprintf('[%s]', $itemsInTemplateCount);
+
+ list($twigSpentMs, $twigSpentMsWithCache) = $this->benchmarkForTwig(
+ $rootDir,
+ $this->getTestTemplate('.twig'),
+ $templatesCount,
+ $templateNameLength,
+ $templateArguments,
+ $validationString
+ );
+
+ list($bladeOriginSpentMs, $bladeOriginSpentMsWithCache) = $this->benchmarkForBladeOrigin(
+ $rootDir,
+ $this->getTestTemplate('.blade.php'),
+ $templatesCount,
+ $templateNameLength,
+ $templateArguments,
+ $validationString
+ );
+
+ $phpViewsSpentMs = $this->benchmarkForPhpViews(
+ $rootDir,
+ $this->getTestTemplate('.blade.php'),
+ $templatesCount,
+ $templateNameLength,
+ $templateArguments,
+ $validationString
+ );
+
+ $phpViewsWithModelsSpentMs = $this->benchmarkForPhpViewsWithModels(
+ $rootDir,
+ $this->getTestTemplate('.blade.php'),
+ $templatesCount,
+ $templateNameLength,
+ $templateArguments,
+ $validationString
+ );
+
+ $results = [
+ 'Blade from Laravel (raw)' => $bladeOriginSpentMs,
+ 'Blade from Laravel (with cache)' => $bladeOriginSpentMsWithCache,
+ 'PHP Views with Models (built-in Blade)' => $phpViewsWithModelsSpentMs,
+ 'PHP Views without Models (using built-in Blade)' => $phpViewsSpentMs,
+ 'Twig (raw)' => $twigSpentMs,
+ 'Twig (with cache)' => $twigSpentMsWithCache,
+ ];
+
+ // sort asc
+ asort($results);
+
+ printf("Renders Count: %sx\n", $templatesCount);
+
+ array_walk($results, function ($spentMs, $contestant) {
+ printf("%s ms: %s\n", $spentMs, $contestant);
+ });
+
+ $this->removeDir($rootDir);
+ }
+
+ public function benchmarkForBladeOrigin(
+ string $rootDir,
+ string $template,
+ int $templatesCount,
+ int $templateNameLength,
+ array $templateArguments,
+ string $validationString
+ ): array {
+ $bladeOriginDir = $rootDir . '/origin-blade';
+ $bladeOriginCacheDir = $rootDir . '/origin-blade-cache';
+
+ mkdir($bladeOriginDir);
+ mkdir($bladeOriginCacheDir);
+
+ $blade = new Blade($bladeOriginDir, $bladeOriginCacheDir);
+
+ $bladeFiles = $this->writeUniqueTemplates(
+ $bladeOriginDir,
+ '.blade.php',
+ $template,
+ $templatesCount,
+ $templateNameLength,
+ true
+ );
+
+ $calc = fn()=> $this->measureFileRenders(
+ 'blade-origin',
+ function ($templateFile) use ($blade, $templateArguments) {
+ return $blade->render($templateFile, $templateArguments);
+ },
+ $bladeFiles,
+ $validationString
+ );
+
+ return [$calc(),$calc()];
+ }
+
+ protected function benchmarkForPhpViews(
+ string $rootDir,
+ string $template,
+ int $templatesCount,
+ int $templateNameLength,
+ array $templateArguments,
+ string $validationString
+ ): float {
+ $phpViewsDir = $rootDir . '/php-views';
+
+ mkdir($phpViewsDir);
+
+ $phpViewsRenderer = new ViewTemplateRenderer();
+
+ $phpViewsFiles = $this->writeUniqueTemplates(
+ $phpViewsDir,
+ '.blade.php',
+ $template,
+ $templatesCount,
+ $templateNameLength,
+ false
+ );
+
+ return $this->measureFileRenders(
+ 'php-views',
+ function ($templateFile) use ($phpViewsRenderer, $templateArguments) {
+ return $phpViewsRenderer->renderTemplate($templateFile, $templateArguments);
+ },
+ $phpViewsFiles,
+ $validationString
+ );
+ }
+
+ protected function benchmarkForPhpViewsWithModels(
+ string $rootDir,
+ string $template,
+ int $templatesCount,
+ int $templateNameLength,
+ array $templateArguments,
+ string $validationString
+ ): float {
+ $phpViewsWithModelsDir = $rootDir . '/php-views-with-models';
+
+ mkdir($phpViewsWithModelsDir);
+
+ $phpViewsRenderer = new ViewTemplateRenderer();
+ $phpViews = new ViewsManager();
+
+ $namespaceConfig = new ViewNamespaceConfig($phpViewsRenderer);
+ $namespaceConfig->setTemplateFileExtension('.blade.php');
+ $namespaceConfig->setTemplatesRootPath($phpViewsWithModelsDir);
+
+ $namespace = '_php_views_with_models';
+
+ $phpViews->registerNamespace($namespace, $namespaceConfig);
+
+ $phpViewsWithModelFiles = $this->writeUniqueTemplates(
+ $phpViewsWithModelsDir,
+ '.blade.php',
+ $template,
+ $templatesCount,
+ $templateNameLength,
+ true
+ );
+
+ return $this->measureFileRenders(
+ 'php-views-with-models',
+ function ($templateFile) use ($namespace, $phpViews, $templateArguments) {
+
+ $modelClass = $this->defineModelClass($namespace, $templateFile);
+
+ return $phpViews->renderModel($modelClass, function ($model) use ($templateArguments) {
+ $model->items = $templateArguments['items'];
+ });
+ },
+ $phpViewsWithModelFiles,
+ $validationString
+ );
+ }
+
+ protected function benchmarkForTwig(
+ string $rootDir,
+ string $template,
+ int $templatesCount,
+ int $templateNameLength,
+ array $templateArguments,
+ string $validationString
+ ): array {
+ $twigDir = $rootDir . '/twig';
+ $twigCacheDir = $rootDir . '/twig-cache';
+
+ mkdir($twigDir);
+
+ $twigLoader = new FilesystemLoader($twigDir);
+ $twig = new Environment($twigLoader, [
+ 'cache' => $twigCacheDir,
+ ]);
+
+ $twigFiles = $this->writeUniqueTemplates(
+ $twigDir,
+ '.twig',
+ $template,
+ $templatesCount,
+ $templateNameLength,
+ true
+ );
+
+ $calc = fn() => $this->measureFileRenders(
+ 'twig',
+ function ($templateFile) use ($twig, $templateArguments) {
+ return $twig->render($templateFile . '.twig', $templateArguments);
+ },
+ $twigFiles,
+ $validationString
+ );
+
+ return [$calc(),$calc()];
+ }
+
+ protected function defineModelClass(string $namespace, string $className): string
+ {
+ $code = sprintf(
+ 'namespace %s; class %s extends \Prosopo\Views\BaseTemplateModel { public array $items; }',
+ $namespace,
+ $className
+ );
+
+ eval($code);
+
+ return $namespace . '\\' . $className;
+ }
+
+ protected function removeDir(string $directory): void
+ {
+ if (false === is_dir($directory)) {
+ return;
+ }
+
+ $fsItems = scandir($directory);
+
+ array_walk($fsItems, function ($item) use ($directory) {
+ if (
+ $item === '.' ||
+ $item === '..'
+ ) {
+ return;
+ }
+
+ $path = $directory . DIRECTORY_SEPARATOR . $item;
+
+ if (true === is_dir($path)) {
+ $this->removeDir($path);
+ } else {
+ unlink($path);
+ }
+ });
+
+ rmdir($directory);
+ }
+
+ protected function writeUniqueTemplates(
+ string $rootPath,
+ string $extension,
+ string $template,
+ int $count,
+ int $nameLength,
+ bool $isNameOnly
+ ): array {
+ $randomStrings = $this->getRandomUniqueStrings($count, $nameLength);
+
+ return array_reduce(
+ $randomStrings,
+ function ($templateFiles, $randomString) use ($rootPath, $extension, $template, $isNameOnly) {
+ $templateFile = $rootPath . '/' . $randomString . $extension;
+ // add name to the content to avoid any potential content-related cache.
+ $templateContent = $template . ' ' . $randomString;
+
+ file_put_contents($templateFile, $templateContent);
+
+ $templateFiles[] = true === $isNameOnly ?
+ $randomString :
+ $templateFile;
+
+ return $templateFiles;
+ },
+ []
+ );
+ }
+
+ protected function getSpentTimeInMilliseconds(float $start): float
+ {
+ $spendTime = (microtime(true) - $start) * 1000;
+
+ return round($spendTime, 2);
+ }
+
+ protected function measureFileRenders(
+ string $vendor,
+ callable $render,
+ array $templateFiles,
+ string $validationString
+ ): float {
+ $start = microtime(true);
+
+ array_walk($templateFiles, function ($templateFile) use ($vendor, $render, $validationString) {
+ $rendered = $render($templateFile);
+
+ if (false === strpos($rendered, $validationString)) {
+ throw new Exception('Unexpected render result for ' . $vendor . ' (' . $templateFile . ')');
+ }
+ });
+
+ return $this->getSpentTimeInMilliseconds($start);
+ }
+
+ protected function getRandomUniqueStrings(int $count, int $stringLength, array $uniqueStrings = []): array
+ {
+ if (count($uniqueStrings) >= $count) {
+ return array_keys($uniqueStrings);
+ }
+
+ $randomString = $this->getRandomString($stringLength);
+ $uniqueStrings[$randomString] = true;
+
+ return $this->getRandomUniqueStrings($count, $stringLength, $uniqueStrings);
+ }
+
+ protected function getRandomString(int $length): string
+ {
+ $characters = array_merge(
+ range('a', 'z'),
+ );
+
+ $charactersLength = count($characters);
+ $initialArray = array_fill(0, $length, null);
+
+ $randomLetters = array_map(function () use ($characters, $charactersLength) {
+ $index = random_int(0, $charactersLength - 1);
+
+ return $characters[$index];
+ }, $initialArray);
+
+ return implode('', $randomLetters);
+ }
+
+ protected function getTestTemplate(string $extension): string
+ {
+ $file = __DIR__ . '/../template/template' . $extension;
+
+ if (false === file_exists($file)) {
+ throw new Exception('Template file not found');
+ }
+
+ return (string)file_get_contents($file);
+ }
+}
diff --git a/benchmark/template/template.blade.php b/benchmark/template/template.blade.php
new file mode 100644
index 0000000..297cc42
--- /dev/null
+++ b/benchmark/template/template.blade.php
@@ -0,0 +1,7 @@
+@foreach ($items as $item)
+1
+@endforeach
+[{{ count($items) }}]
+@if (count($items) === 100)
+1
+@endif
\ No newline at end of file
diff --git a/benchmark/template/template.twig b/benchmark/template/template.twig
new file mode 100644
index 0000000..ed66b64
--- /dev/null
+++ b/benchmark/template/template.twig
@@ -0,0 +1,7 @@
+{% for item in items %}
+1
+{% endfor %}
+[{{ items|length }}]
+{% if 100 == items|length %}
+1
+{% endif %}
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 531a184..5383e2b 100644
--- a/composer.json
+++ b/composer.json
@@ -1,4 +1,21 @@
{
+ "name": "prosopo/views",
+ "description": "Blazing fast Views with model-driven approach, multi-namespace support and custom Blade implementation as a default template engine.",
+ "homepage": "https://github.com/prosopo/php-views",
+ "keywords": [
+ "Views",
+ "templates",
+ "models",
+ "Blade",
+ "Twig"
+ ],
+ "license": "Apache-2.0",
+ "authors": [
+ {
+ "name": "Maxim Akimov",
+ "homepage": "https://github.com/light-source/"
+ }
+ ],
"require": {
"php": "^7.4|^8.0"
},
diff --git a/private-classes/CodeExecutor/CodeExecutorWithErrorHandler.php b/private-classes/CodeRunner/CodeRunnerWithErrorHandler.php
similarity index 77%
rename from private-classes/CodeExecutor/CodeExecutorWithErrorHandler.php
rename to private-classes/CodeRunner/CodeRunnerWithErrorHandler.php
index bae0715..b07ab06 100644
--- a/private-classes/CodeExecutor/CodeExecutorWithErrorHandler.php
+++ b/private-classes/CodeRunner/CodeRunnerWithErrorHandler.php
@@ -2,10 +2,10 @@
declare(strict_types=1);
-namespace Prosopo\Views\PrivateClasses\CodeExecutor;
+namespace Prosopo\Views\PrivateClasses\CodeRunner;
use ErrorException;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\EventDispatcherInterface;
use Throwable;
@@ -13,14 +13,14 @@
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class CodeExecutorWithErrorHandler implements CodeExecutorInterface
+final class CodeRunnerWithErrorHandler implements CodeRunnerInterface
{
- private CodeExecutorInterface $codeExecutor;
+ private CodeRunnerInterface $codeExecutor;
private EventDispatcherInterface $eventDispatcher;
private string $errorEventName;
public function __construct(
- CodeExecutorInterface $codeExecutor,
+ CodeRunnerInterface $codeExecutor,
EventDispatcherInterface $eventDispatcher,
string $errorEventName
) {
@@ -29,7 +29,7 @@ public function __construct(
$this->errorEventName = $errorEventName;
}
- public function executeCode(string $code, array $arguments = []): void
+ public function runCode(string $code, array $arguments = []): void
{
$errorDetails = [
'arguments' => $arguments,
@@ -43,7 +43,7 @@ public function executeCode(string $code, array $arguments = []): void
throw new ErrorException($message, 0, $severity, $file, $line);
});
- $this->codeExecutor->executeCode($code, $arguments);
+ $this->codeExecutor->runCode($code, $arguments);
} catch (Throwable $error) {
$errorDetails['error'] = $error;
diff --git a/private-classes/CodeExecutor/CodeExecutorWithGlobalArguments.php b/private-classes/CodeRunner/CodeRunnerWithGlobalArguments.php
similarity index 55%
rename from private-classes/CodeExecutor/CodeExecutorWithGlobalArguments.php
rename to private-classes/CodeRunner/CodeRunnerWithGlobalArguments.php
index d85f4aa..46570c1 100644
--- a/private-classes/CodeExecutor/CodeExecutorWithGlobalArguments.php
+++ b/private-classes/CodeRunner/CodeRunnerWithGlobalArguments.php
@@ -2,17 +2,17 @@
declare(strict_types=1);
-namespace Prosopo\Views\PrivateClasses\CodeExecutor;
+namespace Prosopo\Views\PrivateClasses\CodeRunner;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
/**
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class CodeExecutorWithGlobalArguments implements CodeExecutorInterface
+final class CodeRunnerWithGlobalArguments implements CodeRunnerInterface
{
- private CodeExecutorInterface $codeExecutor;
+ private CodeRunnerInterface $codeExecutor;
/**
* @var array
*/
@@ -21,16 +21,16 @@ final class CodeExecutorWithGlobalArguments implements CodeExecutorInterface
/**
* @param array $globalArguments
*/
- public function __construct(CodeExecutorInterface $codeExecutor, array $globalArguments)
+ public function __construct(CodeRunnerInterface $codeExecutor, array $globalArguments)
{
$this->codeExecutor = $codeExecutor;
$this->globalArguments = $globalArguments;
}
- public function executeCode(string $code, array $arguments = []): void
+ public function runCode(string $code, array $arguments = []): void
{
$arguments = array_merge($this->globalArguments, $arguments);
- $this->codeExecutor->executeCode($code, $arguments);
+ $this->codeExecutor->runCode($code, $arguments);
}
}
diff --git a/private-classes/CodeExecutor/CodeExecutorWithTemplateCompilation.php b/private-classes/CodeRunner/CodeRunnerWithTemplateCompilation.php
similarity index 52%
rename from private-classes/CodeExecutor/CodeExecutorWithTemplateCompilation.php
rename to private-classes/CodeRunner/CodeRunnerWithTemplateCompilation.php
index b285adf..99791f9 100644
--- a/private-classes/CodeExecutor/CodeExecutorWithTemplateCompilation.php
+++ b/private-classes/CodeRunner/CodeRunnerWithTemplateCompilation.php
@@ -2,30 +2,30 @@
declare(strict_types=1);
-namespace Prosopo\Views\PrivateClasses\CodeExecutor;
+namespace Prosopo\Views\PrivateClasses\CodeRunner;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\Template\TemplateCompilerInterface;
/**
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class CodeExecutorWithTemplateCompilation implements CodeExecutorInterface
+final class CodeRunnerWithTemplateCompilation implements CodeRunnerInterface
{
- private CodeExecutorInterface $codeExecutor;
+ private CodeRunnerInterface $codeExecutor;
private TemplateCompilerInterface $templateCompiler;
- public function __construct(CodeExecutorInterface $codeExecutor, TemplateCompilerInterface $templateCompiler)
+ public function __construct(CodeRunnerInterface $codeExecutor, TemplateCompilerInterface $templateCompiler)
{
$this->codeExecutor = $codeExecutor;
$this->templateCompiler = $templateCompiler;
}
- public function executeCode(string $code, array $arguments = []): void
+ public function runCode(string $code, array $arguments = []): void
{
$compiledCode = $this->templateCompiler->compileTemplate($code);
- $this->codeExecutor->executeCode($compiledCode, $arguments);
+ $this->codeExecutor->runCode($compiledCode, $arguments);
}
}
diff --git a/private-classes/CodeExecutor/PhpCodeExecutor.php b/private-classes/CodeRunner/PhpCodeRunner.php
similarity index 59%
rename from private-classes/CodeExecutor/PhpCodeExecutor.php
rename to private-classes/CodeRunner/PhpCodeRunner.php
index b4cc2b2..0d19879 100644
--- a/private-classes/CodeExecutor/PhpCodeExecutor.php
+++ b/private-classes/CodeRunner/PhpCodeRunner.php
@@ -2,17 +2,17 @@
declare(strict_types=1);
-namespace Prosopo\Views\PrivateClasses\CodeExecutor;
+namespace Prosopo\Views\PrivateClasses\CodeRunner;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
/**
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class PhpCodeExecutor implements CodeExecutorInterface
+final class PhpCodeRunner implements CodeRunnerInterface
{
- public function executeCode(string $code, array $arguments = []): void
+ public function runCode(string $code, array $arguments = []): void
{
// @phpcs:ignore
extract($arguments);
diff --git a/private-classes/EventDispatcher.php b/private-classes/EventDispatcher.php
index 3c92a06..4c78b38 100644
--- a/private-classes/EventDispatcher.php
+++ b/private-classes/EventDispatcher.php
@@ -64,14 +64,14 @@ public function removeEventListener(string $eventName, callable $eventListener):
$this->eventListeners[$eventName] = $eventListeners;
}
- public function attachEventDetails(string $eventName, array $eventDetails): void
+ public function registerEventDetails(string $eventName, array $eventDetails): void
{
$eventDetails = array_merge($this->getEventDetails($eventName), $eventDetails);
$this->eventDetails[$eventName] = $eventDetails;
}
- public function detachEventDetails(string $eventName, array $eventDetails): void
+ public function unregisterEventDetails(string $eventName, array $eventDetails): void
{
$eventDetails = array_diff_key($this->getEventDetails($eventName), $eventDetails);
diff --git a/private-classes/Model/ModelFactory.php b/private-classes/Model/ModelFactory.php
index 39eecdf..df302d7 100644
--- a/private-classes/Model/ModelFactory.php
+++ b/private-classes/Model/ModelFactory.php
@@ -7,6 +7,8 @@
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
use Prosopo\Views\Interfaces\Object\ObjectReaderInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
+use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
/**
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
@@ -16,17 +18,28 @@ final class ModelFactory implements ModelFactoryInterface
{
private ObjectReaderInterface $objectReader;
private PropertyValueProviderInterface $propertyValueProvider;
+ private ModelTemplateResolverInterface $modelTemplateResolver;
+ private TemplateRendererInterface $templateRenderer;
public function __construct(
ObjectReaderInterface $objectReader,
- PropertyValueProviderInterface $propertyValueProvider
+ PropertyValueProviderInterface $propertyValueProvider,
+ ModelTemplateResolverInterface $modelTemplateResolver,
+ TemplateRendererInterface $templateRenderer
) {
$this->objectReader = $objectReader;
$this->propertyValueProvider = $propertyValueProvider;
+ $this->modelTemplateResolver = $modelTemplateResolver;
+ $this->templateRenderer = $templateRenderer;
}
- public function makeModel(string $modelClass)
+ public function createModel(string $modelClass)
{
- return new $modelClass($this->objectReader, $this->propertyValueProvider);
+ return new $modelClass(
+ $this->objectReader,
+ $this->propertyValueProvider,
+ $this->modelTemplateResolver,
+ $this->templateRenderer
+ );
}
}
diff --git a/private-classes/Model/ModelFactoryWithDefaultsManagement.php b/private-classes/Model/ModelFactoryWithDefaultsManagement.php
index e325560..08fe05a 100644
--- a/private-classes/Model/ModelFactoryWithDefaultsManagement.php
+++ b/private-classes/Model/ModelFactoryWithDefaultsManagement.php
@@ -29,9 +29,9 @@ public function __construct(
$this->objectPropertyWriter = $objectPropertyWriter;
}
- public function makeModel(string $modelClass)
+ public function createModel(string $modelClass)
{
- $model = $this->modelFactory->makeModel($modelClass);
+ $model = $this->modelFactory->createModel($modelClass);
if (true === ($model instanceof TemplateModelWithDefaultsInterface)) {
$this->setDefaultValuesRecursively($model);
@@ -42,12 +42,12 @@ public function makeModel(string $modelClass)
protected function setDefaultValuesRecursively(TemplateModelWithDefaultsInterface $modelWithDefaults): void
{
- $defaultsPropertyValueProvider = $modelWithDefaults->getDefaultsPropertyValueProvider();
+ $defaultsPropertyValueProvider = $modelWithDefaults->getDefaultPropertyValueProvider();
- $this->objectPropertyWriter->setObjectPropertyValues($modelWithDefaults, $defaultsPropertyValueProvider);
+ $this->objectPropertyWriter->assignPropertyValues($modelWithDefaults, $defaultsPropertyValueProvider);
$innerModelsWithDefaults = $this->getInnerModels(
- $this->objectPropertyReader->getObjectVariables($modelWithDefaults)
+ $this->objectPropertyReader->extractObjectVariables($modelWithDefaults)
);
array_map(function (TemplateModelWithDefaultsInterface $innerModelWithDefaults) {
diff --git a/private-classes/Model/ModelNameProvider.php b/private-classes/Model/ModelNameResolver.php
similarity index 82%
rename from private-classes/Model/ModelNameProvider.php
rename to private-classes/Model/ModelNameResolver.php
index 5d3f703..f833073 100644
--- a/private-classes/Model/ModelNameProvider.php
+++ b/private-classes/Model/ModelNameResolver.php
@@ -4,7 +4,7 @@
namespace Prosopo\Views\PrivateClasses\Model;
-use Prosopo\Views\Interfaces\Model\ModelNameProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNameResolverInterface;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
use Prosopo\Views\PrivateClasses\Object\ObjectClassReader;
@@ -12,7 +12,7 @@
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class ModelNameProvider implements ModelNameProviderInterface
+final class ModelNameResolver implements ModelNameResolverInterface
{
private ObjectClassReader $objectClassReader;
@@ -21,7 +21,7 @@ public function __construct(ObjectClassReader $objectClassReader)
$this->objectClassReader = $objectClassReader;
}
- public function getModelName(TemplateModelInterface $model): string
+ public function resolveModelName(TemplateModelInterface $model): string
{
$modelNamespaceWithClassName = $this->objectClassReader->getObjectClass($model) ;
diff --git a/private-classes/Model/ModelNamespaceProvider.php b/private-classes/Model/ModelNamespaceResolver.php
similarity index 83%
rename from private-classes/Model/ModelNamespaceProvider.php
rename to private-classes/Model/ModelNamespaceResolver.php
index 2a5d0ac..0ecdfea 100644
--- a/private-classes/Model/ModelNamespaceProvider.php
+++ b/private-classes/Model/ModelNamespaceResolver.php
@@ -4,14 +4,14 @@
namespace Prosopo\Views\PrivateClasses\Model;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\PrivateClasses\Object\ObjectClassReader;
/**
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class ModelNamespaceProvider implements ModelNamespaceProviderInterface
+final class ModelNamespaceResolver implements ModelNamespaceResolverInterface
{
private ObjectClassReader $objectClassReader;
@@ -20,7 +20,7 @@ public function __construct(ObjectClassReader $objectClassReader)
$this->objectClassReader = $objectClassReader;
}
- public function getModelNamespace($modelOrClass): string
+ public function resolveModelNamespace($modelOrClass): string
{
$modelNamespaceWithClassName = false === is_string($modelOrClass) ?
$this->objectClassReader->getObjectClass($modelOrClass) :
diff --git a/private-classes/Model/ModelRenderer.php b/private-classes/Model/ModelRenderer.php
index d35d0f3..12af6e0 100644
--- a/private-classes/Model/ModelRenderer.php
+++ b/private-classes/Model/ModelRenderer.php
@@ -7,7 +7,7 @@
use Closure;
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
use Prosopo\Views\Interfaces\Model\ModelRendererInterface;
-use Prosopo\Views\Interfaces\Template\ModelTemplateProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
/**
@@ -18,31 +18,31 @@ final class ModelRenderer implements ModelRendererInterface
{
private TemplateRendererInterface $templateRenderer;
private ModelFactoryInterface $viewFactory;
- private ModelTemplateProviderInterface $templateProvider;
+ private ModelTemplateResolverInterface $templateProvider;
public function __construct(
TemplateRendererInterface $templateRenderer,
ModelFactoryInterface $modelFactory,
- ModelTemplateProviderInterface $templateProvider
+ ModelTemplateResolverInterface $templateProvider
) {
$this->templateRenderer = $templateRenderer;
$this->viewFactory = $modelFactory;
$this->templateProvider = $templateProvider;
}
- public function renderModel($modelOrClass, ?Closure $setupCallback = null, bool $doPrint = false): string
+ public function renderModel($modelOrClass, ?Closure $setupModelCallback = null): string
{
$model = true === is_string($modelOrClass) ?
- $this->viewFactory->makeModel($modelOrClass) :
+ $this->viewFactory->createModel($modelOrClass) :
$modelOrClass;
- if (null !== $setupCallback) {
- $setupCallback($model);
+ if (null !== $setupModelCallback) {
+ $setupModelCallback($model);
}
$variables = $model->getTemplateArguments();
- $template = $this->templateProvider->getModelTemplate($model);
+ $template = $this->templateProvider->resolveModelTemplate($model);
- return $this->templateRenderer->renderTemplate($template, $variables, $doPrint);
+ return $this->templateRenderer->renderTemplate($template, $variables);
}
}
diff --git a/private-classes/Model/ModelRendererWithEventDetails.php b/private-classes/Model/ModelRendererWithEventDetails.php
index c21268a..fff5a3e 100644
--- a/private-classes/Model/ModelRendererWithEventDetails.php
+++ b/private-classes/Model/ModelRendererWithEventDetails.php
@@ -28,21 +28,21 @@ public function __construct(
$this->eventName = $eventName;
}
- public function renderModel($modelOrClass, Closure $setupCallback = null, bool $doPrint = false): string
+ public function renderModel($modelOrClass, Closure $setupModelCallback = null): string
{
- $viewClass = true === is_string($modelOrClass) ?
+ $modelClass = true === is_string($modelOrClass) ?
$modelOrClass :
get_class($modelOrClass);
$eventDetails = [
- 'viewClass' => $viewClass,
+ 'modelClass' => $modelClass,
];
- $this->eventDispatcher->attachEventDetails($this->eventName, $eventDetails);
+ $this->eventDispatcher->registerEventDetails($this->eventName, $eventDetails);
- $response = $this->viewRenderer->renderModel($modelOrClass, $setupCallback, $doPrint);
+ $response = $this->viewRenderer->renderModel($modelOrClass, $setupModelCallback);
- $this->eventDispatcher->detachEventDetails($this->eventName, $eventDetails);
+ $this->eventDispatcher->unregisterEventDetails($this->eventName, $eventDetails);
return $response;
}
diff --git a/private-classes/Object/ObjectPropertyWriter.php b/private-classes/Object/ObjectPropertyWriter.php
index 1f7fc82..8d003e8 100644
--- a/private-classes/Object/ObjectPropertyWriter.php
+++ b/private-classes/Object/ObjectPropertyWriter.php
@@ -15,7 +15,7 @@
*/
final class ObjectPropertyWriter implements ObjectPropertyWriterInterface
{
- public function setObjectPropertyValues(
+ public function assignPropertyValues(
object $instance,
PropertyValueProviderInterface $propertyValueProvider
): void {
diff --git a/private-classes/Object/ObjectReader.php b/private-classes/Object/ObjectReader.php
index ec1fc67..3440c77 100644
--- a/private-classes/Object/ObjectReader.php
+++ b/private-classes/Object/ObjectReader.php
@@ -15,7 +15,7 @@
*/
final class ObjectReader implements ObjectReaderInterface
{
- public function getObjectVariables(object $instance): array
+ public function extractObjectVariables(object $instance): array
{
$reflectionClass = new ReflectionClass($instance);
diff --git a/private-classes/Object/PropertyValueProviderForModels.php b/private-classes/Object/PropertyValueProviderForModels.php
index 4a1e80a..c5d4e6d 100644
--- a/private-classes/Object/PropertyValueProviderForModels.php
+++ b/private-classes/Object/PropertyValueProviderForModels.php
@@ -4,9 +4,9 @@
namespace Prosopo\Views\PrivateClasses\Object;
+use Prosopo\Views\BaseTemplateModel;
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
-use Prosopo\Views\TemplateModel;
use ReflectionProperty;
/**
@@ -47,19 +47,19 @@ public function getPropertyValue(ReflectionProperty $property)
$modelClassString = $this->getModelClassStringForInheritors($type);
return null !== $modelClassString ?
- $this->modelFactory->makeModel($modelClassString) :
+ $this->modelFactory->createModel($modelClassString) :
null;
}
/**
- * @param class-string|string $propertyType
+ * @param class-string|string $propertyType
*
- * @return class-string|null
+ * @return class-string|null
*/
protected function getModelClassStringForInheritors(string $propertyType)
{
return true === class_exists($propertyType) &&
- true === is_a($propertyType, TemplateModel::class, true) ?
+ true === is_a($propertyType, BaseTemplateModel::class, true) ?
$propertyType :
null;
}
diff --git a/private-classes/Template/FileModelTemplateProvider.php b/private-classes/Template/FileModelTemplateResolver.php
similarity index 76%
rename from private-classes/Template/FileModelTemplateProvider.php
rename to private-classes/Template/FileModelTemplateResolver.php
index 9cdccbf..f0bc621 100644
--- a/private-classes/Template/FileModelTemplateProvider.php
+++ b/private-classes/Template/FileModelTemplateResolver.php
@@ -4,31 +4,31 @@
namespace Prosopo\Views\PrivateClasses\Template;
-use Prosopo\Views\Interfaces\Model\ModelNameProviderInterface;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNameResolverInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-use Prosopo\Views\Interfaces\Template\ModelTemplateProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
/**
* This class is marked as a final and placed under the 'Private' namespace to prevent anyone from using it directly.
* We reserve the right to change its name and implementation.
*/
-final class FileModelTemplateProvider implements ModelTemplateProviderInterface
+final class FileModelTemplateResolver implements ModelTemplateResolverInterface
{
private string $templatesRootPath;
private string $namespace;
private string $extension;
private bool $isFileBasedTemplate;
- private ModelNameProviderInterface $modelNameProvider;
- private ModelNamespaceProviderInterface $modelNamespaceProvider;
+ private ModelNameResolverInterface $modelNameProvider;
+ private ModelNamespaceResolverInterface $modelNamespaceProvider;
public function __construct(
string $namespace,
string $templatesRootPath,
string $extension,
bool $isFileBasedTemplate,
- ModelNamespaceProviderInterface $modelNamespaceProvider,
- ModelNameProviderInterface $modelNameProvider
+ ModelNamespaceResolverInterface $modelNamespaceProvider,
+ ModelNameResolverInterface $modelNameProvider
) {
$this->templatesRootPath = $templatesRootPath;
$this->namespace = $namespace;
@@ -38,14 +38,14 @@ public function __construct(
$this->modelNamespaceProvider = $modelNamespaceProvider;
}
- public function getModelTemplate(TemplateModelInterface $model): string
+ public function resolveModelTemplate(TemplateModelInterface $model): string
{
- $modelNamespace = $this->modelNamespaceProvider->getModelNamespace($model);
+ $modelNamespace = $this->modelNamespaceProvider->resolveModelNamespace($model);
$relativeModelNamespace = substr($modelNamespace, strlen($this->namespace));
$relativeModelNamespace = ltrim($relativeModelNamespace, '\\');
- $modelName = $this->modelNameProvider->getModelName($model);
+ $modelName = $this->modelNameProvider->resolveModelName($model);
$relativeTemplatePath = $this->getRelativeTemplatePath($relativeModelNamespace, $modelName);
diff --git a/private-classes/Template/TemplateRenderer.php b/private-classes/Template/TemplateRenderer.php
index 3df0dea..d1b2627 100644
--- a/private-classes/Template/TemplateRenderer.php
+++ b/private-classes/Template/TemplateRenderer.php
@@ -4,7 +4,7 @@
namespace Prosopo\Views\PrivateClasses\Template;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
/**
@@ -13,26 +13,19 @@
*/
final class TemplateRenderer implements TemplateRendererInterface
{
- private CodeExecutorInterface $codeExecutor;
+ private CodeRunnerInterface $codeExecutor;
- public function __construct(CodeExecutorInterface $codeExecutor)
+ public function __construct(CodeRunnerInterface $codeExecutor)
{
$this->codeExecutor = $codeExecutor;
}
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
ob_start();
- $this->codeExecutor->executeCode($template, $variables);
+ $this->codeExecutor->runCode($template, $variables);
- $html = (string)ob_get_clean();
-
- if (true === $doPrint) {
- // @phpcs:ignore
- echo $html;
- }
-
- return $html;
+ return (string)ob_get_clean();
}
}
diff --git a/private-classes/Template/TemplateRendererWithCustomEscape.php b/private-classes/Template/TemplateRendererWithCustomEscape.php
index 1dfe821..8c50f0e 100644
--- a/private-classes/Template/TemplateRendererWithCustomEscape.php
+++ b/private-classes/Template/TemplateRendererWithCustomEscape.php
@@ -32,7 +32,7 @@ public function __construct(
$this->escapeVariableName = $escapeVariableName;
}
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
$variables = $this->setOutputEscapeCallback(
$variables,
@@ -40,7 +40,7 @@ public function renderTemplate(string $template, array $variables = [], bool $do
$this->customOutputEscapeCallback
);
- return $this->templateRenderer->renderTemplate($template, $variables, $doPrint);
+ return $this->templateRenderer->renderTemplate($template, $variables);
}
/**
diff --git a/private-classes/Template/TemplateRendererWithEventDetails.php b/private-classes/Template/TemplateRendererWithEventDetails.php
index 30af8a8..f3e4075 100644
--- a/private-classes/Template/TemplateRendererWithEventDetails.php
+++ b/private-classes/Template/TemplateRendererWithEventDetails.php
@@ -27,17 +27,17 @@ public function __construct(
$this->eventName = $eventName;
}
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
$eventDetails = [
'template' => $template,
];
- $this->eventDispatcher->attachEventDetails($this->eventName, $eventDetails);
+ $this->eventDispatcher->registerEventDetails($this->eventName, $eventDetails);
- $response = $this->templateRenderer->renderTemplate($template, $variables, $doPrint);
+ $response = $this->templateRenderer->renderTemplate($template, $variables);
- $this->eventDispatcher->detachEventDetails($this->eventName, $eventDetails);
+ $this->eventDispatcher->unregisterEventDetails($this->eventName, $eventDetails);
return $response;
}
diff --git a/private-classes/Template/TemplateRendererWithFileTemplate.php b/private-classes/Template/TemplateRendererWithFileTemplate.php
index 29bd30e..8d70e43 100644
--- a/private-classes/Template/TemplateRendererWithFileTemplate.php
+++ b/private-classes/Template/TemplateRendererWithFileTemplate.php
@@ -19,11 +19,11 @@ public function __construct(TemplateRendererInterface $templateRenderer)
$this->templateRenderer = $templateRenderer;
}
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
$template = $this->getFileContent($template);
- return $this->templateRenderer->renderTemplate($template, $variables, $doPrint);
+ return $this->templateRenderer->renderTemplate($template, $variables);
}
protected function getFileContent(string $file): string
diff --git a/private-classes/Template/TemplateRendererWithModelsRender.php b/private-classes/Template/TemplateRendererWithModelsRender.php
index f3e4002..b18c0b1 100644
--- a/private-classes/Template/TemplateRendererWithModelsRender.php
+++ b/private-classes/Template/TemplateRendererWithModelsRender.php
@@ -24,11 +24,11 @@ public function __construct(TemplateRendererInterface $templateRenderer, ModelRe
$this->modelRenderer = $modelRenderer;
}
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
$variables = $this->renderModels($variables);
- return $this->templateRenderer->renderTemplate($template, $variables, $doPrint);
+ return $this->templateRenderer->renderTemplate($template, $variables);
}
/**
diff --git a/private-classes/View/ViewNamespace.php b/private-classes/View/ViewNamespace.php
index 51d3659..5663e4b 100644
--- a/private-classes/View/ViewNamespace.php
+++ b/private-classes/View/ViewNamespace.php
@@ -16,12 +16,12 @@
PropertyValueProviderForNullable};
use Prosopo\Views\PrivateClasses\Model\{ModelFactory,
ModelFactoryWithDefaultsManagement,
- ModelNameProvider,
- ModelNamespaceProvider,
+ ModelNameResolver,
+ ModelNamespaceResolver,
ModelRenderer,
ModelRendererWithEventDetails};
use Prosopo\Views\PrivateClasses\EventDispatcher;
-use Prosopo\Views\PrivateClasses\Template\FileModelTemplateProvider;
+use Prosopo\Views\PrivateClasses\Template\FileModelTemplateResolver;
use Prosopo\Views\PrivateClasses\Template\TemplateRendererWithModelsRender;
use Prosopo\Views\View\ViewNamespaceConfig;
use Prosopo\Views\View\ViewNamespaceModules;
@@ -71,27 +71,27 @@ public function __construct(
new ObjectPropertyWriter() :
$objectPropertyWriter;
- $modelNamespaceProvider = $modules->getModelNamespaceProvider();
+ $modelNamespaceProvider = $modules->getModelNamespaceResolver();
$modelNamespaceProvider = null === $modelNamespaceProvider ?
- new ModelNamespaceProvider(new ObjectClassReader()) :
+ new ModelNamespaceResolver(new ObjectClassReader()) :
$modelNamespaceProvider;
- $modelNameProvider = $modules->getModelNameProvider();
+ $modelNameProvider = $modules->getModelNameResolver();
$modelNameProvider = null === $modelNameProvider ?
- new ModelNameProvider(new ObjectClassReader()) :
+ new ModelNameResolver(new ObjectClassReader()) :
$modelNameProvider;
- $templateProvider = $modules->getModelTemplateProvider();
- $templateProvider = null === $templateProvider ?
- new FileModelTemplateProvider(
+ $modelTemplateResolver = $modules->getModelTemplateResolver();
+ $modelTemplateResolver = null === $modelTemplateResolver ?
+ new FileModelTemplateResolver(
$namespace,
$config->getTemplatesRootPath(),
$config->getTemplateFileExtension(),
- $config->isFileBasedTemplate(),
+ $config->fileBasedTemplates(),
$modelNamespaceProvider,
$modelNameProvider
) :
- $templateProvider;
+ $modelTemplateResolver;
$propertyValueProvider = $modules->getPropertyValueProvider();
$propertyValueProvider = null === $propertyValueProvider ?
@@ -112,13 +112,25 @@ public function __construct(
// Without null check - templateRenderer is a mandatory module.
$templateRenderer = $modules->getTemplateRenderer();
- $templateRenderer = new TemplateRendererWithModelsRender($templateRenderer, $modelRendererWithNamespace);
+ $templateRendererWithModelsRender = new TemplateRendererWithModelsRender(
+ $templateRenderer,
+ $modelRendererWithNamespace
+ );
+
+ if (true === $config->modelsAsStringsInTemplates()) {
+ $templateRenderer = $templateRendererWithModelsRender;
+ }
- //// 2. Real Factory and Renderer creation (used in the Views class):
+ //// 2. Real Factory and Renderer creation (used in the ViewsManager class):
$realModelFactory = $modules->getModelFactory();
$realModelFactory = null === $realModelFactory ?
- new ModelFactory($objectReader, $propertyValueProvider) :
+ new ModelFactory(
+ $objectReader,
+ $propertyValueProvider,
+ $modelTemplateResolver,
+ $templateRendererWithModelsRender
+ ) :
$realModelFactory;
$realModelFactory = new ModelFactoryWithDefaultsManagement(
@@ -133,7 +145,7 @@ public function __construct(
new ModelRenderer(
$templateRenderer,
$modelFactoryWithNamespaces,
- $templateProvider
+ $modelTemplateResolver
) :
$realModelRenderer;
@@ -148,12 +160,12 @@ public function __construct(
$modules->setEventDispatcher($eventDispatcher)
->setObjectReader($objectReader)
->setObjectPropertyWriter($objectPropertyWriter)
- ->setModelTemplateProvider($templateProvider)
+ ->setModelTemplateResolver($modelTemplateResolver)
->setPropertyValueProvider($propertyValueProvider)
->setModelFactory($realModelFactory)
->setModelRenderer($realModelRenderer)
- ->setModelNamespaceProvider($modelNamespaceProvider)
- ->setModelNameProvider($modelNameProvider);
+ ->setModelNamespaceResolver($modelNamespaceProvider)
+ ->setModelNameResolver($modelNameProvider);
$this->modules = $modules;
}
diff --git a/private-classes/View/ViewNamespaceModulesContainer.php b/private-classes/View/ViewNamespaceModulesContainer.php
index 164efc8..bb2ecd7 100644
--- a/private-classes/View/ViewNamespaceModulesContainer.php
+++ b/private-classes/View/ViewNamespaceModulesContainer.php
@@ -19,7 +19,7 @@ public function __construct()
$this->viewNamespaceModules = [];
}
- public function addNamespaceModules(
+ public function registerNamespaceModules(
string $namespace,
ViewNamespaceModules $viewNamespaceModules
): void {
@@ -32,7 +32,7 @@ public function addNamespaceModules(
});
}
- public function getNamespaceModulesByModelNamespace(string $modelNamespace): ?ViewNamespaceModules
+ public function resolveNamespaceModules(string $modelNamespace): ?ViewNamespaceModules
{
$matchedNamespaces = array_filter($this->viewNamespaceModules, function (
ViewNamespaceModules $viewNamespaceModules,
diff --git a/src/TemplateModel.php b/src/BaseTemplateModel.php
similarity index 67%
rename from src/TemplateModel.php
rename to src/BaseTemplateModel.php
index 1dc2cdc..f493d96 100644
--- a/src/TemplateModel.php
+++ b/src/BaseTemplateModel.php
@@ -8,11 +8,15 @@
use Prosopo\Views\Interfaces\Model\TemplateModelWithDefaultsInterface;
use Prosopo\Views\Interfaces\Object\ObjectReaderInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
+use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
-abstract class TemplateModel implements TemplateModelInterface, TemplateModelWithDefaultsInterface
+abstract class BaseTemplateModel implements TemplateModelInterface, TemplateModelWithDefaultsInterface
{
private ObjectReaderInterface $objectReader;
private PropertyValueProviderInterface $propertyValueProviderForDefaults;
+ private ModelTemplateResolverInterface $modelTemplateResolver;
+ private TemplateRendererInterface $templateRenderer;
/**
* The constructor is marked as final to prevent accidental argument overrides.
@@ -37,20 +41,24 @@ abstract class TemplateModel implements TemplateModelInterface, TemplateModelWit
*/
final public function __construct(
ObjectReaderInterface $objectPropertyReader,
- PropertyValueProviderInterface $propertyValueProviderForDefaults
+ PropertyValueProviderInterface $propertyValueProviderForDefaults,
+ ModelTemplateResolverInterface $modelTemplateResolver,
+ TemplateRendererInterface $templateRenderer
) {
$this->objectReader = $objectPropertyReader;
$this->propertyValueProviderForDefaults = $propertyValueProviderForDefaults;
+ $this->modelTemplateResolver = $modelTemplateResolver;
+ $this->templateRenderer = $templateRenderer;
$this->setCustomDefaults();
}
public function getTemplateArguments(): array
{
- return $this->objectReader->getObjectVariables($this);
+ return $this->objectReader->extractObjectVariables($this);
}
- public function getDefaultsPropertyValueProvider(): PropertyValueProviderInterface
+ public function getDefaultPropertyValueProvider(): PropertyValueProviderInterface
{
return $this->propertyValueProviderForDefaults;
}
@@ -58,4 +66,12 @@ public function getDefaultsPropertyValueProvider(): PropertyValueProviderInterfa
protected function setCustomDefaults(): void
{
}
+
+ public function __toString()
+ {
+ $template = $this->modelTemplateResolver->resolveModelTemplate($this);
+ $arguments = $this->getTemplateArguments();
+
+ return $this->templateRenderer->renderTemplate($template, $arguments);
+ }
}
diff --git a/src/Interfaces/CodeExecutorInterface.php b/src/Interfaces/CodeRunnerInterface.php
similarity index 55%
rename from src/Interfaces/CodeExecutorInterface.php
rename to src/Interfaces/CodeRunnerInterface.php
index c52ff3c..2c5b31f 100644
--- a/src/Interfaces/CodeExecutorInterface.php
+++ b/src/Interfaces/CodeRunnerInterface.php
@@ -4,10 +4,10 @@
namespace Prosopo\Views\Interfaces;
-interface CodeExecutorInterface
+interface CodeRunnerInterface
{
/**
* @param array $arguments
*/
- public function executeCode(string $code, array $arguments = []): void;
+ public function runCode(string $code, array $arguments = []): void;
}
diff --git a/src/Interfaces/EventDispatcherInterface.php b/src/Interfaces/EventDispatcherInterface.php
index 7d5377b..5865cdb 100644
--- a/src/Interfaces/EventDispatcherInterface.php
+++ b/src/Interfaces/EventDispatcherInterface.php
@@ -24,10 +24,10 @@ public function removeEventListener(string $eventName, callable $eventListener):
/**
* @param array $eventDetails
*/
- public function attachEventDetails(string $eventName, array $eventDetails): void;
+ public function registerEventDetails(string $eventName, array $eventDetails): void;
/**
* @param array $eventDetails
*/
- public function detachEventDetails(string $eventName, array $eventDetails): void;
+ public function unregisterEventDetails(string $eventName, array $eventDetails): void;
}
diff --git a/src/Interfaces/Model/ModelFactoryInterface.php b/src/Interfaces/Model/ModelFactoryInterface.php
index 268710f..10a196c 100644
--- a/src/Interfaces/Model/ModelFactoryInterface.php
+++ b/src/Interfaces/Model/ModelFactoryInterface.php
@@ -17,5 +17,5 @@ interface ModelFactoryInterface
*
* @throws Exception
*/
- public function makeModel(string $modelClass);
+ public function createModel(string $modelClass);
}
diff --git a/src/Interfaces/Model/ModelNameProviderInterface.php b/src/Interfaces/Model/ModelNameProviderInterface.php
deleted file mode 100644
index 658934c..0000000
--- a/src/Interfaces/Model/ModelNameProviderInterface.php
+++ /dev/null
@@ -1,10 +0,0 @@
- $modelOrClass
*/
- public function getModelNamespace($modelOrClass): string;
+ public function resolveModelNamespace($modelOrClass): string;
}
diff --git a/src/Interfaces/Model/ModelRendererInterface.php b/src/Interfaces/Model/ModelRendererInterface.php
index 961f9d5..ac3e2b3 100644
--- a/src/Interfaces/Model/ModelRendererInterface.php
+++ b/src/Interfaces/Model/ModelRendererInterface.php
@@ -13,9 +13,9 @@ interface ModelRendererInterface
* @template T of TemplateModelInterface
*
* @param T|class-string $modelOrClass
- * @param Closure(T):void|null $setupCallback
+ * @param Closure(T):void|null $setupModelCallback
*
* @throws Exception
*/
- public function renderModel($modelOrClass, Closure $setupCallback = null, bool $doPrint = false): string;
+ public function renderModel($modelOrClass, Closure $setupModelCallback = null): string;
}
diff --git a/src/Interfaces/Model/TemplateModelWithDefaultsInterface.php b/src/Interfaces/Model/TemplateModelWithDefaultsInterface.php
index 3bd6f6e..c7cd168 100644
--- a/src/Interfaces/Model/TemplateModelWithDefaultsInterface.php
+++ b/src/Interfaces/Model/TemplateModelWithDefaultsInterface.php
@@ -8,5 +8,5 @@
interface TemplateModelWithDefaultsInterface
{
- public function getDefaultsPropertyValueProvider(): PropertyValueProviderInterface;
+ public function getDefaultPropertyValueProvider(): PropertyValueProviderInterface;
}
diff --git a/src/Interfaces/Object/ObjectPropertyWriterInterface.php b/src/Interfaces/Object/ObjectPropertyWriterInterface.php
index ff5a1e8..948fd7e 100644
--- a/src/Interfaces/Object/ObjectPropertyWriterInterface.php
+++ b/src/Interfaces/Object/ObjectPropertyWriterInterface.php
@@ -6,8 +6,5 @@
interface ObjectPropertyWriterInterface
{
- public function setObjectPropertyValues(
- object $instance,
- PropertyValueProviderInterface $propertyValueProvider
- ): void;
+ public function assignPropertyValues(object $instance, PropertyValueProviderInterface $propertyValueProvider): void;
}
diff --git a/src/Interfaces/Object/ObjectReaderInterface.php b/src/Interfaces/Object/ObjectReaderInterface.php
index 0747ab2..a479e40 100644
--- a/src/Interfaces/Object/ObjectReaderInterface.php
+++ b/src/Interfaces/Object/ObjectReaderInterface.php
@@ -9,5 +9,5 @@ interface ObjectReaderInterface
/**
* @return array name => value (or callback)
*/
- public function getObjectVariables(object $instance): array;
+ public function extractObjectVariables(object $instance): array;
}
diff --git a/src/Interfaces/Template/ModelTemplateProviderInterface.php b/src/Interfaces/Template/ModelTemplateResolverInterface.php
similarity index 53%
rename from src/Interfaces/Template/ModelTemplateProviderInterface.php
rename to src/Interfaces/Template/ModelTemplateResolverInterface.php
index d3974f4..c6a0558 100644
--- a/src/Interfaces/Template/ModelTemplateProviderInterface.php
+++ b/src/Interfaces/Template/ModelTemplateResolverInterface.php
@@ -6,7 +6,7 @@
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-interface ModelTemplateProviderInterface
+interface ModelTemplateResolverInterface
{
- public function getModelTemplate(TemplateModelInterface $model): string;
+ public function resolveModelTemplate(TemplateModelInterface $model): string;
}
diff --git a/src/Interfaces/Template/TemplateRendererInterface.php b/src/Interfaces/Template/TemplateRendererInterface.php
index 9520467..29de7ca 100644
--- a/src/Interfaces/Template/TemplateRendererInterface.php
+++ b/src/Interfaces/Template/TemplateRendererInterface.php
@@ -9,5 +9,5 @@ interface TemplateRendererInterface
/**
* @param array $variables
*/
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string;
+ public function renderTemplate(string $template, array $variables = []): string;
}
diff --git a/src/Interfaces/View/ViewNamespaceManagerInterface.php b/src/Interfaces/View/ViewNamespaceManagerInterface.php
index f0ea583..cb6c1ce 100644
--- a/src/Interfaces/View/ViewNamespaceManagerInterface.php
+++ b/src/Interfaces/View/ViewNamespaceManagerInterface.php
@@ -9,5 +9,5 @@
interface ViewNamespaceManagerInterface
{
- public function addNamespace(string $namespace, ViewNamespaceConfig $config): ViewNamespaceModules;
+ public function registerNamespace(string $namespace, ViewNamespaceConfig $config): ViewNamespaceModules;
}
diff --git a/src/Interfaces/View/ViewNamespaceModulesContainerInterface.php b/src/Interfaces/View/ViewNamespaceModulesContainerInterface.php
index 3f207a6..8a07407 100644
--- a/src/Interfaces/View/ViewNamespaceModulesContainerInterface.php
+++ b/src/Interfaces/View/ViewNamespaceModulesContainerInterface.php
@@ -8,7 +8,7 @@
interface ViewNamespaceModulesContainerInterface
{
- public function addNamespaceModules(string $namespace, ViewNamespaceModules $viewNamespaceModules): void;
+ public function registerNamespaceModules(string $namespace, ViewNamespaceModules $viewNamespaceModules): void;
- public function getNamespaceModulesByModelNamespace(string $modelNamespace): ?ViewNamespaceModules;
+ public function resolveNamespaceModules(string $modelNamespace): ?ViewNamespaceModules;
}
diff --git a/src/View/ViewNamespaceConfig.php b/src/View/ViewNamespaceConfig.php
index b4a24e0..24fb668 100644
--- a/src/View/ViewNamespaceConfig.php
+++ b/src/View/ViewNamespaceConfig.php
@@ -14,7 +14,8 @@ final class ViewNamespaceConfig
{
private string $templatesRootPath;
private string $templateFileExtension;
- private bool $isFileBasedTemplate;
+ private bool $fileBasedTemplates;
+ private bool $modelsAsStringsInTemplates;
/**
* @var callable(array $eventDetails): void|null
*/
@@ -31,7 +32,8 @@ public function __construct(TemplateRendererInterface $templateRenderer)
{
$this->templatesRootPath = '';
$this->templateFileExtension = '';
- $this->isFileBasedTemplate = true;
+ $this->fileBasedTemplates = true;
+ $this->modelsAsStringsInTemplates = false;
$this->templateErrorHandler = null;
$this->defaultPropertyValues = array(
'array' => array(),
@@ -57,9 +59,14 @@ public function getTemplateFileExtension(): string
return $this->templateFileExtension;
}
- public function isFileBasedTemplate(): bool
+ public function fileBasedTemplates(): bool
{
- return $this->isFileBasedTemplate;
+ return $this->fileBasedTemplates;
+ }
+
+ public function modelsAsStringsInTemplates(): bool
+ {
+ return $this->modelsAsStringsInTemplates;
}
/**
@@ -104,9 +111,16 @@ public function setTemplateFileExtension(string $templateFileExtension): self
return $this;
}
- public function setIsFileBasedTemplate(bool $isFileBasedTemplate): self
+ public function setFileBasedTemplates(bool $fileBasedTemplates): self
+ {
+ $this->fileBasedTemplates = $fileBasedTemplates;
+
+ return $this;
+ }
+
+ public function setModelsAsStringsInTemplates(bool $modelsAsStringsInTemplates): self
{
- $this->isFileBasedTemplate = $isFileBasedTemplate;
+ $this->modelsAsStringsInTemplates = $modelsAsStringsInTemplates;
return $this;
}
diff --git a/src/View/ViewNamespaceModules.php b/src/View/ViewNamespaceModules.php
index b4c6aa4..a161a35 100644
--- a/src/View/ViewNamespaceModules.php
+++ b/src/View/ViewNamespaceModules.php
@@ -6,13 +6,13 @@
use Prosopo\Views\Interfaces\EventDispatcherInterface;
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
-use Prosopo\Views\Interfaces\Model\ModelNameProviderInterface;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNameResolverInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\Interfaces\Model\ModelRendererInterface;
use Prosopo\Views\Interfaces\Object\ObjectPropertyWriterInterface;
use Prosopo\Views\Interfaces\Object\ObjectReaderInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
-use Prosopo\Views\Interfaces\Template\ModelTemplateProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
/**
@@ -28,27 +28,27 @@ final class ViewNamespaceModules
//// Custom modules: define them only when you need to override the default behavior:
private ?ModelFactoryInterface $modelFactory;
- private ?ModelTemplateProviderInterface $modelTemplateProvider;
+ private ?ModelTemplateResolverInterface $modelTemplateResolver;
private ?ObjectReaderInterface $objectReader;
private ?ObjectPropertyWriterInterface $objectPropertyWriter;
private ?PropertyValueProviderInterface $propertyValueProvider;
private ?ModelRendererInterface $modelRenderer;
private ?EventDispatcherInterface $eventDispatcher;
- private ?ModelNameProviderInterface $modelNameProvider;
- private ?ModelNamespaceProviderInterface $modelNamespaceProvider;
+ private ?ModelNameResolverInterface $modelNameResolver;
+ private ?ModelNamespaceResolverInterface $modelNamespaceResolver;
public function __construct(TemplateRendererInterface $templateRenderer)
{
$this->templateRenderer = $templateRenderer;
$this->modelFactory = null;
- $this->modelTemplateProvider = null;
+ $this->modelTemplateResolver = null;
$this->objectReader = null;
$this->objectPropertyWriter = null;
$this->propertyValueProvider = null;
$this->modelRenderer = null;
$this->eventDispatcher = null;
- $this->modelNameProvider = null;
- $this->modelNamespaceProvider = null;
+ $this->modelNameResolver = null;
+ $this->modelNamespaceResolver = null;
}
//// Getters.
@@ -63,9 +63,9 @@ public function getModelFactory(): ?ModelFactoryInterface
return $this->modelFactory;
}
- public function getModelTemplateProvider(): ?ModelTemplateProviderInterface
+ public function getModelTemplateResolver(): ?ModelTemplateResolverInterface
{
- return $this->modelTemplateProvider;
+ return $this->modelTemplateResolver;
}
public function getObjectReader(): ?ObjectReaderInterface
@@ -93,14 +93,14 @@ public function getEventDispatcher(): ?EventDispatcherInterface
return $this->eventDispatcher;
}
- public function getModelNameProvider(): ?ModelNameProviderInterface
+ public function getModelNameResolver(): ?ModelNameResolverInterface
{
- return $this->modelNameProvider;
+ return $this->modelNameResolver;
}
- public function getModelNamespaceProvider(): ?ModelNamespaceProviderInterface
+ public function getModelNamespaceResolver(): ?ModelNamespaceResolverInterface
{
- return $this->modelNamespaceProvider;
+ return $this->modelNamespaceResolver;
}
//// Setters.
@@ -119,9 +119,9 @@ public function setModelFactory(?ModelFactoryInterface $viewFactory): self
return $this;
}
- public function setModelTemplateProvider(?ModelTemplateProviderInterface $modelTemplateProvider): self
+ public function setModelTemplateResolver(?ModelTemplateResolverInterface $modelTemplateResolver): self
{
- $this->modelTemplateProvider = $modelTemplateProvider;
+ $this->modelTemplateResolver = $modelTemplateResolver;
return $this;
}
@@ -161,16 +161,16 @@ public function setEventDispatcher(?EventDispatcherInterface $eventDispatcher):
return $this;
}
- public function setModelNameProvider(?ModelNameProviderInterface $modelNameProvider): self
+ public function setModelNameResolver(?ModelNameResolverInterface $modelNameResolver): self
{
- $this->modelNameProvider = $modelNameProvider;
+ $this->modelNameResolver = $modelNameResolver;
return $this;
}
- public function setModelNamespaceProvider(?ModelNamespaceProviderInterface $modelNamespaceProvider): self
+ public function setModelNamespaceResolver(?ModelNamespaceResolverInterface $modelNamespaceResolver): self
{
- $this->modelNamespaceProvider = $modelNamespaceProvider;
+ $this->modelNamespaceResolver = $modelNamespaceResolver;
return $this;
}
diff --git a/src/View/ViewTemplateRenderer.php b/src/View/ViewTemplateRenderer.php
index 23231a0..454f138 100644
--- a/src/View/ViewTemplateRenderer.php
+++ b/src/View/ViewTemplateRenderer.php
@@ -6,10 +6,10 @@
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
use Prosopo\Views\PrivateClasses\Blade\BladeCompiler;
-use Prosopo\Views\PrivateClasses\CodeExecutor\CodeExecutorWithErrorHandler;
-use Prosopo\Views\PrivateClasses\CodeExecutor\CodeExecutorWithGlobalArguments;
-use Prosopo\Views\PrivateClasses\CodeExecutor\CodeExecutorWithTemplateCompilation;
-use Prosopo\Views\PrivateClasses\CodeExecutor\PhpCodeExecutor;
+use Prosopo\Views\PrivateClasses\CodeRunner\CodeRunnerWithErrorHandler;
+use Prosopo\Views\PrivateClasses\CodeRunner\CodeRunnerWithGlobalArguments;
+use Prosopo\Views\PrivateClasses\CodeRunner\CodeRunnerWithTemplateCompilation;
+use Prosopo\Views\PrivateClasses\CodeRunner\PhpCodeRunner;
use Prosopo\Views\PrivateClasses\EventDispatcher;
use Prosopo\Views\PrivateClasses\Template\TemplateRenderer;
use Prosopo\Views\PrivateClasses\Template\TemplateRendererWithCustomEscape;
@@ -53,19 +53,19 @@ public function __construct(?ViewTemplateRendererConfig $config = null)
$codeExecutor = $modules->getCodeExecutor();
$codeExecutor = null === $codeExecutor ?
- new PhpCodeExecutor() :
+ new PhpCodeRunner() :
$codeExecutor;
- $codeExecutor = new CodeExecutorWithErrorHandler($codeExecutor, $eventDispatcher, $errorEventName);
- $codeExecutor = new CodeExecutorWithGlobalArguments($codeExecutor, $config->getGlobalVariables());
- $codeExecutor = new CodeExecutorWithTemplateCompilation($codeExecutor, $templateCompiler);
+ $codeExecutor = new CodeRunnerWithErrorHandler($codeExecutor, $eventDispatcher, $errorEventName);
+ $codeExecutor = new CodeRunnerWithGlobalArguments($codeExecutor, $config->getGlobalVariables());
+ $codeExecutor = new CodeRunnerWithTemplateCompilation($codeExecutor, $templateCompiler);
$templateRenderer = $modules->getTemplateRenderer();
$templateRenderer = null === $templateRenderer ?
new TemplateRenderer($codeExecutor) :
$templateRenderer;
- if (true === $config->isFileBasedTemplate()) {
+ if (true === $config->fileBasedTemplates()) {
$templateRenderer = new TemplateRendererWithFileTemplate($templateRenderer);
}
@@ -85,9 +85,9 @@ public function __construct(?ViewTemplateRendererConfig $config = null)
$this->templateRenderer = $templateRenderer;
}
- public function renderTemplate(string $template, array $variables = [], bool $doPrint = false): string
+ public function renderTemplate(string $template, array $variables = []): string
{
- return $this->templateRenderer->renderTemplate($template, $variables, $doPrint);
+ return $this->templateRenderer->renderTemplate($template, $variables);
}
public function getModules(): ViewTemplateRendererModules
diff --git a/src/View/ViewTemplateRendererConfig.php b/src/View/ViewTemplateRendererConfig.php
index 2df00e7..5bef2b2 100644
--- a/src/View/ViewTemplateRendererConfig.php
+++ b/src/View/ViewTemplateRendererConfig.php
@@ -10,7 +10,7 @@
*/
final class ViewTemplateRendererConfig
{
- private bool $isFileBasedTemplate;
+ private bool $fileBasedTemplates;
private string $escapeVariableName;
private string $templateErrorEventName;
/**
@@ -35,7 +35,7 @@ final class ViewTemplateRendererConfig
public function __construct()
{
- $this->isFileBasedTemplate = true;
+ $this->fileBasedTemplates = true;
$this->escapeVariableName = 'escape';
$this->templateErrorEventName = 'template_error';
$this->globalVariables = [];
@@ -49,9 +49,9 @@ public function __construct()
//// Getters:
- public function isFileBasedTemplate(): bool
+ public function fileBasedTemplates(): bool
{
- return $this->isFileBasedTemplate;
+ return $this->fileBasedTemplates;
}
/**
@@ -103,9 +103,9 @@ public function getModules(): ViewTemplateRendererModules
//// Setters:
- public function setIsFileBasedTemplate(bool $isFileBasedTemplate): self
+ public function setFileBasedTemplates(bool $fileBasedTemplates): self
{
- $this->isFileBasedTemplate = $isFileBasedTemplate;
+ $this->fileBasedTemplates = $fileBasedTemplates;
return $this;
}
diff --git a/src/View/ViewTemplateRendererModules.php b/src/View/ViewTemplateRendererModules.php
index 7a82cb7..583555f 100644
--- a/src/View/ViewTemplateRendererModules.php
+++ b/src/View/ViewTemplateRendererModules.php
@@ -4,7 +4,7 @@
namespace Prosopo\Views\View;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\EventDispatcherInterface;
use Prosopo\Views\Interfaces\Template\TemplateCompilerInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
@@ -20,7 +20,7 @@ final class ViewTemplateRendererModules
private ?TemplateRendererInterface $templateRenderer;
private ?EventDispatcherInterface $eventDispatcher;
private ?TemplateCompilerInterface $templateCompiler;
- private ?CodeExecutorInterface $phpCodeExecutor;
+ private ?CodeRunnerInterface $phpCodeExecutor;
public function __construct()
{
@@ -47,7 +47,7 @@ public function getTemplateCompiler(): ?TemplateCompilerInterface
return $this->templateCompiler;
}
- public function getCodeExecutor(): ?CodeExecutorInterface
+ public function getCodeExecutor(): ?CodeRunnerInterface
{
return $this->phpCodeExecutor;
}
@@ -75,7 +75,7 @@ public function setTemplateCompiler(?TemplateCompilerInterface $templateCompiler
return $this;
}
- public function setCodeExecutor(?CodeExecutorInterface $codeExecutor): self
+ public function setCodeExecutor(?CodeRunnerInterface $codeExecutor): self
{
$this->phpCodeExecutor = $codeExecutor;
diff --git a/src/Views.php b/src/ViewsManager.php
similarity index 76%
rename from src/Views.php
rename to src/ViewsManager.php
index bb8d698..eab1a7e 100644
--- a/src/Views.php
+++ b/src/ViewsManager.php
@@ -7,12 +7,12 @@
use Closure;
use Exception;
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\Interfaces\Model\ModelRendererInterface;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
use Prosopo\Views\Interfaces\View\ViewNamespaceManagerInterface;
use Prosopo\Views\Interfaces\View\ViewNamespaceModulesContainerInterface;
-use Prosopo\Views\PrivateClasses\Model\ModelNamespaceProvider;
+use Prosopo\Views\PrivateClasses\Model\ModelNamespaceResolver;
use Prosopo\Views\PrivateClasses\Object\ObjectClassReader;
use Prosopo\Views\PrivateClasses\View\ViewNamespace;
use Prosopo\Views\PrivateClasses\View\ViewNamespaceModulesContainer;
@@ -23,22 +23,22 @@
* This class is marked as a final to prevent anyone from extending it.
* We reserve the right to change its private and protected methods, properties and introduce new public ones.
*/
-final class Views implements ViewNamespaceManagerInterface, ModelFactoryInterface, ModelRendererInterface
+final class ViewsManager implements ViewNamespaceManagerInterface, ModelFactoryInterface, ModelRendererInterface
{
private string $namespaceNotFoundErrorMessage;
private string $wrongModelErrorMessage;
- private ModelNamespaceProviderInterface $modelNamespaceProvider;
+ private ModelNamespaceResolverInterface $modelNamespaceProvider;
private ViewNamespaceModulesContainerInterface $namespaceModulesContainer;
- public function __construct(?ViewsConfig $config = null)
+ public function __construct(?ViewsManagerConfig $config = null)
{
$config = null === $config ?
- new ViewsConfig() :
+ new ViewsManagerConfig() :
$config;
$modelNamespaceProvider = $config->getModelNamespaceProvider();
$this->modelNamespaceProvider = null === $modelNamespaceProvider ?
- new ModelNamespaceProvider(new ObjectClassReader()) :
+ new ModelNamespaceResolver(new ObjectClassReader()) :
$modelNamespaceProvider;
$namespaceModulesContainer = $config->getNamespaceModulesContainer();
@@ -50,25 +50,25 @@ public function __construct(?ViewsConfig $config = null)
$this->wrongModelErrorMessage = $config->getWrongModelErrorMessage();
}
- public function addNamespace(string $namespace, ViewNamespaceConfig $config): ViewNamespaceModules
+ public function registerNamespace(string $namespace, ViewNamespaceConfig $config): ViewNamespaceModules
{
$viewNamespace = $this->makeViewNamespace($namespace, $config);
$viewNamespaceModules = $viewNamespace->getModules();
- $this->namespaceModulesContainer->addNamespaceModules($namespace, $viewNamespaceModules);
+ $this->namespaceModulesContainer->registerNamespaceModules($namespace, $viewNamespaceModules);
return $viewNamespaceModules;
}
- public function makeModel(string $modelClass)
+ public function createModel(string $modelClass)
{
if (false === $this->isModel($modelClass)) {
throw $this->makeWrongModelException($modelClass);
}
- $modelNamespace = $this->modelNamespaceProvider->getModelNamespace($modelClass);
- $namespaceModules = $this->namespaceModulesContainer->getNamespaceModulesByModelNamespace($modelNamespace);
+ $modelNamespace = $this->modelNamespaceProvider->resolveModelNamespace($modelClass);
+ $namespaceModules = $this->namespaceModulesContainer->resolveNamespaceModules($modelNamespace);
if (null === $namespaceModules) {
throw $this->makeNamespaceNotResolvedException($modelNamespace);
@@ -80,17 +80,17 @@ public function makeModel(string $modelClass)
throw $this->makeNamespaceNotResolvedException($modelNamespace);
}
- return $modelFactory->makeModel($modelClass);
+ return $modelFactory->createModel($modelClass);
}
- public function renderModel($modelOrClass, Closure $setupCallback = null, bool $doPrint = false): string
+ public function renderModel($modelOrClass, Closure $setupModelCallback = null): string
{
if (false === $this->isModel($modelOrClass)) {
throw $this->makeWrongModelException($modelOrClass);
}
- $modelNamespace = $this->modelNamespaceProvider->getModelNamespace($modelOrClass);
- $namespaceModules = $this->namespaceModulesContainer->getNamespaceModulesByModelNamespace($modelNamespace);
+ $modelNamespace = $this->modelNamespaceProvider->resolveModelNamespace($modelOrClass);
+ $namespaceModules = $this->namespaceModulesContainer->resolveNamespaceModules($modelNamespace);
if (null === $namespaceModules) {
throw $this->makeNamespaceNotResolvedException($modelNamespace);
@@ -102,7 +102,7 @@ public function renderModel($modelOrClass, Closure $setupCallback = null, bool $
throw $this->makeNamespaceNotResolvedException($modelNamespace);
}
- return $modelRenderer->renderModel($modelOrClass, $setupCallback, $doPrint);
+ return $modelRenderer->renderModel($modelOrClass, $setupModelCallback);
}
protected function makeViewNamespace(string $namespace, ViewNamespaceConfig $config): ViewNamespace
diff --git a/src/ViewsConfig.php b/src/ViewsManagerConfig.php
similarity index 88%
rename from src/ViewsConfig.php
rename to src/ViewsManagerConfig.php
index d49c557..d8e7bed 100644
--- a/src/ViewsConfig.php
+++ b/src/ViewsManagerConfig.php
@@ -4,18 +4,18 @@
namespace Prosopo\Views;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\Interfaces\View\ViewNamespaceModulesContainerInterface;
/**
* This class is marked as a final to prevent anyone from extending it.
* We reserve the right to change its private and protected methods, properties and introduce new public ones.
*/
-final class ViewsConfig
+final class ViewsManagerConfig
{
private string $namespaceNotFoundErrorMessage;
private string $wrongModelErrorMessage;
- private ?ModelNamespaceProviderInterface $modelNamespaceProvider;
+ private ?ModelNamespaceResolverInterface $modelNamespaceProvider;
private ?ViewNamespaceModulesContainerInterface $namespaceModulesContainer;
public function __construct()
@@ -38,7 +38,7 @@ public function getWrongModelErrorMessage(): string
return $this->wrongModelErrorMessage;
}
- public function getModelNamespaceProvider(): ?ModelNamespaceProviderInterface
+ public function getModelNamespaceProvider(): ?ModelNamespaceResolverInterface
{
return $this->modelNamespaceProvider;
}
@@ -64,7 +64,7 @@ public function setWrongModelErrorMessage(string $wrongModelErrorMessage): self
return $this;
}
- public function setModelNamespaceProvider(?ModelNamespaceProviderInterface $modelNamespaceProvider): self
+ public function setModelNamespaceProvider(?ModelNamespaceResolverInterface $modelNamespaceProvider): self
{
$this->modelNamespaceProvider = $modelNamespaceProvider;
diff --git a/tests/pest/Feature/BladeTemplateRendererTest.php b/tests/pest/Feature/BladeTemplateRendererTest.php
index 72df6cb..d38bb84 100644
--- a/tests/pest/Feature/BladeTemplateRendererTest.php
+++ b/tests/pest/Feature/BladeTemplateRendererTest.php
@@ -32,7 +32,7 @@ public function testRendersStringWhenFileBasedFlagIsDisabled(): void
{
// given
$bladeRendererConfig = new ViewTemplateRendererConfig();
- $bladeRendererConfig->setIsFileBasedTemplate(false);
+ $bladeRendererConfig->setFileBasedTemplates(false);
$bladeRenderer = new ViewTemplateRenderer($bladeRendererConfig);
// when
@@ -48,7 +48,7 @@ public function testTemplateErrorHandlerIsCalledOnError(): void
{
// given
$bladeRendererConfig = new ViewTemplateRendererConfig();
- $bladeRendererConfig->setIsFileBasedTemplate(false);
+ $bladeRendererConfig->setFileBasedTemplates(false);
$receivedEventDetails = null;
$bladeRendererConfig->setTemplateErrorHandler(function (array $eventDetails) use (&$receivedEventDetails) {
$receivedEventDetails = $eventDetails;
@@ -73,7 +73,7 @@ public function testTemplateErrorHandlerNotCalledWithoutReason(): void
{
// given
$bladeRendererConfig = new ViewTemplateRendererConfig();
- $bladeRendererConfig->setIsFileBasedTemplate(false);
+ $bladeRendererConfig->setFileBasedTemplates(false);
$receivedEventDetails = null;
$bladeRendererConfig->setTemplateErrorHandler(function (array $eventDetails) use (&$receivedEventDetails) {
$receivedEventDetails = $eventDetails;
diff --git a/tests/pest/Feature/ViewsTest.php b/tests/pest/Feature/ViewsManagerTest.php
similarity index 73%
rename from tests/pest/Feature/ViewsTest.php
rename to tests/pest/Feature/ViewsManagerTest.php
index 4742d10..6f78632 100644
--- a/tests/pest/Feature/ViewsTest.php
+++ b/tests/pest/Feature/ViewsManagerTest.php
@@ -7,15 +7,15 @@
use org\bovigo\vfs\vfsStream;
use ParseError;
use PHPUnit\Framework\TestCase;
+use Prosopo\Views\BaseTemplateModel;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
use Prosopo\Views\Interfaces\Template\TemplateCompilerInterface;
-use Prosopo\Views\TemplateModel;
use Prosopo\Views\View\ViewNamespaceConfig;
use Prosopo\Views\View\ViewTemplateRenderer;
use Prosopo\Views\View\ViewTemplateRendererConfig;
-use Prosopo\Views\Views;
+use Prosopo\Views\ViewsManager;
-class ViewsTest extends TestCase
+class ViewsManagerTest extends TestCase
{
//// renderModel
@@ -40,10 +40,10 @@ public function testRenderModelThatImplementsInterface(): void
],
false
);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
$model = new $modelClass();
@@ -80,10 +80,10 @@ public function testRenderModelThatImplementInterfaceIgnoresPublicProperties():
false,
['data',]
);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
$model = new $modelClass();
@@ -100,7 +100,7 @@ public function testRenderModelThatExtendsBaseClass(): void
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
->setTemplatesRootPath(vfsStream::url('templates'))
->setTemplateFileExtension('.blade.php');
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -116,10 +116,10 @@ public function testRenderModelThatExtendsBaseClass(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
- $model = $views->makeModel($modelClass);
+ $model = $views->createModel($modelClass);
$model->message = 'Hello World!';
// then
@@ -134,7 +134,7 @@ public function testRenderCallsSetupCallback(): void
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
->setTemplatesRootPath(vfsStream::url('templates'))
->setTemplateFileExtension('.blade.php');
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -150,7 +150,7 @@ public function testRenderCallsSetupCallback(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
@@ -165,12 +165,12 @@ public function testRenderModelPassesStringToTemplateRendererWhenFileBasedModeIs
// given
vfsStream::setup('templates', null, ['first-model.blade.php' => '{{ $message }}']);
$bladeConfig = new ViewTemplateRendererConfig();
- $bladeConfig->setIsFileBasedTemplate(false);
+ $bladeConfig->setFileBasedTemplates(false);
$bladeRenderer = new ViewTemplateRenderer($bladeConfig);
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
->setTemplatesRootPath(vfsStream::url('templates'))
->setTemplateFileExtension('.blade.php')
- ->setIsFileBasedTemplate(false);
+ ->setFileBasedTemplates(false);
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
'FirstModel',
@@ -184,10 +184,10 @@ public function testRenderModelPassesStringToTemplateRendererWhenFileBasedModeIs
],
false
);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
$model = new $modelClass();
@@ -211,7 +211,7 @@ public function testRenderCallsTemplateErrorHandler(): void
$namespaceConfig
->getModules()
->setEventDispatcher($bladeRenderer->getModules()->getEventDispatcher());
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -227,7 +227,7 @@ public function testRenderCallsTemplateErrorHandler(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
$rendered = $views->renderModel($modelClass, (function ($model) {
$model->message = 'some data';
@@ -235,8 +235,8 @@ public function testRenderCallsTemplateErrorHandler(): void
// then
$this->assertSame('', $rendered);
- $this->assertSame(['viewClass','template','arguments','code','error',], array_keys($receivedEventDetails));
- $this->assertSame($modelClass, $receivedEventDetails['viewClass']);
+ $this->assertSame(['modelClass','template','arguments','code','error',], array_keys($receivedEventDetails));
+ $this->assertSame($modelClass, $receivedEventDetails['modelClass']);
$this->assertSame(vfsStream::url('templates/first-model.blade.php'), $receivedEventDetails['template']);
$this->assertSame('some data', $receivedEventDetails['arguments']['message']);
$this->assertSame('wrong template', $receivedEventDetails['code']);
@@ -258,7 +258,7 @@ public function testRenderNotCallTemplateErrorHandlerWithoutReason(): void
$namespaceConfig
->getModules()
->setEventDispatcher($bladeRenderer->getModules()->getEventDispatcher());
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -274,7 +274,7 @@ public function testRenderNotCallTemplateErrorHandlerWithoutReason(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
$rendered = $views->renderModel($modelClass, (function ($model) {
$model->message = 'some data';
@@ -311,10 +311,10 @@ public function testRenderSupportsInnerNamespaces(): void
false
);
$namespace = str_replace('\inner', '', $innerModelNamespace);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($namespace, $namespaceConfig);
+ $views->registerNamespace($namespace, $namespaceConfig);
$modelClass = $innerModelNamespace . '\\FirstModel';
$model = new $modelClass();
@@ -363,11 +363,11 @@ public function testRenderSupportsDifferentNamespaces(): void
],
true
);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($firstNamespace, $firstNamespaceConfig);
- $views->addNamespace($secondNamespace, $secondNamespaceConfig);
+ $views->registerNamespace($firstNamespace, $firstNamespaceConfig);
+ $views->registerNamespace($secondNamespace, $secondNamespaceConfig);
$firstModelClass = $firstNamespace . '\\FirstModel';
$firstModel = new $firstModelClass();
@@ -378,24 +378,72 @@ public function testRenderSupportsDifferentNamespaces(): void
$this->assertSame('Looks good!', $views->renderModel($secondModelClass));
}
- public function testRenderIncludesInnerModel(): void
+ public function testRenderSupportsCustomCompiler(): void
{
// given
vfsStream::setup('templates', null, [
- 'inner-model.blade.php' => 'inner!',
- 'top-model.blade.php' => 'Hey {!! $inner !!}',
+ 'pure.php' => '',
]);
- $bladeRenderer = new ViewTemplateRenderer();
- $namespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ $compilerStub = new class implements TemplateCompilerInterface{
+ public function compileTemplate(string $template): string
+ {
+ return $template;
+ }
+ };
+ $viewTemplateRendererConfig = new ViewTemplateRendererConfig();
+ $viewTemplateRendererConfig->getModules()
+ ->setTemplateCompiler($compilerStub);
+ $viewTemplateRenderer = new ViewTemplateRenderer($viewTemplateRendererConfig);
+ $views = new ViewsManager();
+ $viewNamespaceConfig = new ViewNamespaceConfig($viewTemplateRenderer);
+ $modelNamespace = $this->defineRealModelClass(
+ __METHOD__,
+ 'Pure',
+ [
+ [
+ 'name' => 'message',
+ 'visibility' => 'public',
+ ]
+ ],
+ false
+ );
+
+ // when
+ $viewNamespaceConfig
->setTemplatesRootPath(vfsStream::url('templates'))
+ ->setTemplateFileExtension('.php');
+
+ $views->registerNamespace($modelNamespace, $viewNamespaceConfig);
+
+ $modelClass = $modelNamespace . '\\Pure';
+ $model = new $modelClass();
+ $model->message = 'Hello World!';
+
+ // then
+ $this->assertSame('Hello World! and again: Hello World!', $views->renderModel($model));
+ }
+
+ public function testRenderPassesInnerModelsAsObjects(): void
+ {
+ // given
+ vfsStream::setup('top', null, [
+ 'folder1' => ['top-model.blade.php' => 'Hey {{ true === is_object($inner)? "inner object": "string" }}'],
+ 'folder2' => [ 'inner-model.blade.php' => 'inner!'],
+ ]);
+ $bladeRenderer = new ViewTemplateRenderer();
+ $firstNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ ->setTemplatesRootPath(vfsStream::url('top/folder1'))
->setTemplateFileExtension('.blade.php');
- $this->defineRealModelClass(
- __METHOD__,
+ $secondNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ ->setTemplatesRootPath(vfsStream::url('top/folder2'))
+ ->setTemplateFileExtension('.blade.php');
+ $secondNamespace = $this->defineRealModelClass(
+ __METHOD__ . '__second',
'InnerModel',
[],
false
);
- $modelNamespace = $this->defineRealModelClass(
+ $firstNamespace = $this->defineRealModelClass(
__METHOD__,
'TopModel',
[
@@ -406,66 +454,69 @@ public function testRenderIncludesInnerModel(): void
],
false
);
- $views = new Views();
+ $viewsManager = new ViewsManager();
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $viewsManager->registerNamespace($firstNamespace, $firstNamespaceConfig);
+ $viewsManager->registerNamespace($secondNamespace, $secondNamespaceConfig);
- $innerModelClass = $modelNamespace . '\\InnerModel';
- $topModelClass = $modelNamespace . '\\TopModel';
+ $innerModelClass = $secondNamespace . '\\InnerModel';
+ $topModelClass = $firstNamespace . '\\TopModel';
$topModel = new $topModelClass();
$topModel->inner = new $innerModelClass();
// then
- $this->assertSame('Hey inner!', $views->renderModel($topModel));
+ $this->assertSame('Hey inner object', $viewsManager->renderModel($topModel));
}
- public function testRenderSupportsCustomCompiler(): void
+ public function testRenderSupportsInnerModelPrintWhenModelExtendsTheBaseClass(): void
{
// given
- vfsStream::setup('templates', null, [
- 'pure.php' => '',
+ vfsStream::setup('top', null, [
+ 'folder1' => ['top-model.blade.php' => 'Hey {{ $inner }}'],
+ 'folder2' => [ 'inner-model.blade.php' => 'inner!'],
]);
- $compilerStub = new class implements TemplateCompilerInterface{
- public function compileTemplate(string $template): string
- {
- return $template;
- }
- };
- $viewTemplateRendererConfig = new ViewTemplateRendererConfig();
- $viewTemplateRendererConfig->getModules()
- ->setTemplateCompiler($compilerStub);
- $viewTemplateRenderer = new ViewTemplateRenderer($viewTemplateRendererConfig);
- $views = new Views();
- $viewNamespaceConfig = new ViewNamespaceConfig($viewTemplateRenderer);
- $modelNamespace = $this->defineRealModelClass(
+ $bladeRenderer = new ViewTemplateRenderer();
+ $firstNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ ->setTemplatesRootPath(vfsStream::url('top/folder1'))
+ ->setTemplateFileExtension('.blade.php');
+ $secondNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ ->setTemplatesRootPath(vfsStream::url('top/folder2'))
+ ->setTemplateFileExtension('.blade.php');
+ $secondNamespace = $this->defineRealModelClass(
+ __METHOD__ . '__second',
+ 'InnerModel',
+ [],
+ true
+ );
+ $innerModelClass = $secondNamespace . '\\InnerModel';
+ $firstNamespace = $this->defineRealModelClass(
__METHOD__,
- 'Pure',
+ 'TopModel',
[
[
- 'name' => 'message',
+ 'name' => 'inner',
+ 'type' => '\\' . $innerModelClass,
'visibility' => 'public',
]
],
- false
+ true
);
+ $viewsManager = new ViewsManager();
// when
- $viewNamespaceConfig
- ->setTemplatesRootPath(vfsStream::url('templates'))
- ->setTemplateFileExtension('.php');
+ $viewsManager->registerNamespace($firstNamespace, $firstNamespaceConfig);
+ $viewsManager->registerNamespace($secondNamespace, $secondNamespaceConfig);
- $views->addNamespace($modelNamespace, $viewNamespaceConfig);
-
- $modelClass = $modelNamespace . '\\Pure';
- $model = new $modelClass();
- $model->message = 'Hello World!';
+ $topModelClass = $firstNamespace . '\\TopModel';
+ $topModel = $viewsManager->createModel($topModelClass);
+ $topModel->inner = $viewsManager->createModel($innerModelClass);
// then
- $this->assertSame('Hello World! and again: Hello World!', $views->renderModel($model));
+ $this->assertSame('Hey inner!', $viewsManager->renderModel($topModel));
}
- public function testRenderIncludesInnerModelFromDifferentNamespace(): void
+ public function testRenderPassesInnerModelsAsStringsWhenFlagIsSet(): void
{
// given
vfsStream::setup('top', null, [
@@ -475,7 +526,55 @@ public function testRenderIncludesInnerModelFromDifferentNamespace(): void
$bladeRenderer = new ViewTemplateRenderer();
$firstNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
->setTemplatesRootPath(vfsStream::url('top/folder1'))
+ ->setTemplateFileExtension('.blade.php')
+ ->setModelsAsStringsInTemplates(true);
+ $secondNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ ->setTemplatesRootPath(vfsStream::url('top/folder2'))
->setTemplateFileExtension('.blade.php');
+ $secondNamespace = $this->defineRealModelClass(
+ __METHOD__ . '__second',
+ 'InnerModel',
+ [],
+ false
+ );
+ $firstNamespace = $this->defineRealModelClass(
+ __METHOD__,
+ 'TopModel',
+ [
+ [
+ 'name' => 'inner',
+ 'visibility' => 'public',
+ ]
+ ],
+ false
+ );
+ $views = new ViewsManager();
+
+ // when
+ $views->registerNamespace($firstNamespace, $firstNamespaceConfig);
+ $views->registerNamespace($secondNamespace, $secondNamespaceConfig);
+
+ $innerModelClass = $secondNamespace . '\\InnerModel';
+ $topModelClass = $firstNamespace . '\\TopModel';
+ $topModel = new $topModelClass();
+ $topModel->inner = new $innerModelClass();
+
+ // then
+ $this->assertSame('Hey inner!', $views->renderModel($topModel));
+ }
+
+ public function testRenderPassesInnerModelsFromDifferentNamespaces(): void
+ {
+ // given
+ vfsStream::setup('top', null, [
+ 'folder1' => ['top-model.blade.php' => 'Hey {!! $inner !!}'],
+ 'folder2' => [ 'inner-model.blade.php' => 'inner!'],
+ ]);
+ $bladeRenderer = new ViewTemplateRenderer();
+ $firstNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
+ ->setTemplatesRootPath(vfsStream::url('top/folder1'))
+ ->setTemplateFileExtension('.blade.php')
+ ->setModelsAsStringsInTemplates(true);
$secondNamespaceConfig = (new ViewNamespaceConfig($bladeRenderer))
->setTemplatesRootPath(vfsStream::url('top/folder2'))
->setTemplateFileExtension('.blade.php');
@@ -496,11 +595,11 @@ public function testRenderIncludesInnerModelFromDifferentNamespace(): void
],
false
);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($firstNamespace, $firstNamespaceConfig);
- $views->addNamespace($secondNamespace, $secondNamespaceConfig);
+ $views->registerNamespace($firstNamespace, $firstNamespaceConfig);
+ $views->registerNamespace($secondNamespace, $secondNamespaceConfig);
$innerModelClass = $secondNamespace . '\\InnerModel';
$topModelClass = $firstNamespace . '\\TopModel';
@@ -518,7 +617,7 @@ public function testMakeModelThatExtendsBaseClass(): void
// given
$bladeRenderer = new ViewTemplateRenderer();
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer));
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -528,10 +627,10 @@ public function testMakeModelThatExtendsBaseClass(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
- $model = $views->makeModel($modelClass);
+ $model = $views->createModel($modelClass);
// then
$this->assertSame($modelClass, get_class($model));
@@ -542,7 +641,7 @@ public function testMakeModelImplementsInterface(): void
// given
$bladeRenderer = new ViewTemplateRenderer();
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer));
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -558,10 +657,10 @@ public function testMakeModelImplementsInterface(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
- $model = $views->makeModel($modelClass);
+ $model = $views->createModel($modelClass);
// then
$this->assertSame($modelClass, get_class($model));
@@ -572,7 +671,7 @@ public function testMakeModelSetsDefaultsForModelsThatExtendBaseClass(): void
// given
$bladeRenderer = new ViewTemplateRenderer();
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer));
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -588,10 +687,10 @@ public function testMakeModelSetsDefaultsForModelsThatExtendBaseClass(): void
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
- $model = $views->makeModel($modelClass);
+ $model = $views->createModel($modelClass);
// then
$this->assertSame('', $model->message);
@@ -602,7 +701,7 @@ public function testMakeModelNotSetDefaultsForModelsWithoutDefaultsInterface():
// given
$bladeRenderer = new ViewTemplateRenderer();
$namespaceConfig = (new ViewNamespaceConfig($bladeRenderer));
- $views = new Views();
+ $views = new ViewsManager();
$modelNamespace = $this->defineRealModelClass(
__METHOD__,
@@ -618,10 +717,10 @@ public function testMakeModelNotSetDefaultsForModelsWithoutDefaultsInterface():
);
// when
- $views->addNamespace($modelNamespace, $namespaceConfig);
+ $views->registerNamespace($modelNamespace, $namespaceConfig);
$modelClass = $modelNamespace . '\\FirstModel';
- $model = $views->makeModel($modelClass);
+ $model = $views->createModel($modelClass);
// then
$this->assertFalse(isset($model->message));
@@ -645,18 +744,18 @@ public function testMakeModelSupportsDifferentNamespaces(): void
[],
true
);
- $views = new Views();
+ $views = new ViewsManager();
// when
- $views->addNamespace($firstNamespace, $firstNamespaceConfig);
- $views->addNamespace($secondNamespace, $secondNamespaceConfig);
+ $views->registerNamespace($firstNamespace, $firstNamespaceConfig);
+ $views->registerNamespace($secondNamespace, $secondNamespaceConfig);
$firstModelClass = $firstNamespace . '\\FirstModel';
$secondModelClass = $secondNamespace . '\\SecondModel';
// then
- $this->assertSame($firstModelClass, get_class($views->makeModel($firstModelClass)));
- $this->assertSame($secondModelClass, get_class($views->makeModel($secondModelClass)));
+ $this->assertSame($firstModelClass, get_class($views->createModel($firstModelClass)));
+ $this->assertSame($secondModelClass, get_class($views->createModel($secondModelClass)));
}
/**
@@ -676,7 +775,7 @@ protected function defineRealModelClass(
$namespace = '_views_test_' . strtolower($methodName);
$classContent = $this->getClassProperties($properties);
$extends = true === $extendsClass ?
- 'extends \\' . TemplateModel::class :
+ 'extends \\' . BaseTemplateModel::class :
'implements \\' . TemplateModelInterface::class;
if (false === $extendsClass) {
diff --git a/tests/pest/Unit/CodeExecutor/CodeExecutorWithErrorHandlerTest.php b/tests/pest/Unit/CodeRunner/CodeRunnerWithErrorHandlerTest.php
similarity index 76%
rename from tests/pest/Unit/CodeExecutor/CodeExecutorWithErrorHandlerTest.php
rename to tests/pest/Unit/CodeRunner/CodeRunnerWithErrorHandlerTest.php
index e8b9c56..bb682a6 100644
--- a/tests/pest/Unit/CodeExecutor/CodeExecutorWithErrorHandlerTest.php
+++ b/tests/pest/Unit/CodeRunner/CodeRunnerWithErrorHandlerTest.php
@@ -7,30 +7,30 @@
use Error;
use Exception;
use Mockery;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\EventDispatcherInterface;
-use Prosopo\Views\PrivateClasses\CodeExecutor\CodeExecutorWithErrorHandler;
+use Prosopo\Views\PrivateClasses\CodeRunner\CodeRunnerWithErrorHandler;
use Tests\TestCase;
use Throwable;
-class CodeExecutorWithErrorHandlerTest extends TestCase
+class CodeRunnerWithErrorHandlerTest extends TestCase
{
public function testNotCallsDispatcherWithoutReason(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
$eventDispatcher = Mockery::mock(EventDispatcherInterface::class);
- $contestant = new CodeExecutorWithErrorHandler(
+ $contestant = new CodeRunnerWithErrorHandler(
$codeExecutor,
$eventDispatcher,
'error'
);
// when
- $executeCode = fn() => $contestant->executeCode('correct code', ['var' => 1]);
+ $executeCode = fn() => $contestant->runCode('correct code', ['var' => 1]);
// then
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once();
$eventDispatcher->shouldNotReceive('dispatchEvent');
@@ -58,19 +58,19 @@ public function testCallsDispatcherOnWarning(): void
protected function testCallsDispatcher(?Throwable $error, bool $isWarning = false): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
$eventDispatcher = Mockery::mock(EventDispatcherInterface::class);
- $contestant = new CodeExecutorWithErrorHandler(
+ $contestant = new CodeRunnerWithErrorHandler(
$codeExecutor,
$eventDispatcher,
'errorEventName'
);
// when
- $executeCode = fn() => $contestant->executeCode('wrong code', ['var' => 1]);
+ $executeCode = fn() => $contestant->runCode('wrong code', ['var' => 1]);
// then
- $executorRule = $codeExecutor->shouldReceive('executeCode')
+ $executorRule = $codeExecutor->shouldReceive('runCode')
->once();
if (null !== $error) {
diff --git a/tests/pest/Unit/CodeExecutor/CodeExecutorWithGlobalArgumentsTest.php b/tests/pest/Unit/CodeRunner/CodeRunnerWithGlobalArgumentsTest.php
similarity index 56%
rename from tests/pest/Unit/CodeExecutor/CodeExecutorWithGlobalArgumentsTest.php
rename to tests/pest/Unit/CodeRunner/CodeRunnerWithGlobalArgumentsTest.php
index b20a7c3..b1ac575 100644
--- a/tests/pest/Unit/CodeExecutor/CodeExecutorWithGlobalArgumentsTest.php
+++ b/tests/pest/Unit/CodeRunner/CodeRunnerWithGlobalArgumentsTest.php
@@ -6,22 +6,22 @@
use Mockery;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
-use Prosopo\Views\PrivateClasses\CodeExecutor\CodeExecutorWithGlobalArguments;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
+use Prosopo\Views\PrivateClasses\CodeRunner\CodeRunnerWithGlobalArguments;
-class CodeExecutorWithGlobalArgumentsTest extends TestCase
+class CodeRunnerWithGlobalArgumentsTest extends TestCase
{
public function testMergesGlobalAndProvidedArgumentsBeforeExecutingCode(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
- $executor = new CodeExecutorWithGlobalArguments($codeExecutor, ['globalKey' => 'globalValue']);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
+ $executor = new CodeRunnerWithGlobalArguments($codeExecutor, ['globalKey' => 'globalValue']);
// when
- $executeCode = fn() => $executor->executeCode('sample code', ['key' => 'value']);
+ $executeCode = fn() => $executor->runCode('sample code', ['key' => 'value']);
// then
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once()
->with('sample code', [
'globalKey' => 'globalValue',
@@ -37,14 +37,14 @@ public function testMergesGlobalAndProvidedArgumentsBeforeExecutingCode(): void
public function testUsesOnlyGlobalArgumentsWhenNoAdditionalArgumentsAreProvided(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
- $executor = new CodeExecutorWithGlobalArguments($codeExecutor, ['globalKey' => 'globalValue']);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
+ $executor = new CodeRunnerWithGlobalArguments($codeExecutor, ['globalKey' => 'globalValue']);
// when
- $executeCode = fn() => $executor->executeCode('sample code', []);
+ $executeCode = fn() => $executor->runCode('sample code', []);
// then
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once()
->with('sample code', [
'globalKey' => 'globalValue',
@@ -59,14 +59,14 @@ public function testUsesOnlyGlobalArgumentsWhenNoAdditionalArgumentsAreProvided(
public function testOverridesGlobalArgumentsWithProvidedArgumentsIfKeysOverlap(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
- $executor = new CodeExecutorWithGlobalArguments($codeExecutor, ['key' => 'globalValue']);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
+ $executor = new CodeRunnerWithGlobalArguments($codeExecutor, ['key' => 'globalValue']);
// when
- $executeCode = fn() => $executor->executeCode('sample code', ['key' => 'providedValue']);
+ $executeCode = fn() => $executor->runCode('sample code', ['key' => 'providedValue']);
// then
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once()
->with('sample code', [
'key' => 'providedValue',
diff --git a/tests/pest/Unit/CodeExecutor/CodeExecutorWithTemplateCompilerTest.php b/tests/pest/Unit/CodeRunner/CodeRunnerWithTemplateCompilerTest.php
similarity index 63%
rename from tests/pest/Unit/CodeExecutor/CodeExecutorWithTemplateCompilerTest.php
rename to tests/pest/Unit/CodeRunner/CodeRunnerWithTemplateCompilerTest.php
index 824af64..38b9c52 100644
--- a/tests/pest/Unit/CodeExecutor/CodeExecutorWithTemplateCompilerTest.php
+++ b/tests/pest/Unit/CodeRunner/CodeRunnerWithTemplateCompilerTest.php
@@ -6,21 +6,21 @@
use Mockery;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\Template\TemplateCompilerInterface;
-use Prosopo\Views\PrivateClasses\CodeExecutor\CodeExecutorWithTemplateCompilation;
+use Prosopo\Views\PrivateClasses\CodeRunner\CodeRunnerWithTemplateCompilation;
-class CodeExecutorWithTemplateCompilationTest extends TestCase
+class CodeRunnerWithTemplateCompilationTest extends TestCase
{
public function testExecutesCompiledTemplateCode(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
$templateCompiler = Mockery::mock(TemplateCompilerInterface::class);
- $contestant = new CodeExecutorWithTemplateCompilation($codeExecutor, $templateCompiler);
+ $contestant = new CodeRunnerWithTemplateCompilation($codeExecutor, $templateCompiler);
// when
- $executeCode = fn() => $contestant->executeCode('template code', ['arg1' => 'value1']);
+ $executeCode = fn() => $contestant->runCode('template code', ['arg1' => 'value1']);
// then
$templateCompiler->shouldReceive('compileTemplate')
@@ -28,7 +28,7 @@ public function testExecutesCompiledTemplateCode(): void
->with('template code')
->andReturn('compiled code');
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once()
->with('compiled code', ['arg1' => 'value1']);
@@ -41,12 +41,12 @@ public function testExecutesCompiledTemplateCode(): void
public function testHandlesEmptyTemplateCode(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
$templateCompiler = Mockery::mock(TemplateCompilerInterface::class);
- $contestant = new CodeExecutorWithTemplateCompilation($codeExecutor, $templateCompiler);
+ $contestant = new CodeRunnerWithTemplateCompilation($codeExecutor, $templateCompiler);
// when
- $executeCode = fn() => $contestant->executeCode('', []);
+ $executeCode = fn() => $contestant->runCode('', []);
// then
$templateCompiler->shouldReceive('compileTemplate')
@@ -54,7 +54,7 @@ public function testHandlesEmptyTemplateCode(): void
->with('')
->andReturn('');
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once()
->with('', []);
@@ -67,12 +67,12 @@ public function testHandlesEmptyTemplateCode(): void
public function testHandlesArgumentsCorrectly(): void
{
// given
- $codeExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $codeExecutor = Mockery::mock(CodeRunnerInterface::class);
$templateCompiler = Mockery::mock(TemplateCompilerInterface::class);
- $contestant = new CodeExecutorWithTemplateCompilation($codeExecutor, $templateCompiler);
+ $contestant = new CodeRunnerWithTemplateCompilation($codeExecutor, $templateCompiler);
// when
- $executeCode = fn() => $contestant->executeCode('template code with args', ['key1' => 'value1', 'key2' => 'value2']);
+ $executeCode = fn() => $contestant->runCode('template code with args', ['key1' => 'value1', 'key2' => 'value2']);
// then
$templateCompiler->shouldReceive('compileTemplate')
@@ -80,7 +80,7 @@ public function testHandlesArgumentsCorrectly(): void
->with('template code with args')
->andReturn('compiled code with args');
- $codeExecutor->shouldReceive('executeCode')
+ $codeExecutor->shouldReceive('runCode')
->once()
->with('compiled code with args', ['key1' => 'value1', 'key2' => 'value2']);
diff --git a/tests/pest/Unit/CodeExecutor/PhpCodeExecutorTest.php b/tests/pest/Unit/CodeRunner/PhpCodeRunnerTest.php
similarity index 72%
rename from tests/pest/Unit/CodeExecutor/PhpCodeExecutorTest.php
rename to tests/pest/Unit/CodeRunner/PhpCodeRunnerTest.php
index 1b8e476..c04c589 100644
--- a/tests/pest/Unit/CodeExecutor/PhpCodeExecutorTest.php
+++ b/tests/pest/Unit/CodeRunner/PhpCodeRunnerTest.php
@@ -5,19 +5,19 @@
namespace Tests\Unit\CodeExecutor;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\PrivateClasses\CodeExecutor\PhpCodeExecutor;
+use Prosopo\Views\PrivateClasses\CodeRunner\PhpCodeRunner;
-class PhpCodeExecutorTest extends TestCase
+class PhpCodeRunnerTest extends TestCase
{
public function testExecutesCodeWithoutArguments(): void
{
// given
- $executor = new PhpCodeExecutor();
+ $executor = new PhpCodeRunner();
$code = 'executeCode($code, []);
+ $executor->runCode($code, []);
// then
$this->assertSame("Hello, World!", $output);
@@ -26,13 +26,13 @@ public function testExecutesCodeWithoutArguments(): void
public function testExecutesCodeWithArguments(): void
{
// given
- $executor = new PhpCodeExecutor();
+ $executor = new PhpCodeRunner();
$code = ' 10, 'arg2' => 20];
// when
global $result;
- $executor->executeCode($code, $arguments);
+ $executor->runCode($code, $arguments);
// then
$this->assertSame(30, $result);
@@ -41,12 +41,12 @@ public function testExecutesCodeWithArguments(): void
public function testExecutesCodeWithEchoStatement(): void
{
// given
- $executor = new PhpCodeExecutor();
+ $executor = new PhpCodeRunner();
$code = 'executeCode($code, []);
+ $executor->runCode($code, []);
$response = ob_get_clean();
// apply
diff --git a/tests/pest/Unit/EventDispatcherTest.php b/tests/pest/Unit/EventDispatcherTest.php
index e892a9b..37bf2e8 100644
--- a/tests/pest/Unit/EventDispatcherTest.php
+++ b/tests/pest/Unit/EventDispatcherTest.php
@@ -92,7 +92,7 @@ public function testAttachEventDetails(): void
};
// when
- $dispatcher->attachEventDetails('testEvent', ['attachedKey' => 'attachedValue']);
+ $dispatcher->registerEventDetails('testEvent', ['attachedKey' => 'attachedValue']);
$dispatcher->addEventListener('testEvent', $listener);
$dispatcher->dispatchEvent('testEvent', ['key' => 'value']);
@@ -117,8 +117,8 @@ public function testDetachEventDetails(): void
};
// when
- $dispatcher->attachEventDetails('testEvent', ['key1' => 'value1', 'key2' => 'value2']);
- $dispatcher->detachEventDetails('testEvent', ['key2' => 'value2']);
+ $dispatcher->registerEventDetails('testEvent', ['key1' => 'value1', 'key2' => 'value2']);
+ $dispatcher->unregisterEventDetails('testEvent', ['key2' => 'value2']);
$dispatcher->addEventListener('testEvent', $listener);
$dispatcher->dispatchEvent('testEvent', ['key3' => 'value3']);
@@ -174,7 +174,7 @@ public function testEventDetailsAreIsolatedPerEvent(): void
};
// when
- $dispatcher->attachEventDetails('eventA', ['attachedKey' => 'attachedValue']);
+ $dispatcher->registerEventDetails('eventA', ['attachedKey' => 'attachedValue']);
$dispatcher->addEventListener('eventB', $listener);
$dispatcher->dispatchEvent('eventB', ['key' => 'value']);
diff --git a/tests/pest/Unit/Model/ModelFactoryTest.php b/tests/pest/Unit/Model/ModelFactoryTest.php
index 054e08d..8ec31bf 100644
--- a/tests/pest/Unit/Model/ModelFactoryTest.php
+++ b/tests/pest/Unit/Model/ModelFactoryTest.php
@@ -10,6 +10,8 @@
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
use Prosopo\Views\Interfaces\Object\ObjectReaderInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
+use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
use Prosopo\Views\PrivateClasses\Model\ModelFactory;
class ModelFactoryTest extends TestCase
@@ -19,18 +21,37 @@ public function testMakeModelCreatesInstanceOfModelClass(): void
// given
$objectReaderMock = Mockery::mock(ObjectReaderInterface::class);
$propertyValueProviderMock = Mockery::mock(PropertyValueProviderInterface::class);
- $factory = new ModelFactory($objectReaderMock, $propertyValueProviderMock);
-
- $modelClass = new class ($objectReaderMock, $propertyValueProviderMock) implements TemplateModelInterface {
+ $modelTemplateResolverMock = Mockery::mock(ModelTemplateResolverInterface::class);
+ $templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
+
+ $factory = new ModelFactory(
+ $objectReaderMock,
+ $propertyValueProviderMock,
+ $modelTemplateResolverMock,
+ $templateRendererMock
+ );
+
+ $modelClass = new class (
+ $objectReaderMock,
+ $propertyValueProviderMock,
+ $modelTemplateResolverMock,
+ $templateRendererMock
+) implements TemplateModelInterface {
public ObjectReaderInterface $objectReader;
public PropertyValueProviderInterface $propertyValueProvider;
+ public ModelTemplateResolverInterface $modelTemplateResolver;
+ public TemplateRendererInterface $templateRenderer;
public function __construct(
ObjectReaderInterface $objectReader,
- PropertyValueProviderInterface $propertyValueProvider
+ PropertyValueProviderInterface $propertyValueProvider,
+ ModelTemplateResolverInterface $modelTemplateResolver,
+ TemplateRendererInterface $templateRenderer
) {
$this->objectReader = $objectReader;
$this->propertyValueProvider = $propertyValueProvider;
+ $this->modelTemplateResolver = $modelTemplateResolver;
+ $this->templateRenderer = $templateRenderer;
}
public function getTemplateArguments(): array
@@ -40,12 +61,14 @@ public function getTemplateArguments(): array
};
// when
- $result = $factory->makeModel(get_class($modelClass));
+ $result = $factory->createModel(get_class($modelClass));
// then
$this->assertInstanceOf(get_class($modelClass), $result);
$this->assertSame($objectReaderMock, $result->objectReader);
$this->assertSame($propertyValueProviderMock, $result->propertyValueProvider);
+ $this->assertSame($modelTemplateResolverMock, $result->modelTemplateResolver);
+ $this->assertSame($templateRendererMock, $result->templateRenderer);
// apply
Mockery::close();
@@ -55,11 +78,20 @@ public function testMakeModelThrowsExceptionForInvalidClass(): void
{
// given
$objectReaderMock = Mockery::mock(ObjectReaderInterface::class);
+ $modelTemplateResolverMock = Mockery::mock(ModelTemplateResolverInterface::class);
+ $templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
+
$propertyValueProviderMock = Mockery::mock(PropertyValueProviderInterface::class);
- $factory = new ModelFactory($objectReaderMock, $propertyValueProviderMock);
+
+ $factory = new ModelFactory(
+ $objectReaderMock,
+ $propertyValueProviderMock,
+ $modelTemplateResolverMock,
+ $templateRendererMock
+ );
// when
- $makeModel = fn() => $factory->makeModel('NonExistentClass');
+ $makeModel = fn() => $factory->createModel('NonExistentClass');
// when & then
$this->expectException(Error::class);
@@ -74,7 +106,15 @@ public function testMakeModelThrowsExceptionForInvalidConstructor(): void
// given
$objectReaderMock = Mockery::mock(ObjectReaderInterface::class);
$propertyValueProviderMock = Mockery::mock(PropertyValueProviderInterface::class);
- $factory = new ModelFactory($objectReaderMock, $propertyValueProviderMock);
+ $modelTemplateResolverMock = Mockery::mock(ModelTemplateResolverInterface::class);
+ $templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
+
+ $factory = new ModelFactory(
+ $objectReaderMock,
+ $propertyValueProviderMock,
+ $modelTemplateResolverMock,
+ $templateRendererMock
+ );
$invalidModelClass = new class (1) {
public function __construct(int $test)
{
@@ -82,7 +122,7 @@ public function __construct(int $test)
};
// when
- $makeModel = fn() => $factory->makeModel(get_class($invalidModelClass));
+ $makeModel = fn() => $factory->createModel(get_class($invalidModelClass));
// then
$this->expectException(Error::class);
diff --git a/tests/pest/Unit/Model/ModelFactoryWithDefaultsManagementTest.php b/tests/pest/Unit/Model/ModelFactoryWithDefaultsManagementTest.php
index 8656724..1c365cc 100644
--- a/tests/pest/Unit/Model/ModelFactoryWithDefaultsManagementTest.php
+++ b/tests/pest/Unit/Model/ModelFactoryWithDefaultsManagementTest.php
@@ -31,25 +31,25 @@ public function testMakeModelInitializesPropertiesWhenObjectImplementsWithDefaul
);
// when
- $result = fn() =>$factory->makeModel('ModelClass');
+ $result = fn() =>$factory->createModel('ModelClass');
// then
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
->with('ModelClass')
->andReturn($modelWithDefaultsMock);
$modelWithDefaultsMock
- ->shouldReceive('getDefaultsPropertyValueProvider')
+ ->shouldReceive('getDefaultPropertyValueProvider')
->once()
->andReturn($propertyValueProviderMock);
- $objectReaderMock->shouldReceive('getObjectVariables')
+ $objectReaderMock->shouldReceive('extractObjectVariables')
->once()
->with($modelWithDefaultsMock)
->andReturn([]);
- $objectPropertyWriterMock->shouldReceive('setObjectPropertyValues')
+ $objectPropertyWriterMock->shouldReceive('assignPropertyValues')
->once()
->with($modelWithDefaultsMock, $propertyValueProviderMock);
@@ -73,10 +73,10 @@ public function testMakeModelSkipsPropertiesInitializationWhenObjectWithoutDefau
);
// when
- $result = fn() =>$factory->makeModel('ModelClass');
+ $result = fn() =>$factory->createModel('ModelClass');
// then
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
->with('ModelClass')
->andReturn($modelMock);
@@ -104,53 +104,53 @@ public function testMakeModelHandlesInnerObjectsWithDefaultsInterface(): void
);
// when
- $result = fn()=>$factory->makeModel('ModelClass');
+ $result = fn()=>$factory->createModel('ModelClass');
// then
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
->with('ModelClass')
->andReturn($mainModelMock);
$mainModelMock
- ->shouldReceive('getDefaultsPropertyValueProvider')
+ ->shouldReceive('getDefaultPropertyValueProvider')
->once()
->andReturn($propertyValueProviderMock);
- $objectReaderMock->shouldReceive('getObjectVariables')
+ $objectReaderMock->shouldReceive('extractObjectVariables')
->once()
->with($mainModelMock)
->andReturn(['inner1' => $innerModelMock1, 'inner2' => $innerModelMock2]);
- $objectPropertyWriterMock->shouldReceive('setObjectPropertyValues')
+ $objectPropertyWriterMock->shouldReceive('assignPropertyValues')
->once()
->with($mainModelMock, $propertyValueProviderMock);
$innerModelMock1
- ->shouldReceive('getDefaultsPropertyValueProvider')
+ ->shouldReceive('getDefaultPropertyValueProvider')
->once()
->andReturn($propertyValueProviderMock);
- $objectReaderMock->shouldReceive('getObjectVariables')
+ $objectReaderMock->shouldReceive('extractObjectVariables')
->once()
->with($innerModelMock1)
->andReturn([]);
- $objectPropertyWriterMock->shouldReceive('setObjectPropertyValues')
+ $objectPropertyWriterMock->shouldReceive('assignPropertyValues')
->once()
->with($innerModelMock1, $propertyValueProviderMock);
$innerModelMock2
- ->shouldReceive('getDefaultsPropertyValueProvider')
+ ->shouldReceive('getDefaultPropertyValueProvider')
->once()
->andReturn($propertyValueProviderMock);
- $objectReaderMock->shouldReceive('getObjectVariables')
+ $objectReaderMock->shouldReceive('extractObjectVariables')
->once()
->with($innerModelMock2)
->andReturn([]);
- $objectPropertyWriterMock->shouldReceive('setObjectPropertyValues')
+ $objectPropertyWriterMock->shouldReceive('assignPropertyValues')
->once()
->with($innerModelMock2, $propertyValueProviderMock);
@@ -176,25 +176,25 @@ public function testMakeModelSkipsInnerObjectsWithoutDefaultsInterface(): void
);
// when
- $result = fn()=>$factory->makeModel('ModelClass');
+ $result = fn()=>$factory->createModel('ModelClass');
// then
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
->with('ModelClass')
->andReturn($mainModelMock);
$mainModelMock
- ->shouldReceive('getDefaultsPropertyValueProvider')
+ ->shouldReceive('getDefaultPropertyValueProvider')
->once()
->andReturn($propertyValueProviderMock);
- $objectReaderMock->shouldReceive('getObjectVariables')
+ $objectReaderMock->shouldReceive('extractObjectVariables')
->once()
->with($mainModelMock)
->andReturn(['inner1' => $innerModelMock1,]);
- $objectPropertyWriterMock->shouldReceive('setObjectPropertyValues')
+ $objectPropertyWriterMock->shouldReceive('assignPropertyValues')
->once()
->with($mainModelMock, $propertyValueProviderMock);
diff --git a/tests/pest/Unit/Model/ModelNameProviderTest.php b/tests/pest/Unit/Model/ModelNameProviderTest.php
index 0250b44..49377f9 100644
--- a/tests/pest/Unit/Model/ModelNameProviderTest.php
+++ b/tests/pest/Unit/Model/ModelNameProviderTest.php
@@ -7,7 +7,7 @@
use Mockery;
use PHPUnit\Framework\TestCase;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-use Prosopo\Views\PrivateClasses\Model\ModelNameProvider;
+use Prosopo\Views\PrivateClasses\Model\ModelNameResolver;
use Prosopo\Views\PrivateClasses\Object\ObjectClassReader;
class ModelNameProviderTest extends TestCase
@@ -16,11 +16,11 @@ public function testGetModelNameReturnsClassName(): void
{
// given
$objectClassReaderMock = Mockery::mock(ObjectClassReader::class);
- $provider = new ModelNameProvider($objectClassReaderMock);
+ $provider = new ModelNameResolver($objectClassReaderMock);
$modelMock = Mockery::mock(TemplateModelInterface::class);
// when
- $getModelName = fn()=> $provider->getModelName($modelMock);
+ $getModelName = fn()=> $provider->resolveModelName($modelMock);
// then
$objectClassReaderMock
@@ -37,11 +37,11 @@ public function testGetModelNameReturnsClassNameForRoot(): void
{
// given
$objectClassReaderMock = Mockery::mock(ObjectClassReader::class);
- $provider = new ModelNameProvider($objectClassReaderMock);
+ $provider = new ModelNameResolver($objectClassReaderMock);
$modelMock = Mockery::mock(TemplateModelInterface::class);
// when
- $getModelNamespace = fn()=> $provider->getModelName($modelMock);
+ $getModelNamespace = fn()=> $provider->resolveModelName($modelMock);
// then
$objectClassReaderMock
@@ -58,11 +58,11 @@ public function testGetModelNameReturnsClassNameForDeeplyNested(): void
{
// given
$objectClassReaderMock = Mockery::mock(ObjectClassReader::class);
- $provider = new ModelNameProvider($objectClassReaderMock);
+ $provider = new ModelNameResolver($objectClassReaderMock);
$modelMock = Mockery::mock(TemplateModelInterface::class);
// when
- $getModelNamespace = fn()=> $provider->getModelName($modelMock);
+ $getModelNamespace = fn()=> $provider->resolveModelName($modelMock);
// then
$objectClassReaderMock
diff --git a/tests/pest/Unit/Model/ModelNamespaceProviderTest.php b/tests/pest/Unit/Model/ModelNamespaceProviderTest.php
index 90dcd70..06bdebb 100644
--- a/tests/pest/Unit/Model/ModelNamespaceProviderTest.php
+++ b/tests/pest/Unit/Model/ModelNamespaceProviderTest.php
@@ -7,7 +7,7 @@
use Mockery;
use PHPUnit\Framework\TestCase;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-use Prosopo\Views\PrivateClasses\Model\ModelNamespaceProvider;
+use Prosopo\Views\PrivateClasses\Model\ModelNamespaceResolver;
use Prosopo\Views\PrivateClasses\Object\ObjectClassReader;
class ModelNamespaceProviderTest extends TestCase
@@ -16,11 +16,11 @@ public function testGetModelNamespaceReturnsNamespace(): void
{
// given
$objectClassReaderMock = Mockery::mock(ObjectClassReader::class);
- $provider = new ModelNamespaceProvider($objectClassReaderMock);
+ $provider = new ModelNamespaceResolver($objectClassReaderMock);
$modelMock = Mockery::mock(TemplateModelInterface::class);
// when
- $getModelNamespace = fn()=> $provider->getModelNamespace($modelMock);
+ $getModelNamespace = fn()=> $provider->resolveModelNamespace($modelMock);
// then
$objectClassReaderMock
@@ -37,11 +37,11 @@ public function testGetModelNamespaceReturnsNamespaceForRoot(): void
{
// given
$objectClassReaderMock = Mockery::mock(ObjectClassReader::class);
- $provider = new ModelNamespaceProvider($objectClassReaderMock);
+ $provider = new ModelNamespaceResolver($objectClassReaderMock);
$modelMock = Mockery::mock(TemplateModelInterface::class);
// when
- $getModelNamespace = fn()=> $provider->getModelNamespace($modelMock);
+ $getModelNamespace = fn()=> $provider->resolveModelNamespace($modelMock);
// then
$objectClassReaderMock
@@ -58,11 +58,11 @@ public function testGetModelNamespaceReturnsNamespaceForDeeplyNested(): void
{
// given
$objectClassReaderMock = Mockery::mock(ObjectClassReader::class);
- $provider = new ModelNamespaceProvider($objectClassReaderMock);
+ $provider = new ModelNamespaceResolver($objectClassReaderMock);
$modelMock = Mockery::mock(TemplateModelInterface::class);
// when
- $getModelNamespace = fn()=> $provider->getModelNamespace($modelMock);
+ $getModelNamespace = fn()=> $provider->resolveModelNamespace($modelMock);
// then
$objectClassReaderMock
diff --git a/tests/pest/Unit/Model/ModelRendererTest.php b/tests/pest/Unit/Model/ModelRendererTest.php
index 631aa6e..b85b3b8 100644
--- a/tests/pest/Unit/Model/ModelRendererTest.php
+++ b/tests/pest/Unit/Model/ModelRendererTest.php
@@ -8,8 +8,7 @@
use PHPUnit\Framework\TestCase;
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-use Prosopo\Views\Interfaces\Object\ObjectReaderInterface;
-use Prosopo\Views\Interfaces\Template\ModelTemplateProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
use Prosopo\Views\PrivateClasses\Model\ModelRenderer;
@@ -20,7 +19,7 @@ public function testRenderModelWithModelInstance(): void
// given
$templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
$modelFactoryMock = Mockery::mock(ModelFactoryInterface::class);
- $templateProviderMock = Mockery::mock(ModelTemplateProviderInterface::class);
+ $templateProviderMock = Mockery::mock(ModelTemplateResolverInterface::class);
$modelMock = Mockery::mock(TemplateModelInterface::class);
$renderer = new ModelRenderer(
$templateRendererMock,
@@ -36,14 +35,14 @@ public function testRenderModelWithModelInstance(): void
->once()
->andReturn(['key' => 'value']);
- $templateProviderMock->shouldReceive('getModelTemplate')
+ $templateProviderMock->shouldReceive('resolveModelTemplate')
->once()
->with($modelMock)
->andReturn('{{ $key }}
');
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('{{ $key }}
', ['key' => 'value'], false)
+ ->with('{{ $key }}
', ['key' => 'value'])
->andReturn('value
');
// then
@@ -58,7 +57,7 @@ public function testRenderModelWithModelClass(): void
// given
$templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
$modelFactoryMock = Mockery::mock(ModelFactoryInterface::class);
- $templateProviderMock = Mockery::mock(ModelTemplateProviderInterface::class);
+ $templateProviderMock = Mockery::mock(ModelTemplateResolverInterface::class);
$modelMock = Mockery::mock(TemplateModelInterface::class);
$renderer = new ModelRenderer(
$templateRendererMock,
@@ -70,7 +69,7 @@ public function testRenderModelWithModelClass(): void
$result = fn() => $renderer->renderModel('ModelClass');
// then
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
->with('ModelClass')
->andReturn($modelMock);
@@ -79,14 +78,14 @@ public function testRenderModelWithModelClass(): void
->once()
->andReturn(['key' => 'value']);
- $templateProviderMock->shouldReceive('getModelTemplate')
+ $templateProviderMock->shouldReceive('resolveModelTemplate')
->once()
->with($modelMock)
->andReturn('{{ $key }}
');
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('{{ $key }}
', ['key' => 'value'], false)
+ ->with('{{ $key }}
', ['key' => 'value'])
->andReturn('value
');
$this->assertSame('value
', $result());
@@ -100,7 +99,7 @@ public function testRenderModelAppliesSetupCallback(): void
// given
$templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
$modelFactoryMock = Mockery::mock(ModelFactoryInterface::class);
- $templateProviderMock = Mockery::mock(ModelTemplateProviderInterface::class);
+ $templateProviderMock = Mockery::mock(ModelTemplateResolverInterface::class);
$modelMock = Mockery::mock(TemplateModelInterface::class);
$renderer = new ModelRenderer(
$templateRendererMock,
@@ -115,7 +114,7 @@ public function testRenderModelAppliesSetupCallback(): void
$result = fn()=>$renderer->renderModel('ModelClass', $setupCallback);
// then
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
->with('ModelClass')
->andReturn($modelMock);
@@ -124,14 +123,14 @@ public function testRenderModelAppliesSetupCallback(): void
->once()
->andReturn(['key' => 'modified_value']);
- $templateProviderMock->shouldReceive('getModelTemplate')
+ $templateProviderMock->shouldReceive('resolveModelTemplate')
->once()
->with($modelMock)
->andReturn('{{ $key }}
');
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('{{ $key }}
', ['key' => 'modified_value'], false)
+ ->with('{{ $key }}
', ['key' => 'modified_value'])
->andReturn('modified_value
');
$this->assertSame('modified_value
', $result());
@@ -139,41 +138,4 @@ public function testRenderModelAppliesSetupCallback(): void
// apply
Mockery::close();
}
-
- public function testRenderModelPrintsOutput(): void
- {
- // given
- $templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
- $modelFactoryMock = Mockery::mock(ModelFactoryInterface::class);
- $templateProviderMock = Mockery::mock(ModelTemplateProviderInterface::class);
- $modelMock = Mockery::mock(TemplateModelInterface::class);
- $renderer = new ModelRenderer(
- $templateRendererMock,
- $modelFactoryMock,
- $templateProviderMock
- );
-
- // when
- $renderModel = fn()=>$renderer->renderModel($modelMock, null, true);
-
- // then
- $modelMock->shouldReceive('getTemplateArguments')
- ->once()
- ->andReturn(['key' => 'value']);
-
- $templateProviderMock->shouldReceive('getModelTemplate')
- ->once()
- ->with($modelMock)
- ->andReturn('{{ $key }}
');
-
- $templateRendererMock->shouldReceive('renderTemplate')
- ->once()
- ->with('{{ $key }}
', ['key' => 'value'], true)
- ->andReturn('value
');
-
- $this->assertSame('value
', $renderModel());
-
- // apply
- Mockery::close();
- }
}
diff --git a/tests/pest/Unit/Model/ModelRendererWithEventDetailsTest.php b/tests/pest/Unit/Model/ModelRendererWithEventDetailsTest.php
index 1fe7587..d54061e 100644
--- a/tests/pest/Unit/Model/ModelRendererWithEventDetailsTest.php
+++ b/tests/pest/Unit/Model/ModelRendererWithEventDetailsTest.php
@@ -25,18 +25,18 @@ public function testRenderModelAttachesAndDetachesEventDetails(): void
$result = fn()=>$renderer->renderModel($modelMock);
// then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
+ $eventDispatcherMock->shouldReceive('registerEventDetails')
->once()
- ->with('render_event', ['viewClass' => get_class($modelMock)]);
+ ->with('render_event', ['modelClass' => get_class($modelMock)]);
$viewRendererMock->shouldReceive('renderModel')
->once()
- ->with($modelMock, null, false)
+ ->with($modelMock, null)
->andReturn('Rendered View
');
- $eventDispatcherMock->shouldReceive('detachEventDetails')
+ $eventDispatcherMock->shouldReceive('unregisterEventDetails')
->once()
- ->with('render_event', ['viewClass' => get_class($modelMock)]);
+ ->with('render_event', ['modelClass' => get_class($modelMock)]);
$this->assertSame('Rendered View
', $result());
@@ -55,18 +55,18 @@ public function testRenderModelHandlesModelClass(): void
$result = fn()=> $renderer->renderModel('TestModelClass');
// then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
+ $eventDispatcherMock->shouldReceive('registerEventDetails')
->once()
- ->with('render_event', ['viewClass' => 'TestModelClass']);
+ ->with('render_event', ['modelClass' => 'TestModelClass']);
$viewRendererMock->shouldReceive('renderModel')
->once()
- ->with('TestModelClass', null, false)
+ ->with('TestModelClass', null)
->andReturn('Rendered Model
');
- $eventDispatcherMock->shouldReceive('detachEventDetails')
+ $eventDispatcherMock->shouldReceive('unregisterEventDetails')
->once()
- ->with('render_event', ['viewClass' => 'TestModelClass']);
+ ->with('render_event', ['modelClass' => 'TestModelClass']);
$this->assertSame('Rendered Model
', $result());
@@ -92,54 +92,22 @@ public function testRenderModelPassesSetupCallback(): void
$result = fn()=>$renderer->renderModel($modelMock, $setupCallback);
// then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
+ $eventDispatcherMock->shouldReceive('registerEventDetails')
->once()
- ->with('render_event', ['viewClass' => get_class($modelMock)]);
+ ->with('render_event', ['modelClass' => get_class($modelMock)]);
$viewRendererMock->shouldReceive('renderModel')
->once()
- ->with($modelMock, $setupCallback, false)
+ ->with($modelMock, $setupCallback)
->andReturn('Modified View
');
- $eventDispatcherMock->shouldReceive('detachEventDetails')
+ $eventDispatcherMock->shouldReceive('unregisterEventDetails')
->once()
- ->with('render_event', ['viewClass' => get_class($modelMock)]);
+ ->with('render_event', ['modelClass' => get_class($modelMock)]);
$this->assertSame('Modified View
', $result());
// apply
Mockery::close();
}
-
- public function testRenderModelHandlesDoPrintFlag(): void
- {
- // given
- $viewRendererMock = Mockery::mock(ModelRendererInterface::class);
- $eventDispatcherMock = Mockery::mock(EventDispatcherInterface::class);
- $modelMock = new class {
- };
- $renderer = new ModelRendererWithEventDetails($viewRendererMock, $eventDispatcherMock, 'render_event');
-
- // when
- $renderModel = fn()=>$renderer->renderModel($modelMock, null, true);
-
- // then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
- ->once()
- ->with('render_event', ['viewClass' => get_class($modelMock)]);
-
- $viewRendererMock->shouldReceive('renderModel')
- ->once()
- ->with($modelMock, null, true)
- ->andReturn('Printed View
');
-
- $eventDispatcherMock->shouldReceive('detachEventDetails')
- ->once()
- ->with('render_event', ['viewClass' => get_class($modelMock)]);
-
- $this->assertSame('Printed View
', $renderModel());
-
- // apply
- Mockery::close();
- }
}
diff --git a/tests/pest/Unit/Object/ObjectPropertyWriterTest.php b/tests/pest/Unit/Object/ObjectPropertyWriterTest.php
index 50815b9..61c7d95 100644
--- a/tests/pest/Unit/Object/ObjectPropertyWriterTest.php
+++ b/tests/pest/Unit/Object/ObjectPropertyWriterTest.php
@@ -21,7 +21,7 @@ public function testSetsDefaultValuesUsingProvider(): void
$writer = new ObjectPropertyWriter();
// when
- $result = fn() => $writer->setObjectPropertyValues($testInstance, $propertyValueProvider);
+ $result = fn() => $writer->assignPropertyValues($testInstance, $propertyValueProvider);
// then
$propertyValueProvider->shouldReceive('supportsProperty')
@@ -51,7 +51,7 @@ public function testIgnoresInitializedProperties(): void
};
// when
- $result = fn() => $writer->setObjectPropertyValues($testInstance, $propertyValueProvider);
+ $result = fn() => $writer->assignPropertyValues($testInstance, $propertyValueProvider);
// then
$result();
@@ -69,7 +69,7 @@ public function testSkipsNonSupportedType(): void
$writer = new ObjectPropertyWriter();
// when
- $result = fn() => $writer->setObjectPropertyValues($testInstance, $propertyValueProvider);
+ $result = fn() => $writer->assignPropertyValues($testInstance, $propertyValueProvider);
// then
$propertyValueProvider->shouldReceive('supportsProperty')
diff --git a/tests/pest/Unit/Object/ObjectReaderTest.php b/tests/pest/Unit/Object/ObjectReaderTest.php
index 1ff978e..99d5cdf 100644
--- a/tests/pest/Unit/Object/ObjectReaderTest.php
+++ b/tests/pest/Unit/Object/ObjectReaderTest.php
@@ -29,7 +29,7 @@ public function calculate(): int
};
// when
- $variables = $objectReader->getObjectVariables($testInstance);
+ $variables = $objectReader->extractObjectVariables($testInstance);
// then
$this->assertEquals([
@@ -50,7 +50,7 @@ public function testExcludesNonTypedPublicProperties(): void
};
// when
- $variables = $objectReader->getObjectVariables($testInstance);
+ $variables = $objectReader->extractObjectVariables($testInstance);
// then
$this->assertEquals([
@@ -72,7 +72,7 @@ public function someMethod(): string
};
// when
- $variables = $objectReader->getObjectVariables($testInstance);
+ $variables = $objectReader->extractObjectVariables($testInstance);
// then
diff --git a/tests/pest/Unit/Object/PropertyValueProviderForModelsTest.php b/tests/pest/Unit/Object/PropertyValueProviderForModelsTest.php
index fc0524d..182d024 100644
--- a/tests/pest/Unit/Object/PropertyValueProviderForModelsTest.php
+++ b/tests/pest/Unit/Object/PropertyValueProviderForModelsTest.php
@@ -9,7 +9,7 @@
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
use Prosopo\Views\PrivateClasses\Object\PropertyValueProviderForModels;
-use Prosopo\Views\TemplateModel;
+use Prosopo\Views\BaseTemplateModel;
use ReflectionProperty;
class PropertyValueProviderForModelsTest extends TestCase
@@ -51,7 +51,7 @@ public function testSupportsPropertyReturnsTrueForValidModelClass(): void
// then
$propertyMock->shouldReceive('getType->getName')
->once()
- ->andReturn(TemplateModel::class);
+ ->andReturn(BaseTemplateModel::class);
$propertyValueProviderMock->shouldReceive('supportsProperty')
->once()
@@ -126,7 +126,7 @@ public function testGetPropertyValueCreatesModelForValidClass(): void
$modelFactoryMock = Mockery::mock(ModelFactoryInterface::class);
$provider = new PropertyValueProviderForModels($propertyValueProviderMock, $modelFactoryMock);
$propertyMock = Mockery::mock(ReflectionProperty::class);
- $model = Mockery::mock(TemplateModel::class);
+ $model = Mockery::mock(BaseTemplateModel::class);
// when
$result = fn() => $provider->getPropertyValue($propertyMock);
@@ -134,16 +134,16 @@ public function testGetPropertyValueCreatesModelForValidClass(): void
// then
$propertyMock->shouldReceive('getType->getName')
->once()
- ->andReturn(TemplateModel::class);
+ ->andReturn(BaseTemplateModel::class);
$propertyValueProviderMock->shouldReceive('supportsProperty')
->once()
->with($propertyMock)
->andReturn(false);
- $modelFactoryMock->shouldReceive('makeModel')
+ $modelFactoryMock->shouldReceive('createModel')
->once()
- ->with(TemplateModel::class)
+ ->with(BaseTemplateModel::class)
->andReturn($model);
$this->assertSame($model, $result());
diff --git a/tests/pest/Unit/Template/FileModelTemplateProviderTest.php b/tests/pest/Unit/Template/FileModelTemplateProviderTest.php
index a42f72d..7c14f99 100644
--- a/tests/pest/Unit/Template/FileModelTemplateProviderTest.php
+++ b/tests/pest/Unit/Template/FileModelTemplateProviderTest.php
@@ -7,10 +7,10 @@
use Mockery;
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\Interfaces\Model\ModelNameProviderInterface;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNameResolverInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
-use Prosopo\Views\PrivateClasses\Template\FileModelTemplateProvider;
+use Prosopo\Views\PrivateClasses\Template\FileModelTemplateResolver;
class FileModelTemplateProviderTest extends TestCase
{
@@ -19,9 +19,9 @@ public function testGetTemplateReturnsFileContent(): void
// given
vfsStream::setup('templates', null, ['sample-view.blade.php' => 'View Content']);
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -31,14 +31,14 @@ public function testGetTemplateReturnsFileContent(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('SampleView');
@@ -54,9 +54,9 @@ public function testGetFileBasedTemplateReturnsFileName(): void
// given
vfsStream::setup('templates', null, ['sample-view.blade.php' => 'View Content']);
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -66,14 +66,14 @@ public function testGetFileBasedTemplateReturnsFileName(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('SampleView');
@@ -89,9 +89,9 @@ public function testGetTemplateReturnsEmptyStringForMissingFile(): void
// given
vfsStream::setup('templates');
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -101,14 +101,14 @@ public function testGetTemplateReturnsEmptyStringForMissingFile(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('SampleView');
@@ -124,9 +124,9 @@ public function testGetFileBasedTemplateReturnsPathForMissingFile(): void
// given
vfsStream::setup('templates');
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -136,14 +136,14 @@ public function testGetFileBasedTemplateReturnsPathForMissingFile(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('SampleView');
@@ -159,9 +159,9 @@ public function testGetTemplateHandlesCamelCaseConversion(): void
// given
vfsStream::setup('templates', null, ['some-camel-case-view.blade.php' => 'Camel Case Content']);
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -171,14 +171,14 @@ public function testGetTemplateHandlesCamelCaseConversion(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('SomeCamelCaseView');
@@ -194,9 +194,9 @@ public function testGetFileBasedTemplateHandlesCamelCaseConversion(): void
// given
vfsStream::setup('templates', null, ['some-camel-case-view.blade.php' => 'Camel Case Content']);
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -206,14 +206,14 @@ public function testGetFileBasedTemplateHandlesCamelCaseConversion(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('SomeCamelCaseView');
@@ -229,9 +229,9 @@ public function testGetTemplateHandlesNestedNamespaces(): void
// given
vfsStream::setup('templates', null, ['admin/dashboard-view.blade.php' => 'Dashboard Content']);
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -241,14 +241,14 @@ public function testGetTemplateHandlesNestedNamespaces(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views\\Admin');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('DashboardView');
@@ -263,9 +263,9 @@ public function testGetFileBasedTemplateHandlesNestedNamespaces(): void
// given
vfsStream::setup('templates', null, ['admin/dashboard-view.blade.php' => 'Dashboard Content']);
$templateModel = Mockery::mock(TemplateModelInterface::class);
- $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceProviderInterface::class);
- $modelNameProviderMock = Mockery::mock(ModelNameProviderInterface::class);
- $provider = new FileModelTemplateProvider(
+ $modelNamespaceProviderMock = Mockery::mock(ModelNamespaceResolverInterface::class);
+ $modelNameProviderMock = Mockery::mock(ModelNameResolverInterface::class);
+ $provider = new FileModelTemplateResolver(
'App\\Views',
vfsStream::url('templates'),
'.blade.php',
@@ -275,14 +275,14 @@ public function testGetFileBasedTemplateHandlesNestedNamespaces(): void
);
// when
- $result = fn() => $provider->getModelTemplate($templateModel);
+ $result = fn() => $provider->resolveModelTemplate($templateModel);
// then
- $modelNamespaceProviderMock->shouldReceive('getModelNamespace')
+ $modelNamespaceProviderMock->shouldReceive('resolveModelNamespace')
->once()
->with($templateModel)
->andReturn('App\\Views\\Admin');
- $modelNameProviderMock->shouldReceive('getModelName')
+ $modelNameProviderMock->shouldReceive('resolveModelName')
->once()
->with($templateModel)
->andReturn('DashboardView');
diff --git a/tests/pest/Unit/Template/TemplateRendererTest.php b/tests/pest/Unit/Template/TemplateRendererTest.php
index 9828218..0f33e95 100644
--- a/tests/pest/Unit/Template/TemplateRendererTest.php
+++ b/tests/pest/Unit/Template/TemplateRendererTest.php
@@ -6,7 +6,7 @@
use Mockery;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\PrivateClasses\Template\TemplateRenderer;
class TemplateRendererTest extends TestCase
@@ -14,14 +14,14 @@ class TemplateRendererTest extends TestCase
public function testRenderTemplateReturnsRenderedContent(): void
{
// given
- $templateExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $templateExecutor = Mockery::mock(CodeRunnerInterface::class);
$renderer = new TemplateRenderer($templateExecutor);
// when
$result = fn() => $renderer->renderTemplate('{{ $var }}
', ['var' => 'Test Content']);
// then
- $templateExecutor->shouldReceive('executeCode')
+ $templateExecutor->shouldReceive('runCode')
->once()
->with('{{ $var }}
', ['var' => 'Test Content'])
->andReturnUsing(function () {
@@ -36,7 +36,7 @@ public function testRenderTemplateReturnsRenderedContent(): void
public function testRenderTemplateDoesNotPrintByDefault(): void
{
// given
- $templateExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $templateExecutor = Mockery::mock(CodeRunnerInterface::class);
$renderer = new TemplateRenderer($templateExecutor);
// when
@@ -45,7 +45,7 @@ public function testRenderTemplateDoesNotPrintByDefault(): void
$output = ob_get_clean();
// then
- $templateExecutor->shouldReceive('executeCode')
+ $templateExecutor->shouldReceive('runCode')
->once()
->with('{{ $message }}
', ['message' => 'Hello, World!'])
->andReturnUsing(function () {
@@ -59,45 +59,17 @@ public function testRenderTemplateDoesNotPrintByDefault(): void
Mockery::close();
}
- public function testRenderTemplatePrintsWhenDoPrintIsTrue(): void
- {
- // given
- $templateExecutor = Mockery::mock(CodeExecutorInterface::class);
- $renderer = new TemplateRenderer($templateExecutor);
-
- // when
- $result = fn() => $renderer->renderTemplate('{{ $title }}
', ['title' => 'Welcome'], true);
-
- // then
- $templateExecutor->shouldReceive('executeCode')
- ->once()
- ->with('{{ $title }}
', ['title' => 'Welcome'])
- ->andReturnUsing(function () {
- echo 'Welcome
';
- });
-
- ob_start();
- $rendered = $result();
- $output = ob_get_clean();
-
- $this->assertSame('Welcome
', $rendered);
- $this->assertSame('Welcome
', $output);
-
- // apply
- Mockery::close();
- }
-
public function testRenderTemplateHandlesEmptyTemplate(): void
{
// given
- $templateExecutor = Mockery::mock(CodeExecutorInterface::class);
+ $templateExecutor = Mockery::mock(CodeRunnerInterface::class);
$renderer = new TemplateRenderer($templateExecutor);
// when
$result = fn() => $renderer->renderTemplate('', []);
// then
- $templateExecutor->shouldReceive('executeCode')
+ $templateExecutor->shouldReceive('runCode')
->once()
->with('', [])
->andReturnUsing(function () {
diff --git a/tests/pest/Unit/Template/TemplateRendererWithCustomEscapeTest.php b/tests/pest/Unit/Template/TemplateRendererWithCustomEscapeTest.php
index 39e82de..14cb652 100644
--- a/tests/pest/Unit/Template/TemplateRendererWithCustomEscapeTest.php
+++ b/tests/pest/Unit/Template/TemplateRendererWithCustomEscapeTest.php
@@ -33,8 +33,7 @@ public function testRenderTemplateUsesCustomEscapeCallback(): void
Mockery::on(function ($variables) {
return is_callable($variables['escape'])
&& call_user_func($variables['escape'], 'test') === 'TEST';
- }),
- false
+ })
)
->andReturn('TEST
');
@@ -68,8 +67,7 @@ public function testRenderTemplateUsesDefaultEscapeCallback(): void
Mockery::on(function ($variables) {
return is_callable($variables['escape'])
&& call_user_func($variables['escape'], '') === '<script>alert("test")</script>';
- }),
- false
+ })
)
->andReturn('<script>alert("test")</script>
');
@@ -101,8 +99,7 @@ public function testRenderTemplateMergesVariablesWithEscapeCallback(): void
return isset($mergedVariables['escape']) &&
is_callable($mergedVariables['escape']) &&
$mergedVariables['escape']('hello') === 'hello';
- }),
- false
+ })
)
->andReturn('hello
');
diff --git a/tests/pest/Unit/Template/TemplateRendererWithEventDetailsTest.php b/tests/pest/Unit/Template/TemplateRendererWithEventDetailsTest.php
index ff3cfdb..6276382 100644
--- a/tests/pest/Unit/Template/TemplateRendererWithEventDetailsTest.php
+++ b/tests/pest/Unit/Template/TemplateRendererWithEventDetailsTest.php
@@ -23,16 +23,16 @@ public function testRenderTemplateAttachesAndDetachesEventDetails(): void
$result = fn() => $renderer->renderTemplate('{{ $var }}
', ['var' => 'Test Content']);
// then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
+ $eventDispatcherMock->shouldReceive('registerEventDetails')
->once()
->with('render_event', ['template' => '{{ $var }}
',]);
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('{{ $var }}
', ['var' => 'Test Content'], false)
+ ->with('{{ $var }}
', ['var' => 'Test Content'])
->andReturn('Test Content
');
- $eventDispatcherMock->shouldReceive('detachEventDetails')
+ $eventDispatcherMock->shouldReceive('unregisterEventDetails')
->once()
->with('render_event', ['template' => '{{ $var }}
']);
@@ -42,40 +42,6 @@ public function testRenderTemplateAttachesAndDetachesEventDetails(): void
Mockery::close();
}
- public function testRenderTemplatePassesDoPrintFlag(): void
- {
- // given
- $templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
- $eventDispatcherMock = Mockery::mock(EventDispatcherInterface::class);
- $renderer = new TemplateRendererWithEventDetails($templateRendererMock, $eventDispatcherMock, 'render_event');
-
- // when
- $result = fn() => $renderer->renderTemplate(
- '{{ $message }}
',
- ['message' => 'Hello, World!'],
- true
- );
-
- // then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
- ->once()
- ->with('render_event', ['template' => '{{ $message }}
']);
-
- $templateRendererMock->shouldReceive('renderTemplate')
- ->once()
- ->with('{{ $message }}
', ['message' => 'Hello, World!'], true)
- ->andReturn('Hello, World!
');
-
- $eventDispatcherMock->shouldReceive('detachEventDetails')
- ->once()
- ->with('render_event', ['template' => '{{ $message }}
']);
-
- $this->assertSame('Hello, World!
', $result());
-
- // apply
- Mockery::close();
- }
-
public function testRenderTemplateHandlesEmptyTemplate(): void
{
// given
@@ -87,16 +53,16 @@ public function testRenderTemplateHandlesEmptyTemplate(): void
$result = fn() => $renderer->renderTemplate('', []);
// then
- $eventDispatcherMock->shouldReceive('attachEventDetails')
+ $eventDispatcherMock->shouldReceive('registerEventDetails')
->once()
->with('render_event', ['template' => '']);
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('', [], false)
+ ->with('', [])
->andReturn('');
- $eventDispatcherMock->shouldReceive('detachEventDetails')
+ $eventDispatcherMock->shouldReceive('unregisterEventDetails')
->once()
->with('render_event', ['template' => '']);
diff --git a/tests/pest/Unit/Template/TemplateRendererWithFileTemplateTest.php b/tests/pest/Unit/Template/TemplateRendererWithFileTemplateTest.php
index 4b41d1d..5c244bc 100644
--- a/tests/pest/Unit/Template/TemplateRendererWithFileTemplateTest.php
+++ b/tests/pest/Unit/Template/TemplateRendererWithFileTemplateTest.php
@@ -28,7 +28,7 @@ public function testRenderTemplateReadsFileAndRendersContent(): void
// then
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('{{ $key }}
', ['key' => 'value'], false)
+ ->with('{{ $key }}
', ['key' => 'value'])
->andReturn('value
');
$this->assertSame('value
', $result());
@@ -51,7 +51,7 @@ public function testRenderTemplateReturnsEmptyStringForMissingFile(): void
// then
$templateRendererMock->shouldReceive('renderTemplate')
->once()
- ->with('', ['key' => 'value'], false)
+ ->with('', ['key' => 'value'])
->andReturn('');
$this->assertSame('', $result());
@@ -59,29 +59,4 @@ public function testRenderTemplateReturnsEmptyStringForMissingFile(): void
// apply
Mockery::close();
}
-
- public function testRenderTemplateHandlesDoPrintFlag(): void
- {
- // given
- vfsStream::setup('templates', null, [
- 'template.blade.php' => '{{ $key }}
',
- ]);
- $templateFilePath = vfsStream::url('templates/template.blade.php');
- $templateRendererMock = Mockery::mock(TemplateRendererInterface::class);
- $renderer = new TemplateRendererWithFileTemplate($templateRendererMock);
-
- // when
- $result = fn() => $renderer->renderTemplate($templateFilePath, ['key' => 'value'], true);
-
- // then
- $templateRendererMock->shouldReceive('renderTemplate')
- ->once()
- ->with('{{ $key }}
', ['key' => 'value'], true)
- ->andReturn('value
');
-
- $this->assertSame('value
', $result());
-
- // apply
- Mockery::close();
- }
}
diff --git a/tests/pest/Unit/Template/TemplateRendererWithModelRenderTest.php b/tests/pest/Unit/Template/TemplateRendererWithModelRenderTest.php
index 5757e59..26cfec4 100644
--- a/tests/pest/Unit/Template/TemplateRendererWithModelRenderTest.php
+++ b/tests/pest/Unit/Template/TemplateRendererWithModelRenderTest.php
@@ -40,7 +40,7 @@ public function testRenderTemplateRendersInnerModels(): void
'key1' => 'value1',
'key2' => 'Rendered Model
',
'key3' => ['nestedKey' => 'Rendered Model
'],
- ], false)
+ ])
->andReturn('Final Rendered Output
');
$this->assertEquals('Final Rendered Output
', $result());
@@ -80,7 +80,7 @@ public function testRenderTemplateIgnoresNonModelObjects(): void
'key2' => 123,
'key3' => ['nestedKey' => 'string'],
'key4' => $nonModelObject,
- ], false)
+ ])
->andReturn('Final Rendered Output
');
$this->assertEquals('Final Rendered Output
', $result());
diff --git a/tests/pest/Unit/View/ViewNamespaceContainerTest.php b/tests/pest/Unit/View/ViewNamespaceContainerTest.php
index 7dde988..5a1d333 100644
--- a/tests/pest/Unit/View/ViewNamespaceContainerTest.php
+++ b/tests/pest/Unit/View/ViewNamespaceContainerTest.php
@@ -20,10 +20,10 @@ public function testGetModulesByModelNamespace(): void
$container = new ViewNamespaceModulesContainer();
// when
- $container->addNamespaceModules('App\\Package\\Specific', $viewNamespaceModules);
+ $container->registerNamespaceModules('App\\Package\\Specific', $viewNamespaceModules);
// then
- $resolvedModules = $container->getNamespaceModulesByModelNamespace('App\\Package\\Specific\\Model');
+ $resolvedModules = $container->resolveNamespaceModules('App\\Package\\Specific\\Model');
$this->assertSame(
$viewNamespaceModules,
@@ -42,11 +42,11 @@ public function testGetModulesByModelNamespacePrefersLongerNamespace(): void
$container = new ViewNamespaceModulesContainer();
// when
- $container->addNamespaceModules('App\\Package', $shortNamespaceModules);
- $container->addNamespaceModules('App\\Package\\Specific', $longNamespaceModules);
+ $container->registerNamespaceModules('App\\Package', $shortNamespaceModules);
+ $container->registerNamespaceModules('App\\Package\\Specific', $longNamespaceModules);
// then
- $resolvedModules = $container->getNamespaceModulesByModelNamespace('App\\Package\\Specific\\Model');
+ $resolvedModules = $container->resolveNamespaceModules('App\\Package\\Specific\\Model');
$this->assertSame(
$longNamespaceModules,
@@ -64,10 +64,10 @@ public function testGetModulesByModelNamespaceReturnsNullWhenNotFound(): void
$container = new ViewNamespaceModulesContainer();
// when
- $container->addNamespaceModules('App\\Package\\Specific', $viewNamespaceModules);
+ $container->registerNamespaceModules('App\\Package\\Specific', $viewNamespaceModules);
// then
- $resolvedModules = $container->getNamespaceModulesByModelNamespace('Another\\Package');
+ $resolvedModules = $container->resolveNamespaceModules('Another\\Package');
$this->assertNull(
$resolvedModules
diff --git a/tests/pest/Unit/View/ViewNamespaceTest.php b/tests/pest/Unit/View/ViewNamespaceTest.php
index abbd65e..13f93f1 100644
--- a/tests/pest/Unit/View/ViewNamespaceTest.php
+++ b/tests/pest/Unit/View/ViewNamespaceTest.php
@@ -8,14 +8,14 @@
use PHPUnit\Framework\TestCase;
use Prosopo\Views\Interfaces\EventDispatcherInterface;
use Prosopo\Views\Interfaces\Model\ModelFactoryInterface;
-use Prosopo\Views\Interfaces\Model\ModelNameProviderInterface;
-use Prosopo\Views\Interfaces\Model\ModelNamespaceProviderInterface;
+use Prosopo\Views\Interfaces\Model\ModelNameResolverInterface;
+use Prosopo\Views\Interfaces\Model\ModelNamespaceResolverInterface;
use Prosopo\Views\Interfaces\Model\ModelRendererInterface;
use Prosopo\Views\Interfaces\Model\TemplateModelInterface;
use Prosopo\Views\Interfaces\Object\ObjectPropertyWriterInterface;
use Prosopo\Views\Interfaces\Object\ObjectReaderInterface;
use Prosopo\Views\Interfaces\Object\PropertyValueProviderInterface;
-use Prosopo\Views\Interfaces\Template\ModelTemplateProviderInterface;
+use Prosopo\Views\Interfaces\Template\ModelTemplateResolverInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
use Prosopo\Views\PrivateClasses\View\ViewNamespace;
use Prosopo\Views\View\ViewNamespaceConfig;
@@ -72,7 +72,7 @@ public function testMakesModelTemplateProvider()
$this->testUsesGivenModule(
null,
function (ViewNamespaceModules $modules) {
- $this->assertNotNull($modules->getModelTemplateProvider());
+ $this->assertNotNull($modules->getModelTemplateResolver());
}
);
}
@@ -102,7 +102,7 @@ public function testMakesModelNameProvider()
$this->testUsesGivenModule(
null,
function (ViewNamespaceModules $modules) {
- $this->assertNotNull($modules->getModelNameProvider());
+ $this->assertNotNull($modules->getModelNameResolver());
}
);
}
@@ -112,7 +112,7 @@ public function testMakesModelNamespaceProvider()
$this->testUsesGivenModule(
null,
function (ViewNamespaceModules $modules) {
- $this->assertNotNull($modules->getModelNamespaceProvider());
+ $this->assertNotNull($modules->getModelNamespaceResolver());
}
);
}
@@ -158,12 +158,12 @@ function (ViewNamespaceModules $modules) use ($module) {
function (ViewNamespaceModules $modules) {
$instance = Mockery::mock(StdClass::class);
- $modules->getObjectReader()->getObjectVariables($instance);
+ $modules->getObjectReader()->extractObjectVariables($instance);
}
);
// then
- $module->shouldReceive('getObjectVariables')
+ $module->shouldReceive('extractObjectVariables')
->once()
->andReturn([]);
@@ -217,12 +217,12 @@ function (ViewNamespaceModules $modules) {
$instance = Mockery::mock(StdClass::class);
$propertyValueProvider = Mockery::mock(PropertyValueProviderInterface::class);
- $modules->getObjectPropertyWriter()->setObjectPropertyValues($instance, $propertyValueProvider);
+ $modules->getObjectPropertyWriter()->assignPropertyValues($instance, $propertyValueProvider);
}
);
// then
- $module->shouldReceive('setObjectPropertyValues')
+ $module->shouldReceive('assignPropertyValues')
->once();
// apply
@@ -242,12 +242,12 @@ function (ViewNamespaceModules $modules) use ($module) {
$modules->setModelFactory($module);
},
function (ViewNamespaceModules $modules) {
- $modules->getModelFactory()->makeModel('test');
+ $modules->getModelFactory()->createModel('test');
}
);
// then
- $module->shouldReceive('makeModel')
+ $module->shouldReceive('createModel')
->once()
->andReturn(null);
@@ -260,22 +260,22 @@ function (ViewNamespaceModules $modules) {
public function testUsesGivenModelTemplateProvider(): void
{
// given
- $module = Mockery::mock(ModelTemplateProviderInterface::class);
+ $module = Mockery::mock(ModelTemplateResolverInterface::class);
// when
$test = fn()=>$this->testUsesGivenModule(
function (ViewNamespaceModules $modules) use ($module) {
- $modules->setModelTemplateProvider($module);
+ $modules->setModelTemplateResolver($module);
},
function (ViewNamespaceModules $modules) {
$model = Mockery::mock(TemplateModelInterface::class);
- $modules->getModelTemplateProvider()->getModelTemplate($model);
+ $modules->getModelTemplateResolver()->resolveModelTemplate($model);
}
);
// then
- $module->shouldReceive('getModelTemplate')
+ $module->shouldReceive('resolveModelTemplate')
->once()
->andReturn('');
@@ -324,12 +324,12 @@ function (ViewNamespaceModules $modules) use ($module) {
$modules->setEventDispatcher($module);
},
function (ViewNamespaceModules $modules) {
- $modules->getEventDispatcher()->attachEventDetails('test', []);
+ $modules->getEventDispatcher()->registerEventDetails('test', []);
}
);
// then
- $module->shouldReceive('attachEventDetails')
+ $module->shouldReceive('registerEventDetails')
->once();
// apply
@@ -341,22 +341,22 @@ function (ViewNamespaceModules $modules) {
public function testUsesGivenModelNameProvider(): void
{
// given
- $module = Mockery::mock(ModelNameProviderInterface::class);
+ $module = Mockery::mock(ModelNameResolverInterface::class);
// when
$test = fn()=>$this->testUsesGivenModule(
function (ViewNamespaceModules $modules) use ($module) {
- $modules->setModelNameProvider($module);
+ $modules->setModelNameResolver($module);
},
function (ViewNamespaceModules $modules) {
$model = Mockery::mock(TemplateModelInterface::class);
- $modules->getModelNameProvider()->getModelName($model);
+ $modules->getModelNameResolver()->resolveModelName($model);
}
);
// then
- $module->shouldReceive('getModelName')
+ $module->shouldReceive('resolveModelName')
->once();
// apply
@@ -368,20 +368,20 @@ function (ViewNamespaceModules $modules) {
public function testUsesGivenModelNamespaceProvider(): void
{
// given
- $module = Mockery::mock(ModelNamespaceProviderInterface::class);
+ $module = Mockery::mock(ModelNamespaceResolverInterface::class);
// when
$test = fn()=>$this->testUsesGivenModule(
function (ViewNamespaceModules $modules) use ($module) {
- $modules->setModelNamespaceProvider($module);
+ $modules->setModelNamespaceResolver($module);
},
function (ViewNamespaceModules $modules) {
- $modules->getModelNamespaceProvider()->getModelNamespace('test');
+ $modules->getModelNamespaceResolver()->resolveModelNamespace('test');
}
);
// then
- $module->shouldReceive('getModelNamespace')
+ $module->shouldReceive('resolveModelNamespace')
->once();
// apply
diff --git a/tests/pest/Unit/View/ViewTemplateRendererTest.php b/tests/pest/Unit/View/ViewTemplateRendererTest.php
index 125b6a8..e77b098 100644
--- a/tests/pest/Unit/View/ViewTemplateRendererTest.php
+++ b/tests/pest/Unit/View/ViewTemplateRendererTest.php
@@ -6,7 +6,7 @@
use Mockery;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\Interfaces\CodeExecutorInterface;
+use Prosopo\Views\Interfaces\CodeRunnerInterface;
use Prosopo\Views\Interfaces\EventDispatcherInterface;
use Prosopo\Views\Interfaces\Template\TemplateCompilerInterface;
use Prosopo\Views\Interfaces\Template\TemplateRendererInterface;
@@ -85,12 +85,12 @@ function (ViewTemplateRendererModules $modules) use ($module) {
$modules->setEventDispatcher($module);
},
function (ViewTemplateRendererModules $modules) {
- $modules->getEventDispatcher()->attachEventDetails('test', []);
+ $modules->getEventDispatcher()->registerEventDetails('test', []);
}
);
// then
- $module->shouldReceive('attachEventDetails')
+ $module->shouldReceive('registerEventDetails')
->once();
// apply
@@ -127,7 +127,7 @@ function (ViewTemplateRendererModules $modules) {
public function testUsesGivenCodeExecutor(): void
{
// given
- $module = Mockery::mock(CodeExecutorInterface::class);
+ $module = Mockery::mock(CodeRunnerInterface::class);
// when
$test = fn()=>$this->testUsesGivenModule(
@@ -135,12 +135,12 @@ function (ViewTemplateRendererModules $modules) use ($module) {
$modules->setCodeExecutor($module);
},
function (ViewTemplateRendererModules $modules) {
- $modules->getCodeExecutor()->executeCode('test');
+ $modules->getCodeExecutor()->runCode('test');
}
);
// then
- $module->shouldReceive('executeCode')
+ $module->shouldReceive('runCode')
->once();
// apply
diff --git a/tests/pest/Unit/ViewsTest.php b/tests/pest/Unit/ViewsManagerTest.php
similarity index 80%
rename from tests/pest/Unit/ViewsTest.php
rename to tests/pest/Unit/ViewsManagerTest.php
index f46d5fc..2dc0766 100644
--- a/tests/pest/Unit/ViewsTest.php
+++ b/tests/pest/Unit/ViewsManagerTest.php
@@ -6,17 +6,17 @@
use Exception;
use PHPUnit\Framework\TestCase;
-use Prosopo\Views\Views;
+use Prosopo\Views\ViewsManager;
-class ViewsTest extends TestCase
+class ViewsManagerTest extends TestCase
{
public function testMakeModelThrowsExceptionForMissingClass(): void
{
// given
- $views = new Views();
+ $views = new ViewsManager();
// when
- $makeModel = fn()=> $views->makeModel('MissingClass');
+ $makeModel = fn()=> $views->createModel('MissingClass');
// then
$this->expectException(Exception::class);
@@ -28,10 +28,10 @@ public function testMakeModelThrowsExceptionForMissingClass(): void
public function testMakeModelThrowsExceptionForClassThatNotImplementTemplateModelInterface(): void
{
// given
- $views = new Views();
+ $views = new ViewsManager();
// when
- $makeModel = fn()=> $views->makeModel(get_class($this));
+ $makeModel = fn()=> $views->createModel(get_class($this));
// then
$this->expectException(Exception::class);
@@ -43,7 +43,7 @@ public function testMakeModelThrowsExceptionForClassThatNotImplementTemplateMode
public function testRenderThrowsExceptionForMissingClass(): void
{
// given
- $views = new Views();
+ $views = new ViewsManager();
// when
$makeModel = fn()=> $views->renderModel('MissingClass');
@@ -58,7 +58,7 @@ public function testRenderThrowsExceptionForMissingClass(): void
public function testRenderThrowsExceptionForClassThatNotImplementTemplateModelInterface(): void
{
// given
- $views = new Views();
+ $views = new ViewsManager();
// when
$makeModel = fn()=> $views->renderModel(get_class($this));
@@ -73,7 +73,7 @@ public function testRenderThrowsExceptionForClassThatNotImplementTemplateModelIn
public function testRenderThrowsExceptionForInstanceThatNotImplementTemplateModelInterface(): void
{
// given
- $views = new Views();
+ $views = new ViewsManager();
// when
$makeModel = fn()=> $views->renderModel($this);