Další Call to undefined method po update nette

scientific
Člen | 94
+
0
-

Ahoj všem,

narazil jsem na další undefined hlášku.

  • Souvislosti: Nedávno jsem aktualizoval součásti Nette pro podporu PHP 7.2.
  • Celé znění hlášky: Call to undefined method PdfResponse\PdfResponse::setDocumentTitle().
  • Debugger: Tu hlášku nezobrazuje apache, ani Nette/Tracy, ale přímo aplikace (oznamovací část webu pro notifikace po odeslání formuláře).
  • Část kódy, která vyvolává toto hlášení: To bych také rád věděl, budu rád, když mi někdo poradí, jak to zjistím. Tracy připnutá lišta v dolní stránce mi řekne jen něco, jaký presenter zprostředkovává data.
  • Můj projekt (composer.json):
{
	"name": "nette/sandbox",
	"description": "The sandbox is a pre-packaged Nette Framework project, basic configured structure for your application.",
	"homepage": "http://nette.org",
	"type": "project",
	"license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
	"authors": [
		{
			"name": "David Grudl",
			"homepage": "http://davidgrudl.com"
		},
		{
			"name": "Nette Community",
			"homepage": "http://nette.org/contributors"
		}
	],
	"require": {
		"php": ">= 7.0.0",
		"nette/application": "~2.4.0",
		"nette/bootstrap": "~2.4.0",
		"nette/caching": "~2.5.0",
		"nette/database": "~2.4.0",
		"nette/di": "~2.4.0",
		"nette/finder": "~2.4.0",
		"nette/forms": "~2.4.0",
		"nette/http": "~2.4.0",
		"nette/mail": "~2.4.0",
		"nette/robot-loader": "~2.4.0",
		"nette/safe-stream": "~2.4.0",
		"nette/security": "~2.4.0",
		"nette/utils": "~2.5.0",
		"latte/latte": "~2.4.0",
		"tracy/tracy": "~2.4.0",
		"dg/adminer-custom": "~1.6",
		"jkuchar/pdfresponse": "dev-master",
		"braintree/braintree_php" : "5.0.0",
		"vlucas/phpdotenv": "2.1.0"
	},
	"require-dev": {
		"nette/tester": "~1.3"
	}
}

Prosím si o typy, jak to uvést zase do provozu.

Editoval scientific (22. 4. 2020 13:00)

David Matějka
Moderator | 6445
+
+2
-

aktualizoval si dle vseho i jkuchar/pdfresponse

hledej v kodu, kde volas ->setDocumentTitle(...) na te pdf response a nahrad to za ->documentTitle = ...

scientific
Člen | 94
+
0
-

Super pomohlo, děkuji. Pak následovalo ještě upravit „$pdf->SetOutputFile(…)“ na „$pdf->outputName = $filename;“ a nyní jsem zaseknutý na „$pdf->output();“, který je též pravděpodobně potřeba nějak modifikovat, ale nemohu najít jak.

Chybová hláška vypadá nyní takto: Call to undefined method PdfResponse\PdfResponse::output().

$pdf->output(); mám nahradit $pdf->output = ""; ? :-D

Editoval scientific (23. 4. 2020 8:33)

nightfish
Člen | 519
+
0
-

V presenteru na vhodném místě (hádám v handle metodě) zavolej $this->sendResponse($pdf);, kde $pdf je instance PdfResponse – viz příklad v dokumentaci

EDIT: $this->send opraveno na $this->sendResponse, sorry

Editoval nightfish (23. 4. 2020 12:29)

scientific
Člen | 94
+
-1
-

To mi jen vygenrovalo další undefined method.

Původní chybovka: Call to undefined method PdfResponse\PdfResponse::output().
Původní kód: $pdf->output();

Nová chybovka: Call to undefined method App\Model\OrderManager::sendResponse()
Nový kód: $this->sendResponse($pdf);
Podle mě v mém případě bez namespace by to mělo být: $pdf->sendResponse($pdf)
Celý aktuální blok kódu:

$data = $latte->renderToString(__DIR__."/../templates/File/Report.latte", $values);
$pdf = new \PdfResponse\PdfResponse($data);
$pdf->documentTitle = "Report: ".$id;
$pdf->outputName = $filename;
//$pdf->output();
$pdf->sendResponse($pdf);
return true;

Zkoušel jsem i přidat: use PdfResponse\PdfResponse;, ale nebylo to k ničemu. Zřejmě ani v tom (nevím kde k tomu najít kod, možná někde ve vendor) také ta metoda neexistuje. Možná ten example je pro jinou verzi pdfreponse nebo nevím.

Editoval scientific (23. 4. 2020 9:36)

David Matějka
Moderator | 6445
+
+1
-

$this->sendResponse, nikoliv $pdf->sendResponse

scientific
Člen | 94
+
0
-

Jak sem psal, to právě háže tuhle aktuální chybovku od tracy: Call to undefined method App\Model\OrderManager::sendResponse()

