# hryvinskyi/magento2-base

> N/A

`composer require hryvinskyi/magento2-base`

Canonical URL: https://packagento.com/hryvinskyi/magento2-base

## At a glance

- **Vendor**: hryvinskyi (https://packagento.com/hryvinskyi.md)
- **Latest version**: 2.1.12 — released 2026-06-04
- **Pricing**: Free
- **Package type**: Magento 2 module
- **Status**: active, accepting new buyers

## Installation

Packagento is licence-gated, so even free packages need a licence on a project before Composer can resolve them.

1. **Sign in or create an account** at https://packagento.com/customer/account/.

2. **Add the package to your account.** Open https://packagento.com/hryvinskyi/magento2-base and complete the free checkout. A licence is minted automatically.

3. **Create or pick a project, then activate the licence on it.**
   - Projects represent the Magento installs you deploy to. Manage them at https://packagento.com/projects/.
   - Activate the new licence on the project you'll deploy this package to. Activation is what generates the Composer credentials scoped to that project.

4. **Add the project credentials to your Magento codebase.**

   Grab the project's public + private key from https://packagento.com/projects/ (open the project, then its Credentials tab), and add them to `auth.json`:

   ```json
   {
     "http-basic": {
       "packagento.com": {
         "username": "ppk_live_...",
         "password": "psk_live_..."
       }
     }
   }
   ```

   Add the Packagento Composer repository to `composer.json`:

   ```json
   {
     "repositories": [
       { "type": "composer", "url": "https://packagento.com" }
     ]
   }
   ```

5. **Install and apply.**

   ```bash
   composer require hryvinskyi/magento2-base:*
   bin/magento setup:upgrade
   bin/magento setup:di:compile
   bin/magento cache:flush
   ```

## What it does

N/A

## README

A comprehensive Magento 2 base module providing:
- **Yii2 Framework Helpers**: Battle-tested utility classes for array manipulation, HTML generation, JSON handling, and debugging
- **ViewModel Registry**: Global access to view models in templates without layout XML configuration
- **Console Utilities**: ANSI terminal control, progress bars, and formatted CLI output
- **Layout Debugging**: Developer mode tools for layout XML and block structure inspection

### Installation Guide

```bash
composer require hryvinskyi/magento2-base
bin/magento module:enable Hryvinskyi_Base
bin/magento setup:upgrade
```

### Table of Contents

1. [Core Features](#core-features)
   - [ViewModel Registry](#1-viewmodel-registry-viewmodels)
   - [Layout Debugging](#2-layout-debugging-developer-mode-only)
   - [Extensible Admin Menu](#3-extensible-admin-menu)
2. [Yii2 Framework Helpers](#yii2-framework-helper-classes)
   - [ArrayHelper](#arrayhelper)
   - [Html](#html)
   - [Json](#json)
   - [VarDumper](#vardumper)
3. [Console Utilities](#console-utilities-consolehelper)
4. [Requirements](#requirements)
5. [License](#license)

### Core Features

#### 1. ViewModel Registry (`$viewModels`)

Access any view model directly in templates without declaring them in layout XML. The `$viewModels` variable is automatically available in all `.phtml` templates.

**Usage in templates:**
```php
<?php
/** @var Magento\Framework\View\Element\Template $block */
/** @var Hryvinskyi\Base\Model\ViewModelRegistry $viewModels */

// Get any view model by class name
$productViewModel = $viewModels->require(\Vendor\Module\ViewModel\Product::class);
$categoryViewModel = $viewModels->require(\Vendor\Module\ViewModel\Category::class);

// For ESI blocks with TTL, pass the block reference for proper cache handling
$esiViewModel = $viewModels->require(\Vendor\Module\ViewModel\Esi::class, $block);

// Use the view model
echo $productViewModel->getProductName();
?>
```

**How it works:**
- Automatically injected into all PHP template engines via `di.xml`
- Collects cache tags from view models implementing `IdentityInterface`
- Properly handles Varnish ESI blocks to prevent incorrect cache purging
- Validates that requested classes implement `ArgumentInterface`

**Cache handling for ESI blocks:**
```php
// Main page - cache tags collected normally
$viewModel = $viewModels->require(MyViewModel::class);

// ESI block (ttl="300") - pass $block to prevent main page cache pollution
$viewModel = $viewModels->require(MyViewModel::class, $block);
```

#### 2. Layout Debugging (Developer Mode Only)

Automatic layout debugging tools enabled when Magento is in developer mode.

**Features:**
- Visual block hierarchy display
- Layout XML structure viewer
- Block rendering time tracking
- Cache status indicators

**Automatically enabled when:**
```bash
bin/magento deploy:mode:set developer
```

**Configuration:**
The debugging information is controlled by `Hryvinskyi\Base\Helper\Config`:
- Only works in developer mode (`State::MODE_DEVELOPER`)
- Injected into responses via event observers
- No configuration needed - works out of the box

**What you get:**
- Block nesting and parent-child relationships
- Template file locations with full paths
- Block class names and cache keys
- Layout handle processing order
- Visual hierarchy with indentation

#### 3. Extensible Admin Menu

A reusable dropdown menu component for Magento admin pages that can be configured entirely via layout XML. Perfect for creating navigation menus in custom admin modules.

**Features:**
- Fully configurable via layout XML (no PHP code required)
- Route-based URL generation with parameters support
- Sortable menu items with sort_order
- Custom CSS classes and icons per item
- Translatable labels
- Reusable across multiple modules

**Basic Usage in Layout XML:**

```xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css src="Hryvinskyi_Base::css/styles.css"/>
    </head>
    <body>
        <referenceBlock name="page.title">
            <block class="Hryvinskyi\Base\Block\Adminhtml\Menu" name="my.module.menu">
                <arguments>
                    <argument name="menu_title" xsi:type="string" translate="true">My Module</argument>
                    <argument name="items" xsi:type="array">
                        <item name="dashboard" xsi:type="array">
                            <item name="label" xsi:type="string" translate="true">Dashboard</item>
                            <item name="route" xsi:type="string">mymodule/dashboard/index</item>
                            <item name="sort_order" xsi:type="number">10</item>
                        </item>
                        <item name="settings" xsi:type="array">
                            <item name="label" xsi:type="string" translate="true">Settings</item>
                            <item name="route" xsi:type="string">adminhtml/system_config/edit</item>
                            <item name="route_params" xsi:type="array">
                                <item name="section" xsi:type="string">mymodule</item>
                            </item>
                            <item name="sort_order" xsi:type="number">20</item>
                        </item>
                    </argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>
```

**Creating a Reusable Menu Handle:**

Create a shared layout handle file (e.g., `mymodule_menu.xml`) to avoid duplication:

_(README truncated for .md surface. Full README on https://packagento.com/hryvinskyi/magento2-base.)_

## Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### [2.1.12] - 2026-06-04

#### Fixed
- PHP 8.5 compatibility: use explicit nullable type for the `$block` parameter in `ViewModelRegistry::require()` (`AbstractBlock $block = null` → `?AbstractBlock $block = null`). Implicitly marking a typed parameter as nullable is deprecated since PHP 8.4 and emits a deprecation notice on PHP 8.5.

### [2.1.7] - 2026-02-04

#### Fixed
- Renamed `$class` parameter to `$cssClass` in `MenuItem` constructor to avoid PHP reserved keyword conflict that caused DI compilation failure

### [2.1.6] - 2026-02-02

#### Added
- **Admin Menu Component** - A reusable dropdown menu block for Magento admin pages
  - `Hryvinskyi\Base\Block\Adminhtml\Menu` - Block class with layout XML configuration support
  - `Hryvinskyi\Base\Api\Menu\MenuItemInterface` - Interface for menu items
  - `Hryvinskyi\Base\Api\Menu\MenuItemFactoryInterface` - Factory interface for creating menu items
  - `Hryvinskyi\Base\Model\Menu\MenuItem` - Menu item implementation with route-based URL generation
  - `Hryvinskyi\Base\Model\Menu\MenuItemFactory` - Factory for creating menu items from array configuration
  - `view/adminhtml/templates/menu.phtml` - Admin menu template
- Menu items support:
  - Route-based URL generation with parameters
  - Sortable items via `sort_order`
  - Custom CSS classes per item
  - SVG/HTML icons per item
  - Translatable labels
  - Active/inactive state

#### Changed
- Admin CSS styles now include menu component styles in `view/adminhtml/web/css/styles.css`

### [2.1.5] - Previous Release

#### Features
- ViewModel Registry (`$viewModels`) - Global access to view models in templates
- Layout Debugging tools for developer mode
- Yii2 Framework Helpers:
  - ArrayHelper - Array manipulation utilities
  - Html - HTML generation helper
  - Json - JSON encoding/decoding utilities
  - VarDumper - Variable dumping for debugging
- ConsoleHelper - ANSI terminal control for CLI commands

## Recent Versions

| Version | Released |
|---|---|
| 2.1.12 | 2026-06-04 |
| 2.1.11 | 2026-04-17 |
| 1.0.10 | 2026-03-25 |
| 2.1.9 | 2026-02-17 |
| 2.1.8 | 2026-02-17 |
| 2.1.7 | 2026-02-03 |
| 2.1.6 | 2026-02-03 |
| 2.1.5 | 2025-10-06 |
| 2.1.4 | 2025-10-06 |
| 2.1.3 | 2024-12-17 |

Showing 10 of 23 versions. Full release history on https://packagento.com/hryvinskyi/magento2-base.

## Dependencies

### Require

| Package | Constraint |
|---|---|
| magento/framework | * |
| php | >=8.0 |

## Quality

Latest release (2.1.12) fails the Packagento QA pipeline. Verdicts below are per-cell (Magento line × PHP version) for the matrixed tools, and run-once for the static / security tiers.


### Compatibility

Each Magento line is installed on its supported PHP versions, then the module is built (DI compile + static-content deploy). Cells show passed / failed / untested; staircase gaps render as `–`.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | Pass | Pass | – | – |
| 2.4.8 | – | Pass | Pass | – |
| 2.4.9 | – | – | Pass | Pass |


### Code Quality

Advisory checks against the module's source. Never affect the Compatibility verdict — a phpcs finding can't make a module incompatible.

#### Static Analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Fail | 2330 | 65 errors, 2265 warnings (ruleset: Magento2) — 1963 auto-fixable with phpcbf |
| PHPMD | Warning | 97 | 97 rule violations (MissingImport:38, CyclomaticComplexity:13, IfStatementAssignment:8, TooManyPublicMethods:5, ExcessiveClassComplexity:5) |
| Cpd | Pass | 0 |  |
| Composer validate | Info | 2 | valid; 2 advisory notes (composer validate --strict) |

#### PHPStan

Type-checks the module against a real Magento install. Re-runs per Magento + PHP version because resolvable symbols differ between releases.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | 16 | 16 | – | – |
| 2.4.8 | – | 16 | 15 | – |
| 2.4.9 | – | – | 15 | 15 |


### Tests

Unit and integration suites run per Magento + PHP cell. Test failures speak to the module's behaviour, not its compatibility with a line, so they're reported here separately.

#### Unit Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |

#### Integration Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |


### Security

Dependency-advisory audit (composer audit) plus a source malware scan. A malware detection fails the version outright.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| Composer audit | Pass | 0 |  |
| Malware scan | Pass | 0 |  |

## Licence and pricing

Free. A licence is still minted on checkout and bound to your project for Composer access — no payment step.

Refundable within 14 days of first purchase via https://packagento.com/account/refunds/.

## Install via Claude Code or any MCP client

The Packagento MCP server can run the licence + project + Composer steps above in one tool call:

```
purchase_and_install_packages(
  composer_names=["hryvinskyi/magento2-base"],
  project_id="proj_xxx"
)
```

This handles cart, checkout, licence minting, project activation, and writes auth.json credentials. Connect a client with `claude mcp add packagento https://mcp.packagento.com`. Full setup at https://packagento.com/docs/mcp-setup.

## Vendor

hryvinskyi is a Magento 2 vendor on Packagento. See https://packagento.com/hryvinskyi.md for their full catalogue.

