PHP code example of quellabs / discover

1. Go to this page and download the library: Download quellabs/discover library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

quellabs / discover example snippets


use Quellabs\Discover\Discover;
use Quellabs\Discover\Scanner\ComposerScanner;
use Quellabs\Discover\Scanner\DirectoryScanner;

// Create a Discover instance
$discover = new Discover();

// Configure scanners to discover providers
$discover->addScanner(new ComposerScanner());
$discover->addScanner(new DirectoryScanner([
    __DIR__ . '/app/Providers'
], '/Provider$/'));

// Run the discovery process (gathers metadata without instantiation)
$discover->discover();

// Use the fluent query builder to find specific providers
$cacheProviders = $discover->findProviders()
    ->withCapability('redis')
    ->withMinPriority(5)
    ->get();

foreach ($cacheProviders as $provider) {
    // Register with your container or use directly
    $yourContainer->register($provider);
}



namespace App\Providers;

use Quellabs\Discover\Provider\AbstractProvider;

class ExampleServiceProvider extends AbstractProvider {

    /**
     * Get metadata about this provider's capabilities (static method)
     * @return array<string, mixed>
     */
    public static function getMetadata(): array {
        return [
            'capabilities' => ['redis', 'clustering'],
            'version'      => '1.0.0',
            'priority'     => 10
        ];
    }
}

interface ProviderInterface {
    
    // Static methods for discovery (no instantiation needed)
    public static function getMetadata(): array;
    
    // Instance methods for runtime configuration
    public function setConfig(array $config): void;
    public function getConfig(): array;
}

$discover->addScanner(new ComposerScanner('default'));

$discover->addScanner(new DirectoryScanner([
    __DIR__ . '/app/Providers',
    __DIR__ . '/src/Providers'
], '/Provider$/', 'cache')); // Pattern and family name

interface MetadataScannerInterface {
    // The family name this scanner reads from (e.g. 'canvas')
    public function getFamilyName(): string;

    // Returns all metadata for this family, grouped by package name
    // e.g. ['vendor/pkg' => ['controllers' => 'src/Controllers', ...]]
    public function collect(): array;
}

use Quellabs\Discover\Discover;
use Quellabs\Discover\Scanner\ComposerScanner;
use Quellabs\Discover\Scanner\MetadataCollector;

$discover = new Discover();

// Provider scanner and metadata scanner can coexist
$discover->addScanner(new ComposerScanner('canvas'));
$discover->addScanner(new MetadataCollector('canvas'));

$discover->discover();

new MetadataCollector(
    familyName: 'canvas',          // Required: the family to read
    discoverySection: 'discover',  // Optional: top-level key in extra (default: 'discover')
    logger: $logger,               // Optional: PSR-3 logger for non-fatal warnings
    strictMode: false              // Optional: throw exceptions instead of logging warnings
);

$all = $discover->getAllMetadata();
// [
//   'canvas' => [
//     'vendor/controllers-pkg' => ['controllers' => ['src/Controllers', 'src/Api']],
//     'vendor/middleware-pkg'  => ['middleware' => 'src/Middleware'],
//   ]
// ]

$canvasMeta = $discover->getFamilyMetadata('canvas');
// [
//   'vendor/controllers-pkg' => ['controllers' => ['src/Controllers', 'src/Api']],
//   'vendor/middleware-pkg'  => ['middleware' => 'src/Middleware'],
// ]

foreach ($canvasMeta as $packageName => $packageData) {
    $dirs = (array)($packageData['controllers'] ?? []);
    // resolve $dirs relative to $packageName's install path
}

$controllerDirs = $discover->getFamilyValues('canvas', 'controllers');
// ['src/Controllers', 'src/Api', 'vendor/other-pkg/src/Controllers']

$middlewareDirs = $discover->getFamilyValues('canvas', 'middleware');
// ['src/Middleware']

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('discover');
$logger->pushHandler(new StreamHandler('php://stderr'));

// Log warnings but continue on bad entries
$discover->addScanner(new MetadataCollector('canvas', 'discover', $logger));

// Throw on first malformed entry
$discover->addScanner(new MetadataCollector('canvas', 'discover', $logger, strictMode: true));

use Quellabs\Discover\Scanner\MetadataScannerInterface;

class DatabaseMetadataScanner implements MetadataScannerInterface {

    public function getFamilyName(): string {
        return 'canvas';
    }

    public function collect(): array {
        // Return data grouped by a logical "package" identifier
        return [
            'app/core' => [
                'controllers' => ['src/Controllers'],
                'middleware'  => ['src/Middleware'],
            ],
        ];
    }
}

$discover->addScanner(new DatabaseMetadataScanner());
$discover->discover();

// Find Redis providers with high priority
$providers = $discover->findProviders()
    ->withCapability('redis')
    ->withMinPriority(10)
    ->get();

// Find database providers in a specific family
$dbProviders = $discover->findProviders()
    ->withFamily('database')
    ->get();

// Combine multiple filters
$providers = $discover->findProviders()
    ->withCapability('clustering')
    ->withFamily('cache')
    ->withMinPriority(5)
    ->get();

// Custom filter example
$providers = $discover->findProviders()
    ->withFamily('cache')
    ->where(fn($meta) => isset($meta['region']) && $meta['region'] === 'us-east-1')
    ->lazy();

// Get a specific provider by class name (O(1) lookup)
$provider = $discover->get('App\\Providers\\RedisProvider');

// Check if a provider exists
if ($discover->exists('App\\Providers\\RedisProvider')) {
    // Provider is available
}

// Get the definition for a provider (metadata without instantiation)
$definition = $discover->getDefinition('App\\Providers\\RedisProvider');

// Get all providers (warning: instantiates everything)
foreach ($discover->getProviders() as $provider) {
    // Use provider
}

// First request: discover and cache
$discover = new Discover();
$discover->addScanner(new ComposerScanner());
$discover->discover();

$cache->set('providers_' . md5_file('composer.lock'), $discover->exportForCache());

// Subsequent requests: skip discovery
$discover = new Discover();
$discover->importDefinitionsFromCache($cache->get($cacheKey));

// config/providers/example.php
return [
    'option1' => 'value1',
    'option2' => 'value2',
    'enabled' => true,
    // Any configuration your provider needs
];

class ExampleServiceProvider extends \Quellabs\Discover\Provider\AbstractProvider {

    public function getServiceOptions(): array {
        return [
            'option1' => $this->config['option1'],
            'option2' => $this->config['option2'],
        ];
    }
}

$discover = new Discover();
$discover->addScanner(new ComposerScanner('database'));
$discover->addScanner(new ComposerScanner('cache'));
$discover->discover();

// Query by family
$databaseProviders = $discover->findProviders()
    ->withFamily('database')
    ->get();

$cacheProviders = $discover->findProviders()
    ->withFamily('cache')
    ->get();



namespace App\Discovery;

use Quellabs\Contracts\Discovery\ProviderDefinition;
use Quellabs\Discover\Scanner\ScannerInterface;

class CustomScanner implements ScannerInterface {
    public function scan(): array {
        // Your custom discovery logic
        // Return an array of ProviderDefinition objects
        return [
            new ProviderDefinition(
                className: 'App\\Providers\\CustomProvider',
                family: 'custom',
                configFiles: ['config/custom.php'],
                metadata: ['capability' => 'special'],
                defaults: ['enabled' => true]
            )
        ];
    }
}