Napomáhá ani přidat use;, což je kvůli použití přes this hádám potřeba.

Aktuální kód:

<?php

namespace App\Model;

use Nette;
use PdfResponse\PdfResponse;  // ZMĚNA #1 (PŘIDÁNO)

...

$data = $latte->renderToString(__DIR__."/../templates/File/Report.latte", $values);
$pdf = new \PdfResponse\PdfResponse($data);
$pdf->documentTitle = "Report: ".$id;
$pdf->outputName = $filename;
//$pdf->output();
//$pdf->sendResponse($pdf);
$this->sendResponse($pdf); // ZMĚNA #2 (PŘIDÁNO) a tento řádek failuje v tracy
return true;

...

Editoval scientific (23. 4. 2020 11:18)

David Matějka
Moderator | 6445
+
0
-

musíš to volat v presenteru (tedy $this musí být presenter)

scientific
Člen | 94
+
0
-

Není jiná cesta, jak to zprovoznit, aniž bych se musel milion hodin učit jak se pracuje s modely, presentery apod. celkově vůbec tenhle zřejmě správný způsob práce s OOP nechápu namespace a polymorfismus vůbec nepoužívám :-) ? Pro tebe to přijde jako easy práce na pár minut, pro mě je to pár stovek hodin učení a lámání si hlavy. :-) Chtěl bych se vyhnout jakémukoliv složitějšímu programování a zabředávání do nette, potřebuji to hlavně zprovoznit. 5 let to je takhle v modelu, musí to přece jít zařídit i nadále. Nehledě na to, že když tohle přesunu z modelu někam do presenteru, tak tím jistě způsobím řetězovou reakci problémů a ve finále to bude chtít třeba předělat celé ne. :-D

Případně bych to musel celé smazat a provozovat tu aplikaci nadále na PHP5.

Můžeš se tedy prosím ještě zamyslet, jestli by to nešlo nějak zrovoznit, jako to funguje do teď, abych se vyhnul hned programování kamsi do presenteru? Případně ještě, kdybys mi vysvětlil, proč to má (tvůj postoj je spíš takový, že vyloženě musí) být zrovna v tom presenteru, po tutoriálu jsem možná pochopil něco, jakože presenter je nějaký vrstva, která pracuje s výstupem dat do latte. Nicméně taky tohle asi není ten případ, tady se nic z toho (to PDF) na webu nezobrazuje.

Editoval scientific (23. 4. 2020 11:46)

nightfish
Člen | 519
+
0
-

scientific napsal(a):
Případně ještě, kdybys mi vysvětlil, proč to má (tvůj postoj je spíš takový, že vyloženě musí) být zrovna v tom presenteru, po tutoriálu jsem možná pochopil něco, jakože presenter je nějaký vrstva, která pracuje s výstupem dat do latte. Nicméně taky tohle asi není ten případ, tady se nic z toho (to PDF) na webu nezobrazuje.

Hlavním úkolem presenteru je zpracovat požadavek a odeslat odpověď aplikace prohlížeči a je jedno, jestli tou odpovědí bude HTML (latte šablona) nebo JSON nebo soubor ke stažení (např. tvé PDF).

Úkolem manažeru (ve tvém případě OrderManager) by měla být nějaká manipulace s daty, nikoliv posílání PDF do prohlížeče. Metodu v OrderManager stejně musíš volat buď z presenteru nebo z komponenty, takže nejjednodušším řešením je v OrderManageru v té metodě odstranit sendResponse(), dát tam return $pdf; a následně v příslušném presenteru místo $this->orderManager->createPdf() (nebo jak se ta tvá metoda jmenuje) použít $this->sendResponse($this->orderManager->createPdf());. Je možné, že to nebude fungovat – v takovém případě budeme potřebovat větší vhled do tvého kódu – ideálně celé tělo metody na vytváření PDF v OrderManageru + ideálně část presenteru, ve kterém tuto metodu voláš.

Kamil Valenta
Člen | 822
+
0
-

scientific napsal(a):

Není jiná cesta, jak to zprovoznit, aniž bych se musel milion hodin učit jak se pracuje s modely, presentery apod. celkově vůbec tenhle zřejmě správný způsob práce s OOP nechápu namespace a polymorfismus vůbec nepoužívám :-)

Určitě se na to může najmout někdo, kdo to umí.

David Grudl
Nette Core | 8239
+
+7
-

@scientific Jak to sleduju, ukousl sis větší sousto, než na jaké jsi připravený, a fórum ti moc nepomůže. Vlastně trošku plýtváš energií lidí, co tu radí (jako kdybych já se bavil s raketovým inženýrem o motorech) a odpovědi tě jen stejně posunou k další otázce v nekonečné řadě, která skončí tím, že se jedna strana unaví.

Prostě neaktualizuj PHP a Nette. Většina webů taky není aktualizovaných, nevím o žádných zásadních bezpečnostních rizicích, které by starší verze měly, a můžeš čas vkládat do něčeho, co ti bude přinášet radost.