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
36 changes: 34 additions & 2 deletions components/ILIAS/BackgroundTasks/BackgroundTasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,18 @@
namespace ILIAS;

use ILIAS\Component\Component;
use ILIAS\Component\Resource\PublicAsset;
use ILIAS\Component\Resource\ComponentJS;
use ILIAS\Setup\Agent;
use ILIAS\Refinery\Factory;
use ILIAS\Language\ComponentTranslation\LanguageFileDirectory;
use ILIAS\Language\ComponentTranslation\ComponentLanguageFileDirectory;
use ILIAS\BackgroundTasks\Registry\Registry;
use ILIAS\BackgroundTasks\Task;
use ILIAS\BackgroundTasks\Value;
use ILIAS\BackgroundTasks\Implementation\Registry\BasicRegistry;
use ILIAS\BackgroundTasks\Implementation\Values;
use ILIAS\BackgroundTasks\Implementation\Tasks;

class BackgroundTasks implements Component
{
Expand All @@ -38,8 +46,27 @@ public function init(
array | \ArrayAccess &$pull,
array | \ArrayAccess &$internal,
): void {
$contribute[Agent::class] = static fn(): \ilBackgroundTasksSetupAgent =>
new \ilBackgroundTasksSetupAgent(
$define[] = Registry::class;

// components putting tasks or values into buckets contribute them, see Registry\Registry
$implement[Registry::class] = static fn(): Registry =>
new BasicRegistry(
$seek[Task::class],
$seek[Value::class]
);

$contribute[Value::class] = static fn() => new Values\ScalarValues\ScalarValue();
$contribute[Value::class] = static fn() => new Values\ScalarValues\BooleanValue();
$contribute[Value::class] = static fn() => new Values\ScalarValues\FloatValue();
$contribute[Value::class] = static fn() => new Values\ScalarValues\IntegerValue();
$contribute[Value::class] = static fn() => new Values\ScalarValues\StringValue();
$contribute[Value::class] = static fn() => new Values\AggregationValues\ListValue();
$contribute[Value::class] = static fn() => new Values\ThunkValue();
$contribute[Task::class] = static fn() => new Tasks\Aggregation\ConcatenationJob();
$contribute[Task::class] = static fn() => new Tasks\NotFoundUserInteraction();

$contribute[Agent::class] = static fn(): Agent =>
new \ILIAS\BackgroundTasks\Setup\Agent(
$pull[Factory::class]
);
$contribute[LanguageFileDirectory::class] = fn() => new ComponentLanguageFileDirectory(
Expand All @@ -50,5 +77,10 @@ public function init(
$this,
'background_tasks'
);

$contribute[PublicAsset::class] = fn(): ComponentJS => new ComponentJS(
$this,
"background_task_refresh.js"
);
}
}
29 changes: 29 additions & 0 deletions components/ILIAS/BackgroundTasks/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Roadmap

## Mid Term

### Build all Tasks and Values from their Contributions

Components contribute their tasks and values to the bootstrap, see `Registry\Registry`. The task
factory and the persistence clone these contributions. A task or value nobody contributed is still
built by the `Dependencies\Injector`, which resolves its constructor arguments from the legacy
container. This fallback is needed as long as not all components contribute their tasks and values,
and as long as plugins cannot contribute to the bootstrap at all.

The goal is to build all tasks and values from their contributions and to remove the `Injector`
together with its `DependencyMap`. Before that, every component putting tasks or values into
buckets has to contribute them and pass their dependencies through the constructor, and plugins
need a way to contribute theirs.

### Move the Initialisation out of ilInitialisation

The task factory, the persistence, the task manager and the injector are still set up in
`ilInitialisation::initBackgroundTasks()` and `ilInitialisation::initInjector()` and reach the
rest of the system through the legacy container, while only the `Registry` comes from the bootstrap.
Scripts calling `ilInitialisation::initILIAS()` directly get an empty `Registry`. The goal is to
initialise BackgroundTasks completely through the component bootstrap, as described in
`components/ILIAS/Component/docs/component-bootstrap-migration.md`, and to bridge the services into
the legacy container through `AllModernComponents` as long as they are needed there. This includes
putting the settings read from `ilias.ini.php` (`concurrency`, `number_of_concurrent_tasks`) behind
a configuration interface and replacing the static `BasicPersistence::instance()` and the global
`$DIC` it uses.
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*/

il = il || {};
il.BGTask = il.BGTask || {};
(function ($, il) {
Expand Down
2 changes: 1 addition & 1 deletion components/ILIAS/BackgroundTasks/service.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<service xmlns="http://www.w3.org" version="$Id$"
id="bgtk">
<baseclasses>
<baseclass name="ilBTControllerGUI" dir="classes" />
<baseclass name="ILIAS\BackgroundTasks\Implementation\UI\ControllerGUI" dir="src/Implementation/UI" />
</baseclasses>
<gsproviders>
<gsprovider class_name="ilBTGSProvider" purpose="meta_bar_static"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use ILIAS\BackgroundTasks\TaskManager;
use ILIAS\DI\Container;
use ILIAS\BackgroundTasks\Dependencies\Injector;
use ILIAS\BackgroundTasks\Registry\Registry;

/**
* Class BackgroundTaskServices
Expand Down Expand Up @@ -54,4 +55,9 @@ public function injector(): Injector
{
return $this->container['bt.injector'];
}

public function registry(): Registry
{
return $this->container[Registry::class];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ private function loadTask(int $taskContainerId, Bucket $bucket, BucketContainer
private function loadValue($valueContainerId, Bucket $bucket, BucketContainer $bucketContainer): Value
{
global $DIC;
$registry = $DIC->backgroundTasks()->registry();
$factory = $DIC->backgroundTasks()->injector();

/** @var ValueContainer $valueContainer */
Expand All @@ -461,7 +462,9 @@ private function loadValue($valueContainerId, Bucket $bucket, BucketContainer $b
/** @noinspection PhpIncludeInspection */

/** @var Value $value */
$value = $factory->createInstance($valueContainer->getClassName());
$value = $registry->isRegistered($valueContainer->getClassName())
? $registry->newValue($valueContainer->getClassName())
: $factory->createInstance($valueContainer->getClassName());

$value->unserialize($valueContainer->getSerialized());
if ($valueContainer->getHasParenttask() !== 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/
declare(strict_types=1);

namespace ILIAS\BackgroundTasks\Implementation\Registry;

use ILIAS\BackgroundTasks\Registry\Registry;
use ILIAS\BackgroundTasks\Task;
use ILIAS\BackgroundTasks\Value;

class BasicRegistry implements Registry
{
/**
* @var array<string, Task>
*/
private array $tasks = [];

/**
* @var array<string, Value>
*/
private array $values = [];

/**
* @param Task[] $tasks
* @param Value[] $values
*/
public function __construct(array $tasks, array $values)
{
foreach ($tasks as $task) {
$this->tasks[$this->unique($task)] = $task;
}
foreach ($values as $value) {
$this->values[$this->unique($value)] = $value;
}
}

public function isRegistered(string $class_name): bool
{
$class_name = ltrim($class_name, '\\');
return isset($this->tasks[$class_name]) || isset($this->values[$class_name]);
}

public function newTask(string $class_name): Task
{
$class_name = ltrim($class_name, '\\');
if (!isset($this->tasks[$class_name])) {
throw new \OutOfBoundsException("No task $class_name is registered.");
}
return clone $this->tasks[$class_name];
}

public function newValue(string $class_name): Value
{
$class_name = ltrim($class_name, '\\');
if (!isset($this->values[$class_name])) {
throw new \OutOfBoundsException("No value $class_name is registered.");
}
return clone $this->values[$class_name];
}

private function unique(Task|Value $prototype): string
{
$class_name = $prototype::class;
if (isset($this->tasks[$class_name]) || isset($this->values[$class_name])) {
throw new \LogicException("$class_name is contributed more than once.");
}
return $class_name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,32 @@
use ILIAS\BackgroundTasks\Task;
use ILIAS\BackgroundTasks\Task\TaskFactory;
use ILIAS\BackgroundTasks\Value;
use ILIAS\BackgroundTasks\Registry\Registry;

class BasicTaskFactory implements TaskFactory
{
use BasicScalarValueFactory;

public function __construct(protected Injector $injector)
{
public function __construct(
protected Injector $injector,
protected Registry $registry
) {
}

/**
* @inheritdoc
*/
public function createTask(string $class_name, ?array $input = null): Task
{
if (!class_exists($class_name)) {
if ($this->registry->isRegistered($class_name)) {
$task = $this->registry->newTask($class_name);
} elseif (class_exists($class_name)) {
// not contributed (yet), e.g. tasks of plugins, see ROADMAP.md
/** @var Task $task */
$task = $this->injector->createInstance($class_name);
} else {
return new NotFoundUserInteraction();
}
/** @var Task $task */
$task = $this->injector->createInstance($class_name);
if ($input) {
$wrappedInput = array_map(function ($i): Value {
if ($i instanceof Task) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*
*********************************************************************/

namespace ILIAS\BackgroundTasks\Implementation\UI;

use ILIAS\HTTP\StatusCode;
use ILIAS\Filesystem\Stream\Streams;
use ILIAS\Data\URI;
Expand All @@ -25,14 +27,15 @@
use ILIAS\HTTP\Response\ResponseHeader;
use ILIAS\BackgroundTasks\Implementation\Tasks\UserInteraction\UserInteractionOption;
use ILIAS\components\OrgUnit\ARHelper\DIC;
use ilCtrlBaseClassInterface;
use ilCtrlSecurityInterface;
use ilUtil;

/**
* Class ilBTControllerGUI
*
* @author Oskar Truffer <ot@studer-raimann.ch>
* @author Fabian Schmid <fs@studer-raimann.ch>
*/
class ilBTControllerGUI implements ilCtrlBaseClassInterface, ilCtrlSecurityInterface
class ControllerGUI implements ilCtrlBaseClassInterface, ilCtrlSecurityInterface
{
use DIC;
public const FROM_URL = 'from_url';
Expand Down Expand Up @@ -130,7 +133,7 @@ protected function getAsyncReplacementItem(): void

$this->enforceBucketBelongsToCurrentUser($bucket);

$item_source = new ilBTPopOverGUI($this->dic());
$item_source = new PopOverGUI($this->dic());
$this->dic()->language()->loadLanguageModule('background_tasks');
$item = $item_source->getItemForObserver($bucket);

Expand Down
Loading
Loading