$dice->create(\Friendica\Core\PConfig\Capability\IManagePersonalConfigValues::class),
$dice->create(\Friendica\Security\Authentication::class),
$dice->create(\Friendica\App\Page::class),
+ $dice,
$start_time
);
namespace Friendica;
+use Dice\Dice;
use Exception;
use Friendica\App\Arguments;
use Friendica\App\BaseURL;
* @throws HTTPException\InternalServerErrorException
* @throws \ImagickException
*/
- public function runFrontend(App\Module $module, App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, float $start_time)
+ public function runFrontend(App\Module $module, App\Router $router, IManagePersonalConfigValues $pconfig, Authentication $auth, App\Page $page, Dice $dice, float $start_time)
{
$this->profiler->set($start_time, 'start');
$this->profiler->set(microtime(true), 'classinit');
$page['page_title'] = $moduleName;
if (!$this->mode->isInstall() && !$this->mode->has(App\Mode::MAINTENANCEDISABLED)) {
- $module = new Module('maintenance', Maintenance::class);
+ $module = new Module('maintenance', new Maintenance());
} else {
// determine the module class and save it to the module instance
// @todo there's an implicit dependency due SESSION::start(), so it has to be called here (yet)
- $module = $module->determineClass($this->args, $router, $this->config);
+ $module = $module->determineClass($this->args, $router, $this->config, $dice);
}
// Let the module run it's internal process (init, get, post, ...)
namespace Friendica\App;
+use Dice\Dice;
use Friendica\App;
-use Friendica\BaseModule;
+use Friendica\Capabilities\ICanHandleRequests;
use Friendica\Core;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\LegacyModule;
private $module;
/**
- * @var BaseModule The module class
+ * @var ICanHandleRequests The module class
*/
private $module_class;
- /**
- * @var array The module parameters
- */
- private $module_parameters;
-
/**
* @var bool true, if the module is a backend module
*/
}
/**
- * @return string The base class name
+ * @return ICanHandleRequests The base class name
*/
- public function getClassName()
+ public function getClass(): ICanHandleRequests
{
return $this->module_class;
}
- /**
- * @return array The module parameters extracted from the route
- */
- public function getParameters()
- {
- return $this->module_parameters;
- }
-
/**
* @return bool True, if the current module is a backend module
* @see Module::BACKEND_MODULES for a list
return $this->isBackend;
}
- public function __construct(string $module = self::DEFAULT, string $moduleClass = self::DEFAULT_CLASS, array $moduleParameters = [], bool $isBackend = false, bool $printNotAllowedAddon = false)
+ public function __construct(string $module = self::DEFAULT, ICanHandleRequests $module_class = null, bool $isBackend = false, bool $printNotAllowedAddon = false)
{
+ $defaultClass = static::DEFAULT_CLASS;
+
$this->module = $module;
- $this->module_class = $moduleClass;
- $this->module_parameters = $moduleParameters;
+ $this->module_class = $module_class ?? new $defaultClass();
$this->isBackend = $isBackend;
$this->printNotAllowedAddon = $printNotAllowedAddon;
}
$isBackend = in_array($module, Module::BACKEND_MODULES);;
- return new Module($module, $this->module_class, [], $isBackend, $this->printNotAllowedAddon);
+ return new Module($module,null, $isBackend, $this->printNotAllowedAddon);
}
/**
* Determine the class of the current module
*
- * @param Arguments $args The Friendica execution arguments
- * @param Router $router The Friendica routing instance
+ * @param Arguments $args The Friendica execution arguments
+ * @param Router $router The Friendica routing instance
* @param IManageConfigValues $config The Friendica Configuration
+ * @param Dice $dice The Dependency Injection container
*
* @return Module The determined module of this call
*
* @throws \Exception
*/
- public function determineClass(Arguments $args, Router $router, IManageConfigValues $config)
+ public function determineClass(Arguments $args, Router $router, IManageConfigValues $config, Dice $dice)
{
$printNotAllowedAddon = false;
$module_class = $module_class ?: PageNotFound::class;
}
- return new Module($this->module, $module_class, $module_parameters, $this->isBackend, $printNotAllowedAddon);
+ /** @var ICanHandleRequests $module */
+ $module = $dice->create($module_class, [$module_parameters]);
+
+ return new Module($this->module, $module, $this->isBackend, $printNotAllowedAddon);
}
/**
Core\Hook::callAll($this->module . '_mod_init', $placeholder);
- call_user_func([$this->module_class, 'init'], $this->module_parameters);
+ $this->module_class::init($this->module_class::getParameters());
$profiler->set(microtime(true) - $timestamp, 'init');
if ($server['REQUEST_METHOD'] === Router::DELETE) {
- call_user_func([$this->module_class, 'delete'], $this->module_parameters);
+ $this->module_class::delete($this->module_class::getParameters());
}
if ($server['REQUEST_METHOD'] === Router::PATCH) {
- call_user_func([$this->module_class, 'patch'], $this->module_parameters);
+ $this->module_class::patch($this->module_class::getParameters());
}
if ($server['REQUEST_METHOD'] === Router::POST) {
Core\Hook::callAll($this->module . '_mod_post', $post);
- call_user_func([$this->module_class, 'post'], $this->module_parameters);
+ $this->module_class::post($this->module_class::getParameters());
}
if ($server['REQUEST_METHOD'] === Router::PUT) {
- call_user_func([$this->module_class, 'put'], $this->module_parameters);
+ $this->module_class::put($this->module_class::getParameters());
}
Core\Hook::callAll($this->module . '_mod_afterpost', $placeholder);
- call_user_func([$this->module_class, 'afterpost'], $this->module_parameters);
+ $this->module_class::afterpost($this->module_class::getParameters());
// "rawContent" is especially meant for technical endpoints.
// This endpoint doesn't need any theme initialization or other comparable stuff.
- call_user_func([$this->module_class, 'rawContent'], $this->module_parameters);
+ $this->module_class::rawContent($this->module_class::getParameters());
}
}
$content = '';
try {
- $moduleClass = $module->getClassName();
+ $moduleClass = $module->getClass();
$arr = ['content' => $content];
- Hook::callAll($moduleClass . '_mod_content', $arr);
+ Hook::callAll( $moduleClass::getClassName() . '_mod_content', $arr);
$content = $arr['content'];
- $arr = ['content' => call_user_func([$moduleClass, 'content'], $module->getParameters())];
- Hook::callAll($moduleClass . '_mod_aftercontent', $arr);
+ $arr = ['content' => $moduleClass::content($moduleClass::getParameters())];
+ Hook::callAll($moduleClass::getClassName() . '_mod_aftercontent', $arr);
$content .= $arr['content'];
} catch (HTTPException $e) {
$content = ModuleHTTPException::content($e);
namespace Friendica;
+use Friendica\Capabilities\ICanHandleRequests;
use Friendica\Core\Logger;
use Friendica\Model\User;
*
* @author Hypolite Petovan <hypolite@mrpetovan.com>
*/
-abstract class BaseModule
+abstract class BaseModule implements ICanHandleRequests
{
+ /** @var array */
+ protected static $parameters = [];
+
+ public function __construct(array $parameters = [])
+ {
+ static::$parameters = $parameters;
+ }
+
/**
- * Initialization method common to both content() and post()
- *
- * Extend this method if you need to do any shared processing before both
- * content() or post()
+ * @return array
+ */
+ public static function getParameters(): array
+ {
+ return self::$parameters;
+ }
+
+ /**
+ * {@inheritDoc}
*/
public static function init(array $parameters = [])
{
}
/**
- * Module GET method to display raw content from technical endpoints
- *
- * Extend this method if the module is supposed to return communication data,
- * e.g. from protocol implementations.
+ * {@inheritDoc}
*/
public static function rawContent(array $parameters = [])
{
}
/**
- * Module GET method to display any content
- *
- * Extend this method if the module is supposed to return any display
- * through a GET request. It can be an HTML page through templating or a
- * XML feed or a JSON output.
- *
- * @return string
+ * {@inheritDoc}
*/
public static function content(array $parameters = [])
{
- $o = '';
-
- return $o;
+ return '';
}
/**
- * Module DELETE method to process submitted data
- *
- * Extend this method if the module is supposed to process DELETE requests.
- * Doesn't display any content
+ * {@inheritDoc}
*/
public static function delete(array $parameters = [])
{
}
/**
- * Module PATCH method to process submitted data
- *
- * Extend this method if the module is supposed to process PATCH requests.
- * Doesn't display any content
+ * {@inheritDoc}
*/
public static function patch(array $parameters = [])
{
}
/**
- * Module POST method to process submitted data
- *
- * Extend this method if the module is supposed to process POST requests.
- * Doesn't display any content
+ * {@inheritDoc}
*/
public static function post(array $parameters = [])
{
}
/**
- * Called after post()
- *
- * Unknown purpose
+ * {@inheritDoc}
*/
public static function afterpost(array $parameters = [])
{
}
/**
- * Module PUT method to process submitted data
- *
- * Extend this method if the module is supposed to process PUT requests.
- * Doesn't display any content
+ * {@inheritDoc}
*/
public static function put(array $parameters = [])
{
}
+ /** Gets the name of the current class */
+ public static function getClassName(): string
+ {
+ return static::class;
+ }
+
/*
* Functions used to protect against Cross-Site Request Forgery
* The security token has to base on at least one value that an attacker can't know - here it's the session ID and the private key.
--- /dev/null
+<?php
+
+namespace Friendica\Capabilities;
+
+/**
+ * This interface provides the capability to handle requests from clients and returns the desired outcome
+ */
+interface ICanHandleRequests
+{
+ /**
+ * Initialization method common to both content() and post()
+ *
+ * Extend this method if you need to do any shared processing before both
+ * content() or post()
+ */
+ public static function init(array $parameters = []);
+
+ /**
+ * Module GET method to display raw content from technical endpoints
+ *
+ * Extend this method if the module is supposed to return communication data,
+ * e.g. from protocol implementations.
+ */
+ public static function rawContent(array $parameters = []);
+
+ /**
+ * Module GET method to display any content
+ *
+ * Extend this method if the module is supposed to return any display
+ * through a GET request. It can be an HTML page through templating or a
+ * XML feed or a JSON output.
+ *
+ * @return string
+ */
+ public static function content(array $parameters = []);
+
+ /**
+ * Module DELETE method to process submitted data
+ *
+ * Extend this method if the module is supposed to process DELETE requests.
+ * Doesn't display any content
+ */
+ public static function delete(array $parameters = []);
+
+ /**
+ * Module PATCH method to process submitted data
+ *
+ * Extend this method if the module is supposed to process PATCH requests.
+ * Doesn't display any content
+ */
+ public static function patch(array $parameters = []);
+
+ /**
+ * Module POST method to process submitted data
+ *
+ * Extend this method if the module is supposed to process POST requests.
+ * Doesn't display any content
+ */
+ public static function post(array $parameters = []);
+
+ /**
+ * Called after post()
+ *
+ * Unknown purpose
+ */
+ public static function afterpost(array $parameters = []);
+
+ /**
+ * Module PUT method to process submitted data
+ *
+ * Extend this method if the module is supposed to process PUT requests.
+ * Doesn't display any content
+ */
+ public static function put(array $parameters = []);
+
+ public static function getClassName(): string;
+
+ public static function getParameters(): array;
+}
public function testIsBackendButIndex()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], true);
+ $module = new Module(Module::DEFAULT, null, true);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(false, $module, $server, $mobileDetect);
public function testIsNotBackend()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
+ $module = new Module(Module::DEFAULT, null, false);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(false, $module, $server, $mobileDetect);
'HTTP_X_REQUESTED_WITH' => 'xmlhttprequest',
];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
+ $module = new Module(Module::DEFAULT, null, false);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
public function testIsNotAjax()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
+ $module = new Module(Module::DEFAULT, null, false);
$mobileDetect = new MobileDetect();
$mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
public function testIsMobileIsTablet()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
+ $module = new Module(Module::DEFAULT, null, false);
$mobileDetect = Mockery::mock(MobileDetect::class);
$mobileDetect->shouldReceive('isMobile')->andReturn(true);
$mobileDetect->shouldReceive('isTablet')->andReturn(true);
public function testIsNotMobileIsNotTablet()
{
$server = [];
- $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
+ $module = new Module(Module::DEFAULT, null, false);
$mobileDetect = Mockery::mock(MobileDetect::class);
$mobileDetect->shouldReceive('isMobile')->andReturn(false);
$mobileDetect->shouldReceive('isTablet')->andReturn(false);
namespace Friendica\Test\src\App;
+use Dice\Dice;
use Friendica\App;
use Friendica\Core\Cache\Capability\ICanCache;
use Friendica\Core\Config\Capability\IManageConfigValues;
{
self::assertEquals($assert['isBackend'], $module->isBackend());
self::assertEquals($assert['name'], $module->getName());
- self::assertEquals($assert['class'], $module->getClassName());
+ self::assertEquals($assert['class'], $module->getClass());
}
/**
{
$module = new App\Module();
+ $defaultClass = App\Module::DEFAULT_CLASS;
+
self::assertModule([
'isBackend' => false,
'name' => App\Module::DEFAULT,
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
], $module);
}
public function dataModuleName()
{
+ $defaultClass = App\Module::DEFAULT_CLASS;
+
return [
'default' => [
'assert' => [
'isBackend' => false,
'name' => 'network',
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
],
'args' => new App\Arguments('network/data/in',
'network/data/in',
'assert' => [
'isBackend' => false,
'name' => 'with_strike_and_point',
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
],
'args' => new App\Arguments('with-strike.and-point/data/in',
'with-strike.and-point/data/in',
'assert' => [
'isBackend' => false,
'name' => App\Module::DEFAULT,
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
],
'args' => new App\Arguments(),
],
'assert' => [
'isBackend' => false,
'name' => App\Module::DEFAULT,
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
],
'args' => new App\Arguments(),
],
'assert' => [
'isBackend' => true,
'name' => App\Module::BACKEND_MODULES[0],
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
],
'args' => new App\Arguments(App\Module::BACKEND_MODULES[0] . '/data/in',
App\Module::BACKEND_MODULES[0] . '/data/in',
'assert' => [
'isBackend' => false,
'name' => 'login',
- 'class' => App\Module::DEFAULT_CLASS,
+ 'class' => new $defaultClass(),
],
'args' => new App\Arguments('users/sign_in',
'users/sign_in',
$router = (new App\Router([], __DIR__ . '/../../../static/routes.config.php', $l10n, $cache, $lock));
- $module = (new App\Module($name))->determineClass(new App\Arguments('', $command), $router, $config);
+ $dice = Mockery::mock(Dice::class);
+ $dice->shouldReceive('create')->andReturn(new $assert());
+
+ $module = (new App\Module($name))->determineClass(new App\Arguments('', $command), $router, $config, $dice);
- self::assertEquals($assert, $module->getClassName());
+ self::assertEquals($assert, $module->getClass()::getClassName());
}
/**