class

Analyzer::Php::Nextcloud

Inherits Analyzer::Php::PhpEngine < FileScanEngine < Analyzer < FileHelper < Reference < Object

Nextcloud apps declare routes in appinfo/routes.php:

return [
    'routes'    => [['name' => 'note#update', 'url' => '/notes/{id}', 'verb' => 'PUT']],
    'ocs'       => [['name' => 'api#share', 'url' => '/api/v1/share', 'verb' => 'POST']],
    'resources' => ['note' => ['url' => '/notes']],
];

or with #[FrontpageRoute(verb:, url:)] / #[ApiRoute(verb:, url:)] on controller methods. Frontpage routes and resources are served under /apps/<id>, OCS ones under /ocs/v2.php/apps/<id>; <id> comes from appinfo/info.xml. name resolves to lib/Controller/<Name>Controller, whose method arguments become params and whose #[PublicPage], #[NoAdminRequired], #[NoCSRFRequired], #[AuthorizedAdminSetting] (or legacy @PublicPage-style docblock annotations) become tags.

Constants

APP_ID_RE = /<id>\s*([^<\s]+)\s*<\/id>/
ENTRY_KEY_RE = /['"](name|url|verb|root)['"]\s*=>\s*['"]([^'"]*)['"]/
NAMED_ARG_RE = /\b(verb|url|root)\s*:\s*['"]([^'"]*)['"]/
NAMESPACE_DECL = /\bnamespace\s+([\w\\]+)\s*;/
NAMESPACE_RE = /\bnamespace\s+OCA\\(\w+)/
OCP_BASE_ACTIONS = {"Controller" => {} of String => String, "OCSController" => {"preflightedcors" => "#[PublicPage] #[NoCSRFRequired] #[NoAdminRequired]"}, "ApiController" => {"preflightedcors" => "#[PublicPage] #[NoCSRFRequired] #[NoAdminRequired]"}, "PublicShareController" => {} of String => String, "AuthPublicShareController" => {"showauthenticate" => "#[PublicPage]", "authenticate" => "#[PublicPage]"}}

OCP\AppFramework base controllers, and the attributes of the actions they give their subclasses.

OCS = "/ocs/v2.php"
PARENT_CLASS_RE = /\bclass\s+\w+\s+extends\s+(\\?[\w\\]+)/
RESOURCE_ACTIONS = [{"index", "GET", false}, {"show", "GET", true}, {"create", "POST", false}, {"update", "PUT", true}, {"destroy", "DELETE", true}]

Nextcloud's RouteParser: {action, verb, on the member URL /{id}?}

RESOURCE_GROUPS = {"resources" => false, "ocs-resources" => true}
RESOURCE_KEY = /['"]([^'"]+)['"]\s*=>\s*\z/
ROOT_URL_APPS = ["cloud_federation_api", "core", "files", "files_sharing", "profile", "settings", "spreed"] of ::String

RouteParser honours a frontpage route's root only for these apps; OCS routes may always set one.

ROUTE_ATTR_RE = /\b(FrontpageRoute|ApiRoute)\s*\(([^)]*)\)/
ROUTE_GROUPS = {"routes" => false, "ocs" => true}

group key => OCS?

STRING_RE = /'([^']*)'|"([^"]*)"/
TAGGER = "nextcloud_analyzer"

Class methods

tech_name
Source

Instance methods

analyze
Source
analyze_file(path : String) : Array(Endpoint)
Source
tech

Instance-side view of the same declaration. The per-file rescues live on this base class, which has no way to name the analyzer that is running inside them, so a skipped file could not be attributed to a tech. Deriving it from analyzer_for keeps the name written exactly once.

Source

Nested types