Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ Here is an example of a basic `events.php` file for handling an event:
<?php
return function (\App\EventDispatcher $dispatcher)
{
$dispatcher->addListener(\App\Event\BuildRoutes::NAME, function(\App\Event\BuildRoutes $event) {
$dispatcher->addListener(\App\Event\BuildRoutes::class, function(\App\Event\BuildRoutes $event) {
$app = $event->getApp();

// Modify the app's routes here
}, -5);
};
```

As you can see, each event's name is available as a constant on its class named `::NAME`, and each event listener receives an instance of that event class complete with relevant metadata already attached. Listeners also have a priority (the last argument in the function call); this number can be positive or negative, with the default handler tending to be around zero. Higher numbers are dispatched before lower numbers.
As you can see, each event listener that you register has to provide the event that it listens to as a callable to the `addListener` method's first parameter, and each event listener receives an instance of that event class complete with relevant metadata already attached. Listeners also have a priority (the last argument in the function call); this number can be positive or negative, with the default handler tending to be around zero. Higher numbers are dispatched before lower numbers.

Below is a listing of the events that can be overridden by plugins:

Expand Down
17 changes: 17 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "azuracast/example-plugin",
"description": "An example AzuraCast plugin, demonstrating the capabilities and common use-cases of the plugin system.",
"type": "azuracast-plugin",
"authors": [
{
"name": "Buster Neece",
"email": "buster@busterneece.com"
}
],
"autoload": {
"psr-4": {
"Plugin\\ExamplePlugin\\": "src"
}
},
"require": {}
}
64 changes: 35 additions & 29 deletions events.php
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
<?php
use Azura\Event;

return function (\Azura\EventDispatcher $dispatcher)
{
// Add the "example:list-stations" command to the CLI prompt.
$dispatcher->addListener(Event\BuildConsoleCommands::NAME, function (Event\BuildConsoleCommands $event) {
$event->getConsole()->addCommands([
new \Plugin\ExamplePlugin\Command\ListStations,
]);
}, -1);

// Tell the view handler to look for templates in this directory too
$dispatcher->addListener(Event\BuildView::NAME, function(Event\BuildView $event) {
$event->getView()->addFolder('example', __DIR__.'/templates');
});

// Add a new route handled exclusively by the plugin.
$dispatcher->addListener(Event\BuildRoutes::NAME, function(Event\BuildRoutes $event) {
$app = $event->getApp();

$app->get('/example', \Plugin\ExamplePlugin\Controller\HelloWorld::class)
->setName('example-plugin:index:index')
->add(\Azura\Middleware\EnableView::class);
});

// You can also add classes that implement the EventSubscriberInterface
$dispatcher->addSubscriber(new \Plugin\ExamplePlugin\EventHandler\AllTheListeners);
};
<?php

declare(strict_types=1);

use App\Event;

return function (\App\EventDispatcher $dispatcher)
{
// Add the "example:list-stations" command to the CLI prompt.
$dispatcher->addListener(Event\BuildConsoleCommands::class, function (Event\BuildConsoleCommands $event) {
$console = $event->getConsole();

$console->command(
'example:list-stations',
\Plugin\ExamplePlugin\Command\ListStations::class,
)->setDescription('An example function to list stations in a table view.');
}, -1);

// Tell the view handler to look for templates in this directory too
$dispatcher->addListener(Event\BuildView::class, function(Event\BuildView $event) {
$event->getView()->addFolder('example', __DIR__.'/templates');
});

// Add a new route handled exclusively by the plugin.
$dispatcher->addListener(Event\BuildRoutes::class, function(Event\BuildRoutes $event) {
$app = $event->getApp();

$app->get('/example', \Plugin\ExamplePlugin\Controller\HelloWorld::class)
->setName('example-plugin:index:index')
->add(\App\Middleware\EnableView::class);
});

// You can also add classes that implement the EventSubscriberInterface
$dispatcher->addSubscriber(new \Plugin\ExamplePlugin\EventHandler\AllTheListeners);
};
11 changes: 7 additions & 4 deletions services.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php
return function (\Azura\Container $di) {
// Add your own Dependency Injector services here
};
<?php

declare(strict_types=1);

return [
// Add your own Dependency Injector services here
];
125 changes: 54 additions & 71 deletions src/Command/ListStations.php
Original file line number Diff line number Diff line change
@@ -1,71 +1,54 @@
<?php
namespace Plugin\ExamplePlugin\Command;

use Azura\Console\Command\CommandAbstract;

class ListStations extends CommandAbstract
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setName('example:list-stations')
->setDescription('An example function to list stations in a table view.');
}

/**
* {@inheritdoc}
*/
protected function execute(
\Symfony\Component\Console\Input\InputInterface $input,
\Symfony\Component\Console\Output\OutputInterface $output
) {
$io = new \Symfony\Component\Console\Style\SymfonyStyle($input, $output);
$io->title('Example Plugin: Stations');

$headers = [
'ID',
'Name',
'Frontend',
'Backend',
'Remotes',
];

$rows = [];

/** @var \App\Radio\Adapters $adapters */
$adapters = $this->get(\App\Radio\Adapters::class);

/** @var \Doctrine\ORM\EntityManager $em */
$em = $this->get(\Doctrine\ORM\EntityManager::class);

$stations = $em
->getRepository(\App\Entity\Station::class)
->findAll();

foreach($stations as $station) {
/** @var \App\Entity\Station $station */

$backend = $adapters->getBackendAdapter($station);
$frontend = $adapters->getFrontendAdapter($station);

$rows[] = [
$station->getId(),
$station->getName(),
ucfirst($station->getBackendType()).' ('.($backend->isRunning($station) ? 'Running' : 'Stopped').')',
ucfirst($station->getFrontendType()).' ('.($frontend->isRunning($station) ? 'Running' : 'Stopped').')',
$station->getRemotes()->count(),
];
}


$table = (new \Symfony\Component\Console\Helper\Table($output))
->setHeaders($headers)
->setRows($rows);

$table->render();

return 0;
}
}
<?php

declare(strict_types=1);

namespace Plugin\ExamplePlugin\Command;

use App\Console\Command\CommandAbstract;
use App\Radio\Adapters;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class ListStations extends CommandAbstract
{
public function __invoke(
SymfonyStyle $io,
Adapters $adapters,
EntityManagerInterface $entityManager
) {
$io->title('Example Plugin: Stations');

$headers = [
'ID',
'Name',
'Frontend',
'Backend',
'Remotes',
];

$rows = [];

$stations = $entityManager
->getRepository(\App\Entity\Station::class)
->findAll();

foreach($stations as $station) {
/** @var \App\Entity\Station $station */

$backend = $adapters->getBackendAdapter($station);
$frontend = $adapters->getFrontendAdapter($station);

$rows[] = [
$station->getId(),
$station->getName(),
ucfirst($station->getBackendType()).' ('.($backend->isRunning($station) ? 'Running' : 'Stopped').')',
ucfirst($station->getFrontendType()).' ('.($frontend->isRunning($station) ? 'Running' : 'Stopped').')',
$station->getRemotes()->count(),
];
}

$io->table($headers, $rows);

return 0;
}
}
29 changes: 16 additions & 13 deletions src/Controller/HelloWorld.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?php
namespace Plugin\ExamplePlugin\Controller;

use App\Http\Request;
use App\Http\Response;

class HelloWorld
{
public function __invoke(Request $request, Response $response): Response
{
return $request->getView()->renderToResponse($response, 'example::hello_world');
}
}
<?php

declare(strict_types=1);

namespace Plugin\ExamplePlugin\Controller;

use App\Http\Response;
use App\Http\ServerRequest;

class HelloWorld
{
public function __invoke(ServerRequest $request, Response $response): Response
{
return $request->getView()->renderToResponse($response, 'example::hello_world');
}
}
96 changes: 50 additions & 46 deletions src/EventHandler/AllTheListeners.php
Original file line number Diff line number Diff line change
@@ -1,46 +1,50 @@
<?php
namespace Plugin\ExamplePlugin\EventHandler;

use App\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class AllTheListeners implements EventSubscriberInterface
{
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
*
* @return array The event names to listen to
*/
public static function getSubscribedEvents()
{
return [
Event\Radio\GenerateRawNowPlaying::NAME => [
['setListenerCount', -20]
],
];
}

public function setListenerCount(Event\Radio\GenerateRawNowPlaying $event)
{
$np_raw = $event->getRawResponse();

$np_raw['listeners']['current'] = mt_rand(5, 25);
$np_raw['listeners']['unique'] = mt_rand(0, $np_raw['listeners']['current']);
$np_raw['listeners']['total'] = $np_raw['listeners']['current'];

$event->setRawResponse($np_raw);
}
}
<?php

declare(strict_types=1);

namespace Plugin\ExamplePlugin\EventHandler;

use App\Event;
use NowPlaying\Result\Result;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class AllTheListeners implements EventSubscriberInterface
{
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
*
* @return array The event names to listen to
*/
public static function getSubscribedEvents()
{
return [
Event\Radio\GenerateRawNowPlaying::class => [
['setListenerCount', -20]
],
];
}

public function setListenerCount(Event\Radio\GenerateRawNowPlaying $event)
{
$np_raw = $event->getResult()->toArray();

$np_raw['listeners']['current'] = mt_rand(5, 25);
$np_raw['listeners']['unique'] = mt_rand(0, $np_raw['listeners']['current']);
$np_raw['listeners']['total'] = $np_raw['listeners']['current'];

$event->setResult(Result::fromArray($np_raw));
}
}
Loading