From b9eb7a486dd63d57a6a1bd460265281b75090b90 Mon Sep 17 00:00:00 2001 From: bidi47 Date: Wed, 9 Sep 2026 23:59:39 +0300 Subject: [PATCH 1/4] added article - ai-native coding pods Signed-off-by: bidi47 --- .../best-practice/ai-native-coding-pods.md | 725 ++++++++++++++++++ .../twitter-card-ai-native-coding-pods.png | Bin 0 -> 211428 bytes src/App/src/Fixture/articles_cleaned.json | 14 + 3 files changed, 739 insertions(+) create mode 100644 public/md-articles/best-practice/ai-native-coding-pods.md create mode 100644 public/opengraph/article/twitter-card-ai-native-coding-pods.png diff --git a/public/md-articles/best-practice/ai-native-coding-pods.md b/public/md-articles/best-practice/ai-native-coding-pods.md new file mode 100644 index 0000000..d34f157 --- /dev/null +++ b/public/md-articles/best-practice/ai-native-coding-pods.md @@ -0,0 +1,725 @@ +--- +title: "AI-Native Coding Pods: The Promise, Risks, and How to Make Them Work" +description: "What an AI-native coding pod is, the benefits and risks it introduces to a software team, and concrete mitigations covering code quality, review capacity, architecture, security, and human accountability." +author: "Florin Bidirean" +date_published: "2026-09-09" +canonical_url: "https://www.dotkernel.com/best-practice/ai-native-coding-pods/" +category: "Best Practice" +language: "en" +--- + +# AI-Native Coding Pods: The Promise, Risks, and How to Make Them Work + +## TL;DR + +An AI-native coding pod is a small engineering team - often just two or three people - that builds AI coding agents into every stage of the development lifecycle, letting a small group deliver at the scale of a much larger traditional team. +That leverage cuts both ways: it can produce inconsistent code quality, a code-review bottleneck, propagated architectural mistakes, weaker engineering fundamentals, and concentration risk in a small team, so it needs deliberate quality gates, risk-based review, architectural checkpoints, and explicit human accountability to pay off safely. + +## What Are AI-Native Coding Pods? + +An **AI-native coding pod** is a small software engineering team designed from the ground up to use AI as a core part of how software is designed, built, tested, reviewed, and maintained. + +This is different from simply giving developers access to GitHub Copilot, ChatGPT, or another coding assistant. + +A traditional software team might look like: + +> **6 developers → each person owns particular areas of the codebase → development tools assist them** + +An AI-native coding pod might look more like: + +> **2–3 engineers + AI coding agents → humans provide architecture, product judgment, review, and accountability → AI handles a large portion of implementation and analysis** + +AI may participate throughout the development lifecycle: + +* Requirements analysis +* Codebase exploration +* Architecture proposals +* Code generation +* Refactoring +* Test generation +* Debugging +* Documentation +* Code review +* Dependency analysis +* CI/CD support + +The fundamental idea is that AI becomes part of the **engineering operating model**, rather than simply another developer productivity tool. + +--- + +## What Makes a Coding Pod "AI-Native"? + +Several characteristics distinguish an AI-native coding pod from a conventional team using AI assistants. + +### AI participates throughout the development lifecycle + +Instead of only asking AI to write a function, developers might delegate entire engineering tasks: + +> "Understand this issue, identify the relevant parts of the codebase, propose an implementation, write the tests, implement the change, run the test suite, and prepare a pull request." + +### Engineers become higher-level orchestrators + +Developers spend proportionally more time on: + +* Architecture +* Requirements +* Technical trade-offs +* Code review +* Testing strategy +* Security +* Product decisions +* Debugging complex problems + +### AI agents can specialize + +A pod might use different AI agents for: + +* Codebase exploration +* Implementation +* Testing +* Security review +* Performance analysis +* Documentation +* Code review + +### The unit of work becomes larger + +Instead of: + +> "Write this function." + +The unit of delegation becomes: + +> "Implement this feature." + +That shift has potentially enormous implications for software development organizations. + +--- + +## The Potential Benefits + +AI-native coding pods can dramatically increase the amount of software that a small team can produce. + +A developer who previously spent hours doing this work may be able to delegate much of that work to AI: + +* Reading unfamiliar code +* Writing boilerplate +* Creating tests +* Refactoring repetitive code +* Debugging straightforward problems. + +This can allow a small team to behave more like a substantially larger engineering organization. + +But the same leverage creates significant risks. + +## The Disadvantages of AI-Native Coding Pods + +### 1. Inconsistent Code Quality + +AI can produce functional code very quickly, but **functional does not necessarily mean good**. + +AI-generated code may: + +* Follow poor architectural patterns +* Introduce unnecessary complexity +* Duplicate existing functionality +* Handle edge cases incorrectly +* Create subtle performance problems +* Ignore established conventions +* Introduce technical debt + +The danger is amplified by the speed of generation. + +A developer can now create in minutes what previously took hours to write—which means bad code can accumulate much faster too. + +#### Potential mitigation + +Establish strong **engineering quality gates**. + +These can include: + +* Automated unit and integration tests +* Static analysis +* Type checking +* Linters +* Security scanning +* Code coverage requirements +* Architectural constraints +* Mandatory code review for important changes + +AI-generated code should pass the same engineering standards as human-written code. + +The objective should be: + +> **Increase coding speed without lowering the quality bar.** + +--- + +### 2. The Code Review Bottleneck + +One of the biggest risks is that AI dramatically increases code production while humans remain responsible for reviewing it. + +Consider: + +> **AI generates 10× more code → humans still have to understand and review it** + +At some point, the organization simply cannot review everything carefully. + +This creates a dangerous possibility: + +> **The bottleneck moves from writing code to understanding code.** + +#### Potential mitigation + +Introduce **risk-based code review**. + +For example: + +##### Low-risk changes + +* Automated tests +* Formatting +* Documentation +* Simple refactoring + +→ Primarily automated validation. + +##### Medium-risk changes + +* Business logic +* API changes +* Database queries + +→ Human review plus automated testing. + +##### High-risk changes + +* Authentication +* Payments +* Security +* Data migrations +* Infrastructure +* Privacy-sensitive functionality + +→ Mandatory expert human review. + +AI can increase the volume of code entering the system, but the organization needs to deliberately protect **human review capacity**. + +--- + +### 3. AI Can Propagate Architectural Mistakes + +AI coding agents can work across multiple files and increasingly across entire repositories. + +This creates a new failure mode. + +Suppose an agent misunderstands an architectural constraint. + +It may then implement that misunderstanding consistently across: + +> **10 files → 30 files → multiple services** + +The result can be a large amount of internally consistent but fundamentally incorrect code. + +#### Potential mitigation + +Introduce **architectural checkpoints**. + +Before implementation, important features should have an explicit design phase: + +> Requirements → Architecture proposal → Human approval → AI implementation → Automated validation → Human review + +AI should be encouraged to explain: + +* Which components it intends to modify +* Why those components are relevant +* What architectural assumptions it is making +* What alternatives it considered +* What risks the implementation introduces + +This makes AI reasoning inspectable before large amounts of code are produced. + +--- + +### 4. Loss of Deep Engineering Understanding + +This may be one of the most important long-term risks. + +If developers continuously delegate: + +* Coding +* Debugging +* Testing +* Refactoring +* API research + +to AI, they may become increasingly dependent on it. + +A junior developer might be able to produce sophisticated-looking software without understanding: + +* Memory management +* Concurrency +* Distributed systems +* Database behavior +* Security principles +* Networking +* Performance characteristics + +The result could be **higher short-term productivity but weaker engineering capability over time**. + +#### Potential mitigation + +Preserve deliberate opportunities for engineers to build fundamental skills. + +For example: + +* Require developers to understand AI-generated code before merging it. +* Use AI as a tutor, not only as a code generator. +* Conduct architecture and debugging sessions without AI when appropriate. +* Rotate engineers through difficult technical problems. +* Maintain engineering competency standards independent of AI capability. + +The goal should be: + +> **AI makes engineers more capable—not less capable without AI.** + +--- + +### 5. Reduced Code Ownership + +Traditional development encourages developers to develop a strong mental model of the systems they own. + +With AI agents generating large amounts of code, developers may increasingly become reviewers of code they did not personally write. + +That creates a potential disconnect: + +> **"I approved this code, but I don't really understand how it works."** + +This is particularly dangerous in complex systems. + +#### Potential mitigation + +Make **code ownership about understanding, not authorship**. + +The responsible engineer should be able to explain: + +* What the code does +* Why it exists +* Its dependencies +* Its failure modes +* Its performance characteristics +* Its security implications + +AI-generated code should not be treated as a black box simply because it passed automated tests. + +--- + +### 6. Less Productive Technical Disagreement + +AI often makes it easy to generate an apparently reasonable solution very quickly. + +That can reduce the amount of time teams spend debating alternatives. + +But disagreement is valuable in engineering. + +Questions such as: + +* Should this be a microservice? +* Should we use SQL or NoSQL? +* Should this logic live in the frontend or backend? +* Should we build or buy this component? +* Is this abstraction actually necessary? + +often produce better systems through disagreement. + +#### Potential mitigation + +Use AI to **increase the quality of technical debate**, rather than eliminate it. + +For example, ask AI to provide: + +* The strongest argument for an architecture +* The strongest argument against it +* Alternative designs +* Expected failure modes +* Long-term maintenance costs + +Then have engineers debate the alternatives. + +AI becomes a **technical sparring partner**, not the final architect. + +--- + +### 7. Technical Debt Can Accumulate Faster + +AI makes implementation cheaper. + +This can create a psychological shift: + +> "We can always clean it up later." + +Because AI can generate code so cheaply, teams may accept more shortcuts. + +Over time this can produce: + +* More abstractions +* More dependencies +* More duplicated code +* More configuration +* More services +* More tests that are difficult to maintain +* More undocumented behavior + +The organization can end up with a large codebase that is cheap to create but expensive to understand. + +#### Potential mitigation + +Treat **codebase simplicity as a first-class engineering metric**. + +Regularly measure and review: + +* Complexity +* Duplication +* Dependency count +* Build times +* Test maintenance +* Dead code +* Architecture violations +* Developer time spent understanding the system + +AI should be used for refactoring and simplification as aggressively as it is used for code generation. + +--- + +### 8. Security Risks Can Scale With Coding Speed + +AI can introduce vulnerabilities just as quickly as it can introduce features. + +Potential problems include: + +* Insecure authentication +* Improper authorization +* SQL injection +* Secrets accidentally exposed +* Unsafe dependency choices +* Incorrect cryptographic implementations +* Insecure API endpoints +* Excessive permissions + +The risk becomes more significant when AI agents have the ability to modify repositories, run commands, access databases, or interact with deployment systems. + +#### Potential mitigation + +Build security into the development pipeline. + +Use: + +* Static application security testing +* Dependency scanning +* Secret detection +* Container scanning +* Automated security tests +* Least-privilege access +* Protected production environments +* Mandatory human approval for sensitive changes + +AI agents should have only the permissions necessary for their task. + +For example: + +> **An agent writing application code should not automatically have production database access.** + +--- + +### 9. AI Coding Agents Can Become a Management Problem + +An AI-native pod may have only three engineers but dozens of automated workflows and agents. + +Someone now has to manage: + +* Agents +* Prompts +* Context +* Repository permissions +* Model selection +* Tool access +* Evaluation +* CI/CD integration +* Agent failures + +This can create a new type of engineering management complexity. + +#### Potential mitigation + +Treat every important AI agent as a **software system**. + +Each agent should have: + +* A defined purpose +* An owner +* Explicit permissions +* Input/output specifications +* Evaluation criteria +* Monitoring +* Failure handling +* Documentation + +If nobody can explain why an agent exists or how its performance is measured, it probably shouldn't be part of the production workflow. + +--- + +### 10. Vendor and Model Dependency + +A coding pod may become heavily dependent on a particular AI model or coding platform. + +If that provider changes: + +* Pricing +* Context limits +* Coding performance +* API behavior +* Availability +* Tooling + +the team's productivity could change significantly. + +#### Potential mitigation + +Keep the engineering workflow as **model-agnostic as reasonably practical**. + +Maintain ownership of: + +* Source code +* Prompts +* Agent instructions +* Evaluation tests +* Development workflows +* Documentation + +Critically, build evaluation suites that allow the organization to compare models based on actual engineering tasks. + +The important question is not: + +> "Which model is best?" + +but: + +> **"Which model performs best on our engineering workload, at an acceptable cost and reliability level?"** + +--- + +### 11. Small Teams Can Become Fragile + +An AI-native pod may allow three engineers to accomplish what previously required ten. + +That's powerful—but it can create concentration risk. + +Imagine: + +* Engineer A understands architecture +* Engineer B understands the AI agent infrastructure +* Engineer C understands deployment + +If one person leaves, a disproportionate amount of knowledge may disappear. + +#### Potential mitigation + +Make critical knowledge **team-owned rather than individual-owned**. + +Document: + +* Architecture +* Agent workflows +* Development environments +* Deployment processes +* Important decisions +* Failure modes +* Evaluation procedures + +Every critical system should have more than one person capable of operating and modifying it. + +--- + +## Three Additional Safeguards + +### 12. Measure Engineering Outcomes, Not Lines of Code + +AI makes lines of code almost meaningless as a productivity metric. + +A developer generating 10,000 lines of code isn't necessarily more productive than one generating 1,000. + +Better metrics include: + +* Lead time for changes +* Deployment frequency +* Change failure rate +* Mean time to recovery +* Defect rate +* Customer-impacting incidents +* Developer time per feature +* Review time +* Rework rate +* System performance + +The most important metric is ultimately: + +> **How much valuable, reliable software can the pod deliver per unit of human engineering attention?** + +--- + +### 13. Keep Humans Accountable for Production + +A dangerous organizational pattern is: + +> "The AI wrote it." + +That isn't an engineering responsibility model. + +Someone must still own: + +* The architecture +* The implementation +* The security +* The operational consequences +* The production outcome + +AI can write the code. + +It cannot be the person on call when the system fails. + +For production systems, **human accountability should remain explicit**. + +--- + +### 14. Start With Bounded Engineering Workflows + +Organizations shouldn't necessarily attempt to make every software engineering activity autonomous immediately. + +Start with areas where: + +* Requirements are relatively clear +* Changes are measurable +* Automated tests exist +* Mistakes are recoverable +* Human review is possible + +Good starting points might include: + +* Test generation +* Bug fixes +* Documentation +* Refactoring +* Small feature development +* Dependency upgrades +* Codebase exploration + +Once reliability is demonstrated, the pod can gradually delegate larger units of work. + +A useful progression is: + +> **AI autocomplete → AI-assisted development → AI task delegation → AI coding agents → AI-native coding pod → greater autonomy** + +--- + +## A Practical AI-Native Coding Model + +A useful division of responsibility looks like this: + +| Responsibility | Primary role | +|---------------------------|--------------------| +| Code generation | AI | +| Boilerplate | AI | +| Codebase exploration | AI + engineer | +| Test generation | AI | +| Debugging | AI + engineer | +| Refactoring | AI + engineer | +| Architecture | Human + AI | +| Requirements | Human | +| Technical trade-offs | Human + AI | +| Code review | Human + automation | +| Security | Human + automation | +| Production accountability | Human | + +This creates a useful operating principle: + +> **AI writes more code. Engineers make sure it is the right code.** + +--- + +## The Deeper Principle + +The biggest change introduced by AI-native coding is not simply that **code becomes faster to write**. + +It is that the bottleneck in software engineering begins to move. + +Historically: + +> **Idea → design → coding → testing → deployment** + +Coding was a significant portion of the work. + +With increasingly capable AI: + +> **Idea → design → AI implementation → validation → deployment** + +Implementation becomes cheaper. + +The scarce resources increasingly become: + +* Product judgment +* Architecture +* Context +* Verification +* Engineering taste +* Security +* Human attention + +This creates an important paradox: + +> **When code becomes cheap, understanding code becomes more valuable.** + +--- + +## The Best AI-Native Coding Pod + +The strongest AI-native coding pod is therefore not necessarily the one with the most agents or the highest lines-of-code-per-developer ratio. + +It is the one where: + +* AI handles repetitive implementation +* Engineers understand the resulting system +* Architecture remains deliberate +* Automated tests catch routine failures +* Humans review high-risk changes +* Security is built into the workflow +* Technical debt is actively managed +* Knowledge remains distributed across the team +* Production accountability remains human + +In other words: + +> **AI provides scale. Automation provides repetition. Engineers provide judgment. Tests provide verification. Governance provides safety.** + +The goal is not to remove engineers from software development. + +It is to make a small number of excellent engineers **dramatically more capable and productive**—without sacrificing the qualities that make good software engineering valuable in the first place. + +## FAQ + +**Q: What is an AI-native coding pod?** +A: A small software engineering team, often just two or three engineers, that builds AI coding agents into requirements analysis, codebase exploration, architecture proposals, code generation, testing, debugging, documentation, and review, rather than only using AI as an autocomplete tool. + +**Q: What are the biggest risks of AI-native coding pods?** +A: Inconsistent code quality, a code-review bottleneck as AI output outpaces human review capacity, propagated architectural mistakes across many files, loss of deep engineering understanding, reduced code ownership, faster-accumulating technical debt, security risks that scale with coding speed, and concentration risk in a small team. + +**Q: How should teams manage the code review bottleneck?** +A: With risk-based code review: automated validation for low-risk changes like tests, formatting, and simple refactoring; human review plus automated testing for medium-risk changes like business logic and API changes; and mandatory expert human review for high-risk changes like authentication, payments, security, and data migrations. + +**Q: Who remains accountable when AI writes the code?** +A: A human engineer, not the AI. Someone must still own the architecture, implementation, security, and operational consequences, and be the person on call when the system fails - "the AI wrote it" is not an engineering responsibility model. + +**Q: What is the deeper shift AI-native coding introduces?** +A: As implementation becomes cheaper, the bottleneck in software engineering moves from writing code to understanding it, making product judgment, architecture, verification, and engineering taste the scarce resources rather than raw coding speed. + +**Q: What does the strongest AI-native coding pod look like?** +A: One where AI handles repetitive implementation while engineers still understand the resulting system, architecture stays deliberate, automated tests catch routine failures, humans review high-risk changes, security is built into the workflow, and production accountability remains human. diff --git a/public/opengraph/article/twitter-card-ai-native-coding-pods.png b/public/opengraph/article/twitter-card-ai-native-coding-pods.png new file mode 100644 index 0000000000000000000000000000000000000000..1fcaf82da8fadd75d74f46333f44882ebf9e2ff9 GIT binary patch literal 211428 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

