Skip to content
Open
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
47 changes: 31 additions & 16 deletions lib/private/AppFramework/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,23 @@
use OCP\Server;

/**
* Entry point for every request in your app. You can consider this as your
* public static void main() method
* Internal entry point for AppFramework request execution.
*
* Handles all the dependency injection, controllers and output flow
* Resolves controllers from the app container, runs the dispatcher and
* middleware stack, and writes headers, cookies, and the response body to
* the output layer.
*
* This class is internal to the server and not part of the public app API.
* App code should use OCP\AppFramework\App instead.
*/
class App {
/**
* Turns an app id into a namespace by either reading the appinfo.xml's
* namespace tag or uppercasing the appid's first letter
* @param string $appId the app id
* @param string $topNamespace the namespace which should be prepended to
* the transformed app id, defaults to OCA\
* @return string the starting namespace for the app
* Returns the app namespace for the given app ID, optionally rewritten to a
* different top-level namespace.
*
* @param string $appId the app ID
* @param string $topNamespace the namespace prefix to substitute for OCA\
* @return string the app namespace
* @deprecated 34.0.0 use IAppManager::getAppNamespace
*/
public static function buildAppNamespace(string $appId, string $topNamespace = 'OCA\\'): string {
Expand All @@ -50,21 +54,32 @@ public static function buildAppNamespace(string $appId, string $topNamespace = '
}

/**
* Returns the app ID for the given class namespace.
*
* @param string $className the fully qualified class name
* @param string $topNamespace unused legacy namespace prefix parameter
* @return string|null the app ID, or null if the class does not belong to an app namespace
* @deprecated 34.0.0 use IAppManager::getAppFromNamespace
*/
public static function getAppIdForClass(string $className, string $topNamespace = 'OCA\\'): ?string {
return Server::get(IAppManager::class)->getAppFromNamespace($className);
}

/**
* Shortcut for calling a controller method and printing the result
* Executes an AppFramework controller action and emits the HTTP response.
*
* Resolves the controller from the app container, dispatches the requested
* method, and forwards headers, cookies, and body output to the output layer.
*
* The controller is first resolved as provided and then, if necessary, as
* <AppNamespace>\Controller\<ControllerName>.
*
* @param string $controllerName the name of the controller under which it is
* stored in the DI container
* @param string $methodName the method that you want to call
* @param DIContainer $container an instance of a pimple container.
* @param array $urlParams list of URL parameters (optional)
* @throws HintException
* @param string $controllerName Controller service name or controller class name
* @param string $methodName Controller method to invoke
* @param DIContainer $container App dependency injection container
* @param array|null $urlParams Route parameters to inject into the request
* @throws HintException If a controller from a globally registered route
* belongs to an app that is not enabled
*/
public static function main(
string $controllerName,
Expand Down
68 changes: 27 additions & 41 deletions lib/public/AppFramework/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,27 @@
use Psr\Log\LoggerInterface;

/**
* Class App
* Public base class for AppFramework applications.
*
* Provides access to the app container and a convenience dispatch() method
* for routing requests to controllers.
*
* Apps using the AppFramework typically extend this class to register
* services and dispatch controller actions.
*
* @see https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html
*
* Any application must inherit this call - all controller instances to be used are
* to be registered using IContainer::registerService
* @since 6.0.0
*/
class App {
/** @var IAppContainer */
private $container;
private IAppContainer $container;

/**
* Turns an app id into a namespace by convention. The id is split at the
* underscores, all parts are CamelCased and reassembled. e.g.:
* some_app_id -> OCA\SomeAppId
* @param string $appId the app id
* @param string $topNamespace the namespace which should be prepended to
* the transformed app id, defaults to OCA\
* @return string the starting namespace for the app
* Returns the app namespace for the given app ID.
*
* @param string $appId the app ID
* @param string $topNamespace the namespace prefix to substitute for OCA\
* @return string the app namespace
* @since 8.0.0
* @deprecated 34.0.0 use IAppManager::getAppNamespace
*/
Expand All @@ -44,8 +47,10 @@ public static function buildAppNamespace(string $appId, string $topNamespace = '
}

/**
* @param string $appName
* @param array $urlParams an array with variables extracted from the routes
* Creates or retrieves the app container for the given app.
*
* @param string $appName the app ID
* @param array $urlParams route parameters to make available in the request container
* @since 6.0.0
*/
public function __construct(string $appName, array $urlParams = []) {
Expand Down Expand Up @@ -97,6 +102,8 @@ public function __construct(string $appName, array $urlParams = []) {
}

/**
* Returns the app container.
*
* @return IAppContainer
* @since 6.0.0
*/
Expand All @@ -105,37 +112,16 @@ public function getContainer(): IAppContainer {
}

/**
* This function is called by the routing component to fire up the frameworks dispatch mechanism.
*
* Example code in routes.php of the task app:
* $this->create('tasks_index', '/')->get()->action(
* function($params){
* $app = new TaskApp($params);
* $app->dispatch('PageController', 'index');
* }
* );
*
*
* Example for for TaskApp implementation:
* class TaskApp extends \OCP\AppFramework\App {
*
* public function __construct($params){
* parent::__construct('tasks', $params);
* Dispatches a controller action through the AppFramework runtime.
*
* $this->getContainer()->registerService('PageController', function(IAppContainer $c){
* $a = $c->query('API');
* $r = $c->query('Request');
* return new PageController($a, $r);
* });
* }
* }
* This is a convenience wrapper around the internal AppFramework request
* execution for the current app container.
*
* @param string $controllerName the name of the controller under which it is
* stored in the DI container
* @param string $methodName the method that you want to call
* @param string $controllerName controller service name or controller class basename
* @param string $methodName controller method to invoke
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conflict a bit with #60780

But I can take care of rebasing whichever PR gets merged last

* @since 6.0.0
*/
public function dispatch(string $controllerName, string $methodName) {
public function dispatch(string $controllerName, string $methodName): void {
\OC\AppFramework\App::main($controllerName, $methodName, $this->container);
}
}
Loading