PHPackages                             groupone/marketplace - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. groupone/marketplace

ActiveLibrary[Admin Panels](/categories/admin)

groupone/marketplace
====================

Embeddable React-based marketplace UI for WordPress plugins. Consumed via Composer + Mozart; ships a webpack-built frontend and an MVC PHP backend.

2.0.5(1mo ago)0503↑733.3%[12 PRs](https://github.com/One-com/wp-marketplace/pulls)GPL-2.0-or-laterJavaScriptPHP &gt;=7.4CI passing

Since Oct 16Pushed 2w agoCompare

[ Source](https://github.com/One-com/wp-marketplace)[ Packagist](https://packagist.org/packages/groupone/marketplace)[ Docs](https://github.com/One-com/wp-marketplace)[ RSS](/packages/groupone-marketplace/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (4)DependenciesVersions (78)Used By (0)

Marketplace Module
==================

[](#marketplace-module)

A reusable WordPress plugin module for managing and displaying a marketplace of plugins with a React frontend and PHP backend. Designed to be embedded into other plugins while providing install/activate functionality and a REST API.

---

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation with Mozart ](#installation-with-mozart-recommended-for-distributable-plugins)
- [Configuration Options](#configuration-options)
- [Assets Path Configuration](#assets-path-configuration)
- [How It Works](#how-it-works)
- [Asset Copying](#asset-copying)
- [Releasing a New Version](#releasing-a-new-version)

---

Features
--------

[](#features)

- React-based frontend for displaying plugin listings
- Backend PHP controller &amp; model to handle API requests and install/activate actions
- Works inside WordPress Admin and can be used in React apps
- REST API endpoint for fetching plugin data
- Flexible CSS loading – custom or default styles
- Composer-ready with PSR-4 autoloading
- Mozart-compatible for distribution and wrapping namespaces to avoid conflicts

---

Requirements
------------

[](#requirements)

- PHP &gt;= 7.4
- WordPress &gt;= 6.2
- Composer (for development and building)
- Mozart (for wrapping namespaces and copying assets)

---

Installation with Mozart (Recommended for Distributable Plugins)
----------------------------------------------------------------

[](#installation-with-mozart-recommended-for-distributable-plugins)

This module is designed to work when your plugin uses the Mozart tool to prefix namespaces and copy assets at build time.

Step-by-step

1. Add repository details (under repositories) and other dependencies to your plugin's composer.json

`Note:` Example of a complete composer.json (replace `YourPlugin` with your plugin's namespace and path in`copy-assets` where you want to copy assets ):

```
{
  "name": "",
  "type": "",
  "require": {
    "php": ">=7.4",
    "groupone/marketplace": "^1.0"
  },
  "repositories": [
    { "type": "vcs", "url": "git@github.com:One-com/wp-marketplace.git" }
  ],
  "require-dev": {
    "coenjacobs/mozart": "^0.7"
  },
  "autoload": {
    "psr-4": {
      "YourPlugin\\Dependencies\\": "/inc/Dependencies/YourPlugin/"
    },
    "classmap": [
      "inc/Dependencies/YourPlugin/"
    ]
  },
  "extra": {
    "mozart": {
      "dep_namespace": "YourPlugin\\Dependencies\\",
      "dep_directory": "/inc/Dependencies/YourPlugin/",
      "classmap_directory": "/inc/Dependencies/YourPlugin/",
      "packages": [
        "groupone/marketplace"
      ],
      "delete_vendor_directories": false
    }
  },
  "scripts": {
    "post-install-cmd": [
      "@mozart-compose",
      "@copy-assets",
      "composer dump-autoload -o"
    ],
    "post-update-cmd": [
      "@mozart-compose",
      "@copy-assets",
      "composer dump-autoload -o"
    ],
    "mozart-compose": [
      "[ -f vendor/bin/mozart ] && php vendor/bin/mozart compose || echo 'Mozart not found, skipping...'"
    ],
    "copy-assets": [
      "mkdir -p inc/Dependencies/YourPlugin/Groupone/Marketplace/frontend",
      "mkdir -p inc/Dependencies/YourPlugin/Groupone/Marketplace/assets",
      "[ -d vendor/groupone/marketplace/frontend ] && rsync -a vendor/groupone/marketplace/frontend/ inc/Dependencies/YourPlugin/Groupone/Marketplace/frontend/ || true",
      "[ -d vendor/groupone/marketplace/assets ] && rsync -a vendor/groupone/marketplace/assets/ inc/Dependencies/YourPlugin/Groupone/Marketplace/assets/ || true"
    ]
  },
  "config": {
    "allow-plugins": {
      "composer/installers": true
    }
  }
}
```

2. Install dependencies and run Mozart

When adding this module to a plugin that already has a `composer.json` and `composer.lock`:

- First time (after adding the dependency): run `composer update groupone/marketplace` to update your lock file and install the package. You can also run `composer update` if you want to update all dependencies.
- On CI or environments using an existing lock file: run `composer install`.

Either command will trigger the defined Composer scripts (mozart-compose and copy-assets).

Examples:

```
# First time after adding groupone/marketplace
composer update groupone/marketplace
# or update everything (broader)
composer update
```

```
# Subsequent installs when composer.lock is present (CI, deployments)
composer install
```

3. Bootstrap the module in your plugin code(replace `YourPlugin` with your plugin's namespace)

```
// Composer autoloader registers both your plugin classes and the Mozart-prefixed dependencies
require_once __DIR__ . '/vendor/autoload.php';

// Using the Mozart-prefixed class name after Composer autoload is registered
'\YourPlugin\Dependencies\Groupone\Marketplace\Marketplace'::run([
    'parent_menu_slug' => 'your-menu-slug',
    'page_title'       => 'Plugin Marketplace',
    'menu_title'       => 'Marketplace',
    'menu_slug'        => 'plugin-marketplace',
    'addons_menu_slug' => 'your-addons-menu-slug', // Optional: slug for your addons page
    'addons_page_title' => 'Your Add-ons',        // Optional: page title for your addons page
    'addons_menu_title' => 'Your Add-ons',        // Optional: menu title for your addons page
    'api_url'          => 'https://example.com/marketplace.json',
    'brand'            => 'your_brand_name', // Optional: brand identifier for API filtering
    'payload'          => [                  // Optional: request body data for API payload
        'locale' => 'en_US',
        'action'     => '',
    ],
    // Optional: Explicitly set assets path if auto-detection doesn't work
    'assets_path'      => __DIR__ . '/inc/Dependencies/YourPlugin/Groupone/Marketplace/',
    'mixp_props'       => [ 'is_sandbox' => false ], // Optional: custom Mixpanel properties. 'is_sandbox' => true can be used for testing.
    'mixp_distinct_id' => '',                // Optional: distinct ID for Mixpanel tracking
    'data_consent_status' => false,          // Optional: user data consent status
]);
```

---

Configuration Options
---------------------

[](#configuration-options)

- `parent_menu_slug`: WordPress menu slug under which the module submenu will be added. Default: options-general.php
- `page_title`: Page title for the Marketplace screen. Default: Plugin Marketplace
- `menu_title`: Menu title for the submenu. Default: Marketplace
- `menu_slug`: Slug used for the submenu and page. Default: plugin-marketplace
- `addons_menu_slug`: Slug used for the addons submenu and page. Default: onecom-marketplace-products
- `addons_page_title`: Page title for the your add-ons screen. Default: Marketplace Products
- `addons_menu_title`: Menu title for the your add-ons submenu. Default: Your add-ons
- `api_url`: External API endpoint returning marketplace data. Default: ""
- `brand`: Optional brand identifier used when constructing marketplace API requests. Can be used to filter or customize marketplace content based on brand. Default: ""
- `payload`: Optional key-value array passed in the request body for API authentication when fetching plugins. Can be used to include authentication tokens, API keys, or other custom data required by the marketplace API. Default: \[\]
- `css_url`: URL to a custom CSS file that styles the frontend. Default: ""
- `css_handle`: WordPress style handle when registering/enqueuing styles. Default: marketplace-frontend-style
- `assets_path`: Filesystem path to the package root containing the frontend/ directory. If empty, the module auto-detects it (see below).
- `register_menu`: Boolean flag to control automatic menu registration. Set to `false` to skip menu registration when your plugin handles it manually (prevents duplicate menus). Default: true
- `mixp_props`: Optional key-value array for custom Mixpanel properties. Used to send additional tracking data. Including `'is_sandbox' => true` will switch the tracking to the sandbox Mixpanel project. Default: \[\]
- `mixp_distinct_id`: Optional string for Mixpanel tracking to identify a unique user. Default: ""
- `data_consent_status`: Boolean flag for user data consent. Controls whether tracking is enabled. Default: false

---

Assets Path Configuration
-------------------------

[](#assets-path-configuration)

- Explicit: Pass `assets_path` in the config.`(optional) if you are not following the path as mentioned in composer json & moved assets to a custom path`Example:

```
'\YourPlugin\Dependencies\Groupone\Marketplace\Marketplace'::run([
  'assets_path' => WP_PLUGIN_DIR . '/your-plugin/inc/Dependencies/YourPlugin/assets/'
]);
```

---

How It Works
------------

[](#how-it-works)

When booted, the module:

- Registers a submenu page under the provided `parent_menu_slug`
- Enqueues the React frontend (`frontend/build` assets)
- Localizes configuration and labels to JavaScript
- Registers a REST route at `/wp-json/marketplace/v1/plugins`
- Provides AJAX handlers to install, activate, and deactivate plugins

---

Asset Copying
-------------

[](#asset-copying)

How to reference assets

- If you keep the default structure suggested in the example `composer.json`, `assets_path` can be omitted because auto-detection will locate the package root.
- If you move files to a custom location, pass `assets_path` explicitly so the module can find `frontend/build/index.js` and related files.

---

Releasing a New Version
-----------------------

[](#releasing-a-new-version)

Releases are **tag-driven and automated**. `composer.json` (`version` field) is the single source of truth for the version — you never create a Git tag by hand.

### The flow

[](#the-flow)

```
bump composer.json version → open PR → merge to master
        → auto-tag.yml creates & pushes vX.Y.Z
        → Packagist webhook indexes the tag (version available via Composer)
        → CI/CD release job builds the GitHub Release artifact for the tag

```

### How to cut a release

[](#how-to-cut-a-release)

1. In a branch, bump the `version` field in [`composer.json`](composer.json), following [semver](https://semver.org/) (e.g. `2.0.3` → `2.1.0`).
2. Open a PR and merge it to `master`.
3. On merge, the **Auto Tag Release** workflow ([`.github/workflows/auto-tag.yml`](.github/workflows/auto-tag.yml)) reads the version from `composer.json`, and if no matching tag exists it creates and pushes an annotated tag `vX.Y.Z`.
4. Packagist, connected to this repo via GitHub webhook, picks up the new tag and makes the version installable with `composer require groupone/marketplace`. No manual Packagist steps are needed.
5. The `release` job in [`.github/workflows/ci.yml`](.github/workflows/ci.yml) triggers on the new tag and builds the GitHub Release archive (`wp-marketplace-X.Y.Z.zip`).

### Notes &amp; guarantees

[](#notes--guarantees)

- **Idempotent.** If a tag for the current `composer.json` version already exists, `auto-tag.yml` exits cleanly without creating a duplicate or failing.
- **No version change → no tag.** Merging changes that don't bump the version produces no new tag.
- **Single tagger.** Only `auto-tag.yml` creates tags. The CI release job builds artifacts for an already-pushed tag, so the two never race.
- **Packagist resolves from the Git tag, not the `version` field.** Composer warns that a hard-coded `version` field is discouraged for Packagist-published packages — here it is used solely as the CI trigger source. Packagist still derives the released version from the Git tag, so the two always agree.
- **Tagging does not wait for CI.** Version bumps go through PR CI before merge, so the tagged commit on `master` has already passed checks.

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance95

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Recently: every ~11 days

Total

15

Last Release

14d ago

Major Versions

v1.8.0 → v2.0.02026-05-15

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/44494705?v=4)[Robin Chalia](/maintainers/robinc2402)[@robinc2402](https://github.com/robinc2402)

![](https://avatars.githubusercontent.com/u/25048361?v=4)[Dineshkashera](/maintainers/dineshkashera)[@dineshkashera](https://github.com/dineshkashera)

![](https://avatars.githubusercontent.com/u/88835518?v=4)[akshat-trigunait](/maintainers/akshat-trigunait)[@akshat-trigunait](https://github.com/akshat-trigunait)

---

Top Contributors

[![akshat-trigunait](https://avatars.githubusercontent.com/u/88835518?v=4)](https://github.com/akshat-trigunait "akshat-trigunait (388 commits)")[![dineshk-onecom](https://avatars.githubusercontent.com/u/94354933?v=4)](https://github.com/dineshk-onecom "dineshk-onecom (54 commits)")[![deepakrajpal-one](https://avatars.githubusercontent.com/u/28049244?v=4)](https://github.com/deepakrajpal-one "deepakrajpal-one (40 commits)")[![dineshkashera1107](https://avatars.githubusercontent.com/u/148935242?v=4)](https://github.com/dineshkashera1107 "dineshkashera1107 (26 commits)")[![robinc2402](https://avatars.githubusercontent.com/u/44494705?v=4)](https://github.com/robinc2402 "robinc2402 (3 commits)")

---

Tags

wordpresspluginsreactmarketplaceadmin-uiembeddablemozart

### Embed Badge

![Health badge](/badges/groupone-marketplace/health.svg)

```
[![Health](https://phpackages.com/badges/groupone-marketplace/health.svg)](https://phpackages.com/packages/groupone-marketplace)
```

###  Alternatives

[alleyinteractive/wordpress-fieldmanager

A library to build forms and admin screens for WordPress

563794.7k3](/packages/alleyinteractive-wordpress-fieldmanager)[backpack/pagemanager

Create admin panels for presentation websites on Laravel, using page templates and Backpack\\CRUD.

376543.9k6](/packages/backpack-pagemanager)[soberwp/intervention

WordPress plugin containing modules to cleanup and customize wp-admin.

642120.8k1](/packages/soberwp-intervention)[awcodes/filament-quick-create

Plugin for Filament Admin that adds a dropdown menu to the header to quickly create new items.

249220.8k12](/packages/awcodes-filament-quick-create)[wp-user-manager/wp-optionskit

A toolkit for developers to create administration options panels for WordPress powered by Vuejs

13714.2k](/packages/wp-user-manager-wp-optionskit)[upstatement/jigsaw

Provides an easy API for developers to tweak the admin options of a WordPress install

1563.4k](/packages/upstatement-jigsaw)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
