Dvojité přidávání presenterů
- kajinek32
- Člen | 35
Ahoj, u nette 3.1 mám problém s načítáním presenterů
Cannot declare class FrontendModule\HomepagePresenter, because the name is already in use
Což zní celkem jasně, že bych tam měl presenter vícekrát. Nicméně
hledání v souborech žádný další (ve stejném namespace) nenachází.
Navíc, když tento presenter přejmenuju např. na Homepage2Presenter, chyba se
vypíše taky, jen s názvem Homepage2Presenter.
Napadá mě, že se „někde“ dvakrát volá načítání presenterů, nicméně Bootstrap.php mám původní ze sandboxu, stejně tak www/index.php.
HomepagePresenter.php mám v app/FrontendModule/Presenters/ v tomto tvaru:
declare(strict_types=1);
namespace FrontendModule;
/**
* Description of HomepagePresenter
*
*/
final class HomepagePresenter extends FrontendPresenter
{
public function renderDefault()
{
}
}
dědí od FrontendPresenteru ve stejné složce
declare(strict_types=1);
namespace FrontendModule;
/**
* Description of FrontendPresenter
*
*/
class FrontendPresenter extends \BasePresenter
{
protected function error403()
{
throw new \Nette\Application\ForbiddenRequestException;
}
protected function error404()
{
throw new \Nette\Application\BadRequestException;
}
}
a ten dědí od BasePresenteru z app/Presenters/
declare(strict_types=1);
/**
* Base presenter for all application presenters.
*/
class BasePresenter extends \Nette\Application\UI\Presenter
{
protected function startup()
{
parent::startup();
}
protected function beforeRender()
{
}
}
v configu mám mapping:
application:
errorPresenter: Error
mapping:
*: App\*Module\Presenters\*Presenter
a v routeru
$router->addRoute('front/<presenter>[/<action=default>]', array(
'module' => 'Frontend',
'presenter' => array(
Route::VALUE => 'Homepage',
Route::FILTER_TABLE => $presenterTable
),
'action' => 'default'
));
Napadá vás, kde by mohla být chyba? Presentery jsem si zkopíroval
z projektu, který byl na nette 2.4, ale porovnával jsem je se sandboxem, a
rozdíl jsem nenašel.
Díky
- kajinek32
- Člen | 35
Index.php:
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
App\Bootstrap::boot()
->createContainer()
->getByType(Nette\Application\Application::class)
->run();
Bootstrap.php
declare(strict_types=1);
namespace App;
use Nette\Bootstrap\Configurator;
class Bootstrap
{
public static function boot(): Configurator
{
$configurator = new Configurator;
$appDir = dirname(__DIR__);
//$configurator->setDebugMode('secret@23.75.345.200'); // enable for your remote IP
$configurator->enableTracy($appDir . '/log');
error_reporting(~E_USER_DEPRECATED); // note ~ before E_USER_DEPRECATED
$configurator->setTimeZone('Europe/Prague');
$configurator->setTempDirectory($appDir . '/temp');
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
$configurator->addConfig($appDir . '/config/common.neon');
$configurator->addConfig($appDir . '/config/local.neon');
$configurator->addConfig($appDir . '/config/settings.neon');
return $configurator;
}
}
a composer.json
{
"name": "nette/web-project",
"description": "Nette: Standard Web Project",
"keywords": ["nette"],
"type": "project",
"license": ["MIT", "BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
"require": {
"php": ">= 7.2",
"nette/application": "^3.1",
"nette/bootstrap": "^3.1",
"nette/caching": "^3.1",
"nette/database": "^3.1",
"nette/di": "^3.0",
"nette/finder": "^2.5",
"nette/forms": "^3.1",
"nette/http": "^3.1",
"nette/mail": "^3.1",
"nette/robot-loader": "^3.3",
"nette/security": "^3.1",
"nette/utils": "^3.2",
"latte/latte": "^2.9",
"tracy/tracy": "^2.8",
"dg/ftp-deployment": "^3.3",
"ublaboo/datagrid": "^6.6"
},
"require-dev": {
"nette/tester": "^2.3",
"symfony/thanks": "^1"
},
"autoload": {
"psr-4": {
"App\\": "app"
}
},
"minimum-stability": "stable"
}
- Kamil Valenta
- Člen | 815
kajinek32 napsal(a):
Nicméně hledání v souborech žádný další (ve stejném namespace) nenachází.
Hledáš v IDE nebo přímo na disku?
- kajinek32
- Člen | 35
Ondřej Kubíček napsal(a):
takhle to všechno vypadá oukej. Cache si mazal nebo máš prázdnou že?
jj, cache jsem mazal.
Hledal jsem v IDE (VS CODE), ale jak jsem psal, i když ten presenter přejmenuju, chyba se objevuje stále (tj. nejde nejspíš o to, že bych měl dvakrát HomepagePresenter, ale spíš, že se nějak načítá dvakrát…
- Kamil Valenta
- Člen | 815
Zkus hledat i přímo na disku, aby se vyloučily nějaké „on save“
rutiny, které mohou v IDE být nastaveny.
Také se podívej do všech 3 neonů, neregistruješ např.
presentery ručně?
- kajinek32
- Člen | 35
Šaman napsal(a):
Ještě mě napadá, jestli nemáš nějaké načítání presenterů jako služeb v configu. Jinak podobný problém byl se starým RobotLoaderem na PHP8, ale ta hláška zněla jinak a ty máš podle composeru nový. Takže předpokládám, že tímhle to není.
No něco takového (načítání i jako služba) bych právě čekal, že to je, nicméně common.neon mám téměř kompletně zakomentovaný.
Zkusil jsem to i na kompletně čistém nette web-project, kam jsem jen vložil FrontendModule/Presenters/HomepagePresenter.php a upravil router.
říkám si, jestli nějak složku app nenačítá composer
"autoload": {
"psr-4": {
"App\\": "app"
}
},
a zároveň Bootstrap
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
ale ani jedno, když vypustím, problém neřeší…
- kajinek32
- Člen | 35
Šaman napsal(a):
A co je v routeru v té
$presenterTable
? Když píšeš, žes to zkoušel na čistém WebProjectu, vložil jsi Presenter a upravil router, tak bych se asi soutředil na ten router (bo ten presenter vypadá nevinně).
v $presenterTable bylo původně
$presenterTable = [
'uzivatele' => 'Users',
];
nicméně, zkusil jsem router ještě zjednodušit podle dokumentace a ani tak to nejde
$router->addRoute('front/<presenter=Homepage>[/<action=default>]', array(
'module' => 'Front',
));
Případně tenhle pokus dej někam na Github, ať si ho můžeme proklikat.
Díky moc, zjednodušenou verzi jsem umístil zde (je bez složek log, temp a vendor, snad se to takhle dělá)
běžná routa /www/ s defaultním textem se spustí v pohodě, problém nastane, když zavolám /www/front/, nebo když do toho app/Presenters/templates/default.latte dám
<a n:href=":Front:Homepage:default">odkaz</a>
Editoval kajinek32 (10. 2. 2021 14:29)
- Ondřej Kubíček
- Člen | 494
ten namespace v souboru FrontModule/Presenter/HomepagePresenter.php musí
být namespace App\FrontModule\Presenters;
ne
jenom FrontModule
Editoval Ondřej Kubíček (10. 2. 2021 14:52)
- Ondřej Kubíček
- Člen | 494
možná není :D dobře at nekecám, jen jsem si tak tipnul, když mu to na starém projektu šlo
@kajinek32 a na starým projektu jsi měl mapping v konfigu nastavený jak, když ti to fungovalo?
- kajinek32
- Člen | 35
Ondřej Kubíček napsal(a):
možná není :D dobře at nekecám, jen jsem si tak tipnul, když mu to na starém projektu šlo
@kajinek32 a na starým projektu jsi měl mapping v konfigu nastavený jak, když ti to fungovalo?
překvapivě
*: *Module\*Presenter
jen jsem si toho tady nevšimnul… :)
- Šaman
- Člen | 2658
Jinak to
"autoload": {
"psr-4": {
"App\\": "app"
}
},
je myslím jen pro načtení Bootstrapu. V novém index.php
se
už neincluduje bootstrap, ale vendor/autoload.php
. Rozhodně není
nutné držet psr-4 v adresáři app/
.
Dodatek: Teď jsem to zkoušel a i se zakomentovaným Robotloaderem (v Bootstrapu) aplikace funguje, dokud drží PSR-4 strukturu. Ale bez ní pak zafunguje RobotLoader, který třídu najde kdekoliv v zadaných adresářích.
P.S. A tím, že ty jsi neměl presentery v namespace App
, tak
to šlo úplně mimo tebe. To PSR-4 tvoje presentery myslím ani nehledalo.
Editoval Šaman (10. 2. 2021 15:49)
- Daewoo
- Člen | 34
Jen chci dodat, že jsem právě na to narazil teď na jednom starém projektu a totožná chyba měla příčinu v tom, že jsem při definici dokumentačních templates tříd špatně dodržel jejich pořadí – extendující třída byla v kódu dříve, než byla ona sama definovaná. Čili toto je špatně:
class BannerPresenterEditTemplate extends BannerPresenterCreateTemplate
{
/** @var string[] */
public $post;
/** @var string */
public $bannerTitle;
}
class BannerPresenterCreateTemplate extends ProtectedPresenterTemplate
{
/** @var string|null */
public $bannerImageUrl;
}
A toto dobře:
class BannerPresenterCreateTemplate extends ProtectedPresenterTemplate
{
/** @var string|null */
public $bannerImageUrl;
}
class BannerPresenterEditTemplate extends BannerPresenterCreateTemplate
{
/** @var string[] */
public $post;
/** @var string */
public $bannerTitle;
}
Editoval Daewoo (7. 11. 20:52)