User Docs Developer Docs | |

Vetting & Approval

Widgets flagged as malicious by the vetting system are blocked from activation. The pv_safe column (renamed from pv_safe) controls this.

Every extension submitted to the Pubvana Marketplace goes through a manual review process before receiving an approval flag. The pv_safe column in the themes, plugins, and widgets tables records this state locally.

Approval States

State pv_safe Admin UI indicator
Safe 1 Green badge
Not Safe 0 Yellow warning banner
Unchecked null Grey — API unreachable or not yet checked

Unapproved extensions can still be activated and used. The pv_safe = 0 state triggers a warning in the admin panel but does not block operation.

VettingService

VettingService runs automatically during PluginManager::discover(), ThemeService::discover(), and WidgetService::discover(). It POSTs the extension slug and type to pubvana.net/api/marketplace/vetting and stores the returned approval status.

If the API is unreachable, the existing pv_safe value is preserved (not reset to null). Vetting is also re-run on each activation attempt.

Approval Criteria

The Pubvana team evaluates submissions against these criteria:

Security

  • No eval(), exec(), shell_exec(), system(), passthru(), or equivalent
  • No direct file writes outside designated directories (writable/, plugin's own directory)
  • No outbound HTTP calls from PHP to unannounced endpoints (declared update_url / support_url are acceptable)
  • All user input processed through CI4 validation or the query builder parameterisation
  • No storing of credentials in code

Code Quality

  • Follows MVC conventions (plugins)
  • No raw SQL unless absolutely necessary; uses CI4 Query Builder
  • Proper use of CI4 migrations for schema changes (plugins)
  • No hardcoded database table names without the $db->prefixTable() method

Manifest Compliance

  • version is valid semver
  • min_pubvana_version is set and accurate
  • update_url is a reachable HTTPS endpoint (if provided)

Functionality

  • Extension installs and uninstalls cleanly (for plugins: Installer::install() and uninstall() are tested)
  • No conflicts with core table names (plugin tables must be prefixed)
  • Screenshots accurately represent the extension

Activating Unapproved Extensions

Site admins can force-activate a not-approved plugin:

// Admin controller
$result = PluginManager::instance()->activate($folder, force: true);

The force: true parameter bypasses the requires_confirmation status. A warning is logged to activity_logs. This is intended for self-hosted, privately developed extensions that will never be submitted to the marketplace.