use DOMDocument;
use DOMXPath;
use Exception;
+use FastRoute\RouteCollector;
use Friendica\Core\Config\Cache\IConfigCache;
use Friendica\Core\Config\Configuration;
+use Friendica\Core\Hook;
+use Friendica\Core\Theme;
use Friendica\Database\DBA;
use Friendica\Model\Profile;
use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
use Friendica\Util\HTTPSignature;
use Friendica\Util\Profiler;
+use Friendica\Util\Strings;
use Psr\Log\LoggerInterface;
/**
*/
class App
{
- public $module_loaded = false;
public $module_class = null;
public $query_string = '';
public $page = [];
*/
private $mode;
- /**
- * @var string The App base path
- */
- private $basePath;
-
/**
* @var string The App URL path
*/
*/
public function getBasePath()
{
- return $this->basePath;
+ return $this->config->get('system', 'basepath');
}
/**
*/
public function registerStylesheet($path)
{
- $url = str_replace($this->getBasePath() . DIRECTORY_SEPARATOR, '', $path);
+ if (mb_strpos($path, $this->getBasePath() . DIRECTORY_SEPARATOR) === 0) {
+ $path = mb_substr($path, mb_strlen($this->getBasePath() . DIRECTORY_SEPARATOR));
+ }
- $this->stylesheets[] = trim($url, '/');
+ $this->stylesheets[] = trim($path, '/');
}
/**
/**
* @brief App constructor.
*
- * @param string $basePath The basedir of the app
* @param Configuration $config The Configuration
* @param App\Mode $mode The mode of this Friendica app
* @param LoggerInterface $logger The current app logger
*
* @throws Exception if the Basepath is not usable
*/
- public function __construct($basePath, Configuration $config, App\Mode $mode, LoggerInterface $logger, Profiler $profiler, $isBackend = true)
+ public function __construct(Configuration $config, App\Mode $mode, LoggerInterface $logger, Profiler $profiler, $isBackend = true)
{
BaseObject::setApp($this);
$this->config = $config;
$this->profiler = $profiler;
$this->mode = $mode;
- $cfgBasePath = $this->config->get('system', 'basepath');
- $this->basePath = !empty($cfgBasePath) ? $cfgBasePath : $basePath;
-
- if (!Core\System::isDirectoryUsable($this->getBasePath(), false)) {
- throw new Exception('Basepath \'' . $this->getBasePath() . '\' isn\'t usable.');
- }
- $this->basePath = rtrim($this->getBasePath(), DIRECTORY_SEPARATOR);
$this->checkBackend($isBackend);
$this->checkFriendicaApp();
$this->getMode()->determine($this->getBasePath());
if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
- $loader = new ConfigCacheLoader($this->getBasePath(), $this->getMode());
+ $loader = new ConfigFileLoader($this->getBasePath(), $this->getMode());
$this->config->getCache()->load($loader->loadCoreConfig('addon'), true);
$this->profiler->update(
$this->config->get('rendertime', 'callstack', false));
Core\Hook::loadHooks();
- $loader = new ConfigCacheLoader($this->getBasePath(), $this->mode);
+ $loader = new ConfigFileLoader($this->getBasePath(), $this->mode);
Core\Hook::callAll('load_config', $loader);
}
'fetch',
'hcard',
'hostxrd',
+ 'manifest',
'nodeinfo',
'noscrape',
'p',
// Sane default
$this->currentTheme = $system_theme;
- $allowed_themes = explode(',', $this->config->get('system', 'allowed_themes', $system_theme));
-
$page_theme = null;
// Find the theme that belongs to the user whose stuff we are looking at
if ($this->profile_uid && ($this->profile_uid != local_user())) {
$theme_name = $user_theme;
}
+ $theme_name = Strings::sanitizeFilePathItem($theme_name);
if ($theme_name
- && in_array($theme_name, $allowed_themes)
+ && in_array($theme_name, Theme::getAllowedList())
&& (file_exists('view/theme/' . $theme_name . '/style.css')
|| file_exists('view/theme/' . $theme_name . '/style.php'))
) {
$this->module = 'maintenance';
} else {
$this->checkURL();
- Core\Update::check($this->getBasePath(), false);
+ Core\Update::check($this->getBasePath(), false, $this->getMode());
Core\Addon::loadAddons();
Core\Hook::loadHooks();
}
$this->module = "login";
}
+ $router = new App\Router();
+ $this->collectRoutes($router->routeCollector);
+
+ $this->module_class = $router->getModuleClass($this->cmd);
+
$privateapps = $this->config->get('config', 'private_addons', false);
- if (Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
+ if (!$this->module_class && Core\Addon::isEnabled($this->module) && file_exists("addon/{$this->module}/{$this->module}.php")) {
//Check if module is an app and if public access to apps is allowed or not
if ((!local_user()) && Core\Hook::isAddonApp($this->module) && $privateapps) {
info(Core\L10n::t("You must be logged in to use addons. "));
if (function_exists($this->module . '_module')) {
LegacyModule::setModuleFile("addon/{$this->module}/{$this->module}.php");
$this->module_class = 'Friendica\\LegacyModule';
- $this->module_loaded = true;
}
}
}
// Controller class routing
- if (! $this->module_loaded && class_exists('Friendica\\Module\\' . ucfirst($this->module))) {
+ if (!$this->module_class && class_exists('Friendica\\Module\\' . ucfirst($this->module))) {
$this->module_class = 'Friendica\\Module\\' . ucfirst($this->module);
- $this->module_loaded = true;
}
/* If not, next look for a 'standard' program module in the 'mod' directory
* We emulate a Module class through the LegacyModule class
*/
- if (! $this->module_loaded && file_exists("mod/{$this->module}.php")) {
+ if (!$this->module_class && file_exists("mod/{$this->module}.php")) {
LegacyModule::setModuleFile("mod/{$this->module}.php");
$this->module_class = 'Friendica\\LegacyModule';
- $this->module_loaded = true;
}
/* The URL provided does not resolve to a valid module.
*
* Otherwise we are going to emit a 404 not found.
*/
- if (! $this->module_loaded) {
+ if (!$this->module_class) {
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
if (!empty($_SERVER['QUERY_STRING']) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
exit();
$content = '';
// Initialize module that can set the current theme in the init() method, either directly or via App->profile_uid
- if ($this->module_loaded) {
+ if ($this->module_class) {
$this->page['page_title'] = $this->module;
$placeholder = '';
$func($this);
}
- if ($this->module_loaded) {
+ if ($this->module_class) {
if (! $this->error && $_SERVER['REQUEST_METHOD'] === 'POST') {
Core\Hook::callAll($this->module . '_mod_post', $_POST);
call_user_func([$this->module_class, 'post']);
$this->internalRedirect($toUrl);
}
}
+
+ /**
+ * @brief Static declaration of Friendica routes.
+ *
+ * Supports:
+ * - Route groups
+ * - Variable parts
+ * Disregards:
+ * - HTTP method other than GET
+ * - Named parameters
+ *
+ * Handler must be the name of a class extending Friendica\BaseModule.
+ *
+ * @param RouteCollector $routeCollector
+ * @throws InternalServerErrorException
+ */
+ private function collectRoutes(RouteCollector $routeCollector)
+ {
+ $routeCollector->addRoute(['GET', 'POST'], '/itemsource[/{guid}]', Module\Itemsource::class);
+
+ Hook::callAll('route_collection', $routeCollector);
+ }
}