Skip to content

Commit eb8f21d

Browse files
committed
fix twig crlf with lf
1 parent 4c49ccb commit eb8f21d

163 files changed

Lines changed: 19184 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\DBAL\Types;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
9+
class UuidType extends \Ramsey\Uuid\Doctrine\UuidType
10+
{
11+
public const NAME = 'uuid';
12+
13+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
14+
{
15+
return 'UUID';
16+
}
17+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{% extends '@layout/default.html.twig' %}
2+
3+
{% block title %}Listen for Android install referrer{% endblock %}
4+
5+
{% block page_title %}
6+
<div class="mb-2 text-uppercase small fw-bold text-primary tracking-wider">Android</div>
7+
<h1 class="fw-bold text-dark display-6 mb-0">Listen for Android install referrer</h1>
8+
<hr class="mt-4 mb-2 opacity-25">
9+
{% endblock %}
10+
11+
{% block content %}
12+
<div class="container py-4">
13+
<div class="row g-4">
14+
15+
{% include '@partial/left-menu.html.twig' %}
16+
17+
<main class="col-12 col-md-8 col-lg-9">
18+
<article class="card border-0 shadow-sm p-4 p-md-5 h-100">
19+
<header class="mb-4">
20+
<h1 class="h2 text-dark fw-bold">Listen for Android install referrer</h1>
21+
<div class="text-muted small">
22+
<i class="bi bi-folder2-open me-1"></i> Android
23+
</div>
24+
</header>
25+
26+
<section class="post-content text-secondary lh-lg fs-6">
27+
Have you ever wondered if Android market sends you information at the moment of app install? Wouldn"t be nice to create custom links to your android application, including bits of information about the referrer, and send it directly to the app for <a href="http://www.cillap.com/">online casino</a> processing at install? This could be a simple and accurate solution for mobile app install tracking but I"m sure you can find this useful in many ways.
28+
29+
With Android, you actually get this information as a broadcasted intent by android market at install time - even before opening your app...
30+
31+
&nbsp;
32+
</section>
33+
</article>
34+
</main>
35+
36+
</div>
37+
</div>
38+
{% endblock %}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{% extends '@layout/default.html.twig' %}
2+
3+
{% block title %}Multiple broadcast receivers in the same app, for the same action{% endblock %}
4+
5+
{% block page_title %}
6+
<div class="mb-2 text-uppercase small fw-bold text-primary tracking-wider">Android</div>
7+
<h1 class="fw-bold text-dark display-6 mb-0">Multiple broadcast receivers in the same app, for the same action</h1>
8+
<hr class="mt-4 mb-2 opacity-25">
9+
{% endblock %}
10+
11+
{% block content %}
12+
<div class="container py-4">
13+
<div class="row g-4">
14+
15+
{% include '@partial/left-menu.html.twig' %}
16+
17+
<main class="col-12 col-md-8 col-lg-9">
18+
<article class="card border-0 shadow-sm p-4 p-md-5 h-100">
19+
<header class="mb-4">
20+
<h1 class="h2 text-dark fw-bold">Multiple broadcast receivers in the same app, for the same action</h1>
21+
<div class="text-muted small">
22+
<i class="bi bi-folder2-open me-1"></i> Android
23+
</div>
24+
</header>
25+
26+
<section class="post-content text-secondary lh-lg fs-6">
27+
Did you come to a point where using multiple broadcast receivers to listen for the same intent, separatly, in the same android app, leads to unexpected results? If that"s the case, one broadcast receiver might consume the broadcasted intent, <a href="http://www.cillap.com/">online casino</a> leaving the others with nothing to receive. This can be the case where you use 3rd party libraries with broadcast receivers defined.
28+
29+
The following is a solution for this kind of problem, a code snippet inspired by the way Admob for android seems to solve this, as shown in their <a title="Admob Download Tracking" href="http://developer.admob.com/wiki/Android_App_Download_Tracking" target="_blank" rel="noopener noreferrer">documentation</a>, using meta-data in manifest file....
30+
</section>
31+
</article>
32+
</main>
33+
34+
</div>
35+
</div>
36+
{% endblock %}
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
{% extends '@layout/default.html.twig' %}
2+
3+
{% block title %}ConfigProvider - Bootstrap Modern PHP Applications{% endblock %}
4+
5+
{% block page_title %}
6+
<div class="mb-2 text-uppercase small fw-bold text-primary tracking-wider">Architecture</div>
7+
<h1 class="fw-bold text-dark display-6 mb-0">ConfigProvider - Bootstrap Modern PHP Applications</h1>
8+
<hr class="mt-4 mb-2 opacity-25">
9+
{% endblock %}
10+
11+
{% block content %}
12+
<div class="container py-4">
13+
<div class="row g-4">
14+
15+
{% include '@partial/left-menu.html.twig' %}
16+
17+
<main class="col-12 col-md-8 col-lg-9">
18+
<article class="card border-0 shadow-sm p-4 p-md-5 h-100">
19+
<header class="mb-4">
20+
<h1 class="h2 text-dark fw-bold">ConfigProvider - Bootstrap Modern PHP Applications</h1>
21+
<div class="text-muted small">
22+
<i class="bi bi-folder2-open me-1"></i> Architecture
23+
</div>
24+
</header>
25+
26+
<section class="post-content text-secondary lh-lg fs-6">
27+
<!-- wp:paragraph -->
28+
<p class="mb-3">In PHP, the <code>ConfigProvider</code> is a class that is part of an application's bootstrap process. <strong>It's a class or callable that returns configuration data telling the platform which middleware should run, in what order, and sometimes under what conditions.</strong></p>
29+
<!-- /wp:paragraph -->
30+
31+
<!-- wp:paragraph -->
32+
<p class="mb-3">If you're talking specifically about the ConfigProvider in the Laminas/Mezzio ecosystem, it's literally an array of configuration, settings, or anything else your application needs.</p>
33+
<!-- /wp:paragraph -->
34+
35+
<!-- wp:heading -->
36+
<h2 class="wp-block-heading"><a href="#where-is-the-configprovider-used"></a>Where Is the ConfigProvider Used?</h2>
37+
<!-- /wp:heading -->
38+
39+
<!-- wp:paragraph -->
40+
<p class="mb-3">Mezzio (formerly Zend Expressive), Laminas, Slim, the Dotkernel Headless Platform, or other middleware-based frameworks often have a <code>ConfigProvider</code> class. In Laminas/Mezzio specifically, each module or package may contain a <code>ConfigProvider</code> that returns:</p>
41+
<!-- /wp:paragraph -->
42+
43+
<!-- wp:list -->
44+
<ul class="wp-block-list"><!-- wp:list-item -->
45+
<li>Middleware pipeline configuration.<!-- wp:list -->
46+
<ul class="wp-block-list"><!-- wp:list-item -->
47+
<li>Middleware classes or service names.</li>
48+
<!-- /wp:list-item -->
49+
50+
<!-- wp:list-item -->
51+
<li>Error-handling middleware, which should have the lowest priority.</li>
52+
<!-- /wp:list-item -->
53+
54+
<!-- wp:list-item -->
55+
<li>Middleware groups or nested arrays.</li>
56+
<!-- /wp:list-item --></ul>
57+
<!-- /wp:list --></li>
58+
<!-- /wp:list-item -->
59+
60+
<!-- wp:list-item -->
61+
<li>Dependency injection mappings.</li>
62+
<!-- /wp:list-item -->
63+
64+
<!-- wp:list-item -->
65+
<li>Request Handlers.</li>
66+
<!-- /wp:list-item --></ul>
67+
<!-- /wp:list -->
68+
69+
<!-- wp:paragraph -->
70+
<p class="mb-3">Example in Dotkernel, which is an approach similar to Laminas/Mezzio:</p>
71+
<!-- /wp:paragraph -->
72+
73+
<!-- wp:enlighter/codeblock {"language":"php"} -->
74+
<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">class ConfigProvider
75+
{
76+
public function __invoke(): array
77+
{
78+
return ;
79+
}
80+
81+
public function getDependencies(): array
82+
{
83+
return ,
84+
'invokables' => ,
85+
];
86+
}
87+
88+
public function getTemplates(): array
89+
{
90+
return ,
91+
'error' => ,
92+
];
93+
}
94+
}</pre>
95+
<!-- /wp:enlighter/codeblock -->
96+
97+
<!-- wp:paragraph -->
98+
<p class="mb-3">What each item above means:</p>
99+
<!-- /wp:paragraph -->
100+
101+
<!-- wp:list -->
102+
<ul class="wp-block-list"><!-- wp:list-item -->
103+
<li><code>dependencies</code> is used by the dependency injector (like <a href="https://docs.mezzio.dev/mezzio/v3/features/container/laminas-servicemanager/" target="_blank" rel="noreferrer noopener">laminas-servicemanager</a>) to construct every requested service.<!-- wp:list -->
104+
<ul class="wp-block-list"><!-- wp:list-item -->
105+
<li><code>factories</code> will have the factory build the service.</li>
106+
<!-- /wp:list-item -->
107+
108+
<!-- wp:list-item -->
109+
<li><code>invokables</code> will use <code>new</code> directly.</li>
110+
<!-- /wp:list-item -->
111+
112+
<!-- wp:list-item -->
113+
<li>You can also use <code>aliases</code> to redirect to another service name and <code>delegators</code> to wrap the original service.</li>
114+
<!-- /wp:list-item --></ul>
115+
<!-- /wp:list --></li>
116+
<!-- /wp:list-item -->
117+
118+
<!-- wp:list-item -->
119+
<li><code>templates</code> defines the paths for the template files.</li>
120+
<!-- /wp:list-item --></ul>
121+
<!-- /wp:list -->
122+
123+
<!-- wp:heading -->
124+
<h2 class="wp-block-heading"><a href="#how-the-configprovider-works"></a>How the ConfigProvider works</h2>
125+
<!-- /wp:heading -->
126+
127+
<!-- wp:paragraph -->
128+
<p class="mb-3">The ConfigProvider is automatically picked up by the framework during application bootstrap. Let's look at it step by step:</p>
129+
<!-- /wp:paragraph -->
130+
131+
<!-- wp:list -->
132+
<ul class="wp-block-list"><!-- wp:list-item -->
133+
<li><strong>Merge the global configuration</strong> - All ConfigProviders are merged into one array.</li>
134+
<!-- /wp:list-item -->
135+
136+
<!-- wp:list-item -->
137+
<li><strong>Read the configuration array</strong> - The call is similar to the below and expects an array of entries:</li>
138+
<!-- /wp:list-item --></ul>
139+
<!-- /wp:list -->
140+
141+
<!-- wp:enlighter/codeblock {"language":"php"} -->
142+
<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">$config = $container->get('config') ?? [];</pre>
143+
<!-- /wp:enlighter/codeblock -->
144+
145+
<!-- wp:list -->
146+
<ul class="wp-block-list"><!-- wp:list-item -->
147+
<li><strong>Resolve item</strong> - <code>$app-&gt;pipe()</code> is called to resolve one of the below instances:<!-- wp:list -->
148+
<ul class="wp-block-list"><!-- wp:list-item -->
149+
<li>Resolve the service name from the container</li>
150+
<!-- /wp:list-item -->
151+
152+
<!-- wp:list-item -->
153+
<li>Wrap the middleware, if an array is provided</li>
154+
<!-- /wp:list-item -->
155+
156+
<!-- wp:list-item -->
157+
<li>Call the closure or invokable object.</li>
158+
<!-- /wp:list-item --></ul>
159+
<!-- /wp:list --></li>
160+
<!-- /wp:list-item -->
161+
162+
<!-- wp:list-item -->
163+
<li><strong>Handle errors</strong> - This middleware is the last one in the pipeline to make sure it handles any exceptions.</li>
164+
<!-- /wp:list-item -->
165+
166+
<!-- wp:list-item -->
167+
<li><strong>Execute at runtime</strong> - <a href="https://docs.laminas.dev/laminas-stratigility/" target="_blank" rel="noreferrer noopener">Laminas Stratigility</a> iterates over the pipeline in the order it was registered.<!-- wp:list -->
168+
<ul class="wp-block-list"><!-- wp:list-item -->
169+
<li>Each middleware can <strong>handle</strong> the request and return a response, or <strong>delegate</strong> execution to the next middleware in the pipeline, until a <code>ResponseInterface</code> is returned to the client.</li>
170+
<!-- /wp:list-item --></ul>
171+
<!-- /wp:list --></li>
172+
<!-- /wp:list-item --></ul>
173+
<!-- /wp:list -->
174+
175+
<!-- wp:paragraph -->
176+
<p class="mb-3">Below you can see how Mezzio and Dotkernel merge and use ConfigProviders to build the middleware pipeline and dependencies.</p>
177+
<!-- /wp:paragraph -->
178+
179+
<!-- wp:image {"id":8186,"sizeSlug":"full","linkDestination":"custom"} -->
180+
<figure class="wp-block-image size-full"><img src="https://www.dotkernel.com/wp-content/uploads/2025/08/ConfigProvider2.png" alt="" class="wp-image-8186"/ class="img-fluid rounded my-2"></figure>
181+
<!-- /wp:image -->
182+
183+
<!-- wp:heading -->
184+
<h2 class="wp-block-heading"><a href="#benefits"></a>Benefits</h2>
185+
<!-- /wp:heading -->
186+
187+
<!-- wp:list -->
188+
<ul class="wp-block-list"><!-- wp:list-item -->
189+
<li>Centralized setup – Instead of hardcoding bootstrap code, you declare it in a config provider so it's easy to read, change, or extend.</li>
190+
<!-- /wp:list-item -->
191+
192+
<!-- wp:list-item -->
193+
<li>Modular – Each package can ship with its own config without interfering with others.</li>
194+
<!-- /wp:list-item -->
195+
196+
<!-- wp:list-item -->
197+
<li>Container-friendly – It works well with frameworks using DI containers like Laminas ServiceManager, PHP-DI, or Pimple.</li>
198+
<!-- /wp:list-item -->
199+
200+
<!-- wp:list-item -->
201+
<li>Standardized service definitions - It has consistent rules for object creation that are separate from business logic.</li>
202+
<!-- /wp:list-item -->
203+
204+
<!-- wp:list-item -->
205+
<li>Auto-Discovery - In Laminas/Mezzio, the <a href="https://docs.laminas.dev/laminas-config-aggregator/" target="_blank" rel="noreferrer noopener">ConfigAggregator</a> automatically loads and merges all ConfigProviders.</li>
206+
<!-- /wp:list-item --></ul>
207+
<!-- /wp:list -->
208+
209+
<!-- wp:quote -->
210+
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
211+
<p class="mb-3">Dotkernel is an exception to this rule: new ConfigProviders have to be added manually in <code>config/config.php</code>, because all the initial ConfigProviders required to install the applications are already injected.</p>
212+
<!-- /wp:paragraph --></blockquote>
213+
<!-- /wp:quote -->
214+
215+
<!-- wp:list -->
216+
<ul class="wp-block-list"><!-- wp:list-item -->
217+
<li>Environment-agnostic - It returns an array that defines dev, test, or prod environments.</li>
218+
<!-- /wp:list-item -->
219+
220+
<!-- wp:list-item -->
221+
<li>Testability - The consistent, central configuration promotes isolated (e.g. per-module) testing, easier swapping of dependencies and the assertion of pipeline setup (e.g. check if a config key is present).</li>
222+
<!-- /wp:list-item --></ul>
223+
<!-- /wp:list -->
224+
225+
<!-- wp:heading -->
226+
<h2 class="wp-block-heading"><a href="#additional-resources"></a>Additional Resources</h2>
227+
<!-- /wp:heading -->
228+
229+
<!-- wp:list -->
230+
<ul class="wp-block-list"><!-- wp:list-item -->
231+
<li><a href="https://docs.mezzio.dev/mezzio/v3/features/container/config/" target="_blank" rel="noreferrer noopener">Mezzio Container</a></li>
232+
<!-- /wp:list-item -->
233+
234+
<!-- wp:list-item -->
235+
<li><a href="https://docs.laminas.dev/laminas-config-aggregator/config-providers/" target="_blank" rel="noreferrer noopener">Laminas Config Aggregator</a></li>
236+
<!-- /wp:list-item -->
237+
238+
<!-- wp:list-item -->
239+
<li><a href="https://www.php-fig.org/psr/psr-15/" target="_blank" rel="noreferrer noopener">PSR-15 (HTTP Server Request Handlers)</a></li>
240+
<!-- /wp:list-item --></ul>
241+
<!-- /wp:list -->
242+
243+
<!-- wp:paragraph -->
244+
<p class="mb-3"></p>
245+
<!-- /wp:paragraph -->
246+
</section>
247+
</article>
248+
</main>
249+
250+
</div>
251+
</div>
252+
{% endblock %}

0 commit comments

Comments
 (0)