Podstrčení jiného obrázku pokud dotazovaný neexistuje

- holantomas
 - Člen | 55
 
Zdravím,
velice jednoduchá věc. Jelikož jsem si tu toho dost přečetl, tak jsem
zjistil, že bych neměl do .htaccess vůbec lést. Takže bych chtěl poprosit
o pomoc s nastavením routeru. A to tak. Pokud napr.
uploads/photos/teachers/1.jpg nebo uploads/photos/students/3.jpg neexistuji, tak
se nahradí prohlížeči podstrčí images/incognito.jpg. O to jaký http kód
odešlě mi nejde může klidně poslat 302(myslím že by to bylo
i lepší).
Zkoušel jsem hodně kombinací a zkončil u téhle.
<?php
	public function createRouter()
	{
		$router = new RouteList();
		$router[] = new Route('<presenter>[-<page>]/<action>[/<id>]', 'Homepage:default');
                $router[] = new Route('uploads/photos/teachers/<photo>', array(
		    'presenter' => 'Homepage',
		    'action'	=> 'default',
                    'photo'     => 'incognito.jpg'
                ));
		return $router;
	}
?>
Problém je v tom, když si otevřu samotný obrázek co existuje např. http://neco.cz/…achers/1.jpg tak URl zůstane stejná a obrázek se zobrazí. Ale když dám např. http://neco.cz/…achers/2.jpg, (tento obrázek neexistuje) tak se mi zobrazí hlavní stránka a a URL se změní na http://neco.cz/?… a já chci http://neco.cz/…ncognito.jpg

- MartinitCZ
 - Člen | 580
 
Tohle nemá v routě co dělat.
Přesun logiku do akce:
function actionDefault($photo)
{
....
	if (file_exists($file = SLOZKA_FOTEK . '/' . $photo)) {
		return $file;
	} else {
		return SLOZKA_FOTEK . '/incognito.jpg';
	}
....
}
				
- holantomas
 - Člen | 55
 
Tak to se omlouvám, ale to je podle mě blbost. Proč kopírovat stejný kód 20× když můžu v .htaccess napsat jeden řádek ? Tomuhle přesně jsem se chtěl vyhnout.

- enumag
 - Člen | 2118
 
Moje představa je přibližně následující:
- všechny obrázky budou v jedné složce (nebo několika málo složkách), např. /upload
 - pokud obrázek existuje tak se prostě zobrazí, Nette se vůbec nedostane ke slovu (nelze použít v případech kdy je vyžadována autorizace pro zobrazení obrázku)
 - pokud obrázek neexistuje, odchytne to přibližně takováhle routa:
 
$router[] = new Route('uploads/<photo .+>', array(
	'presenter' => 'Images',
	'action'    => 'default'
));
Presenter pak dle parametru photo rozezná jaké rozměry má obrázek mít
(to by se dalo řešit už v route a presenter by dostal
$dimensions či $width a $height) a
vrátí výchozí obrázek v potřebných rozměrech, případně na něj
přesměruje pomocí redirectUrl (sám nevím která možnost je lepší –
zda vrátit rovnou nebo přesměrovat).
Editoval enumag (30. 9. 2013 17:33)

- holantomas
 - Člen | 55
 
Nad tím vytvořit čistý presenter pro zobrazení obrázku jsem taky přemýšlel … a zatím se to jeví jako nejlepší nápad

- frosty22
 - Člen | 373
 
Jo a jenom alternative – né vždy to jde, záleží oč se přímo snažíš, ale občas je hezčí toto řešit přes JS/CSS. Minimálně je to méně náročné na server, pokud se jedná o zatíženější web, či pokud se jedná o vyšší množství obrázků, které nemusí existovat.
Buď přes CSS nastavit background v tom bloku rovnou ten blank obrázek a když se načte obrázek, tak ho překryje, či případně přes JS navěsit událost onError na tagy IMG a když se nenačte obrázek nahradit za cestu k neexistujícímu.

- holantomas
 - Člen | 55
 
Nápad s CSS se mi líbí děkuji za inspiraci. JS se mi nelíbí je to zavádějící, uživatel vypne JS a potom tam bude mít hnusné čtverečky.

- petr.pavel
 - Člen | 535
 
CSS pozadí: Ty čtverečky tam v IE budeš mít taky, protože tvůj obrázek bude nad pozadím. Tudíž i ten [x] bude nad pozadím.
Jako další alternativu nabízím definovat přes .htaccess vlastní 404 dokument – adresu nějaké akce v Nette. Ta potom vrátí/přesměruje na ten incognito-123×456.jpg.
Tím mimo jiné také zajistíš, aby se vracela 404 a prohlížeče/vyhledávače tak pochopili, že obrázek opravdu neexistuje – ne, že byl přesunut (302).

- holantomas
 - Člen | 55
 
petr.pavel napsal(a):
adresu nějaké akce v Nette. Ta potom vrátí/přesměruje na ten incognito-123×456.jpg.Tím mimo jiné také zajistíš, aby se vracela 404 a prohlížeče/vyhledávače tak pochopili, že obrázek opravdu neexistuje – ne, že byl přesunut (302).
Ono je to ale stejné řešení jako uvádí enumag

- holantomas
 - Člen | 55
 
enumag napsal(a):
Moje představa je přibližně následující:
- všechny obrázky budou v jedné složce (nebo několika málo složkách), např. /upload
 - pokud obrázek existuje tak se prostě zobrazí, Nette se vůbec nedostane ke slovu (nelze použít v případech kdy je vyžadována autorizace pro zobrazení obrázku)
 - pokud obrázek neexistuje, odchytne to přibližně takováhle routa:
 $router[] = new Route('uploads/<photo .+>', array( 'presenter' => 'Images', 'action' => 'default' ));Presenter pak dle parametru photo rozezná jaké rozměry má obrázek mít (to by se dalo řešit už v route a presenter by dostal
$dimensionsči$widtha$height) a vrátí výchozí obrázek v potřebných rozměrech, případně na něj přesměruje pomocí redirectUrl (sám nevím která možnost je lepší – zda vrátit rovnou nebo přesměrovat).
Jak v tomto případě vyřešit view? Tedy mám udělaný presenter. Z adresy uploads/image.jpg?width=170&height=170 se mi to zroutuje na Noimage:default. Jak teď udělat to aby se mi vykreslil jen samotný nahrazující obrázek ? Aktuálně se mi vykresluje celý layout stránky.

- holantomas
 - Člen | 55
 
enumag napsal(a):
Presenter::sendResponse(new FileResponse)
Můj presenter
<?php
class NoimagePresenter extends BasePresenter {
    protected function startup() {
        parent::startup();
    }
    public function actionDefault() {
        $this->sendReponse(new \Nette\Application\Responses\FileResponse($this->context->params['wwwDir'] . '/images/incognito.jpg'));
    }
}
?>
A laděnka vyhazuje:
`Nette\MemberAccessException
Call to undefined method NoimagePresenter::sendReponse().`
Přižemž se zkoušel i $this->presenter->sendRes… Ale vždy to samé přitom netbeans mi nabízí v obou případech tuto funkci.

- holantomas
 - Člen | 55
 
vvoody napsal(a):
sendReSponse
OMG, tak to se omlouvám :D
Tak všem zúčastněným děkuji. Vše funguje tak jak má.