From cacb9180ea983d02a4015d47112a8343a01b24e3 Mon Sep 17 00:00:00 2001 From: OStefan2001 Date: Mon, 27 Jul 2026 13:00:22 +0300 Subject: [PATCH 1/3] title-section partial modified --- src/App/templates/partial/title-section.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App/templates/partial/title-section.html.twig b/src/App/templates/partial/title-section.html.twig index 154dbb3f..5bbe9952 100644 --- a/src/App/templates/partial/title-section.html.twig +++ b/src/App/templates/partial/title-section.html.twig @@ -1,5 +1,5 @@ -{% set page_title = article.title|default(title|default('')) %} -{% set author_github = article.author.github|default(author_github|default(false)) %} +{% set page_title = article.title ?? (title ?? '') %} +{% set author_github = article.author.github ?? (author.github ?? '') %}
{% if back_href is defined %} From 5b6b96124e7a402cdbd848240c99031115ce7758 Mon Sep 17 00:00:00 2001 From: OStefan2001 Date: Mon, 27 Jul 2026 14:19:41 +0300 Subject: [PATCH 2/3] Fix fixtures (some authors had more posts than expected). Find some twig errors and fix them --- src/App/src/Fixture/AuthorLoader.php | 11 +- src/App/src/Fixture/CategoryLoader.php | 2 +- src/App/src/Fixture/PostLoader.php | 7 +- src/App/src/Fixture/articles_cleaned.json | 126 ++++++++++-------- ...-cookie-remember-me-in-dotkernel.html.twig | 4 +- ...hoice-for-your-presentation-site.html.twig | 19 ++- ...documentation-in-dotkernel-api-3.html.twig | 2 +- ...e-urlgenerator-work-in-fastroute.html.twig | 2 +- ...sis-replacing-psalm-with-phpstan.html.twig | 12 +- 9 files changed, 106 insertions(+), 79 deletions(-) diff --git a/src/App/src/Fixture/AuthorLoader.php b/src/App/src/Fixture/AuthorLoader.php index ea874016..c5b38808 100644 --- a/src/App/src/Fixture/AuthorLoader.php +++ b/src/App/src/Fixture/AuthorLoader.php @@ -38,14 +38,13 @@ public function load(ObjectManager $manager): void continue; } - $wpAuthorId = $authorData['github']; - if (isset($seenAuthorIds[$wpAuthorId])) { + $name = $authorData['display_name']; + if (isset($seenAuthorIds[$name])) { continue; } - $seenAuthorIds[$wpAuthorId] = true; + $seenAuthorIds[$name] = true; - $name = $authorData['display_name']; - $github = $authorData['github']; + $github = $authorData['github'] ?: null; $slug = $this->slugify($name); $author = $repository->findOneBy(['name' => $name]); @@ -71,7 +70,7 @@ public function load(ObjectManager $manager): void echo $changed ? "UPDATE: {$name}\n" : "UNCHANGED: {$name}\n"; } - $this->addReference('author_' . $wpAuthorId, $author); + $this->addReference('author_' . $slug, $author); } } diff --git a/src/App/src/Fixture/CategoryLoader.php b/src/App/src/Fixture/CategoryLoader.php index a175da4f..fdae73cb 100644 --- a/src/App/src/Fixture/CategoryLoader.php +++ b/src/App/src/Fixture/CategoryLoader.php @@ -40,7 +40,7 @@ public function load(ObjectManager $manager): void } $category->setName($cat['name']); - $category->setVisibility($cat['isVisible'] ?? true); + $category->setVisibility((bool) ($cat['isVisible'] ?? true)); $this->addReference('category_' . $cat['slug'], $category); } diff --git a/src/App/src/Fixture/PostLoader.php b/src/App/src/Fixture/PostLoader.php index fdfd49fc..716e0a12 100644 --- a/src/App/src/Fixture/PostLoader.php +++ b/src/App/src/Fixture/PostLoader.php @@ -44,14 +44,15 @@ public function load(ObjectManager $manager): void $category = $this->getReference('category_' . $cat['slug'], Category::class); foreach ($cat['articles'] as $articleData) { - $wpAuthorId = $articleData['author']['github'] ?? null; - if (! $wpAuthorId || ! $this->hasReference('author_' . $wpAuthorId, Author::class)) { + $authorName = $articleData['author']['display_name'] ?? null; + $authorSlug = $authorName ? $this->slugify($authorName) : null; + if (! $authorSlug || ! $this->hasReference('author_' . $authorSlug, Author::class)) { echo "SKIP (no author): {$articleData['post_title']}\n"; continue; } /** @var Author $author */ - $author = $this->getReference('author_' . $wpAuthorId, Author::class); + $author = $this->getReference('author_' . $authorSlug, Author::class); $title = html_entity_decode($articleData['post_title'], ENT_QUOTES, 'UTF-8'); $slug = $this->slugify($title); diff --git a/src/App/src/Fixture/articles_cleaned.json b/src/App/src/Fixture/articles_cleaned.json index f6411e4f..3cf8f3be 100644 --- a/src/App/src/Fixture/articles_cleaned.json +++ b/src/App/src/Fixture/articles_cleaned.json @@ -2,6 +2,7 @@ { "name": "Dotkernel", "slug": "dotkernel", + "isVisible": 1, "articles": [ { "post_title": "DotKernel Database Naming Conventions for MySQL", @@ -39,7 +40,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Finally we reached DotKernel 1.2." }, @@ -49,7 +50,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Yesterday, we released DotKernel 1.2." }, @@ -59,7 +60,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "DotKernel 1.3." }, @@ -69,7 +70,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "GeoIP is the proprietary technology that drives MaxMind's IP geolocation data and services. It is a non-invasive way to determine geographical and other information about Internet visitors in real-time." }, @@ -79,7 +80,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "WURFL is integrated into DotKernel, using the Zend_Http_UserAgent class from the latest release ZF 1.11." }, @@ -89,7 +90,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Before the winter holiday we came with a new release: DotKernel 1.3." }, @@ -99,7 +100,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Zend_Auth and Zend_Acl have been integrated into the DotKernel, starting with version 1.5." }, @@ -109,7 +110,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "DotKernel has an example mobile site at http:\/\/v1.dotkernel." }, @@ -129,7 +130,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "On one of our recent projects 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." }, @@ -139,7 +140,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "In DotKernel, Zend_Registry will contain the following variables: startTime - the result of microtime() at the beginning of the request configuration - the configuration options loaded from configs\/application.ini router - routing settings loaded from configs\/router." }, @@ -159,7 +160,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "After a longer wait than usual, DotKernel 1.5." }, @@ -169,7 +170,7 @@ "post_status": "publish", "author": { "display_name": "deddu", - "github": "NULL" + "github": "" }, "excerpt": "The new DotKernel version 1.6." }, @@ -189,7 +190,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "Starting with 1.5, DotKernel has a Console bootstrap to easily run PHP scripts from the command line." }, @@ -269,7 +270,7 @@ "post_status": "publish", "author": { "display_name": "deddu", - "github": "NULL" + "github": "" }, "excerpt": "Integrating a new charting library in the latest version of DotKernel (1.6." }, @@ -279,7 +280,7 @@ "post_status": "publish", "author": { "display_name": "deddu", - "github": "NULL" + "github": "" }, "excerpt": "Another new feature in version 1.6." }, @@ -329,7 +330,7 @@ "post_status": "publish", "author": { "display_name": "deddu", - "github": "NULL" + "github": "" }, "excerpt": "To test if you have php_geoip extension on your Zend Server, create an php file and copy the following code. This will output true if extension is available or false if not." }, @@ -369,7 +370,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "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 Zend Framework Cache Backends Main cache settings (Cache Frontend) The main cache settings within the application." }, @@ -379,7 +380,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "It's very expensive to load configurations and settings from XML files, on every requests. First because of latency of accessing files from hard drive, second because of the XML file parsing burden." }, @@ -389,7 +390,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article is related to: Caching in DotKernel with Zend Framework Cache The variables that DotKernel cache are below: Router Router is the object that load routes (modules, controllers, actions) settings from router.xml file." }, @@ -399,7 +400,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "In the newest version we have removed the GeoIP City integration. The City database on GeoIP 1." }, @@ -409,7 +410,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "Alerts (or Dot_Alert's) are e-mails usually sent to the site developers, these messages are sent with mail() therefore you shouldn't use them to send regular mail. Alerts should only notify you as a developer: \"Hey, something's wrong here, you might want to know this!\" In this article you will find out how to use the Alerts system in DotKernel, we will also go through an existing example so this can be understood easier." }, @@ -419,7 +420,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "DotKernel 1.8." }, @@ -429,7 +430,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "DotKernel 1.8." }, @@ -439,7 +440,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "Recently we have added the Windows 8, 8.1 and 10 OS icon and Microsoft's Edge browser icon." }, @@ -449,7 +450,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "Composer is an application-level package manager. Composer auto-loads the dependencies on demand and can also auto-load custom classes ." }, @@ -459,7 +460,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article will cover the external dependency usage VIA composer within DotKernel applications. There is also an article explaining how composer can be added to DotKernel learn more." }, @@ -479,7 +480,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "What is DotKernel? The name DotKernel symbiotically  combines the string  Dot, as a representation of the Internet, and Kernel, the quintessence of any IT application. In other words Dotkernel wishes to be, with modesty, the central part of the Internet development and hence ensuring increased development productivity and run-time performance." }, @@ -499,7 +500,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article will explain the usage of the dot-log component within DotKernel, Zend Expressive or in a project that uses Zend Service Manager. Since dot-log extends zendframework\/zend-log this tutorial mostly compatible with zend-log as well." }, @@ -509,7 +510,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article is a follow-up for: Logging with dot-log in Zend Expressive and DotKernel, the mentioned article is a guide to using dot-log.   This article explains the usage of dotkernel\/dot-errorhandler with dotkernel\/dot-log or zendframework\/zend-log to log errors in Zend Expressive applications." }, @@ -519,7 +520,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article is a guide on how to add a CORS implementation on an existing DotKernel3 project. The issue If you're facing this message: \"Access to XMLHttpRequest at ‘url’ has been blocked by cors policy." }, @@ -579,7 +580,7 @@ "post_status": "publish", "author": { "display_name": "SergiuB", - "github": "NULL" + "github": "" }, "excerpt": "Autologin using Cookie \/ Remember Me in Dotkernel This feature is used to automatically log the user who chooses this by checking the remember me box. Implemented in Dotkernel Frontend starting from Release 3." }, @@ -648,6 +649,7 @@ { "name": "Javascript", "slug": "javascript", + "isVisible": 0, "articles": [ { "post_title": "Intro to jQuery", @@ -655,7 +657,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "Starting with the 1.5 release, DotKernel will make the switch from Dojo to jQuery." }, @@ -684,6 +686,7 @@ { "name": "Zend Framework", "slug": "zend-framework", + "isVisible": 0, "articles": [ { "post_title": "WURFL PHP API libraries , GPL versions", @@ -770,6 +773,7 @@ { "name": "PHP Development", "slug": "php-development", + "isVisible": 1, "articles": [ { "post_title": "PHP support back in Aptana 3.0", @@ -797,7 +801,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Following the preview article about SQL Injection, here is more - a strong argument why you should use Zend Framework for handling database access. Zend_Db is the primary class used for access the database, but there is more: Zend_Db_Statement, Zend_Db_Select and Zend_Db_Tables." }, @@ -817,7 +821,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "In hosted software development, the environment refers to a server tier designated to a specific stage in a release process. The purpose of these environments is to improve the development, testing and release processes in client-server applications." }, @@ -827,7 +831,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "In developing DotKernel application framework, we needed a tracking system. DotKernel Tracker is the place where the bugs are reported, new features are announced and other general tickets are added." }, @@ -907,7 +911,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article will cover the steps needed in order to check the PHP7 compatibility, a small troubleshooter. This article will also contain a compatibility issue check on the latest Zend Framework 1 version." }, @@ -917,7 +921,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article applies to PHP 5.x but also to PHP 7 While using floating-point arithmetic you might have noticed that not all the calculus results are as expected, this can usually be observed when casting values." }, @@ -976,6 +980,7 @@ { "name": "How to's", "slug": "how-to", + "isVisible": 1, "articles": [ { "post_title": "What is PSR-7 and how to use it", @@ -983,7 +988,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "What is PSR-7 and how to use itPSR-7 is a set of common interfaces defined by PHP Framework Interop Group. These interfaces are representing HTTP messages, and URIs for use when communicating trough HTTP." }, @@ -1013,7 +1018,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article covers the steps required to migrate a DotKernel 3 instance to the latest Zend Expressive Version. Migration from Zend Expressive 2 to 3." }, @@ -1122,6 +1127,7 @@ { "name": "PHP Troubleshooting", "slug": "php-troubleshooting", + "isVisible": 0, "articles": [ { "post_title": "Where is the intl PHP extension? Problem solved!", @@ -1129,7 +1135,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "Problem PHP packages\/frameworks\/libraries\/scripts we work with might require different PHP extensions. In this case the Intl extension is needed to work with using Internationalization Functions." }, @@ -1139,7 +1145,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This article will cover the solution to the PEAR \"Cannot use result of built-in function in write context\" issue. The Issue If installing a pear package (for instance PHP Code Sniffer), when running: pear install PHP_CodeSniffer This error is shown PHP Fatal error: Cannot use result of built-in function in write context in ." } @@ -1148,6 +1154,7 @@ { "name": "Dotkernel 3", "slug": "dotkernel3", + "isVisible": 0, "articles": [ { "post_title": "Development Report December 11, 2017", @@ -1155,7 +1162,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "This report contains updates about the DotKernel3 documentation. We have added the release notes for DotKernel3 frontend and admin: you can now check the Release Notes page." }, @@ -1165,7 +1172,7 @@ "post_status": "publish", "author": { "display_name": "Gabi DJ", - "github": "NULL" + "github": "" }, "excerpt": "DotKernel was updated to support Zend Expressive 3 alongside with PSR-15 middleware. We have updated the core packages to support PSR-15 Middleware." }, @@ -1244,6 +1251,7 @@ { "name": "Middleware", "slug": "middleware", + "isVisible": 1, "articles": [ { "post_title": "Handling dynamic routing using FastRoute in Dotkernel", @@ -1280,6 +1288,7 @@ { "name": "Best Practice", "slug": "best-practice", + "isVisible": 1, "articles": [ { "post_title": "SQL queries using Zend_Db – SELECT", @@ -1287,7 +1296,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Zend_Db and its related classes provide a simple SQL database interface for Zend Framework. To connect to MySql database, we are using Pdo_Mysql adapter : $db = Zend_Db::factory('Pdo_Mysql', $dbConnect); SELECT query - WHERE clause The below 2 classical SQL queries are equivalent." }, @@ -1297,7 +1306,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Continuing the Zend_DB article series, we are stopping now at FETCH methods that are in Zend_Db_Adapter_Abstract: array fetchAll (string|Zend_Db_Select $sql, , ) array fetchAssoc (string|Zend_Db_Select $sql, ) array fetchCol (string|Zend_Db_Select $sql, ) string fetchOne (string|Zend_Db_Select $sql, ) array fetchPairs (string|Zend_Db_Select $sql, ) array fetchRow (string|Zend_Db_Select $sql, , ) To be more easily to follow, in green box is the classical SQL statement, and in blue box is the query written in Zend_Db style. Lets start." }, @@ -1307,7 +1316,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Continuing the Zend_DB article series, we are stopping now at subqueries. As you note, the below is a complicate query, with COUNT(), LEFT JOIN(), GROUP BY - select from 3 tables, and make a count from 2 different tables: SELECT a." }, @@ -1317,7 +1326,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Continuing the Zend_DB article series, we are stopping now at DML statements. DML (Data Manipulation Language) statements are statements that change data values in database tables." }, @@ -1327,9 +1336,9 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, - "excerpt": "On a TIMESTAMP field that records date and time when inserting a new record, it is encouraged to use as a DEFAULT value, the CURRENT_TIMESTAMP constant. Why? Because when inserting a new row in the table for the date and time field there is no need to specifically add its value, either by creating it from PHP code with the Date\/ Time functions or with MySQL function NOW() ALTER TABLE `user` CHANGE `dateCreated` `dateCreated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; CURRENT_TIMESTAMP is also a solution for  updating date and time fields." + "excerpt": "On a TIMESTAMP field that records date and time when inserting a new record, it is encouraged to use as a DEFAULT value, the CURRENT_TIMESTAMP constant. Why? Because when inserting a new row in the table for the date and time field there is no need to specifically add its value, either by creating it from PHP code with the Date\/ Time functions or with MySQL function NOW() ALTER TABLE `user` CHANGE `dateCreated` `dateCreated` TIMESTAMP NOT DEFAULT CURRENT_TIMESTAMP; CURRENT_TIMESTAMP is also a solution for  updating date and time fields." }, { "post_title": "Using LIKE wildcards with Zend_Db", @@ -1337,7 +1346,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "Continuing the Zend_Db article series, let's discuss the LIKE condition. The LIKE condition allows you to use wildcards in the WHERE clause of an SQL statement." }, @@ -1357,7 +1366,7 @@ "post_status": "publish", "author": { "display_name": "Adrian", - "github": "NULL" + "github": "" }, "excerpt": "The following commands should be run in the terminal (for example, using Putty in Windows) on the host where you want to export the repository). It's recommended that you run them using the domain's user, not root." }, @@ -1367,7 +1376,7 @@ "post_status": "publish", "author": { "display_name": "Teo", - "github": "NULL" + "github": "" }, "excerpt": "In Aptana it's very simple to set the svn:keywords property for a file. For example if you want to set the svn keyword property Id: In the file where you want to add the svn keyword property write $Id$ Right click on the file, then follow Team -> Set Property." }, @@ -1416,6 +1425,7 @@ { "name": "Android", "slug": "android", + "isVisible": 0, "articles": [ { "post_title": "Multiple broadcast receivers in the same app, for the same action", @@ -1423,7 +1433,7 @@ "post_status": "publish", "author": { "display_name": "n3vrax", - "github": "NULL" + "github": "" }, "excerpt": "Did you come to a point where using multiple broadcast receivers to listen for the same intent, separatly, in the same android app, leads to unexpected results? If that\"s the case, one broadcast receiver might consume the broadcasted intent, online casino leaving the others with nothing to receive. This can be the case where you use 3rd party libraries with broadcast receivers defined." }, @@ -1433,7 +1443,7 @@ "post_status": "publish", "author": { "display_name": "n3vrax", - "github": "NULL" + "github": "" }, "excerpt": "Have you ever wondered if Android market sends you information at the moment of app install? Wouldn\"t be nice to create custom links to your android application, including bits of information about the referrer, and send it directly to the app for online casino processing at install? This could be a simple and accurate solution for mobile app install tracking but I\"m sure you can find this useful in many ways. With Android, you actually get this information as a broadcasted intent by android market at install time - even before opening your app." } @@ -1442,6 +1452,7 @@ { "name": "Dotkernel API", "slug": "dotkernel-api", + "isVisible": 1, "articles": [ { "post_title": "DotKernel API Client Side Authorization", @@ -1548,6 +1559,7 @@ { "name": "PHPStorm", "slug": "phpstorm", + "isVisible": 0, "articles": [ { "post_title": "Code Quality: How to setup phpcs in PHPStorm", @@ -1564,6 +1576,7 @@ { "name": "Licensing", "slug": "licensing", + "isVisible": 0, "articles": [ { "post_title": "MIT versus LGPL in practice: Dotkernel case", @@ -1580,6 +1593,7 @@ { "name": "Architecture", "slug": "architecture", + "isVisible": 1, "articles": [ { "post_title": "Understanding Middleware", @@ -1616,6 +1630,7 @@ { "name": "Design Patterns", "slug": "design-pattern", + "isVisible": 1, "articles": [ { "post_title": "Naming pattern for PSR-15 handlers in Dotkernel applications", @@ -1632,6 +1647,7 @@ { "name": "Headless Platform", "slug": "headless-platform", + "isVisible": 1, "articles": [ { "post_title": "Dotkernel Headless Platform - The Whats, Hows and Whys", @@ -1725,4 +1741,4 @@ } ] } -] \ No newline at end of file +] diff --git a/src/Blog/templates/page/blog-resource/dotkernel/autologin-using-cookie-remember-me-in-dotkernel.html.twig b/src/Blog/templates/page/blog-resource/dotkernel/autologin-using-cookie-remember-me-in-dotkernel.html.twig index 805c77b0..ab94c8af 100644 --- a/src/Blog/templates/page/blog-resource/dotkernel/autologin-using-cookie-remember-me-in-dotkernel.html.twig +++ b/src/Blog/templates/page/blog-resource/dotkernel/autologin-using-cookie-remember-me-in-dotkernel.html.twig @@ -30,11 +30,11 @@

To add remember me button to user interface, navigate to src/User/templates/user/login.html.twig and under password element add the following code:

-
<div class="checkbox remember-me-checkbox">
+
{% verbatim %}<div class="checkbox remember-me-checkbox">
      {% set rememberMe = form.get('rememberMe') %}
      {{ formElement(rememberMe) }}
      <p>Remember me</p>
-</div>
+</div>{% endverbatim %}

After you've added the button to your template, navigate to src/User/src/Form/LoginForm.php and add the following element to your form:

diff --git a/src/Blog/templates/page/blog-resource/dotkernel/dotkernel-light-the-best-choice-for-your-presentation-site.html.twig b/src/Blog/templates/page/blog-resource/dotkernel/dotkernel-light-the-best-choice-for-your-presentation-site.html.twig index 5d9337d2..4c226742 100644 --- a/src/Blog/templates/page/blog-resource/dotkernel/dotkernel-light-the-best-choice-for-your-presentation-site.html.twig +++ b/src/Blog/templates/page/blog-resource/dotkernel/dotkernel-light-the-best-choice-for-your-presentation-site.html.twig @@ -80,7 +80,9 @@

Each page has its own template, so the next step is to create the template files in the src/Page/templates/page/ folder. For the example above, the src/Page/templates/page/example-template.html.twig file was created. We won't include the entire code here, just the basic building blocks. The content block is where your page copy goes.

-
{% extends '@layout/default.html.twig' %}
+
+{% verbatim %}
+{% extends '@layout/default.html.twig' %}
 
 {% block title %}Page Title{% endblock %}
 
@@ -96,7 +98,9 @@
     <div>
     Add cool content here!
     </div>
-{% endblock %}
+{% endblock %} +{% endverbatim %} +

Make sure to check the header for any fonts your content requires.

@@ -124,15 +128,17 @@

In the example:

-
  • {{ url('home') }} is the URL for the homepage, but you can also use this code to generate the url for other pages, just like in the canonical URL {% block canonical %}{{ url(routeName ?? null) }}{% endblock %}
    • The block item is present to mitigate for not-found pages, e.g. when the url is typed incorrectly
    • +
      • {% verbatim %}{{ url('home') }}{% endverbatim %} is the URL for the homepage, but you can also use this code to generate the url for other pages, just like in the canonical URL {% verbatim %}{% block canonical %}{{ url(routeName ?? null) }}{% endblock %}{% endverbatim %}
        • The block item is present to mitigate for not-found pages, e.g. when the url is typed incorrectly
      • -
      • The image from {{ url('home') }}images/app/My-image.png is found in public/images/app/My-image.png, but it is copied there by the npm script from src/App/assets/images/PHP-REST-API.png.
      • +
      • The image from {% verbatim %}{{ url('home') }}{% endverbatim %}images/app/My-image.png is found in public/images/app/My-image.png, but it is copied there by the npm script from src/App/assets/images/PHP-REST-API.png.
-
<!-- Twitter card -->
+
+{% verbatim %}
+<!-- Twitter card -->
 <meta name="twitter:card" content="summary_large_image">
 <meta name="twitter:site" content="@example">
 <meta name="twitter:title" content="Page title">
@@ -145,7 +151,8 @@
 <meta property="og:type" content="website"/>
 <meta property="og:url" content="{{ url('home') }}"/>
 <meta property="og:image" content="{{ url('home') }}images/app/My-image.png"/>
-<meta property="og:description" content="Basic description"/>
+<meta property="og:description" content="Basic description"/> +{% endverbatim %}

Top menu

diff --git a/src/Blog/templates/page/blog-resource/how-to/using-postman-for-documentation-in-dotkernel-api-3.html.twig b/src/Blog/templates/page/blog-resource/how-to/using-postman-for-documentation-in-dotkernel-api-3.html.twig index 5ae222cf..991503e8 100644 --- a/src/Blog/templates/page/blog-resource/how-to/using-postman-for-documentation-in-dotkernel-api-3.html.twig +++ b/src/Blog/templates/page/blog-resource/how-to/using-postman-for-documentation-in-dotkernel-api-3.html.twig @@ -83,7 +83,7 @@ VARIABLE INITIAL VALUE CURRENT_VALUE

Inside the collection, right-click on any folder and click Add Request. The new request is automatically opened in a new tab, where you will:

-
  • enter request name by replacing New Request with a short and descriptive name
  • enter request description (first button under the Environment quick look button)
  • enter request URL - you should use the already existing variable APPLICATION_URL by wrapping it in double curly braces, then append the request path. Example: {{ APPLICATION_URL }}/test becomes http://localhost:8080/test when you send the request.
  • select request method
  • (optionally) inspect tabs:
    • Params: manage query parameters
    • Authorization: select authorization type
    • Headers: manage request headers
    • Body: manage request body
    • Pre-request script: provide JavaScript that Postman should run before sending the request
    • Tests: provide JavaScript that Postman should run after receiving the response
    • Settings: manage miscellaneous request settings
  • save the request using the Save button (or Ctrl + S)
+
  • enter request name by replacing New Request with a short and descriptive name
  • enter request description (first button under the Environment quick look button)
  • enter request URL - you should use the already existing variable APPLICATION_URL by wrapping it in double curly braces, then append the request path. Example: {% verbatim %}{{ APPLICATION_URL }}{% endverbatim %}/test becomes http://localhost:8080/test when you send the request.
  • select request method
  • (optionally) inspect tabs:
    • Params: manage query parameters
    • Authorization: select authorization type
    • Headers: manage request headers
    • Body: manage request body
    • Pre-request script: provide JavaScript that Postman should run before sending the request
    • Tests: provide JavaScript that Postman should run after receiving the response
    • Settings: manage miscellaneous request settings
  • save the request using the Save button (or Ctrl + S)

Sending a request

diff --git a/src/Blog/templates/page/blog-resource/how-to/using-the-urlgenerator-work-in-fastroute.html.twig b/src/Blog/templates/page/blog-resource/how-to/using-the-urlgenerator-work-in-fastroute.html.twig index 73e59d33..94aed985 100644 --- a/src/Blog/templates/page/blog-resource/how-to/using-the-urlgenerator-work-in-fastroute.html.twig +++ b/src/Blog/templates/page/blog-resource/how-to/using-the-urlgenerator-work-in-fastroute.html.twig @@ -43,7 +43,7 @@ A controller redirect may then look like this: Using the URLGenerator in views is approximately the same, since you have access to the global path() method. The path method works the same way as the url() method, and takes the route name as the first parameter, and any optional blocks as its second parameter. This is of course done in Twig, so we need to put curly brackets around it since it's dynamic and not static HTML. It could look like this: -
{{ path(name: 'page', parameters: {action: 'thank-you'}, relative: false) }}
+
{% verbatim %}{{ path(name: 'page', parameters: {action: 'thank-you'}, relative: false) }}{% endverbatim %}

Frequently Asked Questions

diff --git a/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig b/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig index 4ed447d5..05fbc697 100644 --- a/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig +++ b/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig @@ -94,8 +94,10 @@
  • create file .github/workflows/static-analysis.yml with the content below to configure the environment and the steps for PHPStan
  • -
    on:
    -  - push
    +
    +{% verbatim %}
    +on:
    +  - 
     
     name: Run PHPStan checks
     
    @@ -121,7 +123,7 @@ jobs:
           - name: Install PHP
             uses: shivammathur/setup-php@v2
             with:
    -          php-version: "${{ matrix.php }}"
    +          php-version: '${{ matrix.php }}'
               coverage: pcov
               ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On
               tools: composer:v2, cs2pr
    @@ -145,7 +147,9 @@ jobs:
               mv config/autoload/mail.local.php.dist config/autoload/mail.local.php
               mv config/autoload/local.test.php.dist config/autoload/local.test.php
           - name: Run static analysis with PHPStan
    -        run:  vendor/bin/phpstan analyse
    + run: vendor/bin/phpstan analyse +{% endverbatim %} +
    • create the file phpstan.neon with the content below to configure the extensions, the rule level and the ignore rules
    From 012394898d792c92bdd124cf6a2e4c5cbd6948b7 Mon Sep 17 00:00:00 2001 From: OStefan2001 Date: Mon, 27 Jul 2026 14:52:33 +0300 Subject: [PATCH 3/3] Applied recommendations to improve --- src/App/src/Fixture/CategoryLoader.php | 5 ++- src/App/src/Fixture/articles_cleaned.json | 32 +++++++++---------- ...sis-replacing-psalm-with-phpstan.html.twig | 2 +- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/App/src/Fixture/CategoryLoader.php b/src/App/src/Fixture/CategoryLoader.php index fdae73cb..3ea87b08 100644 --- a/src/App/src/Fixture/CategoryLoader.php +++ b/src/App/src/Fixture/CategoryLoader.php @@ -20,7 +20,7 @@ public function load(ObjectManager $manager): void $contents = file_get_contents($jsonFile); if ($contents === false) { - throw new RuntimeException("Unable to read file: {$jsonFile}"); + throw new RuntimeException("Unable to read file: $jsonFile"); } $categories = json_decode($contents, true); @@ -40,8 +40,7 @@ public function load(ObjectManager $manager): void } $category->setName($cat['name']); - $category->setVisibility((bool) ($cat['isVisible'] ?? true)); - + $category->setVisibility($cat['isVisible'] ?? true); $this->addReference('category_' . $cat['slug'], $category); } diff --git a/src/App/src/Fixture/articles_cleaned.json b/src/App/src/Fixture/articles_cleaned.json index 3cf8f3be..c05815b5 100644 --- a/src/App/src/Fixture/articles_cleaned.json +++ b/src/App/src/Fixture/articles_cleaned.json @@ -2,7 +2,7 @@ { "name": "Dotkernel", "slug": "dotkernel", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "DotKernel Database Naming Conventions for MySQL", @@ -649,7 +649,7 @@ { "name": "Javascript", "slug": "javascript", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "Intro to jQuery", @@ -686,7 +686,7 @@ { "name": "Zend Framework", "slug": "zend-framework", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "WURFL PHP API libraries , GPL versions", @@ -773,7 +773,7 @@ { "name": "PHP Development", "slug": "php-development", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "PHP support back in Aptana 3.0", @@ -980,7 +980,7 @@ { "name": "How to's", "slug": "how-to", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "What is PSR-7 and how to use it", @@ -1127,7 +1127,7 @@ { "name": "PHP Troubleshooting", "slug": "php-troubleshooting", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "Where is the intl PHP extension? Problem solved!", @@ -1154,7 +1154,7 @@ { "name": "Dotkernel 3", "slug": "dotkernel3", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "Development Report December 11, 2017", @@ -1251,7 +1251,7 @@ { "name": "Middleware", "slug": "middleware", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "Handling dynamic routing using FastRoute in Dotkernel", @@ -1288,7 +1288,7 @@ { "name": "Best Practice", "slug": "best-practice", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "SQL queries using Zend_Db – SELECT", @@ -1425,7 +1425,7 @@ { "name": "Android", "slug": "android", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "Multiple broadcast receivers in the same app, for the same action", @@ -1452,7 +1452,7 @@ { "name": "Dotkernel API", "slug": "dotkernel-api", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "DotKernel API Client Side Authorization", @@ -1559,7 +1559,7 @@ { "name": "PHPStorm", "slug": "phpstorm", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "Code Quality: How to setup phpcs in PHPStorm", @@ -1576,7 +1576,7 @@ { "name": "Licensing", "slug": "licensing", - "isVisible": 0, + "isVisible": false, "articles": [ { "post_title": "MIT versus LGPL in practice: Dotkernel case", @@ -1593,7 +1593,7 @@ { "name": "Architecture", "slug": "architecture", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "Understanding Middleware", @@ -1630,7 +1630,7 @@ { "name": "Design Patterns", "slug": "design-pattern", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "Naming pattern for PSR-15 handlers in Dotkernel applications", @@ -1647,7 +1647,7 @@ { "name": "Headless Platform", "slug": "headless-platform", - "isVisible": 1, + "isVisible": true, "articles": [ { "post_title": "Dotkernel Headless Platform - The Whats, Hows and Whys", diff --git a/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig b/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig index 05fbc697..a4ddde4d 100644 --- a/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig +++ b/src/Blog/templates/page/blog-resource/php-development/static-analysis-replacing-psalm-with-phpstan.html.twig @@ -97,7 +97,7 @@
     {% verbatim %}
     on:
    -  - 
    +  - push
     
     name: Run PHPStan checks