IdaWZm8jT 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 literal 0 HcmV?d00001 diff --git a/src/App/src/Fixture/articles_cleaned.json b/src/App/src/Fixture/articles_cleaned.json index ba73b29..504e939 100644 --- a/src/App/src/Fixture/articles_cleaned.json +++ b/src/App/src/Fixture/articles_cleaned.json @@ -3098,6 +3098,20 @@ "excerpt": "What TOTP Does A Time-based One-Time Password (TOTP) is a security algorithm used as part of two-factor authentication (2FA) to protect against account attacks. The mechanism is integrated into dot-totp to enhance security by requiring both a password and an additional one-time code.", "tl_dr": "dot-totp adds two-factor authentication (2FA) to Dotkernel Admin using time-based one-time passwords.\nUsers authenticate with their password plus a 6-digit code from an Authenticator app that refreshes every 30 seconds.\nInstallation is one Composer command plus a set of forms, handlers, middleware, and templates from the official code examples, applying a TotpTrait to the relevant entity, migrating three new database columns, and registering routes/pipeline/ConfigProvider updates.", "tags": [] + }, + { + "post_title": "AI-Native Coding Pods: The Promise, Risks, and How to Make Them Work", + "post_date": "2026-09-09 12:00:00", + "post_status": "publish", + "author": { + "display_name": "Florin Bidirean", + "github": "bidi47" + }, + "isObsolete": false, + "opengraph_img": "/opengraph/article/twitter-card-ai-native-coding-pods.png", + "excerpt": "What an AI-native coding pod is, the benefits and risks it introduces to a software team, and concrete mitigations covering code quality, review capacity, architecture, security, and human accountability.", + "tl_dr": "An AI-native coding pod is a small engineering team - often just two or three people - that builds AI coding agents into every stage of the development lifecycle, letting a small group deliver at the scale of a much larger traditional team. That leverage cuts both ways: it can produce inconsistent code quality, a code-review bottleneck, propagated architectural mistakes, weaker engineering fundamentals, and concentration risk in a small team, so it needs deliberate quality gates, risk-based review, architectural checkpoints, and explicit human accountability to pay off safely.", + "tags": [] } ] } From 6ccebf8481847d144f52dbd034bed23a95231177 Mon Sep 17 00:00:00 2001 From: bidi47 Date: Thu, 17 Sep 2026 13:01:47 +0300 Subject: [PATCH 2/4] added article - dk vs lumen, slim Signed-off-by: bidi47 --- README.md | 60 +- public/llms-full.txt | 8480 +++-------------- public/llms.txt | 167 + .../dotkernel-vs-lumen-slim-microservices.md | 193 + ...witter-card-dotkernel-vs-lumen-vs-slim.png | Bin 0 -> 250858 bytes src/App/src/Fixture/articles_cleaned.json | 16 +- 6 files changed, 1645 insertions(+), 7271 deletions(-) create mode 100644 public/md-articles/headless-platform/dotkernel-vs-lumen-slim-microservices.md create mode 100644 public/opengraph/article/twitter-card-dotkernel-vs-lumen-vs-slim.png diff --git a/README.md b/README.md index f233cf1..537b437 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,15 @@ Steps to publish a new article and regenerate the public artifacts that depend o ## 1. Add the article data +### Create a new article record + Add a new entry to the category's `articles` array in `src/App/src/Fixture/articles_cleaned.json`: ```json { "post_title": "Your article title", "post_date": "YYYY-MM-DD HH:MM:SS", - "post_status": "publish", + "post_status": "published", "author": { "display_name": "admin", "github": "arhimede" @@ -32,26 +34,23 @@ Add a new entry to the category's `articles` array in `src/App/src/Fixture/artic `tags` can be left empty, but adding tags that describe the article's subject is useful - they show up on the article page and back its tag-resource pages. -**`post_status` values.** `PostLoader` (`src/App/src/Fixture/PostLoader.php`) only recognizes 3 JSON strings — anything else (including the literal `"draft"`) falls through to `Draft`: - -| JSON value | Maps to | Behavior | -| --- | --- | --- | -| `"publish"` | `PostStatusEnum::Published` | The only status shown in listings, the RSS feed, and the sitemap (`getPublishedPosts()` and every category/tag/author query filter on `Published` only). | -| `"private"` | `PostStatusEnum::Private` | Not published: excluded from listings/feed/sitemap same as a draft, and its own page returns `404` — there is currently no route or view that treats `Private` differently from `Draft`. | -| `"archived"` | `PostStatusEnum::Archived` | Not published: excluded from listings/feed/sitemap, but its own page returns `410 Gone` instead of `404` — use this for content that existed and was intentionally removed (outdated articles, leftover test content, etc.), as opposed to content that was never public. | -| anything else (including `"draft"`) | `PostStatusEnum::Draft` | Not published: excluded from listings/feed/sitemap, its own page returns `404`. This is also the fallback for typos in `post_status`. | +**`post_status` values.** `PostLoader` (`src/App/src/Fixture/PostLoader.php`) only recognizes 3 JSON strings - anything else (including the literal `"draft"`) falls through to `Draft`: -After changing `post_status`, follow the same steps: re-run `bin/doctrine-fixtures`, then `bin/generate-feed` and `bin/sitemap`. This applies generally, not just to status changes — **any** edit to `articles_cleaned.json` (title, excerpt, status, date, etc.) needs `bin/doctrine-fixtures` re-run to update the database, followed by re-running the 4 generators in step 4 so `feed.xml`/`sitemap.xml`/`llms.txt`/`llms-full.txt` reflect it. One exception: `bin/generate-llms-full` reads straight from the `.md` files on disk and does **not** check `post_status` at all — a non-published article's `.md` file will still be included in `llms-full.txt` unless you also remove or rename that file. +| JSON value | Maps to | Behavior | +|-------------------------------------|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `"published"` | `PostStatusEnum::Published` | The only status shown in listings, the RSS feed, and the sitemap (`getPublishedPosts()` and every category/tag/author query filter on `Published` only). | +| `"private"` | `PostStatusEnum::Private` | Not published: excluded from listings/feed/sitemap same as a draft, and its own page returns `404` - there is currently no route or view that treats `Private` differently from `Draft`. | +| `"archived"` | `PostStatusEnum::Archived` | Not published: excluded from listings/feed/sitemap, but its own page returns `410 Gone` instead of `404` - use this for content that existed and was intentionally removed (outdated articles, leftover test content, etc.), as opposed to content that was never public. | +| anything else (including `"draft"`) | `PostStatusEnum::Draft` | Not published: excluded from listings/feed/sitemap, its own page returns `404`. This is also the fallback for typos in `post_status`. | -## 2. Create the templates +## 2. Create the markdown file -- `src/Blog/templates/page/blog-resource/{category-slug}/{article-slug}.html.twig` - the page body, extending `@layout/blog-post.html.twig`. -- `src/Blog/templates/page/JSON-LD/{category-slug}/{article-slug}.jsonld.twig` - the `@graph` of `TechArticle` + `BreadcrumbList` + `FAQPage` structured data. -- `public/md-articles/{category-slug}/{article-slug}.md` - the markdown version, with YAML front matter (`title`, `description`, `author`, `date_published`, `canonical_url`, `category`, `language`) followed by the article body (`TL;DR`, sections, `FAQ`). This feeds `llms-full.txt`. +The filename is in this format: `public/md-articles/{category-slug}/{article-slug}.md`. +The file contains the markdown with YAML front matter (`title`, `description`, `author`, `date_published`, `canonical_url`, `category`, `language`) followed by the article body (`TL;DR`, sections, `FAQ`). +This feeds `llms-full.txt`. -Copy an existing set of these three files in the same category as a starting point, to match the established structure (FAQ block matching the `FAQPage` entries, etc.). - -If the article body uses images (via `asset('uploads/article/' ~ article.id ~ '/filename.png')` in the `.html.twig`), just drop the image file anywhere under `public/uploads` - `bin/create-uploads-dir` (step 4) finds it by filename and copies it to the right place. No manual path/folder creation needed. +If the article body uses images (via `asset('uploads/article/' ~ article.id ~ '/filename.png')` in the `.html.twig`), just drop the image file anywhere under `public/uploads` - `bin/create-uploads-dir` (step 4) finds it by filename and copies it to the right place. +No manual path/folder creation needed. ## 3. At deploy - run in this order @@ -63,6 +62,8 @@ php bin/create-uploads-dir - `bin/doctrine-fixtures` loads `articles_cleaned.json` into the database, creating the `Post` entity (with its database-generated UUID) for the new article. - `bin/create-uploads-dir` must run *after* it - it resolves the post by slug to get that UUID, creates `public/uploads/article/{post-id}/`, and copies each image referenced in the `.html.twig` there from wherever it already lives under `public/uploads`. +`bin/doctrine-fixtures` isn't only for new articles - it matches existing posts by slug, so re-running it after editing any field on an existing entry (`post_title`, `excerpt`, `post_status`, etc.) updates that same `Post` row instead of creating a duplicate. + ## 4. Regenerate the public artifacts - any order ```shell @@ -74,10 +75,13 @@ php bin/generate-llms-full - `bin/generate-feed` rewrites `public/feed.xml` from the published posts in the database. - `bin/sitemap` rewrites `public/sitemap.xml` from the published posts in the database. -- `bin/generate-llms` rewrites `public/llms.txt`, the short curated index (one line per article, grouped by category) — built from the published posts in the database, grouped by category (known categories first, in a fixed order, then any remaining categories by post count) and sorted alphabetically by title within each category. Requires the `llms.sourceDir` / `llms.indexFile` keys in `config/autoload/local.php` (see `local.php.dist`); the `llms.pagesDir` key is optional, same as for `bin/generate-llms-full` below. -- `bin/generate-llms-full` rewrites `public/llms-full.txt` by concatenating `public/md-articles/index.md` and every other `public/md-articles/*/*.md` file, sorted by path, then appending each `public/*.md` file — the markdown versions of the static pages. Requires the `llms.sourceDir` / `llms.outputFile` keys in `config/autoload/local.php` (see `local.php.dist`); the `llms.pagesDir` key is optional, and omitting it leaves the page sections out. +- `bin/generate-llms` rewrites `public/llms.txt`, the short curated index (one line per article, grouped by category) - built from the published posts in the database, grouped by category (known categories first, in a fixed order, then any remaining categories by post count) and sorted alphabetically by title within each category. Requires the `llms.sourceDir` / `llms.indexFile` keys in `config/autoload/local.php` (see `local.php.dist`); the `llms.pagesDir` key is optional, same as for `bin/generate-llms-full` below. +- `bin/generate-llms-full` rewrites `public/llms-full.txt` by concatenating `public/md-articles/index.md` and every other `public/md-articles/*/*.md` file, sorted by path, then appending each `public/*.md` file - the markdown versions of the static pages. +Requires the `llms.sourceDir` / `llms.outputFile` keys in `config/autoload/local.php` (see `local.php.dist`); the `llms.pagesDir` key is optional, and omitting it leaves the page sections out. +It reads straight from the `.md` files on disk and does **not** check `post_status` - a non-published article's `.md` file will still be included unless you also remove or rename that file. These four have no ordering dependency on each other, only on step 3 being done first. +Re-run all four after *any* edit to `articles_cleaned.json` (title, excerpt, status, date, etc.), not just when adding a new article - otherwise the committed `feed.xml`/`sitemap.xml`/`llms.txt`/`llms-full.txt` drift from the database. None of this is wired into an automated deploy pipeline in this repository - there is no `deploy` script or CI job that runs these `bin/` scripts. **This must be run manually as part of every deploy** whenever `articles_cleaned.json` changed since the last deploy. `public/feed.xml`, `public/sitemap.xml`, `public/llms.txt`, and `public/llms-full.txt` are committed generated artifacts, so re-running these scripts leaves them modified in git until committed. @@ -86,26 +90,26 @@ None of this is wired into an automated deploy pipeline in this repository - the Steps to edit an existing article (change its status, text, or both) and get the change live. 1. **Edit the article's data.** Find its entry under the category's `articles` array in `src/App/src/Fixture/articles_cleaned.json` and change whatever needs updating: `post_title`, `excerpt`, `tl_dr`, `post_status`, `isObsolete`, etc. `PostLoader` matches the existing article by slug (derived from `post_title`), so as long as you don't change the title, it updates the same `Post` row instead of creating a new one. - - See the `post_status` values table in step 1 above for what each status does — e.g. `"archived"` is the right choice for content that existed and was intentionally removed (outdated content, a leftover test article, etc.), as it serves `410 Gone` instead of `404`. + - See the `post_status` values table in step 1 above for what each status does - e.g. `"archived"` is the right choice for content that existed and was intentionally removed (outdated content, a leftover test article, etc.), as it serves `410 Gone` instead of `404`. 2. **Edit the content, if the body itself changed.** Update the matching files for that article's category/slug: - `public/md-articles/{category-slug}/{article-slug}.md` - `src/Blog/templates/page/blog-resource/{category-slug}/{article-slug}.html.twig` - - `src/Blog/templates/page/JSON-LD/{category-slug}/{article-slug}.jsonld.twig` (only if it has hardcoded text outside of `article.*`/`meta.*` variables — most of its fields pull straight from the database and update automatically) + - `src/Blog/templates/page/JSON-LD/{category-slug}/{article-slug}.jsonld.twig` (only if it has hardcoded text outside of `article.*`/`meta.*` variables - most of its fields pull straight from the database and update automatically) 3. **Re-run the same commands as step 3 and step 4 above** (`bin/doctrine-fixtures`, then `bin/generate-feed` / `bin/sitemap` / `bin/generate-llms-full`) so the database and the generated artifacts reflect the change. `bin/create-uploads-dir` only needs to run again if you added a new image. ## How to move an article to a different category -An article's category isn't a field on the article itself — it's whichever top-level category object its entry sits under in `articles_cleaned.json`. Moving it is a structural move, not a value change, and the article's page/JSON-LD templates are resolved dynamically off the *current* category at render time (`GetPostResourceHandler` renders `page::blog-resource/{article.category.slug}/{article.slug}`, and the layout includes `@jsonld/{article.category.slug}/{article.slug}.jsonld.twig`) — there's no fallback if a file is missing at that path, so skipping any of the steps below leaves the article **404**ing at both the old and the new URL. +An article's category isn't a field on the article itself - it's whichever top-level category object its entry sits under in `articles_cleaned.json`. Moving it is a structural move, not a value change, and the article's page/JSON-LD templates are resolved dynamically off the *current* category at render time (`GetPostResourceHandler` renders `page::blog-resource/{article.category.slug}/{article.slug}`, and the layout includes `@jsonld/{article.category.slug}/{article.slug}.jsonld.twig`) - there's no fallback if a file is missing at that path, so skipping any of the steps below leaves the article **404**ing at both the old and the new URL. -1. **Cut the article's JSON object from its current category's `articles` array and paste it into the target category's `articles` array**, in `src/App/src/Fixture/articles_cleaned.json`. The target category must already exist as a top-level entry. Nothing else in the object needs to change — `PostLoader` matches the existing `Post` by slug and updates its category on the next run. +1. **Cut the article's JSON object from its current category's `articles` array and paste it into the target category's `articles` array**, in `src/App/src/Fixture/articles_cleaned.json`. The target category must already exist as a top-level entry. Nothing else in the object needs to change - `PostLoader` matches the existing `Post` by slug and updates its category on the next run. 2. **Physically move the three per-article files** from the old `{category-slug}` folder to the new one, keeping the same filename: - `public/md-articles/{old-category-slug}/{article-slug}.md` → `public/md-articles/{new-category-slug}/{article-slug}.md` - `src/Blog/templates/page/blog-resource/{old-category-slug}/{article-slug}.html.twig` → `.../{new-category-slug}/{article-slug}.html.twig` - `src/Blog/templates/page/JSON-LD/{old-category-slug}/{article-slug}.jsonld.twig` → `.../{new-category-slug}/{article-slug}.jsonld.twig` -3. **Check the moved `.html.twig` for a hardcoded `json_ld` block override.** Most articles leave that block untouched, so it resolves dynamically via the layout — but a few hardcode a literal path (e.g. `{% block json_ld %}{{ include('@jsonld/some-category/some-slug.jsonld.twig') }}{% endblock %}`). If yours does, update that literal path to the new category too. +3. **Check the moved `.html.twig` for a hardcoded `json_ld` block override.** Most articles leave that block untouched, so it resolves dynamically via the layout - but a few hardcode a literal path (e.g. `{% block json_ld %}{{ include('@jsonld/some-category/some-slug.jsonld.twig') }}{% endblock %}`). If yours does, update that literal path to the new category too. 4. **Re-run `bin/doctrine-fixtures`**, then the 3 generators (`bin/generate-feed`, `bin/sitemap`, `bin/generate-llms-full`), same as any other update. -Note: this changes the article's URL (`/{categorySlug}/{slug}/`), so the old URL will start 404ing — there is no redirect set up for a category move in this app. +Note: this changes the article's URL (`/{categorySlug}/{slug}/`), so the old URL will start 404ing - there is no redirect set up for a category move in this app. ## 5. Scheduled jobs (cron) @@ -116,6 +120,6 @@ Note: this changes the article's URL (`/{categorySlug}/{slug}/`), so the old URL - Runs daily at **04:00**. - Exits non-zero without touching the data file if the run can't be trusted, so the previously generated listing keeps serving. - Logs to `log/generate-packages.log`. -- **`bin/generate-feed`** (RSS, `public/feed.xml`) — **manual only**, no cron. Run it as part of the publish flow in step 4, right after `bin/doctrine-fixtures`/`bin/create-uploads-dir`, whenever an article is added, edited, or its `post_status` changes. -- **`bin/sitemap`** (`public/sitemap.xml`) — **manual only**, no cron. Same trigger as `bin/generate-feed`: re-run after any change to `articles_cleaned.json`. -- **`bin/generate-llms-full`** (`public/llms-full.txt`) — **manual only**, no cron. Re-run after adding/editing a `.md` file under `public/md-articles/` or the static-page `.md` files at the `public/` root, or after removing/renaming a draft's `.md` file (it doesn't check `post_status`, see step 1). The static-page `.md` files are hand-maintained alongside the templates in `src/Page/templates/page/` — editing a page template means updating its `.md` and re-running this. +- **`bin/generate-feed`** (RSS, `public/feed.xml`) - **manual only**, no cron. Run it as part of the publish flow in step 4, right after `bin/doctrine-fixtures`/`bin/create-uploads-dir`, whenever an article is added, edited, or its `post_status` changes. +- **`bin/sitemap`** (`public/sitemap.xml`) - **manual only**, no cron. Same trigger as `bin/generate-feed`: re-run after any change to `articles_cleaned.json`. +- **`bin/generate-llms-full`** (`public/llms-full.txt`) - **manual only**, no cron. Re-run after adding/editing a `.md` file under `public/md-articles/` or the static-page `.md` files at the `public/` root, or after removing/renaming a draft's `.md` file (it doesn't check `post_status`, see step 1). The static-page `.md` files are hand-maintained alongside the templates in `src/Page/templates/page/` - editing a page template means updating its `.md` and re-running this. diff --git a/public/llms-full.txt b/public/llms-full.txt index a906b71..f09efd6 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -1,166 +1,3 @@ - - - - ---- -title: "Dotkernel — A Headless Platform for Modern Web Applications" -description: "Dotkernel is a collection of open-source PHP application skeletons built on Mezzio and Laminas, ranging from a minimal presentation-site skeleton to a full headless platform (API, Admin, Queue) for enterprise-grade applications." -url: "https://www.dotkernel.com/" -language: "en" -entities: - - name: "Dotkernel API" - type: "SoftwareApplication" - url: "https://github.com/dotkernel/api" - - name: "Dotkernel Admin" - type: "SoftwareApplication" - url: "https://github.com/dotkernel/admin" - - name: "Dotkernel Queue" - type: "SoftwareApplication" - url: "https://github.com/dotkernel/queue" - - name: "Dotkernel Light" - type: "SoftwareApplication" - url: "https://github.com/dotkernel/light" - - name: "Dotkernel Frontend" - type: "SoftwareApplication" - url: "https://github.com/dotkernel/frontend" - - name: "Mezzio" - type: "SoftwareFramework" - url: "https://github.com/mezzio/mezzio-skeleton" -standards: ["PSR-7", "PSR-11", "PSR-15"] -keywords: ["headless platform", "PHP", "Mezzio", "Laminas", "PSR-15 middleware", "REST API", "admin panel", "task queue", "open source"] ---- - -# Dotkernel - -## TL;DR - -Dotkernel is a collection of open-source PHP application skeletons built on Mezzio and Laminas, licensed MIT. -Its headless platform combines three components — **API**, **Admin**, and **Queue** — that can be adopted separately or together. -Two additional skeletons, **Light** and **Frontend**, stand outside the platform for simpler or frontend-only use cases. - -## Key facts - -| Fact | Value | -|---|---| -| Runtime | Mezzio + Laminas | -| Standards | PSR-7, PSR-11, PSR-15 | -| License | MIT | -| Router | FastRoute | -| Response | Diactoros | -| Maintainer | Apidemia | - -## Request lifecycle - -Router (FastRoute) → Authentication (dot-authentication) → RBAC guard (dot-rbac-guard) → your PSR-15 handler → Response (Diactoros). - -## The headless platform: three applications, one platform - -API, Admin, and Queue are designed to integrate into a single, unified headless platform - better together than the sum of their parts. - -| Component | Role | Repository | -|---|---|---| -| **API** | Framework-less, opinionated toolkit for shipping REST APIs; an alternative to legacy Laminas API Tools (Apigility) | https://github.com/dotkernel/api | -| **Admin** | Table-based backend for managing platform records, plus tools to build reports and dashboards | https://github.com/dotkernel/admin | -| **Queue** | Asynchronous task queuing built on Symfony Messenger, wired into the Laminas Service Manager container via netglue/laminas-messenger | https://github.com/dotkernel/queue | - -## Skeletons outside the platform - -Not every project needs a headless platform - these two stand on their own. - -| Skeleton | Purpose | Repository | -|---|---|---| -| **Light** | Minimal, PSR-15 compliant skeleton built for learning purposes - a didactic example, not a platform component | https://github.com/dotkernel/light | -| **Frontend** | Standalone skeleton for building frontend applications on Mezzio and Laminas, separate from the headless platform | https://github.com/dotkernel/frontend | - -## Components (dot-* packages) - -Small, independent packages - pull in what you need. Grouped by concern: authentication (dot-authentication, dot-auth-social), authorization (dot-authorization, dot-rbac, dot-rbac-guard), controllers (dot-controller), forms (laminas-form), session (dot-session, dot-flashmessenger, dot-cache), logging & error handling (dot-log, dot-errorhandler), emailing (dot-mail), backend/database abstraction (doctrine/orm, doctrine/dbal, dot-data-fixtures), navigation (dot-navigation), templating (dot-twigrenderer), and supporting tools (dot-annotated-services, dot-event, dot-helpers, dot-cli, dot-doctrine-metadata, dot-response-header, dot-user-agent-sniffer, dot-debugbar, dot-geoip). - -Full package list and lifecycle/support status: https://www.dotkernel.com/dotkernel-packages-oss-lifecycle/ - -## About - -Dotkernel is an open-source project created and led by the dev team at Apidemia - built first as an internal tool for handling complex architectures, now freely shared with the community. - -## Resources - -- Documentation: https://docs.dotkernel.org -- GitHub organization: https://github.com/dotkernel -- Blog: https://www.dotkernel.com/blog/ -- Categories: https://www.dotkernel.com/categories/ -- Contact: https://www.dotkernel.com/contact/ - - - - - - ---- -title: "Listen for Android install referrer" -description: "Android market broadcasts an intent containing referrer information at install time, before the app is opened, which can be used for install tracking." -author: "n3vrax" -date_published: "2011-07-24" -canonical_url: "https://www.dotkernel.com/android/listen-for-android-install-referrer/" -category: "Android" -language: "en" ---- - -# Listen for Android install referrer - -## Getting Referrer Data at Install Time - -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. - -## FAQ - -**Q: Does Android send information when the app is installed?** -A: Yes. -Android market broadcasts an intent containing referrer information at the moment the app is installed. - -**Q: When is this referrer information available to the app?** -A: It's delivered as a broadcasted intent at install time, before the app is ever opened. - - - - - - ---- -title: "Multiple broadcast receivers in the same app, for the same action" -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." -author: "n3vrax" -date_published: "2011-07-22" -canonical_url: "https://www.dotkernel.com/android/multiple-broadcast-receivers-in-the-same-app-for-the-same-action/" -category: "Android" -language: "en" ---- - -# Multiple broadcast receivers in the same app, for the same action - -## The problem - -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. - -## The approach - -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. - -## FAQ - -**Q: What problem does this article address?** -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. - -**Q: When is this issue most likely to occur?** -A: This can happen when you use 3rd party libraries that already define their own broadcast receivers alongside your app's own receivers. - -## Resources - -- [Admob App Download Tracking documentation](http://developer.admob.com/wiki/Android_App_Download_Tracking) - - @@ -254,27 +91,6 @@ Dotkernel is an exception: new ConfigProviders have to be added manually in `con - **Environment-agnostic** - Returns an array that defines dev, test, or prod environments. - **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). -## FAQ - -**Q: What is a ConfigProvider in PHP?** -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. - -**Q: What does the ConfigProvider return in the Laminas/Mezzio ecosystem?** -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. - -**Q: What is the difference between 'factories' and 'invokables' in the dependencies array?** -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. - -**Q: How does the ConfigProvider get used during application bootstrap?** -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. - -**Q: Are new ConfigProviders auto-discovered in Dotkernel?** -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. - -**Q: What are the benefits of using a ConfigProvider?** -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. - ## Resources - [Mezzio Container](https://docs.mezzio.dev/mezzio/v3/features/container/config/) @@ -339,27 +155,6 @@ Middleware can modify headers, cookies, compress content, etc. 11. **Response Emitter** - The final response is sent back to the browser. The page is rendered and sent to the user, as one of `HTTP 20x/30x`, `HTTP 40x`, or `HTTP 50x`. -## FAQ - -**Q: What is the request lifecycle?** -A: The request lifecycle is the sequence of steps that happen from the moment a user makes an HTTP request until the server sends back a response. - -**Q: What happens at the entry point of a request?** -A: The application bootstraps and loads configuration to create the Mezzio application instance, registers factories, aliases and delegators in the service container, reads all available routes with their allowed request methods and registers them (managed by FastRoute), and loads the predefined order of middleware in the pipeline. - -**Q: How does routing work in a Mezzio-based application?** -A: FastRoute matches the incoming URL and method against the registered routes, for example matching a GET request to `/page/about` against the `GetPageViewHandler` handler under the route name `page::about`. - -**Q: What happens during handler invocation?** -A: The matched route name is extracted from the request attribute and passed to the renderer, using code similar to `$template = $request->getAttribute(RouteResult::class)->getMatchedRouteName();`, after which the handler executes the custom business logic. - -**Q: What happens during template rendering?** -A: Twig loads the matched template file, applies the layout it extends, renders its blocks, and includes any partials, producing the final HTML output. - -**Q: How is the response created and returned to the browser?** -A: An `HtmlResponse` is created with a status code, headers, and the rendered HTML body. -It then flows back through the middleware stack in reverse (the response pipeline), where middleware can modify headers, cookies, or compress content, before the response emitter sends the final response back to the browser as HTTP 20x/30x, 40x, or 50x. - ## Resources - [Dotkernel Light on GitHub](https://github.com/dotkernel/light) @@ -489,30 +284,6 @@ The flow begins with a request. Execution passes control to the IP middleware, w Control passes to the custom handler that processes the request and returns a response. The flow continues in reverse order, back to the IP middleware, which can, if needed, change the output before it gets returned to the user that initiated the request. -## FAQ - -**Q: What is middleware?** -A: Middleware is code that exists between the request and response, and which can take the incoming request, perform actions based on it, and either complete the response or pass delegation on to the next middleware in the queue. - -**Q: What is the purpose of middleware?** -A: Middleware makes it easier for software developers to implement communication and input/output, so they can focus on the specific purpose of their application. -In web services, the Input represents the Request received, and Output represents the Response to be sent. - -**Q: What can middleware be used for?** -A: Middleware can be used for purposes such as A/B testing, debugging, caching, CORS, authentication (HTTP Basic Auth, OAuth 2.0, OpenID), CSRF protection, rate limiting, referrals, and IP restriction. - -**Q: What interface must PHP middleware implement to be PSR-15 compliant?** -A: According to PSR-15, a compliant middleware must implement `Psr\Http\Server\MiddlewareInterface`, which requires a `process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface` method. - -**Q: How does middleware get called within the application pipeline?** -A: The application pipeline defines the execution flow: the request passes through the middleware one by one, in the order they are placed. If control passes through all middleware successfully, execution is passed to your custom code, which generates a response, and execution then passes back through the middleware in reverse order. -If execution is terminated before reaching your custom code (e.g. via an exception), the response is generated by the last middleware reached. - -**Q: What is a practical, real-world example of middleware?** -A: A simple example is enhancing a request with the user's IP for logging purposes or geographical reporting. -The request first passes through the IP middleware, which enhances the request with the user's IP and other relevant data, then control passes to the custom handler that processes the request and returns a response. -The flow continues in reverse, back through the IP middleware, which can change the output before it's returned to the user. - ## Resources - [Why Care About PHP Middleware?](https://philsturgeon.uk/php/2016/05/31/why-care-about-php-middleware/) @@ -525,53 +296,6 @@ The flow continues in reverse, back through the IP middleware, which can change - [From Helpers to Middleware](https://www.youtube.com/watch?v=v1I57-_Rsv0) - - - - ---- -title: "Aptana - set SVN keywords" -description: "How to set the svn:keywords property (e.g. Id) for a file in Aptana, so SVN replaces the keyword marker with commit metadata." -author: "Teo" -date_published: "2011-04-04" -canonical_url: "https://www.dotkernel.com/best-practice/aptana-set-svn-keywords/" -category: "Best Practice" -language: "en" ---- - -# Aptana - set SVN keywords - -## Overview - -In Aptana it's very simple to set the svn:keywords property for a file. -For example, to set the svn keyword property `Id`: - -## Steps - -1. In the file where the svn keyword property should be added, write `$Id$`. -2. Right click on the file, then follow Team -> Set Property... -(Note: "Set Property..." will not be active if the file hasn't first been added to SVN via Team -> Add to Version Controller). -3. Select `svn:keywords`, and write `Id` in the text field. - -When the SVN commit of the file is made, the `$Id$` keyword will be replaced with text containing the file's SVN metadata, in a specific format. - -## FAQ - -**Q: How do you set the svn:keywords property for a file in Aptana?** -A: Write the keyword marker (for example `$Id$`) in the file, then right click the file and follow Team -> Set Property..., select `svn:keywords`, and write `Id` in the text field. - -**Q: Why is "Set Property..." not active when I right click the file?** -A: Set Property... will not be active if the file hasn't first been added to SVN. -Use Team -> Add to Version Controller before trying to set the property. - -**Q: What happens to the $Id$ keyword after an SVN commit?** -A: After the SVN commit of the file, the `$Id$` keyword is replaced with text containing the file's SVN metadata, in a specific format. - -## Resources - -- [svn:keywords property documentation](http://svnbook.red-bean.com/en/1.4/svn.advanced.props.special.keywords.html) - - @@ -699,29 +423,6 @@ Sensitive information must only go in `*.local.php` files, since they are ignore Development mode enables features like debug mode, cache clear, and error details, which should be hidden from production to avoid exposing sensitive data or code. The Laminas Continuous Integration GitHub Action is integral to Dotkernel API, running a matrix of static analysis, coding standards checks, and unit tests, most often triggered by commits. -## FAQ - -**Q: What are the main facets of software security to consider?** -A: Software security spans many areas: authentication and access control, data protection, input validation and injection, web and API security, dependency and supply chain risks, configuration and deployment, network and infrastructure security, logging/monitoring and incident response, secure software development lifecycle, and human and organizational factors. - -**Q: How does Dotkernel handle form input validation?** -A: Dotkernel API uses laminas/laminas-inputfilter to ensure a field is present and of the correct type. -Dotkernel Admin additionally uses laminas/laminas-form, which provides form element objects, an InputFilter for each input (or custom validators), and methods for binding data to and from the form, integrating with laminas-escaper, laminas-validator, laminas-session, and laminas-filter. - -**Q: How does Dotkernel API handle content negotiation?** -A: Content negotiation is handled via a middleware configured in the `config/autoload/content-negotiation.global.php` file. -It uses the Content-Type and Accept HTTP request headers to negotiate with the client, returning application/json or application/hal+json data formats. - -**Q: How is CORS handled and configured in Dotkernel API?** -A: CORS is handled by mezzio/mezzio-cors and configured in the `config/autoload/cors.local.php` file, validating calls using configuration items like origins, headers, max age, and credentials. -When configuring the pipeline, the CorsMiddleware must be added before the RouteMiddleware. - -**Q: What should be done with the demo credentials before going to production?** -A: Demo credentials are provided for convenience during installation testing, but it is important to update or remove these accounts in your production environment. - -**Q: What are the security recommendations around OpenAPI documentation?** -A: You should not include sensitive information for your endpoints in the OpenAPI documentation, and you should not enable the documentation in a production environment. - ## Resources - [Basic Security in Dotkernel Admin](https://docs.dotkernel.org/admin-documentation/v6/security/basic-security/) @@ -735,68 +436,6 @@ A: You should not include sensitive information for your endpoints in the OpenAP - [mezzio/mezzio-authentication-oauth2 Configuration](https://docs.mezzio.dev/mezzio-authentication-oauth2/v1/intro/#configuration) - - - - ---- -title: "Golden Rules of Professional PHP Coding" -description: "A short list of practical rules for professional PHP development: error reporting settings, fixing warnings, marking hacks, single-responsibility functions, version control, and IDE usage." -author: "admin" -date_published: "2011-06-12" -canonical_url: "https://www.dotkernel.com/best-practice/golden-rules-of-professional-php-coding/" -category: "Best Practice" -language: "en" ---- - -# Golden Rules of Professional PHP Coding - -## The Rules - -1. Always use, in development and in staging, the highest error reporting level, and display_errors ON: - ```php - error_reporting(-1); - ini_set('display_errors', 1); - ``` -2. Fix every warning or notice that occurs. -3. Check regularly the server's error_log for notices/warnings. -4. Identify any temporary hack with a special mark, for example: - ```php - #@TODO masterpiece by @smartguy, to quick fix the division by zero - ``` -5. Each function must do a single task. -If it logs in the user and records the login in a stats table, create a separate function for the "record the login" part - maybe even a distinct class for stats. -6. Use a version control system. -SVN is NOT dead. -7. Use an IDE, such as Aptana 2, Aptana 3, Eclipse, or Zend Studio. -8. Know your IDE: code snippets, code assist, integration with Zend Framework, SVN integration, bug tracker integration, and so on. - -## FAQ - -**Q: What error reporting settings should be used in development and staging?** -A: Always use the highest error reporting level and turn display_errors ON, for example with `error_reporting(-1);` and `ini_set('display_errors', 1);`. - -**Q: What should you do about warnings and notices?** -A: Fix every warning or notice that occurs, and regularly check the server's error_log for notices and warnings. - -**Q: How should temporary hacks or quick fixes be marked in code?** -A: Identify any temporary hack with a special mark, such as a `#@TODO` comment noting who added it and why. - -**Q: What is the rule about what a function should do?** -A: Each function must do a single task. -For example, if you're logging in a user and also recording that login in a stats table, create a separate function (or even a distinct class) for the stats recording, rather than combining both tasks in one function. - -**Q: What tools does the article recommend for professional PHP development?** -A: It recommends using a version control system (noting that SVN is not dead) and using an IDE such as Aptana 2, Aptana 3, Eclipse, or Zend Studio, and knowing your IDE's code snippets, code assist, Zend Framework integration, SVN integration, and bug tracker integration. - -## Resources - -- [Integrated development environment (Wikipedia)](http://en.wikipedia.org/wiki/Integrated_development_environment) -- [Aptana 2 download](http://www.aptana.com/products/studio2/download) -- [Aptana 3 download](http://www.aptana.com/products/studio3/download) -- [Zend Studio](http://www.zend.com/en/products/studio/) - - @@ -833,14 +472,6 @@ RewriteRule ^(.*)$ http://dotboost.com/$1 Replace `dotboost.com` with your site's domain in either case. -## FAQ - -**Q: How do I redirect a non-www domain to www using .htaccess?** -A: Add `RewriteCond %{HTTP_HOST} ^dotboost.com` and `RewriteRule ^(.*)$ http://www.dotboost.com/$1` to your .htaccess file, right after `RewriteEngine On`, replacing dotboost.com with your own domain. - -**Q: How do I redirect a www domain to non-www instead?** -A: Add `RewriteCond %{HTTP_HOST} ^www.dotboost.com` and `RewriteRule ^(.*)$ http://dotboost.com/$1` instead, again replacing dotboost.com with your own domain. - @@ -861,7 +492,7 @@ language: "en" ## TL;DR DML (Data Manipulation Language) statements change data values in database tables. -This article, continuing the Zend_Db series, shows how the three primary DML statements — INSERT, UPDATE, and DELETE — are written in raw SQL and translated into Zend_Db method calls. +This article, continuing the Zend_Db series, shows how the three primary DML statements - INSERT, UPDATE, and DELETE - are written in raw SQL and translated into Zend_Db method calls. ## Connecting to the database @@ -926,22 +557,6 @@ Zend_Db: $db->delete('user', 'id = '.$id); ``` -## FAQ - -**Q: What are DML statements?** -A: DML (Data Manipulation Language) statements are statements that change data values in database tables. -There are 3 primary DML statements: INSERT, UPDATE, and DELETE. - -**Q: How do you insert a new row with Zend_Db?** -A: Build an associative array of column names to values (e.g. email, password, firstName, lastName, active) and pass it to $db->insert('user', $data), which corresponds to an SQL INSERT INTO ... -VALUES statement. - -**Q: How do you update rows with Zend_Db, including incrementing a column?** -A: Build a $data array of the columns to update, using a Zend_Db_Expr for expressions such as incrementing accountUpdate (new Zend_Db_Expr('accountUpdate+1')), then call $db->update('user', $data, 'id = '.$id). - -**Q: How do you delete a row with Zend_Db?** -A: Call $db->delete('user', 'id = '.$id), which is equivalent to the SQL statement DELETE FROM user WHERE id = '$id'. - ## Resources - [Zend_Db series](http://www.dotkernel.com/dotkernel/sql-select-zend-db/) @@ -976,7 +591,7 @@ $db = Zend_Db::factory('Pdo_Mysql', $dbConnect); ## SELECT query - WHERE clause -The following two classical SQL queries are equivalent — the first is a simple comma join, the second uses INNER JOIN — but the result is the same: +The following two classical SQL queries are equivalent - the first is a simple comma join, the second uses INNER JOIN - but the result is the same: ```sql SELECT a.id, a.name, b.order_id @@ -1057,30 +672,9 @@ If you are not sure the correct query is being generated, echo it before fetchin echo $select->__toString();exit; ``` -## FAQ - -**Q: What does Zend_Db provide?** -A: Zend_Db and its related classes provide a simple SQL database interface for Zend Framework. -To connect to a MySQL database, the Pdo_Mysql adapter is used via Zend_Db::factory('Pdo_Mysql', $dbConnect). - -**Q: How do you write a SELECT with a JOIN and a WHERE clause in Zend_Db style?** -A: Use $db->select()->from(array('a'=>'users'), array('a.id','a.name'))->join(array('b'=>'orders'), 'a.id = b.user_id', array('b.order_id'))->where('a.id = ?', $userId), which is equivalent to a classical SQL query using INNER JOIN. - -**Q: How do you join a table without selecting any of its columns?** -A: Pass an empty string as the 3rd parameter of the join() method, e.g. ->join(array('b'=>'orders'), 'a.id = b.user_id', ''). - -**Q: What happens if the 3rd parameter of join() is omitted entirely?** -A: If the 3rd parameter is not written, it will select all the fields from that joined table (equivalent to SELECT ..., b.* in SQL). - -**Q: How do you write a WHERE IN clause with Zend_Db?** -A: Use ->where('aff_id IN (?)', array(1,2,3)) on the select object, equivalent to SQL's WHERE aff_id IN ('1','2','3'). - -**Q: How can you check that a Zend_Db select is generating the correct query?** -A: Before fetching it, echo the query to visualize it: echo $select->__toString();exit; - ## Resources -- [Zend_Db](http://framework.zend.com/manual/en/zend.db.adapter.html) +- [Zend_Db](https://docs.laminas.dev/laminas-db/adapter/) - [What are returning the FETCH functions from Zend_Db](http://www.dotkernel.com/best-practice/sql-fetch-zend-db/) - [Subqueries with Zend_Db](http://www.dotkernel.com/best-practice/subqueris-with-zend-db/) - [INSERT, UPDATE, DELETE statements with Zend_Db](http://www.dotkernel.com/best-practice/iud-statements-with-zend-d/) @@ -1104,7 +698,7 @@ language: "en" ## TL;DR -Continuing the Zend_Db series, this article shows a more complex query — combining COUNT(), LEFT JOIN, and GROUP BY across 3 tables, with a count taken from 2 different tables — and how to build it, including a nested subquery, using Zend_Db. +Continuing the Zend_Db series, this article shows a more complex query - combining COUNT(), LEFT JOIN, and GROUP BY across 3 tables, with a count taken from 2 different tables - and how to build it, including a nested subquery, using Zend_Db. ## The SQL query @@ -1150,237 +744,61 @@ $db->select() The `count_files` column is built by wrapping a nested `$db->select()` call inside a `Zend_Db_Expr`, correlated back to the outer table via `c.track_id = a.id`. -## FAQ - -**Q: What SQL techniques does this subquery example combine?** -A: The example combines COUNT(), LEFT JOIN, and GROUP BY, selecting from 3 tables and counting rows from 2 different tables. - -**Q: How do you embed a subquery as a selected column in a Zend_Db select?** -A: Wrap a nested $db->select() call inside a Zend_Db_Expr, building the subquery string with the outer table's correlated WHERE condition (e.g. c.track_id = a.id), as shown for the count_files column. - -**Q: How is the LEFT JOIN with a COUNT expressed in Zend_Db?** -A: Use ->joinLeft(array('b'=>'track_courses'), 'a.id = b.track_id', array('count_courses' => 'COUNT(b.track_id)')) followed by ->group('a.id'). - ## Resources - [Zend_Db series](http://www.dotkernel.com/dotkernel/sql-select-zend-db/) - + --- -title: "SVN Export in a virtual host" -description: "How to export the contents of an SVN repository into a virtual host directory using the svn export command." -author: "Adrian" -date_published: "2011-05-30" -canonical_url: "https://www.dotkernel.com/best-practice/svn-export-in-a-virtual-host/" +title: "Using LIKE wildcards with Zend_Db" +description: "How to use the SQL LIKE condition and its _ and % wildcards, including NOT LIKE, with Zend_Db's quoteInto and quoteIdentifier methods." +author: "Teo" +date_published: "2010-09-10" +canonical_url: "https://www.dotkernel.com/best-practice/using-like-wildcards-with-zend-db/" category: "Best Practice" language: "en" --- -# SVN Export in a virtual host +# Using LIKE wildcards with Zend_Db ## TL;DR -`svn export` lets you export the contents of a repository into a virtual host directory. -The commands should be run in a terminal (e.g. via Putty on Windows) on the target host, ideally using the domain's own user rather than root. - -## Steps +The LIKE condition allows pattern matching in the WHERE clause of SELECT, INSERT, UPDATE, or DELETE statements. +The `_` wildcard matches a single character, and `%` matches any string of any length (including zero). +This article shows how to use LIKE and NOT LIKE with both wildcards in Zend_Db. -1. Make sure Subversion is installed on the host by running `svn --version`. -If you don't get a "command not found" message, it's installed; otherwise, install it. -2. Go to the directory where you want to export the contents of the repository (e.g. `cd /var/www/vhosts/example.com/httpdocs` or `cd /home/sitename/public_html`). -3. Run the export command: +## Connecting to the database -```shell -svn export repositoryUrl repositoryUrl +```php +$db = Zend_Db::factory('Pdo_Mysql', $dbConnect); ``` -Where: - -| Parameter | Meaning | -|---|---| -| `-r revisionNumber` | Optional. Exports a specific revision. By default, the latest revision is used. | -| `repositoryUrl` | The repository URL (e.g. `http://example.com/repos/project-name/trunk/`). Remember to add `/trunk/`, or change it appropriately for a branch or tag. | -| `targetDirectory` — `./` | The current directory. | -| `targetDirectory` — `./project-name` | Exports to the `project-name` subdirectory. | -| `targetDirectory` — `/var/www/vhosts/example.com/httpdocs` | Exports to an absolute path. | -| `--force` | Optional. By default SVN will not export into an existing directory; this overrides that. **Be careful, this option can overwrite files.** | - -4. For more information, run `svn help export`. +## LIKE _ -## Examples +Return all ids that start with '1' and whose second digit is between 0 and 9 (10, 11, 12, ..., 18, 19): -```shell -svn export http://v1.dotkernel.net/svn/trunk ./ --force -svn export -r 423 http://v1.dotkernel.net/svn/trunk ./ --force -svn export http://v1.dotkernel.net/svn/trunk /var/www/vhosts/domain.com/httpdocs/dk +```sql +SELECT * FROM `table` WHERE (`id` LIKE '1_' ) ``` -## Fixing permissions afterward - -If the repository was exported using a different user (e.g. root), change the permissions back as root: - -```shell -chown -R siteuser.psacln /var/www/vhosts/example.com/httpdocs +```php +$col = $this->db->quoteIdentifier('id'); +$where = $this->db->quoteInto("$col LIKE ? ", '1_'); +$select = $this->db->select() + ->from('table') + ->where($where); +$result = $this->db->fetchAll($select); ``` -## FAQ +Return all instances whose name is 4 characters long, starting with 'Fr' and ending with 'd' (Frad, Fred, Frod, etc.): -**Q: How do you check if Subversion is installed on the host?** -A: Run svn --version. -If you don't get a "command not found" message, Subversion is installed; otherwise, you need to install it. - -**Q: What is the basic command to export a repository?** -A: The command is svn export repositoryUrl targetDirectory, run from the host where you want to export the repository, ideally using the domain's user rather than root. - -**Q: What does the -r option do?** -A: -r revisionNumber is optional and exports a specific revision; by default, the latest revision is used. - -**Q: What does the --force option do, and what is the risk?** -A: By default SVN will not export into an existing directory; --force overrides this. -Be careful, since this option can overwrite files. - -**Q: How do you fix file permissions if you exported the repository as a different user?** -A: As root, run chown -R siteuser.psacln /var/www/vhosts/example.com/httpdocs to change the permissions back. - - - - - - ---- -title: "SVN keywords setup in PHP IDE ( Zend Studio)" -description: "How to set SVN ignore, bug tracker, and svn:keywords properties per project in the Zend Studio PHP IDE." -author: "admin" -date_published: "2013-02-21" -canonical_url: "https://www.dotkernel.com/best-practice/svn-keywords-setup-in-php-ide-zend-studio/" -category: "Best Practice" -language: "en" ---- - -# SVN keywords setup in PHP IDE ( Zend Studio) - -## TL;DR - -For better integration between SVN, the Zend Studio PHP IDE, and a bug tracker, a set of SVN properties must be set for each project. -This article lists which properties to set and how. - -## Steps - -1. Right click on the **project**. -2. Go to **Team -> Set Propriety**. -3. Set `svn:ignore` so local settings aren't committed to the main repository: - -``` -Name: svn:ignore -Propriety: -*.project -*.prefs -.project -cache -.settings -.buildpath -*.ini -``` - -4. Set up basic bug tracker integration: - -``` -Name: bugtracq:label -Propriety: Tracker ID: -``` - -``` -Name: bugtraq:message -Propriety: -``` - -5. If using a public bug tracker (e.g. Mantis), also set: - -``` -Name: bugtraq:url -Propriety: http://www.dotkernel.net/view.php?id=%BUGID% -``` - -For the properties above, apply them **only** to the project folder, **not** recursively. - -## Final step (svn:keywords only) - -1. Check **Apply property recursively to:**. -2. Select **All resources**. -3. Check **Use filtration by the resource name** and add mask: `*.php`. - -## FAQ - -**Q: Why set these SVN properties on each project?** -A: They provide better integration of SVN, your PHP IDE (Zend Studio), and a bug tracker of choice, and must be set for each project you have. - -**Q: What does the svn:ignore property do here?** -A: It tells SVN to ignore local settings files such as *.project, *.prefs, .project, cache, .settings, .buildpath, and *.ini, since you don't want to commit your local settings to the main repository. - -**Q: How do you set up basic bug tracker integration?** -A: Set the bugtracq:label property to "Tracker ID:" and bugtraq:message; if you have a public bug tracker such as Mantis, also set bugtraq:url to a URL pattern like http://www.dotkernel.net/view.php?id=%BUGID%. - -**Q: Should these properties be applied recursively?** -A: No. For the properties above, apply them only to the project folder, not recursively. - -**Q: How is the svn:keywords property applied differently?** -A: Check "Apply property recursively to:", select "All resources", then check "Use filtration by the resource name" and add the mask *.php. - - - - - - ---- -title: "Using LIKE wildcards with Zend_Db" -description: "How to use the SQL LIKE condition and its _ and % wildcards, including NOT LIKE, with Zend_Db's quoteInto and quoteIdentifier methods." -author: "Teo" -date_published: "2010-09-10" -canonical_url: "https://www.dotkernel.com/best-practice/using-like-wildcards-with-zend-db/" -category: "Best Practice" -language: "en" ---- - -# Using LIKE wildcards with Zend_Db - -## TL;DR - -The LIKE condition allows pattern matching in the WHERE clause of SELECT, INSERT, UPDATE, or DELETE statements. -The `_` wildcard matches a single character, and `%` matches any string of any length (including zero). -This article shows how to use LIKE and NOT LIKE with both wildcards in Zend_Db. - -## Connecting to the database - -```php -$db = Zend_Db::factory('Pdo_Mysql', $dbConnect); -``` - -## LIKE _ - -Return all ids that start with '1' and whose second digit is between 0 and 9 (10, 11, 12, ..., 18, 19): - -```sql -SELECT * FROM `table` WHERE (`id` LIKE '1_' ) -``` - -```php -$col = $this->db->quoteIdentifier('id'); -$where = $this->db->quoteInto("$col LIKE ? ", '1_'); -$select = $this->db->select() - ->from('table') - ->where($where); -$result = $this->db->fetchAll($select); -``` - -Return all instances whose name is 4 characters long, starting with 'Fr' and ending with 'd' (Frad, Fred, Frod, etc.): - -```sql -SELECT * FROM `table` WHERE (`name` LIKE 'Fr_d' ) -``` +```sql +SELECT * FROM `table` WHERE (`name` LIKE 'Fr_d' ) +``` ```php $col = $this->db->quoteIdentifier('name'); @@ -1475,25 +893,6 @@ $select = $this->db->select() $result = $this->db->fetchAll($select); ``` -## FAQ - -**Q: What do the LIKE wildcards _ and % mean?** -A: The _ wildcard matches a single character, while % matches any string of any length, including zero length. - -**Q: Which SQL statements can use the LIKE condition?** -A: LIKE allows pattern matching in the WHERE clause and can be used in any valid SQL statement: SELECT, INSERT, UPDATE, or DELETE. - -**Q: How do you build a LIKE query with Zend_Db?** -A: Quote the column with $this->db->quoteIdentifier(), build the condition with $this->db->quoteInto("$col LIKE ? -", $pattern), and pass the resulting $where string into ->where() on a select, then run it with $this->db->fetchAll($select). - -**Q: How do you combine multiple LIKE conditions with OR?** -A: Build the first condition with quoteInto, then append further ones with quoteInto("OR $col LIKE (?) -", $pattern), as in the example matching 'gallery' or 'folder' in the source field. - -**Q: How does NOT LIKE differ from LIKE?** -A: NOT LIKE negates the pattern match — for example, id NOT LIKE '1_' returns ids that don't start with 1 or don't have exactly 2 digits, and NOT LIKE conditions can be chained with AND to exclude several patterns at once. - @@ -1669,23 +1068,6 @@ Zend_Db style: $a = $db->fetchRow($select); ``` -## FAQ - -**Q: What FETCH methods are available in Zend_Db_Adapter_Abstract?** -A: The article covers fetchAll, fetchAssoc, fetchCol, fetchOne, fetchPairs, and fetchRow. - -**Q: What does fetchAll do compared to the old query style?** -A: `$a = $db->fetchAll($select)` replaces the old-style loop that calls `next_record()` repeatedly and builds an array of associative rows using `f()` for each column. - -**Q: What does fetchRow return?** -A: `$a = $db->fetchRow($select)` returns a single row as an associative array, replacing a single `next_record()` call followed by `f()` calls for each column. - -**Q: What does fetchOne return?** -A: `$a = $db->fetchOne($select)` returns a single value, replacing a single `next_record()` call followed by one `f()` call. - -**Q: How do the old-style query(), next_record(), and f() methods relate to Mysqli?** -A: `query()` is similar to `mysqli_query()`, `next_record()` is similar to `mysqli_next_result()`, and `f()` retrieves the value of the column specified as a parameter. - @@ -1738,27 +1120,10 @@ DEFAULT and ON UPDATE clauses can be used together or separately, depending on y - With a constant `DEFAULT` value, the column has the given default and is not automatically initialized to the current timestamp. If the column also has an `ON UPDATE CURRENT_TIMESTAMP` clause, it is automatically updated; otherwise, it has a constant default and is not automatically updated. -For more details, check out the MySQL Manual. +For more details, check out the [MySQL Manual](https://dev.mysql.com/doc/refman/9.7/en/datetime.html). Note: only one timestamp field can be `DEFAULT CURRENT_TIMESTAMP` in a table. -## FAQ - -**Q: Why use CURRENT_TIMESTAMP as a DEFAULT value for a date/time field?** -A: Because when inserting a new row, there is no need to specifically set the date/time value yourself, either from PHP Date/Time functions or with MySQL's NOW() function. - -**Q: How do you make a field update its timestamp automatically on every UPDATE?** -A: Add the ON UPDATE CURRENT_TIMESTAMP clause, for example: `ALTER TABLE `user` CHANGE `dateLogin` `dateLogin` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP`. - -**Q: What happens if a TIMESTAMP column has neither a DEFAULT nor an ON UPDATE clause?** -A: For the first TIMESTAMP field in the table, having neither clause is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP. - -**Q: What happens with a DEFAULT CURRENT_TIMESTAMP clause but no ON UPDATE clause?** -A: The column gets the current timestamp as its default value but is not automatically updated afterward. - -**Q: Can more than one TIMESTAMP column default to CURRENT_TIMESTAMP in the same table?** -A: No. Only one timestamp field in a table can be DEFAULT CURRENT_TIMESTAMP. - @@ -1778,18 +1143,18 @@ language: "en" ## TL;DR -Laminas MVC is retiring, following Zend Framework and Apigility before it, but this doesn't mean everything with a Laminas logo is going away — Mezzio, built on Laminas components, is the fully-functional successor. +Laminas MVC is retiring, following Zend Framework and Apigility before it, but this doesn't mean everything with a Laminas logo is going away - Mezzio, built on Laminas components, is the fully-functional successor. Maintaining legacy MVC platforms is costly and risky long-term, since the architecture of today and tomorrow is middleware-based, and Apidemia offers a proven, phased migration process to move legacy platforms to Mezzio. ## A Bit of History It all started with the announcement: Laminas MVC Is Retiring. -Some people wrongfully thought everything with a Laminas logo is going away — not so. +Some people wrongfully thought everything with a Laminas logo is going away - not so. Read on for a bit of history about Zend and Laminas, what it means to migrate your platform, and why it's a decision that should not be taken lightly. -Laminas MVC is not even the first framework that has reached its end of life — look at Zend Framework and Apigility. +Laminas MVC is not even the first framework that has reached its end of life - look at Zend Framework and Apigility. Letting go of a flagship product is a difficult decision, but it's made easier when you leave a solid alternative in its wake. -The developers who worked on Laminas MVC already had something better and fully-functional in place — the Mezzio microframework, built using Laminas components. +The developers who worked on Laminas MVC already had something better and fully-functional in place - the Mezzio microframework, built using Laminas components. It has itself gone through rigorous development and testing since being released in 2015, when it was known as Zend Expressive, then was renamed into Mezzio to get to its current state. ## What Is the Issue with Legacy Platforms? @@ -1828,36 +1193,102 @@ Over the long run, the Apidemia team offers support and training. This is the simplified task list: -- Code audit & migration strategy — to understand the code and see what goes where. -- Partial or full migration to Laminas or PSR-compliant frameworks, like Mezzio or Symfony — this decision impacts both time to implement and cost, negotiated with the client. -- Refactoring and decoupling legacy modules — the old code must go and be replaced with the new. -- Unit testing and CI/CD pipeline setup — a vital step to ensure things function the same way in the destination platform. -- Post-migration support and team training — this step depends on the level of collaboration between the original developers and the Apidemia team, so the more closely they work together, the easier it is to onboard the devs for the long run. +- Code audit & migration strategy - to understand the code and see what goes where. +- Partial or full migration to Laminas or PSR-compliant frameworks, like Mezzio or Symfony - this decision impacts both time to implement and cost, negotiated with the client. +- Refactoring and decoupling legacy modules - the old code must go and be replaced with the new. +- Unit testing and CI/CD pipeline setup - a vital step to ensure things function the same way in the destination platform. +- Post-migration support and team training - this step depends on the level of collaboration between the original developers and the Apidemia team, so the more closely they work together, the easier it is to onboard the devs for the long run. + +## Resources + +- [Dotkernel Headless Platform](https://www.dotkernel.com/headless-platform/dotkernel-headless-platform-the-whats-hows-and-whys/) +- [Shared Core Submodule in Dotkernel Headless Platform](https://www.dotkernel.com/headless-platform/shared-core-submodule-in-dotkernel-headless-platform/) +- [Understanding Middleware](https://www.dotkernel.com/architecture/understanding-middleware/) +- [Dotkernel Light](https://www.dotkernel.com/dotkernel/dotkernel-light-starting-with-mezzio-microframework-and-laminas-components/) +- [Migrate Laminas MVC to Dotkernel](https://www.apidemia.com/services/migrate-laminas-mvc-to-dotkernel/) + + + + + + +--- +title: "Naming pattern for PSR-15 handlers in Dotkernel applications" +description: "This naming pattern is used in Dotkernel Admin v6 and will also be implemented in the next releases for Frontend and Light." +author: "Florin Bidirean" +date_published: "2025-04-17" +canonical_url: "https://www.dotkernel.com/design-pattern/naming-pattern-for-psr-15-handlers-in-dotkernel-applications/" +category: "Design Patterns" +language: "en" +--- + +# Naming pattern for PSR-15 handlers in Dotkernel applications + +> This naming pattern is used in Dotkernel Admin v6 and will also be implemented in the next releases for Frontend and Light. + +The bigger a project is, the more time it will take to develop and the more people will be assigned to it. Each developer will use slight variations when it comes to naming files, which is not going to be consistent, sometimes not even with work he has done on the same project in the previous month. + +It might seem ok to use the file names 'CreateUser.php' as much as 'AddUser.php' or 'InsertUser.php', since they perform the same action. But consider that you might have 'CreateUser.php', 'AddProduct.php' and 'InsertOrder.php' in the same application. It's still readable, but chaotic. We will show you a better way to handle file naming, using naming patterns. + +## What is a naming pattern? + +A naming pattern helps you organize and quickly identify your files by using relevant strings in file names like: + +- What a file refers to. +- The action a file performs. +- How a file relates to other files. +- The author of the file's contents. +- The creation date or the event the file refers to. + +Naming patterns can be defined for different types of files, since `image` files might need other information than `php` files or simple `txt` files used for logs. + +Here is a list of items to consider: + +- The file names should be kept as **short** as possible, while retaining relevant items to help outline the file's purpose. +- **Abbreviations** are ok to use, but special characters should be avoided, excepting dash and underscore which are fine, no matter the operating system you use. +- **Versioning and metadata** can also help visually. +- Grouping files into **folders** is also recommended, especially when you are dealing with files that are related. +- If **category names** are relevant to use, you can standardize their names by using a shortened version, maybe with 2-3 letters. + +After defining your naming pattern, the most important item by far is to **communicate the pattern to the team**. A top-level README file with the documentation should be kept handy for any developer who creates new files. + +## The naming pattern for Dotkernel Handlers + +HTTP request handlers are at the core of any web application. They receive a request, process it and return a response. -## FAQ +Even the first paragraph above mentions several elements that are relevant. The naming pattern for our `Handlers` contains: -**Q: What is Laminas MVC being replaced by?** -A: Mezzio microframework, built using Laminas components. It has gone through rigorous development and testing since being released in 2015, when it was known as Zend Expressive, before being renamed Mezzio. +- The **method** or verb used by the handler (e.g. GET, POST). +- The **resource** name (e.g. Admin, Account). +- The performed **action** (e.g. CreateForm, List). +- An optional **Form** if the handler returns a form that will perform another action when submitted. +- The string **Handler**. -**Q: Why is maintaining legacy platforms a problem?** -A: Maintaining legacy platforms over the long term is often costly and time-consuming, so every few years platform owners must consider migrating to a newer platform that offers modern architecture, an active community, easier development/expansion/maintenance, security improvements, and more reliable dependencies. +In this way, the developer can easily figure out what each handler does, just by looking at the name. -**Q: What is the core architectural pain point with legacy MVC platforms?** -A: The MVC architecture is obsolete, fit for monolithic websites. Today's and tomorrow's architecture is based on middleware, building headless platforms, websites, and microservices following the same coding approach. +We have chosen this wording for the performed actions (or CRUD): -**Q: What steps does Apidemia's migration process involve?** -A: A simplified task list: code audit & migration strategy; partial or full migration to Laminas or PSR-compliant frameworks like Mezzio or Symfony; refactoring and decoupling legacy modules; unit testing and CI/CD pipeline setup; and post-migration support and team training. +- **Create** +- **Get** for Read +- **Edit** for Update +- **Delete** -**Q: Who offers this migration guidance?** -A: Apidemia, who has used Zend Framework, Laminas MVC, and Mezzio for years and can analyze and perform the transfer of a legacy platform to Mezzio, offering faster execution times, increased security, faster development, and long-term reliability. +## A practical example + +Let's assume your application requires you to create products managed by admin users. So how do you go about naming a new set of files for this purpose? + +First, you need a form to fill out. The form is returned by a `handler` called with `get`. Its purpose is to perform a `create` action for an `product`, hence you name it: `GetProductCreateFormHandler`. + +Then you send the form data to be saved as a new product. The second `handler` will `create` the new `product` account via `post`, so you get: `PostProductCreateHandler`. + +You will likely need to update and delete products further down the line, so you create the handlers: `GetProductEditFormHandler`, `PostProductEditHandler` and `PostProductDeleteHandler`. The final handler that makes sense in this group is `GetProductListHandler` that will list all the products you have created, with filtering included. + +It takes only a minute to build the proper name for each handler, which takes you and other team members no more than a second to figure out what it does. You will thank yourself in the future. ## Resources -- [Dotkernel Headless Platform](https://www.dotkernel.com/headless-platform/dotkernel-headless-platform-the-whats-hows-and-whys/) -- [Shared Core Submodule in Dotkernel Headless Platform](https://www.dotkernel.com/headless-platform/shared-core-submodule-in-dotkernel-headless-platform/) -- [Understanding Middleware](https://www.dotkernel.com/architecture/understanding-middleware/) -- [Dotkernel Light](https://www.dotkernel.com/dotkernel/dotkernel-light-starting-with-mezzio-microframework-and-laminas-components/) -- [Migrate Laminas MVC to Dotkernel](https://www.apidemia.com/services/migrate-laminas-mvc-to-dotkernel/) +- [PSR-15](https://www.php-fig.org/psr/psr-15/) +- [Dotkernel Application Repositories](https://github.com/dotkernel) @@ -1883,7 +1314,7 @@ Bruno wins on offline access, version control via Git, performance, and (arguabl ## Why We Switched to the Offline-Focused Bruno -Every API developer needs a reliable client for testing and interacting with the API — ideally free, able to store and share endpoint collections easily with a team, fast, and secure. +Every API developer needs a reliable client for testing and interacting with the API - ideally free, able to store and share endpoint collections easily with a team, fast, and secure. Postman has been the team's go-to tool for years, but they are now considering Bruno, part of a general trend in the PHP community toward local-first, Git-native developer tools. ## Comparing Postman to Bruno @@ -1906,12 +1337,12 @@ Bruno stores collections in Git, so everything is offline, which the team consid Bruno is only one of several alternatives to Postman: -- Hoppscotch — runs in the browser or as a PWA -- Insomnia — clear UI and large plugin ecosystem -- HTTPie — focuses on terminal-based workflows -- Thunder Client — built into Visual Studio Code -- Apidog — covers the whole API lifecycle -- Yaak — minimal and fast desktop client +- Hoppscotch - runs in the browser or as a PWA +- Insomnia - clear UI and large plugin ecosystem +- HTTPie - focuses on terminal-based workflows +- Thunder Client - built into Visual Studio Code +- Apidog - covers the whole API lifecycle +- Yaak - minimal and fast desktop client Any of them can get the job done; the decision comes down to choosing a simple, reliable tool for the foreseeable future. @@ -1930,31 +1361,6 @@ Given Bruno's straightforward approach and reasonable learning curve, the team e The team expects Bruno may eventually restrict developers with paid plans too, just like Postman did, but plans to cross that bridge when they get to it. For now, Bruno is becoming their de facto API client, and the whole team is being encouraged to adopt it as soon as possible. -## FAQ - -**Q: Why is the team considering a switch from Postman to Bruno?** -A: They want a reliable API testing client that is free, stores and shares endpoint collections easily with the team, and is fast and secure. -This reflects a broader trend in the PHP community toward local-first, Git-native developer tools. - -**Q: What is the main architectural difference between Postman and Bruno?** -A: Postman's free plan now only allows one user account, while Bruno offers a fully-offline experience based on shared `.bru` files, so there is no restriction on the number of developers using them. - -**Q: How does version control differ between the two tools?** -A: Postman stores collections and handles version control in the cloud, forcing developers to stay online (though collections can be exported/imported via its UI). -Bruno's `.bru` files can be saved directly in a Git repository and are version-controlled through Git like any other project file. - -**Q: How does performance compare between Postman and Bruno?** -A: Bruno is the clear winner on performance: it uses much less RAM and is generally faster. -Postman needs to regularly synchronize with the cloud and store its advanced features in RAM, which can introduce delays. - -**Q: Is Bruno more secure than Postman?** -A: Postman offers Single Sign-On (SSO) and Role-Based Access Control (RBAC), which the team doesn't find useful for its workflow. -Bruno's local files never leave the dev environment, which the article argues makes it more secure, especially for avoiding sharing client files with online tools. - -**Q: What's the overall conclusion on Postman versus Bruno?** -A: Postman is currently a better fit for larger teams willing to allocate a budget for a more feature-rich platform. -Bruno stores collections in Git so everything works offline, which the team considers more secure while also being generally faster, and it has become their de facto API client. - ## Resources - [Bruno homepage](https://www.usebruno.com/) @@ -2003,17 +1409,6 @@ With a body: Note: the error message is stored by default in `/log/error-report-endpoint-log.log`, a separate log for Client, and the message is saved together with a timestamp. -## FAQ - -**Q: Why was this endpoint created?** -A: When a Frontend client (e.g. Angular) running on the user's machine hits an error against the Dotkernel API - whether from an overnight API response change or a simple undefined variable - there is little that can be done from the client side, so this endpoint lets clients "write down" the error instead. - -**Q: How do I submit an error from the client?** -A: Send a simple POST request to your Dotkernel API's `https://api.dotkernel.net/error-report` route, with a body such as `{ "message": "My awesome error!!!" }`. - -**Q: Where is the submitted error message stored?** -A: By default, it is stored in a separate log file for Client, `/log/error-report-endpoint-log.log`, with the message saved alongside a timestamp. - ## Resources - [Dotkernel API on GitHub](https://github.com/dotkernel/api) @@ -2103,31 +1498,6 @@ In this example, the client accepts both JSON and XML, with JSON preferred. If t Out of the box, Dotkernel API uses the `Content-Type` and `Accept` HTTP request headers to handle client-side content negotiation, supporting both `application/json` and `application/hal+json`. These can be changed as development progresses, and per-route content negotiation is also supported. Configuration lives in its own configuration file, validation is automatic, and several explicit errors are handled based on the supported format. -## FAQ - -**Q: What is content negotiation?** -A: It's the act of a client and server agreeing on the format and language of the data they exchange, which is important for RESTful APIs since resources can support multiple representations. - -**Q: What does content negotiation ensure?** -A: It ensures support for diverse clients (e.g. `Accept: application/json` or `Accept: application/xml`), data format flexibility for smaller responses (e.g. `Accept: application/msgpack`, a binary serialization), and language localization via headers like `Accept-Language: en-US`. - -**Q: Who decides the data format, the client or the server?** -A: Either side technically can. -In server-side negotiation, the server decides based on various factors, which can introduce erroneous assumptions and more complex implementation, forcing the client to adhere to server rules. -In client-side negotiation, the client tells the server what format it prefers, which is more versatile and makes more sense. - -**Q: How can the preferred data format be communicated?** -A: Via HTTP request headers (`Content-Type` and `Accept`) or via resource URI patterns, such as a file extension in the URL (e.g. `/record/47.json`) or an extra query parameter (e.g. `/record/47?format=json`). -If the `Accept` header is not present, the server decides the response format. - -**Q: How does the quality factor (q) work in the Accept header?** -A: The `Accept` header can list multiple accepted formats with a `q` value between 0 and 1 to express preference, e.g. `Accept: application/json,application/xml;q=0.9,*/*;q=0.8`. -The server responds with the most preferred format it can satisfy, falling back further down the list if needed. - -**Q: How does Dotkernel API handle content negotiation?** -A: Out of the box, Dotkernel API uses the `Content-Type` and `Accept` HTTP request headers to handle client-side content negotiation, supporting both `application/json` and `application/hal+json`. -These can be changed as needed, and per-route content negotiation is also supported. - ## Resources - [Content Negotiation in Dotkernel API](https://docs.dotkernel.org/api-documentation/v5/core-features/content-validation/) @@ -2184,17 +1554,6 @@ Out-of-the-box, Dotkernel API provides the following features: - Members are allowed to manage only their own accounts - OpenAPI 3 documentation - also an interactive interface that developers can use to integrate your API -## FAQ - -**Q: What is Dotkernel API?** -A: It is a Zend Expressive 3 application aiming to help developers quickly and efficiently develop an API. - -**Q: What key libraries does Dotkernel API 1.0.0 use?** -A: Among others, it's built on the `ezimuel/zend-expressive-api` skeleton, and uses `dotkernel/dot-annotated-services` for dependency injection, `dotkernel/dot-console` for console applications, `dotkernel/dot-errorhandler` for error logging, `dotkernel/dot-mail` for SMTP email, `zend-expressive-authentication-oauth2` for OAuth2 authentication, `zend-expressive-authorization-rbac` for role-based permissions, and `swagger-api/swagger-ui` for OpenAPI 3 documentation. - -**Q: What features does Dotkernel API 1.0.0 offer out of the box?** -A: Secure authentication via OAuth2, two user roles (admin and member), where admins can manage any user account and members can manage only their own, plus OpenAPI 3 documentation with an interactive interface developers can use to integrate the API. - ## Resources - [Dotkernel API 1.0.0 release on GitHub](https://github.com/dotkernel/api/releases/tag/v1.0.0) @@ -2260,17 +1619,6 @@ If the credentials are correct, the API will return a JSON object containing the When sending API requests to an endpoint which requires authorization, an `Authorization` header must be present containing `"Bearer {access_token}"`, where `{access_token}` represents the content of the key with the same name found in the authorization response. -## FAQ - -**Q: What does a client send to request authorization?** -A: The client application sends a POST request to the backend with a JSON object containing `grant_type` (set to "password"), `client_id`, `client_secret`, `scope`, `username`/email, and `password`. - -**Q: What does the API return when authorization succeeds?** -A: If the credentials are correct, the API returns a JSON object containing `token_type` ("Bearer"), `expires_in` (86400 seconds), an `access_token`, and a `refresh_token`. - -**Q: How do I use the access token in subsequent requests?** -A: When sending API requests to an endpoint that requires authorization, include an Authorization header containing `"Bearer {access_token}"`, where `{access_token}` is the value returned in the authorization response. - ## Resources - [Dotkernel API on GitHub](https://github.com/dotkernel/api) @@ -2364,27 +1712,6 @@ Creating a route for such an endpoint will have a structure similar to the follo $app->get('/users', , 'users'); ``` -## FAQ - -**Q: What are the three access levels for protecting an endpoint?** -A: no-auth, where the resource can be accessed without authentication/authorization; authentication, where only authenticated users can access the resource; and authorization, where only authenticated AND authorized users can access it. - -**Q: Where do I configure access to the endpoints?** -A: In `config/autoload/authorization.local.php`. -If that file is missing from your application, locate its dist file `config/autoload/authorization.local.php.dist` and copy it as `config/autoload/authorization.local.php`, then look for the array under the `zend-expressive-authorization-rbac` config key. - -**Q: How does role inheritance work under the roles key?** -A: In the article's example, admin inherits from no other role, member inherits from admin, and guest inherits from member. -The article warns this exact setup is just a model and should not be used in live projects, because guests would end up having the same rights as admins. - -**Q: How do I control which routes a role can access?** -A: Under the `permissions` key you define which routes are accessible to a role. -In the article's example, a member has access to the routes named avatar, users, and user. - -**Q: What response codes are returned for authentication and authorization endpoints?** -A: Endpoints requiring authentication return a 401 Unauthorized response if a valid Bearer token isn't present in the request headers. -Endpoints requiring authorization return a 403 Forbidden response instead under the same condition. - @@ -2436,26 +1763,6 @@ It's intended to highlight the differences between the two and also to showcase - Versioning is replaced by [Deprecations](https://docs.dotkernel.org/api-documentation/v6/tutorials/api-evolution/), using an evolution strategy. -## FAQ - -**Q: What is the purpose of this comparison?** -A: It highlights the differences between Laminas API Tools and Dotkernel API, and shows why Dotkernel API is a good alternative now that Laminas API Tools is archived. - -**Q: Which version of Dotkernel API does the comparison table refer to?** -A: Dotkernel API V7. - -**Q: What architecture does each project use?** -A: Laminas API Tools uses an MVC, event-driven architecture, while Dotkernel API uses a middleware architecture. - -**Q: What license does each project use?** -A: Laminas API Tools is licensed under BSD-3, while Dotkernel API is licensed under MIT. - -**Q: How does Dotkernel API handle API versioning?** -A: Instead of traditional versioning, Dotkernel API replaces it with Deprecations, using an evolution (API Evolution) strategy. - -**Q: What documentation options does each project support?** -A: Laminas API Tools generates Swagger documentation automatically, while Dotkernel API supports manual Postman documentation as well as automated OpenAPI 3.0 (Swagger) documentation. - @@ -2602,26 +1909,6 @@ More often than not, a detailed error report will help developers understand how This article is also included in the full API documentation [https://docs.dotkernel.org/api-documentation/v5/core-features/error-reporting](https://docs.dotkernel.org/api-documentation/v5/core-features/error-reporting). -## FAQ - -**Q: What is the error reporting endpoint for?** -A: It lets frontend developers of an API report bugs and incorrect data processing back to the API in a secure, controlled way, which is especially useful for issues that don't show up as fatal errors in the API logs. - -**Q: How do you generate a token for error reporting?** -A: Run `php ./bin/cli.php token:generate error-reporting`, then copy the resulting token into `config/autoload/error-handling.global.php`. - -**Q: What server-side requirements must be met for error reporting to work?** -A: All required keys (`enabled`, `path`, `tokens`, `domain_whitelist`, `ip_whitelist`) must exist under `ErrorReportServiceInterface::class`, the feature must be enabled, `path` must have a value, `tokens` must contain at least one token, and at least one of `domain_whitelist`/`ip_whitelist` must have a value. - -**Q: What headers must the frontend application send?** -A: The `Error-Reporting-Token` header with a valid stored token, and the `Origin` header set to the application's URL. - -**Q: What happens if a request fails validation?** -A: The `checkRequest()` method checks the domain against `domain_whitelist` and the IP against `ip_whitelist`; if both checks fail, a `ForbiddenException` is thrown and the error message is not stored. - -**Q: How is the error reporting endpoint called?** -A: By sending a POST request to the `/error-report` endpoint along with a valid token in the header. - @@ -2714,23 +2001,6 @@ use DrewM\MailChimp\MailChimp; After this, you can start using the library by @Injecting `MailChimp::class` where it's needed. -## FAQ - -**Q: Which library does this tutorial use to add MailChimp to Dotkernel API?** -A: The tutorial uses drewm/mailchimp-api, installed with the command composer require drewm/mailchimp-api. - -**Q: Where do you place the MailChimp configuration file?** -A: In config/autoload/mailchimp.global.php, a new configuration file created as part of Step 2. - -**Q: What does the MailChimpFactory class do?** -A: It's a factory, created at src/App/src/MailChimp/Factory/MailChimpFactory.php, that reads the config from the container and returns an instance of DrewM\MailChimp\MailChimp. - -**Q: Where do you register the MailChimp factory so the application can use it?** -A: In src/App/src/ConfigProvider.php, inside the getDependencies() method's factories array, by mapping MailChimp::class to MailChimpFactory::class, plus adding the corresponding use statements for MailChimp and MailChimpFactory. - -**Q: How do you use MailChimp once it's wired up?** -A: By injecting MailChimp::class wherever it's needed, using @Inject. - @@ -2857,27 +2127,6 @@ Clicking on the 'Try it out' button will activate the required parameter input f The 'Execute' button will send the request and return the response, along with its HTTP status code. You can read more details [here](https://docs.dotkernel.org/api-documentation/v5/openapi/use-documentation/). -## FAQ - -**Q: What is the OpenAPI Specification?** -A: A consistent way to develop and interact with an API. It defines API structure and syntax in a universal way, regardless of the programming language used, typically described in YAML or JSON so users can quickly discover endpoints, request/response formats, security mechanisms and more. - -**Q: How does OpenAPI compare to Postman?** -A: OpenAPI standardizes how endpoints and request/response models are described, automatically generates machine-readable documentation, lets you define the API specification before development starts, and improves collaboration across teams. -Postman, by contrast, is used mainly to test an already-completed endpoint and has no real focus on standardized documentation or upfront design. - -**Q: Where do you document endpoints in Dotkernel API?** -A: Each module (Admin, App, User) contains an OpenAPI.php file, where all endpoints from that module's RoutesDelegator.php must be documented, primarily describing the method, request and response. - -**Q: What core components does every OpenAPI description need?** -A: OA\Info (basic project info like version and name), OA\Server (one or more target host URLs), OA\SecurityScheme (endpoint protection), OA\ExternalDocumentation (link and description for extended docs), and OA\Schema (describing an object or collection of objects). - -**Q: What generates the documentation file from the OpenAPI.php descriptions?** -A: zircote/swagger-php, which uses the descriptions added in the OpenAPI.php files to build the documentation. The result can be listed in the command line or saved to a file in YAML or JSON format. - -**Q: How is the generated documentation rendered, and how do you test protected endpoints?** -A: It can be rendered with Swagger UI, which lets you visualize and interact with the API's resources, or with Redoc, which lists the documentation in read-only mode. Because most endpoints are protected, testing them in Swagger UI requires generating an authentication token (AuthToken) matching the required privileges, then using the 'Try it out' button to fill in parameters/body and 'Execute' to send the request and see the response with its HTTP status code. - @@ -3006,95 +2255,12 @@ return function (Application $app, MiddlewareFactory $factory, ContainerInterfac Add the CORS middleware **after** the Error handler and **before** the middleware providing the data you want to access, to make sure everything runs smoothly. This should get your project working with CORS. -## FAQ - -**Q: What causes the "No 'Access-Control-Allow-Origin' header" error?** -A: It means the server didn't send the header that lets a local client, such as a browser, access its data. -This is most common when trying to fetch data (usually JSON) that you want to process using JavaScript. - -**Q: What package does the article use to add CORS support?** -A: Tuupola's Cors Middleware package, installed by running `composer require tuupola/cors-middleware` in the project. - -**Q: Where does the CORS configuration live?** -A: In a `cors.global.php` file created in the config/autoload directory, containing a "cors" key with settings like origin, methods, headers.allow, headers.expose, credentials, and cache. - -**Q: How is the CorsMiddleware wired into the container?** -A: A CorsMiddlewareFactory extracts the "cors" config array (or an empty array if it's not provided) and instantiates Tuupola's CorsMiddleware with it. -That factory is registered under the "dependencies" > "factories" section of cors.global.php. - -**Q: Where should the CORS middleware be added in the pipeline?** -A: In config/pipelines.php via `$app->pipe(CorsMiddleware::class)`, placed after the Error handler and before the middleware that provides the data you want to access. - ## Resources - [Tuupola's Cors Middleware package](https://packagist.org/packages/tuupola/cors-middleware) - [Implementing Tuupola CORS in Expressive (inspiration article)](https://akrabat.com/implementing-tuupola-cors-in-expressive/) - - - - ---- -title: "Adding a second caching layer to WURFL in Dotkernel using APC" -description: "How adding a small, custom APC-based caching layer on top of WURFL's own cache cut response time by an order of magnitude." -author: "Adrian" -date_published: "2011-10-14" -canonical_url: "https://www.dotkernel.com/dotkernel/adding-a-second-caching-layer-to-wurfl-in-dotkernel-using-apc/" -category: "Dotkernel" -language: "en" ---- - -# Adding a second caching layer to WURFL in Dotkernel using APC - -## TL;DR -On a high-traffic project using WURFL, profiling showed WURFL's default filesystem cache was costing up to a few hundred milliseconds per request. Adding a small, custom second cache layer on top of WURFL, built on APC, cut response time by an order of magnitude, down to 20-30ms. - -## The problem - -On one recent project that used WURFL, response time was an important factor. -Profiling revealed that the greatest chunk of response time (up to a few hundred milliseconds) was taken up by WURFL. -The default filesystem cache turned out to be too slow for a relatively high-traffic application. - -## How WURFL's caching works - -1. The device data is stored at first in a large, zipped XML file, with one entry for each device. -2. When first called, WURFL unzips the file and reads each device entry. -3. It then serializes the data and writes it to the cache, using an MD5 signature for the file name (or key name if the cache is not on the filesystem). -4. When a user agent is looked up, its MD5 signature is computed and then searched in the cache. -5. Because the data is stored as a tree, with each device inheriting the properties of the nodes above it, **each look-up requires a number of files to be read and their capabilities merged** to get all the capabilities of the requested device. - -WURFL also has cache providers for APC and memcache, which were tried, but the results weren't impressive. - -## The solution - -The team realized their approach was wrong for their use case — the WURFL entry for a device has lots of fields that weren't actually used. - -The solution was adding a **second cache layer** on top of WURFL's own cache, which only cached the fields that were actually needed. This second layer used **APC**, storing arrays of data in **User Cache Entries**. - -This small change (under 10 lines of code) decreased response time by an **order of magnitude**, down to 20-30ms. - -## FAQ - -**Q: Why was WURFL's default caching too slow for this project?** -A: Profiling revealed that WURFL's default filesystem cache was taking up to a few hundred milliseconds of response time, which was too slow for a relatively high-traffic application. - -**Q: How does WURFL's caching work by default?** -A: Device data is stored in a large zipped XML file. -On first use, WURFL unzips the file, serializes each device's data, and writes it to cache using an MD5 signature of the user agent as the key. -Because devices are stored as a tree inheriting properties from parent nodes, each lookup requires reading and merging several files. - -**Q: Did WURFL's built-in APC or memcache cache providers solve the problem?** -A: No. The team tried WURFL's existing cache providers for APC and memcache, but the results weren't impressive. - -**Q: What was the actual solution?** -A: Adding a second cache layer on top of WURFL's own cache, using APC and storing arrays of only the specific fields they actually needed in User Cache Entries. -The change was under 10 lines of code. - -**Q: What performance improvement did this bring?** -A: Response time decreased by an order of magnitude, down to about 20-30ms. - - @@ -3188,96 +2354,14 @@ $myDependency->doSomething(); This article works for any **Dotkernel 1.x** version if your server is running **PHP >5.4.0**. -## FAQ +## Resources -**Q: What does Composer do?** -A: Composer is an application-level package manager. -It auto-loads dependencies on demand and can also auto-load custom classes. +- [Composer install / PHP dependency manager tutorial](https://www.codementor.io/php/tutorial/composer-install-php-dependency-manager) -**Q: What must a Dotkernel project have before Composer can be used?** -A: A composer.json file, for example requiring zendframework/zendframework1 at 1.12.* and mobiledetect/mobiledetectlib at 2.8.*, plus PHP >=5.4.0 listed under require-dev. -**Q: What happens when you run composer update?** -A: If the vendor folder already exists, Composer checks for and applies updates to the packages. -If it doesn't exist, Composer creates the vendor folder containing all requested packages, along with an autoload file. - -**Q: How do you safely load the Composer autoloader in case Composer isn't present?** -A: Check whether vendor/autoload.php exists using file_exists() before calling require_once() on it, and handle the case gracefully (for example by loading fallbacks) if the path is missing. - -**Q: Which Dotkernel versions does this apply to?** -A: The article states it works for any Dotkernel 1.x version, as long as the server is running PHP greater than 5.4.0. - -## Resources - -- [Composer install / PHP dependency manager tutorial](https://www.codementor.io/php/tutorial/composer-install-php-dependency-manager) -- [Using Dotkernel with Composer dependencies](http://www.dotkernel.com/dotkernel/using-dotkernel-…ser-dependencies/) - - - - - - ---- -title: "Adding Windows 10 OS and Browser detection in Dotkernel projects" -description: "A guide to installing the patch that adds Windows 8, 8.1 and 10 OS icons and the Microsoft Edge browser icon in Dotkernel." -author: "Gabi DJ" -date_published: "2015-09-08" -canonical_url: "https://www.dotkernel.com/dotkernel/adding-windows-10-os-and-browser-detection-in-dotkernel-projects/" -category: "Dotkernel" -language: "en" ---- - -# Adding Windows 10 OS and Browser detection in Dotkernel projects - -## TL;DR -Dotkernel added Windows 8, 8.1 and 10 OS icons and a Microsoft Edge browser icon, shown in the User and Admin login icons. -This article is the upgrade guide for applying that icon patch. - -## Upgrade steps - -1. Make sure your project is running version **1.5.0** or **newer**. -2. Download the [patch](http://www.dotkernel.com/download/?did=46). -3. Extract the archive into a folder, e.g. `icons_patch`. -4. Create a backup of your project before continuing (recommended). -5. Copy all the files in the `icons_patch` folder into your Dotkernel project. -6. You will be prompted to replace 2 files — replace them and agree to merge the folders' content (other files will be added, not replaced). -7. Clear the cache for changes to take effect, since the OS and browser XMLs are cached (see "Dotkernel Reserved Variable Names for Caching", the "Browser & OS" section). -8. You can now delete the `icons_patch` folder, or keep it to patch another project. - -## Affected files - -``` -M /configs/useragent/browser.xml -M /configs/useragent/os.xml -A /images/browsers/edge.png -A /images/os/windows_metro.png -``` - -`M` stands for **modify**, `A` stands for **add**. - -## FAQ - -**Q: What Dotkernel version is required before applying this patch?** -A: Your project must be running version 1.5.0 or newer. - -**Q: Which files does the patch modify or add?** -A: It modifies configs/useragent/browser.xml and configs/useragent/os.xml, and adds images/browsers/edge.png and images/os/windows_metro.png. - -**Q: Why do you need to clear the cache after applying the patch?** -A: Because the OS and browser XML files are cached, so the new icons won't show up until the cache is cleared. - -**Q: Will applying the patch overwrite existing files?** -A: You'll be prompted to replace 2 files (browser.xml and os.xml) and should agree, and also agree to merge the folders' contents since the other files listed are added rather than replaced. - -## Resources - -- [Icon patch download](http://www.dotkernel.com/download/?did=46) -- [Dotkernel Reserved Variable Names for Caching](http://www.dotkernel.com/dotkernel/dotkernel-reserved-variable-names-for-caching) - - - - - + + + --- title: "Autologin using Cookie / Remember Me in Dotkernel" @@ -3365,7 +2449,7 @@ npm run prod ```shell vendor/bin/phinx create --configuration=config/migrations.php RememberUserSchema ``` -3. Modify the generated migration file as in [user_remember_schema](https://github.com/dotkernel/frontend/blob/3.0/data/database/migrations/20220621062142_remember_user_schema.php), then run it against the database: +3. Modify the generated migration file as in [user_remember_schema](https://www.dotkernel.com/dotkernel/autologin-cookie-remember-me-feature/), then run it against the database: ```shell vendor/bin/phinx migrate --configuration=config/migrations.php ``` @@ -3388,31 +2472,11 @@ npm run prod 8. Edit `src/User/src/Repository/UserRepository.php` and add the methods `saveRememberUser()`, `getRememberUser()`, `findRememberMeUser()`, `deleteExpiredCookies()`, `removeRememberUser()` as in [UserRepository](https://github.com/dotkernel/frontend/blob/3.0/src/User/src/Repository/UserRepository.php). 9. Edit `src/User/src/Controller/UserController.php`: add a new property called `$config`, and edit `loginAction()` and `logoutAction()` as in [UserController](https://github.com/dotkernel/frontend/blob/3.0/src/User/src/Controller/UserController.php). -## FAQ - -**Q: Since which release is Remember Me implemented in Dotkernel?** -A: It's implemented in Dotkernel Frontend starting from Release 3.3.0. - -**Q: How do you add the Remember Me checkbox to the login UI?** -A: In src/User/templates/user/login.html.twig, under the password element, render the rememberMe element retrieved via form.get('rememberMe') with formElement(). - -**Q: What form and validation changes are needed?** -A: A 'rememberMe' checkbox element must be added to src/User/src/Form/LoginForm.php, and a StringTrim filter plus a NotEmpty validator must be added for it in src/User/src/InputFilter/LoginInputFilter.php. - -**Q: What backend pieces implement the actual remember-me functionality?** -A: A new UserRememberMe entity, a database migration (created and run with phinx) for its table, a new RememberMeMiddleware registered in config/pipeline.php, a rememberMe cookie configuration block added to config/autoload/local.php, and new methods added to UserService, UserRepository, and UserController (including loginAction() and logoutAction()). - -**Q: What does the UserRememberMe table store?** -A: It's used to store data from the cookie, which helps log the user in automatically. - -**Q: How do you apply the new remember-me button styles?** -A: Add the CSS to src/App/assets/scss/components/_profile.scss, then run npm run prod to compile the CSS so the button styling takes effect. - ## Resources - [Dotkernel Frontend on GitHub](https://github.com/dotkernel/frontend) - [UserRememberMe entity example](https://github.com/dotkernel/frontend/blob/3.0/src/User/src/Entity/UserRememberMe.php) -- [Remember user schema migration example](https://github.com/dotkernel/frontend/blob/3.0/data/database/migrations/20220621062142_remember_user_schema.php) +- [Remember user schema migration example](https://www.dotkernel.com/dotkernel/autologin-cookie-remember-me-feature/) - [RememberMeMiddleware example](https://github.com/dotkernel/frontend/blob/3.0/src/App/src/Middleware/RememberMeMiddleware.php) - [pipeline.php example](https://github.com/dotkernel/frontend/blob/3.0/config/pipeline.php) - [UserService example](https://github.com/dotkernel/frontend/blob/3.0/src/User/src/Service/UserService.php) @@ -3455,137 +2519,6 @@ RewriteCond %{REQUEST_FILENAME} (\.gif|\.jpg|\.png|\.css|\.js)$ Save, and don't forget to test. -## FAQ - -**Q: What problem does this fix address?** -A: When missing static files (images, CSS, JS) are routed through the bootstrap (index.php) and the session is set to regenerate on each request, the currently logged-in user gets logged off because the session ID changes. - -**Q: What is the fix?** -A: Below the "RewriteEngine On" line, add a RewriteCond matching file extensions like .gif, .jpg, .png, .css, and .js, so requests for those files are not routed through the bootstrap. - - - - - - ---- -title: "Caching in Dotkernel using Zend Framework" -description: "How Dotkernel's upcoming 1.8 cache layer stores router, ACL, menu and other data between requests, using APC/APCU or file storage." -author: "Gabi DJ" -date_published: "2015-01-29" -canonical_url: "https://www.dotkernel.com/dotkernel/caching-in-dotkernel-using-zend-framework/" -category: "Dotkernel" -language: "en" ---- - -# Caching in Dotkernel using Zend Framework - -## TL;DR -Loading configuration and settings from XML files on every request is expensive, both due to hard-drive latency and XML parsing overhead. -Dotkernel 1.8 implements a cache layer for router, acl_role, menu, options (including seo_xml), browser_xml, os_xml and test data, with a choice of APC/APCU or file-based storage. - -## 1. Configuring the cache - -The configuration is set from `/configs/application.ini`: whether caching is enabled, how long the cache stays valid, the cache namespace, and the storage provider (File or APC). -The article recommends disabling the cache in development mode. -See [Configuring the Cache in Dotkernel](http://www.dotkernel.com/dotkernel/configuring-the-cache-in-dotkernel/) for more details. - -## 2. Using the cache - -The cache is automatically loaded during initialization and stored in the Registry — loading it manually is not needed because it's already loaded on kernel initialization (see `Dot_Kernel::initialize($startTime)`). -If you want to use caching outside of that normal initialization, load it with: - -```php -Dot_Cache::loadCache(); -``` - -Note: the cache key must match a specific RegEx pattern. - -Example of object caching: - -```php -$id = 'MyCachedKey'; -$obj = new stdClass(); -$obj->text = 'I am a cached text'; - -// saving an object -Dot_Cache::save(obj, $id); - -// loading the object -$value = Dot_Cache::load($id); - -// checking if we have the object in cache -if ($value !== false) { - // assuming we only need the text value from the object - echo $value->text; -} else { - echo 'no value cached for '. $id ; -} -``` - -## FAQ - -**Q: What data does Dotkernel's cache layer store?** -A: Router, acl_role, menu, options (including seo_xml), browser_xml, os_xml, and test data between requests. - -**Q: What storage providers are available for the cache?** -A: Two cache factories to choose from: APC (or APCU for newer PHP installations) and File. - -**Q: Where is the cache configured?** -A: In /configs/application.ini, where you can enable or disable caching, set how long the cache stays valid, choose the cache namespace, and pick the storage provider (File or APC). -The article recommends disabling the cache in development mode. - -**Q: Do you need to manually load the cache engine?** -A: No, it's automatically loaded during kernel initialization (Dot_Kernel::initialize()). -Manually calling Dot_Cache::loadCache() is only needed if you want to use caching outside of that normal initialization. - -**Q: Can you cache PHP objects, not just simple values?** -A: Yes, the article shows an example of saving and loading a stdClass object using Dot_Cache::save() and Dot_Cache::load(). - -## Resources - -- [Dotkernel Reserved Variable Names for Caching](http://www.dotkernel.com/dotkernel/dotkernel-reserved-variable-names-for-caching) -- [Configuring the Cache in Dotkernel](http://www.dotkernel.com/dotkernel/configuring-the-cache-in-dotkernel/) - - - - - - ---- -title: "camelCase Table Names in MySQL on Windows" -description: "How to fix MySQL on WAMP/XAMPP lowercasing camelCase table names by setting lower_case_table_names=2 in my.cnf." -author: "admin" -date_published: "2010-03-12" -canonical_url: "https://www.dotkernel.com/dotkernel/camelcase-table-names-in-mysql-on-windows/" -category: "Dotkernel" -language: "en" ---- - -# camelCase Table Names in MySQL on Windows - -If you are using a WAMP stack, like WAMP or XAMPP, and try to create a table in camelCase (example: `adminLogin`), you will notice that camelCase is not working — the table name will be lowercase: `adminlogin`. - -In order to fix this, add the following line to your `my.cnf` file: - -``` -lower_case_table_names=2 -``` - -and restart MySQL. - -## FAQ - -**Q: What happens when you create a camelCase table name on WAMP or XAMPP?** -A: A table created with a camelCase name, for example adminLogin, ends up stored as all lowercase, e.g. adminlogin, instead. - -**Q: How do you fix it?** -A: Add the line `lower_case_table_names=2` to your my.cnf file and restart MySQL. - -## Resources - -- [MySQL lower_case_table_names documentation](http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html#sysvar_lower_case_table_names) - @@ -3609,93 +2542,11 @@ That means we are really taking PHP into serious consideration, and at the very See the [Zend Yellow Pages](http://www.zend.com/store/education/certification/yellow-pages.php#list-cid=0&sid=&certtype_zf=1&certtype_php=1&certtype=&firstname=&lastname=&company=Dotboost%20Technologies&ClientCandidateID=). -## FAQ - -**Q: How many Zend Certified Engineers does the team have?** -A: According to the article, 2 more team members passed the ZCE exam, bringing the team's total to 5 Zend Certified Engineers. - ## Resources - [Zend Yellow Pages listing](http://www.zend.com/store/education/certification/yellow-pages.php#list-cid=0&sid=&certtype_zf=1&certtype_php=1&certtype=&firstname=&lastname=&company=Dotboost%20Technologies&ClientCandidateID=) - - - - ---- -title: "Configuring the Cache in Dotkernel" -description: "A configuration guide for Dotkernel's Zend Framework Cache-based caching layer, covering the main frontend settings and the optional per-backend settings." -author: "Gabi DJ" -date_published: "2015-01-29" -canonical_url: "https://www.dotkernel.com/dotkernel/configuring-the-cache-in-dotkernel/" -category: "Dotkernel" -language: "en" ---- - -# Configuring the Cache in Dotkernel - -## TL;DR - -Dotkernel's caching layer is built on Zend Framework Cache and is configured through `cache.*` settings in `application.ini`. -The main frontend settings control whether caching is enabled, which cache service to use, the namespace prefix, and how long entries live. -Optional backend-specific settings (like the file cache directory) are recommended so that separate projects don't accidentally share the same cache. - -This article contains the Dotkernel cache layer configuration guide. -The Dotkernel Caching Layer is based on Zend Framework Cache; more configuration options can be found at the following links: - -- [Zend Framework Cache Frontends](http://framework.zend.com/manual/1.12/en/zend.cache.frontends.html) -- [Zend Framework Cache Backends](http://framework.zend.com/manual/1.12/en/zend.cache.backends.html) - -## Main Cache Settings (Cache Frontend) - -The main cache settings within the application.ini file should look like this: - -```ini -cache.enable = true -cache.factory = "apc" -cache.lifetime = "86400" -cache.namespace = "dotkernel" -``` - -The cache.enable option can be used to disable caching, mostly used in the development stage. -The cache.factory value will be the cache service we want to use: file or apc. -The cache.namespace will be the cache variables prefix, and the cache.lifetime value will define how long the cached variables will be usable before they need to be re-cached. - -## Individual Cache Settings (Cache Backend) - -The individual cache settings are optional, but it's highly recommended that you have these values set, otherwise other projects might use the same cache. - -```ini -; file caching settings -cache.file.cache_dir = APPLICATION_PATH "/cache" -cache.file.cache_file_perm = 0600 -``` - -For more settings and caching alternatives, see the Zend Framework Cache links at the beginning of the article. -The setting pattern and sample are below: - -```ini -cache.BACKEND_NAME.SETTING = "VALUE" -; example: -cache.file.file_name_prefix = "Dotkernel" -``` - -## FAQ - -**Q: What is Dotkernel's caching layer based on?** -A: It's based on Zend Framework Cache, configured through settings in application.ini, with more configuration options available at the Zend Framework Cache Frontends and Backends documentation links given in the article. - -**Q: What does the cache.enable setting do?** -A: It can be used to disable caching, which is mostly useful during the development stage. - -**Q: What values can cache.factory take?** -A: The cache.factory value is the cache service to use, and the article lists two options: file or apc. - -**Q: Why bother setting the individual/backend cache settings like cache.file.cache_dir?** -A: These settings are optional, but the article highly recommends setting them, otherwise other projects might end up using the same cache. - - @@ -3862,193 +2713,6 @@ class UserService implements UserServiceInterface If you use Doctrine and the repository pattern and you don't want to get your repository from `EntityManager` and want to inject it into your service, this package covers that too. The principle is the same, and for more insight about this, you can check the package documentation at [dot-dependency-injection](https://docs.dotkernel.org/dot-dependency-injection/). -## FAQ - -**Q: What problem does dot-dependency-injection solve?** -A: In Laminas/Mezzio applications, developers normally have to build, update, and maintain a factory class for every class that needs dependencies. dot-dependency-injection autowires those dependencies instead, so you don't need a factory for every class. - -**Q: Does dot-dependency-injection require Doctrine ORM?** -A: The package requires Doctrine ORM, but the article notes it can still be used in applications that don't integrate Doctrine. - -**Q: How do you mark a class's constructor dependencies for injection?** -A: Import Dot\DependencyInjection\Attribute\Inject in the class, then add the attribute to the constructor definition to specify which dependencies should be injected. - -**Q: What do you need to add to the ConfigProvider to use this package?** -A: Only the Dot\DependencyInjection\Factory\AttributedServiceFactory class needs to be added to your config's dependencies. It builds the factory for you and handles the logic for dependencies missing from the container, with appropriate exceptions and messages. - -**Q: Can this package be used with the Doctrine repository pattern?** -A: Yes. If you don't want to fetch a repository from the EntityManager and instead want to inject it directly into your service, the article says this package covers that too, following the same principle, with more details in the package documentation. - - - - - - ---- -title: "Detecting Mobile Devices in Dotkernel 1.6.0" -description: "Explains how mobile device detection changed in Dotkernel 1.6.0 with the move to Wurfl Cloud, including the required application.ini settings and sample Dot_UserAgent usage code." -author: "deddu" -date_published: "2012-05-18" -canonical_url: "https://www.dotkernel.com/dotkernel/detecting-mobile-devices-in-dotkernel-1-6-0/" -category: "Dotkernel" -language: "en" ---- - -# Detecting Mobile Devices in Dotkernel 1.6.0 - -## TL;DR - -Dotkernel 1.6.0 no longer ships with a working built-in mobile detection method, because mobile detection now relies on the new Wurfl Cloud integration and must be configured via a Wurfl Cloud account and API key. -The old Dot_UserAgent_Wurfl class was removed and replaced by Dot_UserAgent_WurflCloud, which uses the Wurfl Cloud API adapter. -The article walks through the application.ini settings and shows sample code for reading device info and redirecting mobile visitors. - -The new Dotkernel version 1.6.0 is coming with some changes to how we detect mobile devices; these changes are because of the new Wurfl Cloud integration. -This version of Dotkernel no longer comes with a working built-in method for mobile detection, so first we have to configure it. - -- Go to the scientiamobile website and register for a Wurfl Cloud account. -- Choose device_os and mobile_browser for your account and save. -- Go to API Keys and copy the right key into application.ini. - -We chose device_os and mobile_browser capabilities because with these two capabilities we can get some extra capabilities (isMobile, isSmartPhone, isIphone, isAndroid, isBlackberry, isSymbian, and isWindowsMobile) using our built-in methods. -Choosing other capabilities from scientiamobile will result in wrong detection of these extra capabilities, but you can get only those capabilities using another method from the Dot_UserAgent_WurflCloud class. - -Wurfl Cloud setting in application.ini: - -```ini -resources.useragent.wurflcloud.active = TRUE -resources.useragent.wurflcloud.redirect = TRUE -resources.useragent.wurflcloud.cache = TRUE -resources.useragent.wurflcloud.cache_lifetime = 3600 -resources.useragent.wurflcloud.cache_namespace = WURFLCLOUD -resources.useragent.wurflcloud.api_key = 000000:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -resources.useragent.wurflcloud.lib_dir = APPLICATION_PATH "/library/WurflCloud/" -``` - -- active - used to turn on (TRUE) or off (FALSE) the Wurfl Cloud detection (default: TRUE). -- redirect - if TRUE, visitors from the frontend will be redirected to the mobile module (default: TRUE). -- cache - caches every distinct result to optimize the number of requests to scientiamobile (default: TRUE). -- cache_lifetime - time in seconds to keep the results in cache (default: 3600). -- cache_namespace - the prefix used for cache keys (default: WURFLCLOUD). -- api_key - the API key from your WURFL Cloud account (change this to your own key). -- lib_dir - the Wurfl Cloud library location in Dotkernel (don't change this, unless you want to move the library). - -Because of these changes, we removed the old Dot_UserAgent_Wurfl class and added the new Dot_UserAgent_WurflCloud class, which uses the Wurfl Cloud API adapter. - -## Example of Dot_UserAgent Usage in Dotkernel - -Get Wurfl configuration: - -```php -$wurflConf = $registry->configuration->resources->useragent->wurflcloud; -``` - -Note: you can have more Wurfl configurations if you have more libraries, like the Wurfl Package (GPL). - -If Wurfl is active, then get device info: - -```php -if($wurflConf->active) -{ - $deviceInfo = Dot_UserAgent :: getDeviceInfo($_SERVER); - ... -} -``` - -If the detected device is a mobile device, we save the device info in the database and redirect it to the mobile controller: - -```php -if( (0 < count((array)$deviceInfo)) && $deviceInfo->isMobile) -{ - - if(!$registry->session->visitId) - { - $registry->session->visitId = Dot_Statistic::registerVisit(); - } - - // if the Statistic module is integrate, record the deviceInfo too, and record TRUE - //in $session->mobile - if(!$registry->session->mobile) - { - $registry->session->mobile = - Dot_Statistic::registerMobileDetails($registry->session->visitId, $deviceInfo); - - //redirect to mobile controller , only if the session is not set. - //Otherwise will trap the user in mobile controller - if($wurflConf->redirect) - { - header('location: '. - $registry->configuration->website->params->url.'/mobile'); - exit; - } - } -} -``` - -## FAQ - -**Q: Why did mobile detection change in Dotkernel 1.6.0?** -A: Because of the new Wurfl Cloud integration. This version no longer ships with a working built-in method for mobile detection, so it must be configured first. - -**Q: What are the steps to configure Wurfl Cloud detection?** -A: Go to the scientiamobile website and register for a Wurfl Cloud account, choose the device_os and mobile_browser capabilities for the account and save, then go to API Keys and copy the key into application.ini. - -**Q: Why choose the device_os and mobile_browser capabilities specifically?** -A: With these two capabilities, Dotkernel's built-in methods can also derive extra capabilities such as isMobile, isSmartPhone, isIphone, isAndroid, isBlackberry, isSymbian, and isWindowsMobile. Choosing other capabilities from scientiamobile results in wrong detection of these extra capabilities. - -**Q: What happened to the old Dot_UserAgent_Wurfl class?** -A: It was removed and replaced with the new Dot_UserAgent_WurflCloud class, which uses the Wurfl Cloud API adapter. - -**Q: What does the redirect setting in application.ini control?** -A: When resources.useragent.wurflcloud.redirect is TRUE (the default), visitors from the frontend are redirected to the mobile module the first time a mobile device is detected. - - - - - - ---- -title: "Disable Wurfl redirect for mobile browsers" -description: "Shows the application.ini setting introduced in revision 408 to control Dotkernel's automatic Wurfl-based redirect of mobile visitors to the mobile site, and the code that checks it." -author: "Adrian" -date_published: "2011-01-31" -canonical_url: "https://www.dotkernel.com/dotkernel/disable-wurfl-redirect-for-mobile-browsers/" -category: "Dotkernel" -language: "en" ---- - -# Disable Wurfl redirect for mobile browsers - -## TL;DR - -Dotkernel's example mobile site normally relies on Wurfl to detect mobile browsers and automatically redirect visitors there on their first homepage view, which isn't always desired. -As of revision 408, this behavior is controlled by a single `resources.useragent.wurflapi.redirect` setting in application.ini. -The article shows that setting along with the matching condition in `IndexController.php` that checks it before registering and redirecting a visit. - -Dotkernel has an example mobile site at [http://v1.dotkernel.net/mobile](http://v1.dotkernel.net/mobile) that uses [jQuery Mobile](http://jquerymobile.com/). -Wurfl is also used to detect mobile browsers (as discussed in a [previous blog post](http://www.dotkernel.com/dotkernel/wurfl-zend-framework-integration-into-dotkernel/)) and automatically redirect them to the mobile site the first time they view the homepage. -Sometimes this behavior isn't desired (for example when you don't have a mobile site, or you don't plan on using Wurfl at all). - -Starting with revision 408, there's an option in application.ini to disable the automatic redirect (by default the redirect is disabled): - -```ini -resources.useragent.wurflapi.redirect = false -``` - -The following condition is also added to Controllers/frontend/IndexController.php (at line 19) to check the configuration: - -```php -//if automatic redirect is enabled in application.ini and the browser is mobile and session->mobileHit is not set, register it and redirect -if($config->resources->useragent->wurflapi->redirect && 'mobile' == Dot_Kernel::getDevice()->getType() && !isset($session->mobileHit)) -``` - -## FAQ - -**Q: How do you disable the automatic mobile redirect in Dotkernel?** -A: Starting with revision 408, set resources.useragent.wurflapi.redirect = false in application.ini. Per the article, this is also the default state of the redirect option. - -**Q: Where in the code is this configuration option checked?** -A: In Controllers/frontend/IndexController.php (around line 19), a condition checks whether the redirect is enabled in application.ini, whether the visiting browser is mobile, and whether session->mobileHit isn't already set, before registering and redirecting the visit. - @@ -4110,23 +2774,6 @@ Dotkernel 3 = Dotkernel 3 #### Dotkernel = Dotkernel 3 -## FAQ - -**Q: What does the name "Dotkernel" mean?** -A: It combines "Dot", as a representation of the Internet, with "Kernel", the quintessence of any IT application, reflecting the aim of being a central part of Internet development. - -**Q: What is Dotkernel 1?** -A: A PHP Application Framework built on top of Zend Framework 1, first publicly released in July 2010, with an architecture based on MVC. Its latest version is 1.8 Long Term Support, which per the article will not be followed by a new version, only bugfixes. - -**Q: What is Dotkernel 3?** -A: A collection of PSR-7 Middleware applications built on top of the Zend Expressive microframework, composed of a set of custom and extended Zend Framework 3 components, with an architecture based on Middleware. It implements PSR-1, PSR-2, PSR-4, PSR-7, and PSR-11. - -**Q: How many applications make up Dotkernel 3?** -A: At the time of the article, there were two available applications, Frontend and Admin, with a third one, API, under development. - -**Q: When someone writes just "Dotkernel", which version is meant?** -A: In posts older than 2017, "Dotkernel" referred to Dotkernel 1, since it was the only version. Since the release of Dotkernel 3, "Dotkernel" refers to Dotkernel 3, and all future references to Dotkernel 1 are made explicitly. - @@ -4238,7 +2885,7 @@ class Admin extends AbstractEntity implements AdminInterface } ``` -For further details about the cache mode please refer to the [official documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/3.0/reference/second-level-cache.html). +For further details about the cache mode please refer to the [official documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/second-level-cache.html). When querying data, you can have Doctrine cache your results. You do this by calling the `setCacheable` method on the query builder. @@ -4257,26 +2904,6 @@ Check the [basic cache usage](https://symfony.com/doc/current/components/cache.h In conclusion, cache plays a vital role in optimizing system performance and improving user experience by storing frequently accessed data. As technology continues to evolve, caching mechanisms will remain an integral part of modern computing architectures, driving faster access to data and smoother user interactions across various digital platforms. -## FAQ - -**Q: What component does this article use for caching Doctrine data?** -A: The dotkernel/dot-cache component, a wrapper that sits on top of symfony/cache. It's installed with composer require dotkernel/dot-cache and registered by adding DotCacheConfigProvider::class to the configuration aggregate. - -**Q: What storage adapters does dot-cache currently support?** -A: Two: array, which stores data in-memory and is the fastest option but uses more RAM, and filesystem, which stores data in local disk files and is slightly slower but more persistent. - -**Q: What are the four types of Doctrine cache covered?** -A: result_cache, metadata_cache, query_cache, and hydration_cache, each configured under the doctrine.configuration.orm_default key. - -**Q: What does the result cache do?** -A: It stores the results of queries, letting Doctrine avoid querying the database or hydrating the data again after the initial retrieval. - -**Q: Why cache class metadata?** -A: Because parsing class metadata on every request is inefficient, so it's advisable to cache it using one of the available cache adapters. - -**Q: How do you mark an entity or a query as cacheable?** -A: To enable caching for entities you add a caching attribute to the entity class; to cache an individual query, call setCacheable(true) on the query builder before getResult(). - @@ -4533,26 +3160,6 @@ There was: The new setup solves both issues, ensuring more consistent flag management for your classes. -## FAQ - -**Q: What update triggered this change to Dotkernel's enum handling?** -A: The update of doctrine/orm to version 3.2.0 introduced EnumType columns, building on the enum type introduced in PHP 8.1. Dotkernel implemented this new data type on both the PHP side and the database side. - -**Q: What was the limitation of Dotkernel's old approach to columns like User->Status?** -A: The old setup used a simple string type, so the value set couldn't be definitively enforced. A typo in a PHP value would still be accepted, and the database was independent of any values the PHP code allowed, so manually editing a value in the database would accept any string. - -**Q: What was the one advantage of the old string-based setup?** -A: It made it easy to add more values to the value set, though the article notes this ease also invites bugs in the execution. - -**Q: What do you need to create to add a new custom enum type?** -A: A PHP enum class (like UserStatusEnum) plus a DBAL type class extending AbstractEnumType, which must define a NAME constant and a getEnumClass() method; the new type is then registered under the types key in config/autoload/doctrine.global.php. - -**Q: Does Types::ENUM still fall back to a string or integer database column?** -A: The article notes that Doctrine still defaults to Types::STRING or Types::INTEGER for columns backed by a PHP enum, as this is considered the more portable and safer default; Types::ENUM is required if you want an actual enum column in MySQL/MariaDB. - -**Q: What must happen when the value set of an enum changes under the new setup?** -A: Any update to the value set must be made on both the PHP code and the database, since the new setup creates an explicit, enforced link between them. - ## Resources - [Dotkernel API Pull Request](https://github.com/dotkernel/api/pull/339/files) @@ -4561,2908 +3168,779 @@ A: Any update to the value set must be made on both the PHP code and the databas - + --- -title: "DotBoost Technologies : Products and Services North American Relaunch" -description: "Dotboost Technologies announces its North American relaunch, centered on the source release of its in-house Dotkernel framework alongside expanded IT integration and consulting services." -author: "admin" -date_published: "2010-01-28" -canonical_url: "https://www.dotkernel.com/dotkernel/dotboost-technologies-products-and-services-north-american-relaunch/" +title: "Dotkernel Light - Starting with Mezzio microframework and Laminas components" +description: "Dotkernel Light is a stripped-down version of Dotkernel Frontend built on Mezzio and Laminas components, keeping only routing, templating, error handling, and tests, for a gentler learning curve." +author: "Florin Bidirean" +date_published: "2024-10-03" +canonical_url: "https://www.dotkernel.com/dotkernel/dotkernel-light-starting-with-mezzio-microframework-and-laminas-components/" category: "Dotkernel" language: "en" --- -# DotBoost Technologies : Products and Services North American Relaunch +# Dotkernel Light - Starting with Mezzio microframework and Laminas components ## TL;DR -Dotboost announces its North American relaunch, aimed at better serving clients in Canada and the US. -The relaunch centers on the source release of its in-house Dotkernel framework, along with expanded business IT integration and clearer consulting services. -Founded in 2005, Dotboost describes itself as treating clients as strategic partners rather than as a typical IT vendor. +Dotkernel Light is a version of Dotkernel Frontend that includes only the bare-bones essentials. +It's built on the Mezzio microframework using Laminas components, and is designed as a presentation site, a fast-start introduction to Mezzio, or a clean starting point for a project where you want full control over functionality. + +## Goal + +Dotkernel Light is designed to be a fast-start example of using the Mezzio microframework, as well as an entry-level version of Dotkernel Frontend. +Its purpose is to present the newbie developer with as few moving parts as possible, while also giving the more advanced developer a starting point with full control of the platform's functionality. + +Light retains the modern architecture of Mezzio microframework and several Laminas components used in Dotkernel Frontend. +The low number of out-of-the-box components encourages active exploration of the functionality required by your application - you add only the packages your application needs. -## The North American Relaunch +## Components and functionality -A new style and advanced approach to accompany the Dotkernel source release. +Dotkernel Light is a stripped-down version of Dotkernel Frontend. +Like Frontend, it is built on top of Mezzio microframework using Laminas components, but with limited features and a lower number of packages, which makes the learning curve of working with the repo considerably gentler. -Dotboost is pleased to announce our North American Relaunch. -This new phase comes as a result of dedicated research and analysis on how to best serve clients in Canada and the US. +### Functionality retained -At the heart of our relaunch is the source release for our exclusive inhouse developed Dotkernel framework. -We have also added business IT integration and increased the clarity to our existing consulting services. +- Routing +- Templating +- Error handling +- Tests and code quality checks -## The Dotboost Approach +### Items removed compared to Frontend -We're not your average IT organization; we view our customers as strategic partners. -This paradigm allows us to take a comprehensive approach towards creating solutions and gain the competitive advantage. +- Doctrine and all database-related stuff +- Sessions/Cookies/Flash messages +- Authentication/Authorization +- Dependency Injection +- Mail-related stuff +- Navigation +- CORS +- Forms/Validators/InputFilters +- User module +- Contact module +- Plugin module +- CSS/JS code no longer in use due to the above module removals +- Instructions from README.md that are no longer needed -Founded in 2005, the Dotboost process can incorporate anywhere into your project's life-cycle including concept development, architecture and design, development and integration, and implementation and support. -We use time and distance to our advantage, pushing competitive boundaries and staking our place as a globally efficient organization. +### Packages no longer required -## FAQ +- dotkernel/dot-authorization +- dotkernel/dot-data-fixtures +- dotkernel/dot-dependency-injection +- dotkernel/dot-flashmessenger +- dotkernel/dot-mail +- dotkernel/dot-navigation +- dotkernel/dot-rbac-guard +- dotkernel/dot-response-header +- dotkernel/dot-session +- laminas/laminas-form +- laminas/laminas-i18n +- mezzio/mezzio-authorization-rbac +- mezzio/mezzio-cors +- ramsey/uuid-doctrine +- roave/psr-container-doctrine +- mezzio/mezzio-tooling +- rector/rector -**Q: What is at the heart of Dotboost's North American relaunch?** -A: The source release of Dotboost's exclusive, in-house developed Dotkernel framework, along with added business IT integration and increased clarity around existing consulting services. +## Resources -**Q: When was Dotboost founded, and at what stages can it join a project?** -A: Dotboost was founded in 2005. Per the article, its process can incorporate anywhere into a project's life-cycle, including concept development, architecture and design, development and integration, and implementation and support. +- Dotkernel Light GitHub repository: https://github.com/dotkernel/light +- Working demo of Dotkernel Light: https://light.dotkernel.net/ +- Dotkernel Light documentation: https://docs.dotkernel.org/light-documentation/ +- Laminas Project: https://getlaminas.org/ +- Documentation of Mezzio: https://docs.mezzio.dev/ - + --- -title: "Dotkernel 1.2.0 release" -description: "Release notes for Dotkernel 1.2.0, covering database naming convention changes, the new 'dots' submodule concept, new and updated library classes, and the use of prepared statements for all SQL queries." -author: "Teo" -date_published: "2010-07-05" -canonical_url: "https://www.dotkernel.com/dotkernel/dotkernel-1-2-0-release/" +title: "Dotkernel Light: the best choice for your presentation site" +description: "A walkthrough of using Dotkernel Light to build a simple presentation site: adding new pages, managing assets, and configuring Twitter/OpenGraph cards, the top menu, and the footer." +author: "Florin Bidirean" +date_published: "2024-10-14" +canonical_url: "https://www.dotkernel.com/dotkernel/dotkernel-light-the-best-choice-for-your-presentation-site/" category: "Dotkernel" language: "en" --- -# Dotkernel 1.2.0 release +# Dotkernel Light: the best choice for your presentation site ## TL;DR -Dotkernel 1.2.0 has been released, bringing changes since the previous 1.1.2 release. -The database tables were renamed and restructured to follow database naming conventions, and configuration for each "dots" (submodule) now lives in XML files instead of being hard-coded in PHP. -The release also adds new library classes (Dot_Geoip, Dot_Seo), updates existing ones (Dot_Curl, Dot_Session), and confirms that all SQL queries are written as prepared statements. +Dotkernel Light is a lightweight starting point for a project when you want full control over its functionality, and it grows into something more complex as you add packages. +It comes with routing, templating, error handling, and tests/code quality checks out of the box, but strips out everything a presentation site doesn't need - database, sessions/cookies/flash messages, auth, dependency injection, mail, navigation, CORS, forms, the user/contact/plugin modules. + +## What's included vs. removed + +| Included out of the box | Removed (not needed for a presentation site) | +|---|---| +| Routing | Everything related to the database | +| Templating | Sessions/Cookies/Flash messages | +| Error handling | Authentication/Authorization | +| Tests and code quality checks | Dependency Injection | +| | Mail related stuff | +| | Navigation | +| | CORS | +| | Forms/Validators/InputFilters | +| | User module | +| | Contact module | +| | Plugin module | + +## Adding new pages + +1. Add an `Action` function for the page in `src/Page/src/Controller/PageController.php`, for example: + +```php +public function examplePageAction(): ResponseInterface +{ + return new HtmlResponse( + $this->template->render('page::example-template') + ); +} +``` + + The URL for this example page would be `/page/example-page`. -## Database Naming Conventions +2. Create the matching template in `src/Page/templates/page/` - for the example above, `src/Page/templates/page/example-template.html.twig`. +Put the page copy inside the `content` block: + +```twig +{% extends '@layout/default.html.twig' %} + +{% block title %}Page Title{% endblock %} + +{% block page_title %}{% endblock %} + +{% block content %} +

