inject modelu do RouterFactory

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Toliceek
Člen | 9
+
0
-

Zdravím,

potřeboval bych poradit jak dostanu model do RouterFactory.

Snažím se udělat hezké URL adresy, soubor RouterFactory.php vypadá takto

<?php

namespace App\Router;

use Nette,
	Nette\Application\Routers\RouteList,
	Nette\Application\Routers\Route,
	Nette\Application\Routers\SimpleRouter;


/**
 * Router factory.
 */
class RouterFactory
{

	/** @var \App\Model\SlugManager @inject */
	public $slugManager;

	/**
	 * @return \Nette\Application\IRouter
	 */
	 public function createRouter()
	 	{
	 		$router = new RouteList();
	 		$router[] = new CustomRouter($this->slugManager);
	 		$router[] = new Route('<presenter>/<action>', 'Homepage:default');

	 		return $router;
	 	}

}

Tanto zápis mi však vyhazuje error

Nette\DI\MissingServiceException
Service ‚slugManager‘ not found.

stejný přístup mi funguje v presenterech, myslel jsem že to tedy zde bude stejné.

Poradíte mi někdo jakým způsobem mám dostat model který má přístup do databáze do routy?

Děkuji

Šaman
Člen | 2666
+
0
-

Anotace @inject funguje JEN v presenterech. Všude jinde použij konstruktor.

CZechBoY
Člen | 3608
+
0
-

Píše to, že taková služba není v configu.
Doporucuju si tam tu závislost předat pres konstruktor.

Toliceek
Člen | 9
+
0
-

Pokud použiji konstruktor místo inject

		/** @var SlugManager */
		private $slugManager;

		public function __construct(SlugManager $slugManager)
		{
			$this->slugManager = $slugManager;
		}

