4cc3f5bee4
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (push) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Blocked by required conditions
Platform: moko-platform CI / Gate 4: Governance (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Successful in 5s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 6s
Generic: Repo Health / Release configuration (push) Successful in 5s
Generic: Repo Health / Scripts governance (push) Successful in 5s
Generic: Repo Health / Release configuration (pull_request) Successful in 6s
Generic: Repo Health / Scripts governance (pull_request) Successful in 6s
Generic: Repo Health / Repository health (push) Successful in 14s
Generic: Repo Health / Repository health (pull_request) Successful in 12s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Failing after 44s
Platform: moko-platform CI / Gate 1: Code Quality (push) Failing after 49s
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Has been skipped
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been skipped
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Platform: moko-platform CI / CI Summary (pull_request) Has been cancelled
- Convert tabs to spaces (3,413 violations) - Fix line endings, trailing whitespace, brace placement - Break lines exceeding 150-char absolute limit - Replace heredoc tab closers with spaces - Fix empty elseif, forbidden function calls - Update phpcs.xml: exclude rules inappropriate for CLI scripts (SideEffects, MissingNamespace, MultipleClasses, HeaderOrder, empty catch blocks) Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
334 lines
9.7 KiB
PHP
334 lines
9.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
*
|
|
* This file is part of a Moko Consulting project.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* FILE INFORMATION
|
|
* DEFGROUP: MokoStandards.Enterprise.Plugins
|
|
* INGROUP: MokoStandards.Enterprise
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
|
* PATH: /lib/Enterprise/PluginFactory.php
|
|
* BRIEF: Plugin factory for project type detection
|
|
*/
|
|
|
|
namespace MokoEnterprise;
|
|
|
|
/**
|
|
* Plugin Factory - Factory for creating and managing plugin instances
|
|
*
|
|
* Provides convenient methods for plugin instantiation with dependency injection
|
|
*
|
|
* @package MokoStandards\Enterprise
|
|
* @version 1.0.0
|
|
*/
|
|
class PluginFactory
|
|
{
|
|
/** @var AuditLogger */
|
|
private $logger;
|
|
|
|
/** @var MetricsCollector */
|
|
private $metricsCollector;
|
|
|
|
/** @var array Default configuration for plugins */
|
|
private $defaultConfig;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param AuditLogger|null $logger Optional audit logger
|
|
* @param MetricsCollector|null $metricsCollector Optional metrics collector
|
|
* @param array $defaultConfig Default configuration for all plugins
|
|
*/
|
|
public function __construct(
|
|
?AuditLogger $logger = null,
|
|
?MetricsCollector $metricsCollector = null,
|
|
array $defaultConfig = []
|
|
) {
|
|
$this->logger = $logger ?? new AuditLogger('plugin_factory');
|
|
$this->metricsCollector = $metricsCollector ?? new MetricsCollector();
|
|
$this->defaultConfig = $defaultConfig;
|
|
|
|
// Set shared instances in registry
|
|
PluginRegistry::setLogger($this->logger);
|
|
PluginRegistry::setMetricsCollector($this->metricsCollector);
|
|
}
|
|
|
|
/**
|
|
* Create plugin for a project type
|
|
*
|
|
* @param string $projectType Project type identifier
|
|
* @param array $config Optional plugin-specific configuration
|
|
* @return ProjectPluginInterface|null Plugin instance or null if not found
|
|
*/
|
|
public function create(string $projectType, array $config = []): ?ProjectPluginInterface
|
|
{
|
|
$config = array_merge($this->defaultConfig, $config);
|
|
return PluginRegistry::getPlugin($projectType, $config);
|
|
}
|
|
|
|
/**
|
|
* Create plugin for a project by auto-detecting type
|
|
*
|
|
* @param string $projectPath Path to project directory
|
|
* @param array $config Optional plugin-specific configuration
|
|
* @return ProjectPluginInterface|null Plugin instance or null if type can't be detected
|
|
*/
|
|
public function createForProject(string $projectPath, array $config = []): ?ProjectPluginInterface
|
|
{
|
|
$detector = new ProjectTypeDetector($this->logger);
|
|
$detection = $detector->detect($projectPath);
|
|
|
|
if (empty($detection['type'])) {
|
|
$this->logger->logWarning('Could not detect project type', [
|
|
'project_path' => $projectPath,
|
|
'detection_result' => $detection,
|
|
]);
|
|
return null;
|
|
}
|
|
|
|
$projectType = $detection['type'];
|
|
$this->logger->logInfo("Detected project type: {$projectType}", [
|
|
'project_path' => $projectPath,
|
|
'confidence' => $detection['confidence'] ?? 0,
|
|
]);
|
|
|
|
return $this->create($projectType, $config);
|
|
}
|
|
|
|
/**
|
|
* Create all available plugins
|
|
*
|
|
* @param array $config Optional configuration for all plugins
|
|
* @return array<string, ProjectPluginInterface> Map of project types to plugin instances
|
|
*/
|
|
public function createAll(array $config = []): array
|
|
{
|
|
$config = array_merge($this->defaultConfig, $config);
|
|
return PluginRegistry::getAllPlugins($config);
|
|
}
|
|
|
|
/**
|
|
* Create multiple plugins
|
|
*
|
|
* @param array $projectTypes List of project type identifiers
|
|
* @param array $config Optional configuration for plugins
|
|
* @return array<string, ProjectPluginInterface> Map of project types to plugin instances
|
|
*/
|
|
public function createMultiple(array $projectTypes, array $config = []): array
|
|
{
|
|
$config = array_merge($this->defaultConfig, $config);
|
|
$plugins = [];
|
|
|
|
foreach ($projectTypes as $projectType) {
|
|
$plugin = $this->create($projectType, $config);
|
|
if ($plugin !== null) {
|
|
$plugins[$projectType] = $plugin;
|
|
}
|
|
}
|
|
|
|
return $plugins;
|
|
}
|
|
|
|
/**
|
|
* Validate and create plugin
|
|
*
|
|
* @param string $projectType Project type identifier
|
|
* @param string $projectPath Path to project directory
|
|
* @param array $projectConfig Project configuration
|
|
* @return array Result with 'plugin' (ProjectPluginInterface|null) and 'validation' (array)
|
|
*/
|
|
public function createAndValidate(
|
|
string $projectType,
|
|
string $projectPath,
|
|
array $projectConfig = []
|
|
): array {
|
|
$plugin = $this->create($projectType);
|
|
|
|
if ($plugin === null) {
|
|
return [
|
|
'plugin' => null,
|
|
'validation' => [
|
|
'valid' => false,
|
|
'errors' => ["Plugin not found for project type: {$projectType}"],
|
|
'warnings' => [],
|
|
],
|
|
];
|
|
}
|
|
|
|
$validation = $plugin->validateProject($projectConfig, $projectPath);
|
|
|
|
return [
|
|
'plugin' => $plugin,
|
|
'validation' => $validation,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get factory statistics
|
|
*
|
|
* @return array Factory and registry statistics
|
|
*/
|
|
public function getStatistics(): array
|
|
{
|
|
return [
|
|
'factory' => [
|
|
'has_logger' => $this->logger !== null,
|
|
'has_metrics_collector' => $this->metricsCollector !== null,
|
|
'default_config_keys' => array_keys($this->defaultConfig),
|
|
],
|
|
'registry' => PluginRegistry::getStatistics(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get all available plugin information
|
|
*
|
|
* @return array Map of project types to plugin information
|
|
*/
|
|
public function getAvailablePlugins(): array
|
|
{
|
|
return PluginRegistry::getAllPluginsInfo();
|
|
}
|
|
|
|
/**
|
|
* Check if a plugin is available for a project type
|
|
*
|
|
* @param string $projectType Project type identifier
|
|
* @return bool True if plugin is available
|
|
*/
|
|
public function hasPlugin(string $projectType): bool
|
|
{
|
|
return PluginRegistry::hasPlugin($projectType);
|
|
}
|
|
|
|
/**
|
|
* Get the logger instance
|
|
*
|
|
* @return AuditLogger
|
|
*/
|
|
public function getLogger(): AuditLogger
|
|
{
|
|
return $this->logger;
|
|
}
|
|
|
|
/**
|
|
* Get the metrics collector instance
|
|
*
|
|
* @return MetricsCollector
|
|
*/
|
|
public function getMetricsCollector(): MetricsCollector
|
|
{
|
|
return $this->metricsCollector;
|
|
}
|
|
|
|
/**
|
|
* Set default configuration for all plugins
|
|
*
|
|
* @param array $config Default configuration
|
|
* @return void
|
|
*/
|
|
public function setDefaultConfig(array $config): void
|
|
{
|
|
$this->defaultConfig = $config;
|
|
}
|
|
|
|
/**
|
|
* Get default configuration
|
|
*
|
|
* @return array Default configuration
|
|
*/
|
|
public function getDefaultConfig(): array
|
|
{
|
|
return $this->defaultConfig;
|
|
}
|
|
|
|
/**
|
|
* Run health check using appropriate plugin
|
|
*
|
|
* @param string $projectType Project type identifier
|
|
* @param string $projectPath Path to project directory
|
|
* @param array $projectConfig Project configuration
|
|
* @return array Health check result
|
|
*/
|
|
public function runHealthCheck(
|
|
string $projectType,
|
|
string $projectPath,
|
|
array $projectConfig = []
|
|
): array {
|
|
$plugin = $this->create($projectType);
|
|
|
|
if ($plugin === null) {
|
|
return [
|
|
'healthy' => false,
|
|
'score' => 0,
|
|
'issues' => [
|
|
[
|
|
'severity' => 'critical',
|
|
'message' => "Plugin not found for project type: {$projectType}",
|
|
'category' => 'plugin',
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
return $plugin->healthCheck($projectPath, $projectConfig);
|
|
}
|
|
|
|
/**
|
|
* Collect metrics using appropriate plugin
|
|
*
|
|
* @param string $projectType Project type identifier
|
|
* @param string $projectPath Path to project directory
|
|
* @param array $projectConfig Project configuration
|
|
* @return array Metrics data
|
|
*/
|
|
public function collectMetrics(
|
|
string $projectType,
|
|
string $projectPath,
|
|
array $projectConfig = []
|
|
): array {
|
|
$plugin = $this->create($projectType);
|
|
|
|
if ($plugin === null) {
|
|
return [
|
|
'error' => "Plugin not found for project type: {$projectType}",
|
|
'metrics' => [],
|
|
];
|
|
}
|
|
|
|
return $plugin->collectMetrics($projectPath, $projectConfig);
|
|
}
|
|
|
|
/**
|
|
* Check project readiness using appropriate plugin
|
|
*
|
|
* @param string $projectType Project type identifier
|
|
* @param string $projectPath Path to project directory
|
|
* @param array $projectConfig Project configuration
|
|
* @return array Readiness result
|
|
*/
|
|
public function checkReadiness(
|
|
string $projectType,
|
|
string $projectPath,
|
|
array $projectConfig = []
|
|
): array {
|
|
$plugin = $this->create($projectType);
|
|
|
|
if ($plugin === null) {
|
|
return [
|
|
'ready' => false,
|
|
'blockers' => ["Plugin not found for project type: {$projectType}"],
|
|
'warnings' => [],
|
|
'score' => 0,
|
|
];
|
|
}
|
|
|
|
return $plugin->checkReadiness($projectPath, $projectConfig);
|
|
}
|
|
}
|