Jak vyrobit odkaz na soubor

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

Ahoj, můžete mi prosím pomoct s následující věcí. Asi jsem něco pochopil špatně a nějak se nemůžu dokomplikovat k výsledku. Mám datagrid a callbackem upravuju sloupec. Rád bych, aby ve sloupci nebyl název souboru vybraný z databáze, ale odkaz na něj.

Takže jsem v callbacku vyrobil tohle:

$path = 'files/neco/' . $value;
return Html::el('a')->href($path)->setText('file');

Jenže to mi do cesty vkládá ještě před files/neco/… aktuální presenter a akci. Předpokládám, že problém bude v routování? Mám klasický routy:

$router = $application->getRouter();

$router[] = new Route('index.php', array(
	'module' => 'Front',
  'presenter' => 'Default',
	'action' => 'default',
), Route::ONE_WAY);

$router[] = new Route('<presenter>/<action>/', array(
	'module' => 'Front',
  'presenter' => 'Default',
	'action' => 'default',
));

Pročetl jsem toho nejen o routování tuny (hledám rady na netu už celej den), ale nějak mi to stále nevlezlo pod kůži (takže moje pokusy o dodání nějaké funkční routy se nepovedly) a nebo jsem nenarazil na ty správný informace. Je mi jasný, že se pak zase budu tahat za nos, jak jsem blbej, ale mohl by jste mi prosím někdo poradit?

Vyki
Člen | 388
+
0
-

Pokud to toho odkazu vkládáš natvrdo cestu k souboru, který na serveru skutečně existuje, obslouží ten request apache a na routy se vůbec nedostane. EDIT: pokud je ta složka files na stejné úrovni jako index.php tak bys měl psát ‚/files/neco/soubor.jpg‘ místo ‚files/neco/soubor.jpg‘. Jinak by ta cesta byla relativní.

Editoval Vyki (22. 7. 2010 12:53)

Gruid
Člen | 25
+
0
-

Mno pokud do odkazu namastim přímo toto http://server/projekt/document_root/files/neco/soubor.jpg tak to funguje, ale jakmile tam dám jen /files/neco/soubor.jpg, tak jest výsledkem: http://server/files/neco/soubor.jpg. Čili chybí projekt/document_root/ a odkaz je nefunkční. Zadávání celý cesty se mi zdá nepraktický, tak hledám, jak na to lépe.

PS: Relativní adresa pak vloží do odkazu ještě presenter a akci: http://server/projekt/document_root/aktualnipresenter.default/files/neco/soubor.jpg, na což laděnka reaguje hláškou, že pro tento požadavek není routa.

Jakožto začátečník jsem zmaten :)

Editoval Gruid (22. 7. 2010 13:19)

Vyki
Člen | 388
+
0
-

S takovou nešikovnou (patrně provizorní) adr. strukturou tam pak musíš psát /projekt/document_root/files/neco/soubor.jpg. Určitě by se ti to odlaďovalo lépe kdyby jsi po zadání http://server/ viděl index.php. Tu základní adr. strukturu, kde je index.php umístěn ve složce document_root neber jako dogma. Pokud ti webserver míří na disku třeba do složky www, kde budeš mít index.php, potom se ti pozadání http://server/ rovnou zobrazí index.php. Není tedy nic jednoduššího, než do stejného adresáře, kde je index.php, nahrát i adresáře app a libs. Stačí pak v index.php mít správně nastavenou cestu do těch adresářů:

<?php
// absolute filesystem path to the web root
define('WWW_DIR', dirname(__FILE__));

// absolute filesystem path to the application root
define('APP_DIR', WWW_DIR . '/app');

// absolute filesystem path to the libraries
define('LIBS_DIR', WWW_DIR . '/libs');

// load bootstrap file
require APP_DIR . '/bootstrap.php';
?>

Va takovém případě je velmi důležité zamezit přístupu do adresářů libs a app, tím že v každém z nich bude .htaccess soubor s obsahem:

Order Allow,Deny
Deny from all

Jinak by byly přístupné přes web a každý by se mohl podívat na hesla do config.ini.

westrem
Člen | 398
+
0
-

Gruid napsal(a):

Mno pokud do odkazu namastim přímo toto http://server/projekt/document_root/files/neco/soubor.jpg tak to funguje, ale jakmile tam dám jen /files/neco/soubor.jpg, tak jest výsledkem: http://server/files/neco/soubor.jpg. Čili chybí projekt/document_root/ a odkaz je nefunkční. Zadávání celý cesty se mi zdá nepraktický, tak hledám, jak na to lépe.

PS: Relativní adresa pak vloží do odkazu ještě presenter a akci: http://server/projekt/document_root/aktualnipresenter.default/files/neco/soubor.jpg, na což laděnka reaguje hláškou, že pro tento požadavek není routa.

Jakožto začátečník jsem zmaten :)

To je jasne, ze sa vlozi presenter a akcia pri coolURI, a nerobi to Nette ale browser ;) proste berie aktualnu URL ako base a pri relativne zadanej ceste appenduje k URL.

Pri pouziti /files/neco/soubor.jpg sa zase za base berie len server adresa takze to spravi presne co si napisal.

Najlepsie je si v indexe nadefinovat dalsiu konstantu ako BASE_DIR, ktora by odkazovala vzdy na umiestnenie indexu (tzn) akoby zakladne tvojho projektu a potom linkovat absolutne pomocou toho, takze:

<?php

//v indexe
define("BASE_DIR", "/projekt/document_root");

//v callbacku
$path = BASE_DIR.'/files/neco/' . $value;

?>

toto by malo fungovat a je to elegantne riesenie, kde ked nahodou presunies projekt inde, staci zmenit jednu konstantu a ides ;)

na1k
Člen | 288
+
0
-

Nevím proč http://server != http://server/document_root, jak bývá zvykem, ale zkusím do placu hodit jednu myšlenku. Co použít DownloadResponse ?

Budeš sice muset přidat jednu akci navíc, které budeš dávat jako parametr cestu k souboru, ale budeš moct přístup plně řídit. Například povolit stažení jen oprávněným uživatelům, a hlavně – soubory budou moct být kdekoliv, tedy ne jen v adresářích přístupných všem. Soubor pak adresuješ cestou relativní k index.php a nebereš v úvahu routy ani mod_rewrite.

Mohlo by to vypadat takto:

<?php
// $file = '/cesta/k/souboru.jpg', předáváno v odkazu např. {plink download, $file}
public function actionDownload($file) {
	$this->terminate( new DownloadResponse($file) );
}
?>
Gruid
Člen | 25
+
0
-

Díík moc všem, přesně takováhle nakopnutí jsem potřeboval. Nějak jsem se v tom plácal a haledal složitosti, přitom je to tak jasný … nakonec jako vždycky :) Ještě jednou dík.

Editoval Gruid (22. 7. 2010 14:23)

Patrik Votoček
Člen | 2221
+
0
-

btw pokdu by jsi to chtěl bez zatěžování frameworkem. Tak můžeě i

$path = Environment::getVariable('baseUri') . 'files/neco/' . $value;
Honza Kuchař
Člen | 1662
+
0
-

… a nebo pokud je potřeba podrobnější nastavení, tak FileDonwloader.