+
+

Add title here!

+
+
+ +
+ Add cool content here! +
+{% endblock %} +``` + + Make sure to check the header for any fonts your content requires. -On database, we changed the names and structure of tables to respect database naming convention. -See [http://www.dotkernel.com/dotkernel/dotkernel-database-naming-conventions-for-mysql/](http://www.dotkernel.com/dotkernel/dotkernel-database-naming-conventions-for-mysql/) for details. +3. Place assets under `src/App/assets/`, in the default folders: + - `src/App/assets/fonts` + - `src/App/assets/images` + - `src/App/assets/js` + - `src/App/assets/scss` -## The "Dots" Concept + Make sure `npm` is installed and running during updates with `npm run watch`, or run `npm run prod` after edits are completed. -A new word came into our Dotkernel discussions: dots. -We use this term when talking about a submodule and all its component files. -For example, "user" is a submodule of the frontend module. -Note that one dots can be part of multiple modules (for example, "user" dots belong to both the frontend and admin module). -For each dots, the configuration values have been added to XML files which are stored in the configs/dots folder. -In the previous versions, these values were hard-coded in the PHP files. +## Optional items -Another change made in the configs folder is resource.xml, which contains the configuration values for the controllers of each module. +### Twitter and OpenGraph cards -To be easier to start an application from Dotkernel, in the admin module, there are now the following dots: admin, user and system. +To promote pages on other platforms, edit the header section in `src/App/templates/layout/default.html.twig`, where the Twitter (X) and OpenGraph cards are placed. Update all items based on your page content. -## Library Class Updates +- `{{ url('home') }}` generates the homepage URL, and the same pattern is used for other pages, as in the canonical URL block: `{% block canonical %}{{ url(routeName ?? null) }}{% endblock %}` (the `block` is present to handle not-found pages, e.g. mistyped URLs). +- An image referenced as `{{ url('home') }}images/app/My-image.png` is found at `public/images/app/My-image.png`, copied there by the `npm` script from `src/App/assets/images/PHP-REST-API.png`. -New library classes have been implemented: Dot_Geoip and Dot_Seo, and some of the existing ones have been updated: Dot_Curl and Dot_Session (each module has its own session). +```html + + + + + + + -## SQL Prepared Statements + + + + + + +``` -In Dotkernel, all SQL queries are written as prepared statements. -We strongly encourage this practice: [http://www.dotkernel.com/php-development/protection-against-sql-injection-using-pdo-and-zend-framework/](http://www.dotkernel.com/php-development/protection-against-sql-injection-using-pdo-and-zend-framework/) +### Top menu -For more details, see [ChangeLog 1.2.0](http://www.dotkernel.com/changelog/1-2-0/). +This menu is displayed on all pages, in the header. +Edit it in `src/App/templates/layout/default.html.twig`, under `id="navbarHeader"`: -## FAQ +```html + +``` -**Q: What is a "dots" in Dotkernel, a term introduced in this release?** -A: A term for a submodule and all its component files. For example, "user" is a dots of the frontend module, and one dots can belong to multiple modules, such as "user" belonging to both frontend and admin. +You can replace the `nav-item` class for the `li` elements with `button-border` for a link that looks more like a button. -**Q: Where are dots configuration values stored, compared to earlier versions?** -A: They're stored in XML files inside the configs/dots folder. In previous versions, these values were hard-coded in the PHP files. +### Footer -**Q: What dots does the admin module include by default?** -A: admin, user, and system, to make it easier to start an application from Dotkernel. +To edit the footer on all pages, search for `