Skip to content

Commit ca4e97c

Browse files
authored
Merge pull request #17 from dotkernel/stefan-dev
.MD files, json-ld updated with faq also twig files updated with faq
2 parents c8d200b + 3903c81 commit ca4e97c

396 files changed

Lines changed: 18870 additions & 3149 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.

config/autoload/app.global.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
$baseUrl = 'https://new.dotkernel.com/';
5+
$baseUrl = 'https://www.dotkernel.com/';
66
$app = [
77
'baseUrl' => $baseUrl,
88
'name' => 'Dotkernel Light | PSR-15 compliant application',

public/css/app.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/llms.txt

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,36 @@ Content spans foundational PHP/middleware architecture (PSR-7, PSR-15, request l
66

77
## Docs
88

9-
- [Blog](https://new.dotkernel.com/blog/): full list of posts, most recent first, paginated
10-
- [Categories](https://new.dotkernel.com/categories/): all categories with post counts
11-
- [About](https://new.dotkernel.com/about/): what Dotkernel Light is
12-
- [Who We Are](https://new.dotkernel.com/who-we-are/): team/company background
13-
- [OSS Package Lifecycle](https://new.dotkernel.com/dotkernel-packages-oss-lifecycle/): support/maintenance status of Dotkernel's open-source packages
14-
- [Contact](https://new.dotkernel.com/contact/)
9+
- [Blog](https://www.dotkernel.com/blog/): full list of posts, most recent first, paginated
10+
- [Categories](https://www.dotkernel.com/categories/): all categories with post counts
11+
- [About](https://www.dotkernel.com/about/): what Dotkernel Light is
12+
- [Who We Are](https://www.dotkernel.com/who-we-are/): team/company background
13+
- [OSS Package Lifecycle](https://www.dotkernel.com/dotkernel-packages-oss-lifecycle/): support/maintenance status of Dotkernel's open-source packages
14+
- [Contact](https://www.dotkernel.com/contact/)
1515

1616
## Categories
1717

18-
- [Dotkernel](https://new.dotkernel.com/category/dotkernel/): the core framework — releases, caching, sessions, auth, WURFL/device detection (64 posts)
19-
- [PHP Development](https://new.dotkernel.com/category/php-development/): general PHP tooling, environments, IDEs, security (20 posts)
20-
- [How to's](https://new.dotkernel.com/category/how-to/): practical guides — migrations, CORS, PSR-7, routing (14 posts)
21-
- [Best Practice](https://new.dotkernel.com/category/best-practice/): coding standards and database access patterns (13 posts)
22-
- [Dotkernel API](https://new.dotkernel.com/category/dotkernel-api/): REST API package — auth, content negotiation, OpenAPI (10 posts)
23-
- [Dotkernel 3](https://new.dotkernel.com/category/dotkernel3/): the v3 rewrite on Zend Expressive/Mezzio (9 posts)
24-
- [Headless Platform](https://new.dotkernel.com/category/headless-platform/): the current Dotkernel headless architecture (9 posts)
25-
- [Zend Framework](https://new.dotkernel.com/category/zend-framework/): Zend Framework 1 history and end-of-life notes (8 posts)
26-
- [Javascript](https://new.dotkernel.com/category/javascript/): frontend/JS topics (3 posts)
27-
- [Middleware](https://new.dotkernel.com/category/middleware/): PSR-15 middleware and routing internals (3 posts)
28-
- [Architecture](https://new.dotkernel.com/category/architecture/): request lifecycle and application bootstrapping (3 posts)
29-
- [PHP Troubleshooting](https://new.dotkernel.com/category/php-troubleshooting/): fixes for common PHP setup issues (2 posts)
30-
- [Android](https://new.dotkernel.com/category/android/): Android install-referrer and broadcast receivers (2 posts)
31-
- [PHPStorm](https://new.dotkernel.com/category/phpstorm/): IDE setup (1 post)
32-
- [Licensing](https://new.dotkernel.com/category/licensing/): open-source license comparisons (1 post)
18+
- [Dotkernel](https://www.dotkernel.com/category/dotkernel/): the core framework — releases, caching, sessions, auth, WURFL/device detection (64 posts)
19+
- [PHP Development](https://www.dotkernel.com/category/php-development/): general PHP tooling, environments, IDEs, security (20 posts)
20+
- [How to's](https://www.dotkernel.com/category/how-to/): practical guides — migrations, CORS, PSR-7, routing (14 posts)
21+
- [Best Practice](https://www.dotkernel.com/category/best-practice/): coding standards and database access patterns (13 posts)
22+
- [Dotkernel API](https://www.dotkernel.com/category/dotkernel-api/): REST API package — auth, content negotiation, OpenAPI (10 posts)
23+
- [Dotkernel 3](https://www.dotkernel.com/category/dotkernel3/): the v3 rewrite on Zend Expressive/Mezzio (9 posts)
24+
- [Headless Platform](https://www.dotkernel.com/category/headless-platform/): the current Dotkernel headless architecture (9 posts)
25+
- [Zend Framework](https://www.dotkernel.com/category/zend-framework/): Zend Framework 1 history and end-of-life notes (8 posts)
26+
- [Javascript](https://www.dotkernel.com/category/javascript/): frontend/JS topics (3 posts)
27+
- [Middleware](https://www.dotkernel.com/category/middleware/): PSR-15 middleware and routing internals (3 posts)
28+
- [Architecture](https://www.dotkernel.com/category/architecture/): request lifecycle and application bootstrapping (3 posts)
29+
- [PHP Troubleshooting](https://www.dotkernel.com/category/php-troubleshooting/): fixes for common PHP setup issues (2 posts)
30+
- [Android](https://www.dotkernel.com/category/android/): Android install-referrer and broadcast receivers (2 posts)
31+
- [PHPStorm](https://www.dotkernel.com/category/phpstorm/): IDE setup (1 post)
32+
- [Licensing](https://www.dotkernel.com/category/licensing/): open-source license comparisons (1 post)
3333

3434
## Optional
3535

36-
- [Dotkernel Headless Platform: The What's, How's and Why's](https://new.dotkernel.com/headless-platform/dotkernel-headless-platform-the-whats-hows-and-whys/): best starting point for understanding the current platform
37-
- [Understanding Middleware](https://new.dotkernel.com/architecture/understanding-middleware/)
38-
- [Request Lifecycle for a Mezzio Based Application](https://new.dotkernel.com/architecture/request-lifecycle-for-a-mezzio-based-application/)
39-
- [ConfigProvider: Bootstrap Modern PHP Applications](https://new.dotkernel.com/architecture/configprovider-bootstrap-modern-php-applications/)
40-
- [What is PSR-7 and How to Use It](https://new.dotkernel.com/how-to/what-is-psr-7-and-how-to-use-it/)
41-
- [Dependency Injection Made Easy in Laminas/Mezzio Applications](https://new.dotkernel.com/dotkernel/dependency-injection-made-easy-in-laminas-mezzio-applications/)
36+
- [Dotkernel Headless Platform: The What's, How's and Why's](https://www.dotkernel.com/headless-platform/dotkernel-headless-platform-the-whats-hows-and-whys/): best starting point for understanding the current platform
37+
- [Understanding Middleware](https://www.dotkernel.com/architecture/understanding-middleware/)
38+
- [Request Lifecycle for a Mezzio Based Application](https://www.dotkernel.com/architecture/request-lifecycle-for-a-mezzio-based-application/)
39+
- [ConfigProvider: Bootstrap Modern PHP Applications](https://www.dotkernel.com/architecture/configprovider-bootstrap-modern-php-applications/)
40+
- [What is PSR-7 and How to Use It](https://www.dotkernel.com/how-to/what-is-psr-7-and-how-to-use-it/)
41+
- [Dependency Injection Made Easy in Laminas/Mezzio Applications](https://www.dotkernel.com/dotkernel/dependency-injection-made-easy-in-laminas-mezzio-applications/)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: "Listen for Android install referrer"
3+
description: "Android market broadcasts an intent containing referrer information at install time, before the app is opened, which can be used for install tracking."
4+
author: "n3vrax"
5+
date_published: "2011-07-24"
6+
canonical_url: "https://www.dotkernel.com/android/listen-for-android-install-referrer/"
7+
category: "Android"
8+
language: "en"
9+
---
10+
11+
# Listen for Android install referrer
12+
13+
## Getting Referrer Data at Install Time
14+
15+
Android market sends information at the moment of app install, delivered as a broadcasted intent by Android market at install time - even before the app is opened for the first time. This can be used to create custom links to an Android application, including bits of information about the referrer, sent directly to the app for processing at install. It can be a simple and accurate solution for mobile app install tracking, among other uses.
16+
17+
## FAQ
18+
19+
**Q: Does Android send information when the app is installed?**
20+
A: Yes. Android market broadcasts an intent containing referrer information at the moment the app is installed.
21+
22+
**Q: When is this referrer information available to the app?**
23+
A: It's delivered as a broadcasted intent at install time, before the app is ever opened.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: "Multiple broadcast receivers in the same app, for the same action"
3+
description: "Using multiple broadcast receivers to listen separately for the same intent in the same Android app can lead to unexpected results, since one receiver may consume the broadcast and leave the others with nothing."
4+
author: "n3vrax"
5+
date_published: "2011-07-22"
6+
canonical_url: "https://www.dotkernel.com/android/multiple-broadcast-receivers-in-the-same-app-for-the-same-action/"
7+
category: "Android"
8+
language: "en"
9+
---
10+
11+
# Multiple broadcast receivers in the same app, for the same action
12+
13+
## The problem
14+
15+
When multiple broadcast receivers are registered separately to listen for the same intent within the same Android app, this can lead to unexpected results: one broadcast receiver might consume the broadcasted intent, leaving the others with nothing to receive. This can happen when using 3rd party libraries that define their own broadcast receivers alongside an app's own receivers.
16+
17+
## The approach
18+
19+
A solution for this kind of problem is a code snippet inspired by the way Admob for Android solves this, as shown in Admob's own documentation, using meta-data in the manifest file.
20+
21+
## FAQ
22+
23+
**Q: What problem does this article address?**
24+
A: When multiple broadcast receivers are registered separately to listen for the same intent in the same Android app, this can lead to unexpected results: one broadcast receiver might consume the broadcasted intent, leaving the others with nothing to receive.
25+
26+
**Q: When is this issue most likely to occur?**
27+
A: This can happen when you use 3rd party libraries that already define their own broadcast receivers alongside your app's own receivers.
28+
29+
## Resources
30+
31+
- [Admob App Download Tracking documentation](http://developer.admob.com/wiki/Android_App_Download_Tracking)
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
title: "ConfigProvider - Bootstrap Modern PHP Applications"
3+
description: "An overview of the ConfigProvider pattern used in Laminas/Mezzio-based applications, including Dotkernel, to bootstrap middleware pipelines and dependency injection."
4+
author: "Florin Bidirean"
5+
date_published: "2025-08-20"
6+
canonical_url: "https://www.dotkernel.com/architecture/configprovider-bootstrap-modern-php-applications/"
7+
category: "Architecture"
8+
language: "en"
9+
---
10+
11+
# ConfigProvider - Bootstrap Modern PHP Applications
12+
13+
## TL;DR
14+
15+
In PHP, a `ConfigProvider` is a class or callable that is part of an application's bootstrap process, returning configuration data that tells the platform which middleware should run, in what order, and under what conditions. Frameworks like Mezzio, Laminas, Slim, and the Dotkernel Headless Platform use ConfigProviders to declare middleware pipeline configuration, dependency injection mappings, and request handlers, which get merged together automatically during bootstrap (except in Dotkernel, where new ConfigProviders must be registered manually).
16+
17+
## Where Is the ConfigProvider Used?
18+
19+
Mezzio (formerly Zend Expressive), Laminas, Slim, the Dotkernel Headless Platform, and other middleware-based frameworks often have a `ConfigProvider` class. In Laminas/Mezzio specifically, each module or package may contain a `ConfigProvider` that returns:
20+
21+
- Middleware pipeline configuration:
22+
- Middleware classes or service names.
23+
- Error-handling middleware, which should have the lowest priority.
24+
- Middleware groups or nested arrays.
25+
- Dependency injection mappings.
26+
- Request Handlers.
27+
28+
Example structure used in Dotkernel:
29+
30+
```php
31+
class ConfigProvider
32+
{
33+
public function __invoke(): array
34+
{
35+
return [ /* ... */ ];
36+
}
37+
38+
public function getDependencies(): array
39+
{
40+
return [
41+
'factories' => [ /* ... */ ],
42+
'invokables' => [ /* ... */ ],
43+
];
44+
}
45+
46+
public function getTemplates(): array
47+
{
48+
return [
49+
'paths' => [ /* ... */ ],
50+
'error' => [ /* ... */ ],
51+
];
52+
}
53+
}
54+
```
55+
56+
What each item means:
57+
58+
| Item | Meaning |
59+
|---|---|
60+
| `dependencies` | Used by the dependency injector (e.g. laminas-servicemanager) to construct every requested service. |
61+
| `factories` | The factory builds the service. |
62+
| `invokables` | The service is built with `new` directly. |
63+
| `aliases` | Redirects to another service name. |
64+
| `delegators` | Wraps the original service. |
65+
| `templates` | Defines the paths for the template files. |
66+
67+
## How the ConfigProvider Works
68+
69+
The ConfigProvider is automatically picked up by the framework during application bootstrap:
70+
71+
1. **Merge the global configuration** - All ConfigProviders are merged into one array.
72+
2. **Read the configuration array** - A call similar to `$config = $container->get('config') ?? [];` reads an array of entries.
73+
3. **Resolve item** - `$app->pipe()` is called to resolve one of the following: resolve the service name from the container, wrap the middleware if an array is provided, or call the closure or invokable object.
74+
4. **Handle errors** - The error-handling middleware is the last one in the pipeline, to make sure it can handle any exceptions.
75+
5. **Execute at runtime** - Laminas Stratigility iterates over the pipeline in the order it was registered. Each middleware can handle the request and return a response, or delegate execution to the next middleware in the pipeline, until a `ResponseInterface` is returned to the client.
76+
77+
## Benefits
78+
79+
- **Centralized setup** - Instead of hardcoding bootstrap code, it's declared in a config provider so it's easy to read, change, or extend.
80+
- **Modular** - Each package can ship with its own config without interfering with others.
81+
- **Container-friendly** - Works well with frameworks using DI containers like Laminas ServiceManager, PHP-DI, or Pimple.
82+
- **Standardized service definitions** - Consistent rules for object creation, separate from business logic.
83+
- **Auto-Discovery** - In Laminas/Mezzio, the ConfigAggregator automatically loads and merges all ConfigProviders. Dotkernel is an exception: new ConfigProviders have to be added manually in `config/config.php`, because all the initial ConfigProviders required to install the applications are already injected.
84+
- **Environment-agnostic** - Returns an array that defines dev, test, or prod environments.
85+
- **Testability** - The consistent, central configuration promotes isolated (e.g. per-module) testing, easier swapping of dependencies, and assertion of pipeline setup (e.g. checking if a config key is present).
86+
87+
## FAQ
88+
89+
**Q: What is a ConfigProvider in PHP?**
90+
A: It is a class that is part of an application's bootstrap process: a class or callable that returns configuration data telling the platform which middleware should run, in what order, and sometimes under what conditions.
91+
92+
**Q: What does the ConfigProvider return in the Laminas/Mezzio ecosystem?**
93+
A: In the Laminas/Mezzio ecosystem, it's literally an array of configuration, settings, or anything else the application needs, and each module or package may contain its own ConfigProvider returning middleware pipeline configuration, dependency injection mappings, and request handlers.
94+
95+
**Q: What is the difference between 'factories' and 'invokables' in the dependencies array?**
96+
A: `factories` will have the factory build the service, while `invokables` will use `new` directly. You can also use `aliases` to redirect to another service name and `delegators` to wrap the original service.
97+
98+
**Q: How does the ConfigProvider get used during application bootstrap?**
99+
A: It is automatically picked up by the framework during bootstrap: all ConfigProviders are merged into one array, the configuration array is read, each item is resolved via `$app->pipe()`, the error-handling middleware is placed last in the pipeline, and at runtime Laminas Stratigility iterates over the pipeline in the order it was registered.
100+
101+
**Q: Are new ConfigProviders auto-discovered in Dotkernel?**
102+
A: Dotkernel is an exception to the usual auto-discovery rule: new ConfigProviders have to be added manually in `config/config.php`, because all the initial ConfigProviders required to install the applications are already injected.
103+
104+
**Q: What are the benefits of using a ConfigProvider?**
105+
A: Benefits include centralized setup instead of hardcoded bootstrap code, modularity so each package can ship its own config, container-friendliness with DI containers like Laminas ServiceManager, PHP-DI or Pimple, standardized service definitions, environment-agnostic configuration for dev/test/prod, and better testability of the pipeline setup.
106+
107+
## Resources
108+
109+
- [Mezzio Container](https://docs.mezzio.dev/mezzio/v3/features/container/config/)
110+
- [Laminas Config Aggregator](https://docs.laminas.dev/laminas-config-aggregator/config-providers/)
111+
- [PSR-15 (HTTP Server Request Handlers)](https://www.php-fig.org/psr/psr-15/)

0 commit comments

Comments
 (0)