chyba zůstává stejná :(

je mi divné, že když přejmenuji proměnou kterou předávám CustomRoutě například takto

$router[] = new CustomRouter($this->slugManager99);

error zůstává stejný, pouze se změní název služby

Service ‚slugManager99‘ not found.

Nemělo by to na mě křičet že proměnná slugManager99 neexistuje?

F.Vesely
Člen | 369
+
0
-

Ukaz config.neon

Toliceek
Člen | 9
+
0
-
#
# WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
# http://nette.org/security-warning
#
parameters:


php:
	date.timezone: Europe/Prague


application:
	errorPresenter: Error
	mapping:
		*: App\*Module\Presenters\*Presenter


session:
	expiration: 14 days


services:
	- App\Model\SlugManager
	- App\Model\UserManager
	- App\Forms\SignFormFactory
	- App\Model\CategoriesModel
	- App\Model\ArticlesModel

	router: App\Router\RouterFactory::createRouter
Šaman
Člen | 2666
+
0
-

Nevím, jestli to v configu je opravdu statické volání, nebo co přesně s tímto zápisem DI kontejner udělá. Pokud by to bylo volání statické funkce, tak tam samozřejmě není možné používat $this. Ale jestli se to nějak spouští jakoby nad kontejnerem, tak by to mohlo vysvětlovat tu podivnou hlášku.

CZechBoY
Člen | 3608
+
0
-

Nemůžeš si předat rovnou instanci CustomRoutereru? Nebo jich může být více a není to služba?
btw. v konstruktoru si tu službu ukládáš do $this->slugManager a v createRouter přistupuješ k $this->slugManager99.

Není chyba až v tom CustomRouteru? Pošli kod

Editoval CZechBoY (23. 12. 2015 18:12)

Toliceek
Člen | 9
+
0
-

CZechBoY napsal(a):

btw. v konstruktoru si tu službu ukládáš do $this->slugManager a v createRouter přistupuješ k $this->slugManager99.

Já vím, to bylo jen pro demonstraci že mi přijde, že si to tu proměnnou naplněnou v konstruktoru stejně nebere.

CustomRouter.php

<?php
namespace App\Router;

use Nette;
use Nette\Application as App;
use Nette\Http;


class CustomRouter extends Nette\Object implements Nette\Application\IRouter
{
	/** @var SlugManager */
	private $slugManager;

	/** @var array (slugs.type => presenter name) */
	private $presenters = array(
		'group' => 'Groups',
		'articles' => 'Articles',
	);

	public function __construct(SlugManager $slugManager)
	{
		$this->slugManager = $slugManager;
	}

	/**
	 * Maps HTTP request to a Request object.
	 *
	 * @return App\Request|NULL
	 */
	public function match(Http\IRequest $httpRequest)
	{
		$slug = $httpRequest->getUrl()->getPathInfo();
		$row = $this->slugManager->getBySlug($slug);
		if (!$row || !isset($this->presenters[$row->type])) return NULL;

		$presenter = $this->presenters[$row->type];
		$params = $httpRequest->getQuery();
		$params['action'] = 'default';
		$params['slug'] = $slug;

		return new App\Request(
			$presenter,
			$httpRequest->getMethod(),
			$params,
			$httpRequest->getPost(),
			$httpRequest->getFiles(),
			array(App\Request::SECURED => $httpRequest->isSecured())
		);
	}

	/**
	 * Constructs absolute URL from Request object.
	 *
	 * @return string|NULL
	 */
	public function constructUrl(App\Request $appRequest, Http\Url $refUrl)
	{
		if (!in_array($appRequest->presenterName, $this->presenters)) return NULL;

		$params = $appRequest->getParameters();
		$slug = isset($params['slug']) ? $params['slug'] : NULL;
		$action = isset($params['action']) ? $params['action'] : NULL;
		if ($action !== 'default' || !is_string($slug)) return NULL;
		unset($params['action'], $params['slug']); // we don't want to have 'action' and 'slug' in query parameters

		$url = new Http\Url($refUrl->getBaseUrl() . $slug);
		$url->setQuery($params);
		return $url->getAbsoluteUrl();
	}
}

do CustomRouteru se mi to ani nedostane. Je zvláštní, že pokud udělám něco jako

$router[] = new CustomRouter($jakykolivretezecjakopromena);

tak mi to začne řvát na CustomRoutě že v konstruktoru není instance App\Router\SlugManager . SlugManager je ale v App\Model\SlugManager.

Editoval Toliceek (23. 12. 2015 18:25)

CZechBoY
Člen | 3608
+
+1
-

Chybí ti nahoře

use App\Model\SlugManager;
Šaman
Člen | 2666
+
+1
-

A v use sekci máš App\Model\SlugManager?

Toliceek
Člen | 9
+
0
-

CZechBoY napsal(a):

Chybí ti nahoře

use App\Model\SlugManager;

ajo, díky.

Šaman napsal(a):

Chybí ti nahoře

use App\Model\SlugManager;

myslíš v RouterFactory? Tam jsem to přidal taky, ale nic se nezměnilo.

už se tu v tom ležím 3 den, stáhnul jsem si projekt kde je ten customrouter řešen přesně takto (jak je teď, slugManager přes konstruktor), jediný rozdíl je že v každém souboru má namespace pouze " namespace App " a v configu tak registruje služby pouze jako – App\SlugManager atd. Zkoušel jsem si namespace změnit i u mě v projektu, ale stále to nefungovalo. Už jsem z toho docela na prášky.

Editoval Toliceek (23. 12. 2015 18:41)

CZechBoY
Člen | 3608
+
0
-

Co to teď hlásí za chybu?
Pošli screen z BSOD kdyžtak.

Toliceek
Člen | 9
+
0
-

Chyba je pořád stejná.

Service ‚slugManager‘ not found.

Nemůžu za boha dostat ten model do RouterFactory.

Myslíš screen laděnky?
http://imgur.com/8e5iiwq

F.Vesely
Člen | 369
+
+2
-

Pokud to nechces staticky, tak takto:

services:
	- App\Router\RouterFactory
	router: @App\Router\RouterFactory::createRouter
Toliceek
Člen | 9
+
0
-

To bohužel můj problém nijak nevyřešilo :(

Pokud by se tu našel někdo kdo by se mi na to byl schopný podívat, respektive zprovoznit (samozřejmě za úplatu) tak se mi prosím ozvěte na email toliceek[zavináč]gmail.com .

Pokud se do toho nikomu nebude chtít, tak si zítra zadám poptávku na webtrhu. Realizace není nutná ihned.

Všem zúčastněným děkuji za reakce.

Editoval Toliceek (23. 12. 2015 19:27)

David Matějka
Moderator | 6445
+
0
-

muzes prosim poslat zazipovany cely ten projekt? ta chyba je hodne divna, zitra bych na to kouknul… (kdyztak privatne na matej21@matej21.cz)

nededi ti nahodou router facotry od containeru?

Toliceek
Člen | 9
+
0
-

David Matějka: díky, už jsem to rozchodil. Nakonec byla chyba v configu, pomohlo co to psal F.Vesely.