Basic scheduler completed
This commit is contained in:
215
src/Scheduler/Scheduler.php
Normal file
215
src/Scheduler/Scheduler.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* AVSDev UF Scheduler (https://avsdev.uk)
|
||||
*
|
||||
* @link https://git.avsdev.uk/avsdev/sprinkle-scheduler
|
||||
* @license https://git.avsdev.uk/avsdev/sprinkle-scheduler/blob/master/LICENSE.md (LGPL-3.0 License)
|
||||
*/
|
||||
|
||||
namespace UserFrosting\Sprinkle\Scheduler\Scheduler;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use UserFrosting\UniformResourceLocator\Resource as ResourceInstance;
|
||||
|
||||
/**
|
||||
* Scheduler Class.
|
||||
*
|
||||
* Finds all tasks class across sprinkles
|
||||
*
|
||||
* @author Craig Williams (https://avsdev.uk)
|
||||
*/
|
||||
class Scheduler
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $ci;
|
||||
|
||||
/**
|
||||
* @var string The resource locator scheme
|
||||
*/
|
||||
protected $scheme = 'tasks://';
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param ContainerInterface $ci
|
||||
*/
|
||||
public function __construct(ContainerInterface $ci)
|
||||
{
|
||||
$this->ci = $ci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop all the available sprinkles and return a list of their tasks.
|
||||
*
|
||||
* @return array An array of all the task classes found for every sprinkle
|
||||
*/
|
||||
public function getTasks()
|
||||
{
|
||||
$tasks = $this->ci->locator->listResources($this->scheme, false, false);
|
||||
|
||||
return $this->loadTasks($tasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single task info.
|
||||
*
|
||||
* @param string $name The task name
|
||||
*
|
||||
* @throws \Exception If task not found
|
||||
*
|
||||
* @return array The details about a task file [name, class, sprinkle]
|
||||
*/
|
||||
public function getTask($name)
|
||||
{
|
||||
// Get task resource
|
||||
$taskResource = $this->ci->locator->getResource($this->scheme . $name . '.php');
|
||||
|
||||
// Make sure we found something
|
||||
if (!$taskResource) {
|
||||
throw new \Exception("Task $name not found");
|
||||
}
|
||||
|
||||
// Return the task info
|
||||
return $this->getTaskDetails($taskResource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class instance of a task.
|
||||
*
|
||||
* @param string $name The task name
|
||||
*
|
||||
* @throws \Exception If class doesn't exist or is not right interface
|
||||
*
|
||||
* @return TaskInterface The task class instance
|
||||
*/
|
||||
public function getTaskClass($name)
|
||||
{
|
||||
// Try to get task info
|
||||
$task = $this->getTask($name);
|
||||
|
||||
// Make sure class exist
|
||||
$classPath = $task['class'];
|
||||
if (!class_exists($classPath)) {
|
||||
throw new \Exception("Task class `$classPath` not found. Make sure the class has the correct namespace.");
|
||||
}
|
||||
|
||||
// Create a new class instance
|
||||
$taskClass = new $classPath($this->ci);
|
||||
|
||||
// Class must be an instance of `TaskerInterface`
|
||||
if (!$taskClass instanceof TaskInterface) {
|
||||
throw new \Exception('Task class must be an instance of `TaskerInterface`');
|
||||
}
|
||||
|
||||
return $taskClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a task class.
|
||||
*
|
||||
* @param TaskInterface $task The task to run
|
||||
*/
|
||||
public function runTask(TaskInterface $task)
|
||||
{
|
||||
$task->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a task based on it's name.
|
||||
*
|
||||
* @param string $taskName
|
||||
*/
|
||||
public function run($taskName)
|
||||
{
|
||||
$task = $this->getTaskClass($taskName);
|
||||
$this->runTask($task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of tasks due to be run
|
||||
*/
|
||||
public function dueTasks()
|
||||
{
|
||||
$tasks = $this->getTasks();
|
||||
|
||||
return array_filter($tasks, function($task) {
|
||||
// Get the task's class
|
||||
$classPath = $task['class'];
|
||||
|
||||
// Create a new class instance
|
||||
$taskClass = new $classPath($this->ci);
|
||||
|
||||
// Class must be an instance of `TaskerInterface`
|
||||
if (!$taskClass instanceof TaskInterface) {
|
||||
throw new \Exception('Task class must be an instance of `TaskerInterface`');
|
||||
}
|
||||
|
||||
return $taskClass->isDue();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Process tasks Resource into info.
|
||||
*
|
||||
* @param array $taskFiles List of tasks files
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function loadTasks(array $taskFiles)
|
||||
{
|
||||
$tasks = [];
|
||||
|
||||
foreach ($taskFiles as $taskFile) {
|
||||
$tasks[] = $this->getTaskDetails($taskFile);
|
||||
}
|
||||
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of task details including the class name and the sprinkle name.
|
||||
*
|
||||
* @param ResourceInstance $file The task file
|
||||
*
|
||||
* @return array The details about a task file [name, class, sprinkle]
|
||||
*/
|
||||
protected function getTaskDetails(ResourceInstance $file)
|
||||
{
|
||||
// Format the sprinkle name for the namespace
|
||||
$sprinkleName = $file->getLocation()->getName();
|
||||
$sprinkleName = Str::studly($sprinkleName);
|
||||
|
||||
// Getting base path, name and class name
|
||||
$basePath = str_replace($file->getBasename(), '', $file->getBasePath());
|
||||
$name = $basePath . $file->getFilename();
|
||||
$className = str_replace('/', '\\', $basePath) . $file->getFilename();
|
||||
$classPath = "\\UserFrosting\\Sprinkle\\$sprinkleName\\Scheduler\\Tasks\\$className";
|
||||
|
||||
if (!class_exists($classPath)) {
|
||||
throw new \Exception("Task class `$className` not found. Make sure the class has the correct namespace.");
|
||||
}
|
||||
|
||||
// Create a new class instance
|
||||
$taskClass = new $classPath($this->ci);
|
||||
|
||||
// Class must be an instance of `TaskerInterface`
|
||||
if (!$taskClass instanceof TaskInterface) {
|
||||
throw new \Exception('Task class must be an instance of `TaskerInterface`');
|
||||
}
|
||||
|
||||
$schedule = $taskClass->cronExpression();
|
||||
|
||||
// Build the class name and namespace
|
||||
return [
|
||||
'schedule' => $schedule,
|
||||
'sprinkle' => $sprinkleName,
|
||||
'name' => $name,
|
||||
'class' => $classPath,
|
||||
'instance' => $taskClass,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user