# mohan-devstack/magento2-product-queue-save

> Magento 2 module — Save all product types asynchronously via message queue (simple, configurable, grouped, bundle, downloadable). No browser timeouts.

`composer require mohan-devstack/magento2-product-queue-save`

Canonical URL: https://packagento.com/mohan-devstack/magento2-product-queue-save

## At a glance

- **Vendor**: mohan-devstack (https://packagento.com/mohan-devstack.md)
- **Latest version**: v1.0.0 — released 2026-07-10
- **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/mohan-devstack/magento2-product-queue-save 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 mohan-devstack/magento2-product-queue-save:*
   bin/magento setup:upgrade
   bin/magento setup:di:compile
   bin/magento cache:flush
   ```

## What it does

Magento 2 module — Save all product types asynchronously via message queue (simple, configurable, grouped, bundle, downloadable). No browser timeouts.

## README

A Magento 2 module that adds a **"Save via Queue & Close"** button to the admin product edit page. Instead of saving the product synchronously (which can time out on large catalogues or configurable products with many variations), it pushes the save operation onto Magento's message queue and processes it in the background via a long-running PHP consumer.

---

### Features

- Async product save via `Magento_MessageQueue` — no browser timeout
- Full support for:
  - Simple and configurable products
  - Variation creation and sync (status, price, qty, images)
  - Media gallery — new uploads, role assignment, image removal
  - Tier prices
  - Custom options
  - Related / upsell / cross-sell links
  - Category assignments
  - Website assignments
  - Stock (qty, in-stock flag)
- Admin queue log grid — see pending, processing, success, and failed jobs
- Nightly cleanup cron — removes completed queue messages automatically (keeps DB size in check)
- CLI status command: `bin/magento mohan:product-queue:status`

---

### Requirements

| Dependency | Version |
|------------|---------|
| PHP | ≥ 8.1 |
| Magento | 2.4.x |
| `magento/module-catalog` | * |
| `magento/module-configurable-product` | * |
| `magento/module-catalog-inventory` | * |

---

### Installation

#### Via Composer (recommended)

```bash
composer require mohan-devstack/magento2-product-queue-save
php bin/magento module:enable Mohan_ProductQueueSave
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush
```

#### Manual

1. Copy the `Mohan/ProductQueueSave` directory into `app/code/Mohan/ProductQueueSave/`
2. Run:

```bash
php bin/magento module:enable Mohan_ProductQueueSave
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush
```

---

### Configuration

Go to **Stores → Configuration → Mohan → Product Queue Save**.

| Setting | Description | Default |
|---------|-------------|---------|
| Enable Module | Show/hide the queue save button | Yes |
| Max Retry Attempts | How many times a failed job is retried | 3 |

---

### Starting the Queue Consumer

The consumer is a long-running PHP process. Start it on your server:

```bash
php bin/magento queue:consumers:start mohan.product.queue.save.consumer
```

For production, manage it with **Supervisor** so it restarts automatically on crash:

```ini
[program:mohan_product_queue]
command=php /var/www/html/magento/bin/magento queue:consumers:start mohan.product.queue.save.consumer
user=www-data
autostart=true
autorestart=true
stderr_logfile=/var/log/mohan_product_queue.err.log
stdout_logfile=/var/log/mohan_product_queue.out.log
```

---

### Usage

1. Open any product in the Magento admin.
2. Make your changes.
3. Click **"Save via Queue & Close"** (next to the standard Save button).
4. You are redirected to the product grid immediately — the save happens in the background.
5. Monitor progress at **Catalog → Product Queue Log**.

---

### Queue Log Grid

The admin grid at **Catalog → Product Queue Log** shows every queued save with:

- Product ID and SKU
- Status: `pending` → `processing` → `success` / `failed`
- Timestamp and error message (on failure)

---

### How It Works

```
[Admin clicks button]
        │
        ▼
Controller (Queue/Save)
  → Collects full product POST data
  → Publishes JSON message to queue topic: mohan.product.queue.save
  → Returns success immediately → browser redirects to grid
        │
        ▼
Queue Consumer (long-running CLI process)
  → Unserializes message
  → Loads existing product from repository
  → Applies: stock, tier prices, links, custom options, gallery, categories
  → productRepository->save()
  → For configurables: creates/syncs child variations, saves images per variation
  → Marks log entry as success / failed
```

#### Why not just use standard save?

Magento's synchronous product save can take 30–120 seconds for:
- Configurable products with 50+ variations
- Products with large media galleries (100+ images)
- Catalogues with deep category trees

This module moves that work off the HTTP request entirely.

---

### Database Table

The module creates one table: **`mohan_product_queue_log`**

| Column | Type | Description |
|--------|------|-------------|
| `log_id` | int | Primary key |
| `message_id` | varchar(64) | Unique queue message ID |
| `product_id` | int | Catalog product entity ID |
| `sku` | varchar(64) | Product SKU |
| `status` | varchar(32) | pending / processing / success / failed / retry |
| `store_id` | smallint | Store scope of the save |
| `admin_user_id` | int | Admin who triggered the save |
| `error_message` | text | Error detail on failure |
| `retry_count` | smallint | Number of retries attempted |
| `created_at` | timestamp | When the job was queued |
| `processed_at` | timestamp | When it completed |

---

### Cleanup Cron

A nightly cron (`0 3 * * *`) automatically:

1. Deletes completed `queue_message` / `queue_message_status` rows for this module's queue — `queue_message.body` is `longtext` and grows large with image data.
2. Trims `mohan_product_queue_log`: success entries older than **30 days**, failed/retry entries older than **90 days**.

---

### CLI Command

Check queue status from the command line:

```bash
php bin/magento mohan:product-queue:status
```

---

### Known Limitations

_(README truncated for .md surface. Full README on https://packagento.com/mohan-devstack/magento2-product-queue-save.)_

## Recent Versions

| Version | Released |
|---|---|
| v1.0.0 | 2026-07-10 |

## Dependencies

### Require

| Package | Constraint |
|---|---|
| magento/framework | * |
| magento/module-backend | * |
| magento/module-catalog | * |
| magento/module-catalog-inventory | * |
| magento/module-configurable-product | * |
| magento/module-store | * |
| php | >=8.1 |

## Quality

Latest release (v1.0.0) 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 | 57 | 2 errors, 55 warnings (ruleset: Magento2), 30 auto-fixable with phpcbf |
| PHPMD | Pass | 0 |  |
| Cpd | Pass | 0 |  |
| Composer validate | Info | 6 | valid; 6 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 | 30 | 30 | – | – |
| 2.4.8 | – | 31 | 31 | – |
| 2.4.9 | – | – | 31 | 31 |


### 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=["mohan-devstack/magento2-product-queue-save"],
  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

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

