I've created a Console route on my zf2 application to dispatch an email via the command line. So in my action I am creating a new PhpRenderer as specified in the documentation (http://framework.zend.com/manual/2.0/en/modules/zend.view.renderer.php-renderer.html) to render my email template (replace variables etc) and dispatch it.
Here is the code I am using:
$renderer = new \Zend\View\Renderer\PhpRenderer();
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap(array(
'mailTemplate' => $config['template']
));
$renderer->setResolver($resolver);
$model = new \Zend\View\Model\ViewModel();
$model->setTemplate('mailTemplate');
$model->setVariables(array(
'recipient' => 'foo#bar.com'
));
$emailBody = $renderer->render($model);
However it seems that the Phprenderer does not render any PHP in my .phtml file. The exact same code works correctly however if I execute it in a normal HTTP Request.
Could anyone help me out with this?
I suspect that it's because you haven't set the correct path to the resolver.
For reference, this is the approach I took:
// render HTML and TEXT bodies
$basePath = realpath(__DIR__ . '/../../../view/emails');
$htmlFilename = 'body.html.phtml';
$txtFilename = 'body.txt.phtml';
$renderer = new PhpRenderer();
$renderer->resolver()->addPath($basePath);
$sm = $this->getServiceManager();
$renderer->setHelperPluginManager($sm->get('ViewHelperManager'));
$model = new ViewModel();
$model->setVariable('name', $user->getName());
$model->setTemplate($txtFilename);
$textContent = $renderer->render($model);
$model->setTemplate($htmlFilename);
$htmlContent = $renderer->render($model);
Related
I added some functionality where if you edit an item that somebody edited in the meantime, you go to an "edit confirm" page where you can select which changes you want to overwrite.
How it's done:
if ($request->isMethod('GET')) {
$session->set('overwriteDate', $language->getUpdatedAt()?->format('Y-m-d H:i:s'));
$session->set('language_referer', $request->headers->get('referer'));
}
$form = $this->createForm(LanguageFormType::class, $language);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
var_dump($language->getUpdatedAt());
var_dump($session->get('overwriteDate'));
if ($session->get('overwriteDate') !== $language->getUpdatedAt()?->format('Y-m-d H:i:s')) {
$session->set('overwriteItem', $language);
return $this->redirectToRoute('languages_edit_confirm', ['id' => $language->getId()]);
} else {
$baseEntityService->save($language);
return $this->redirect($session->get('language_referer'));
}
}
return $this->render('admin/language/edit.html.twig', [
'language' => $language,
'form' => $form->createView()
]);
If the overwriteDate in the session doesn't match the updatedAt from the object, it will redirect to the edit confirm page. This all works fine in the browser (tested it manually a lot, never had an issue).
However, now I try to write a functional test for this, and it's inconsistent. This is the begin of the test:
$crawler1 = $this->client->request('GET', '/admin/languages');
$crawler1 = $this->filterTable($crawler1, $originalEnglishName);
$crawler1 = $this->client->click($crawler1->filter('a.edit-language')->link());
$crawler2 = $this->client->request('GET', '/admin/languages');
$crawler2 = $this->filterTable($crawler2, $originalEnglishName);
$crawler2 = $this->client->click($crawler2->filter('a.edit-language')->link());
$form = $crawler1->selectButton('saveLanguage')->form();
$form['language_form[abbreviation]'] = $firstEditAbbreviation;
$form['language_form[englishName]'] = $firstEditEnglishName;
$form['language_form[name]'] = $firstEditName;
$form['language_form[flag]'] = $firstEditFlag;
$form2 = $crawler2->selectButton('saveLanguage')->form();
$form2['language_form[abbreviation]'] = $secondEditAbbreviation;
$form2['language_form[englishName]'] = $secondEditEnglishName;
$form2['language_form[name]'] = $secondEditName;
$form2['language_form[flag]'] = $secondEditFlag;
$this->client->submit($form);
$this->client->submit($form2);
$crawler2 = $this->client->followRedirect();
$tbody = $crawler2->filter('table#difference-table tbody')->first();
After this I try to assert some stuff from $tbody however sometimes the test works fine but sometimes it gives errors because it acts like a normal edit and redirects to the homepage and the data from $tbody I search on doesn't exist.
Edit:
I tried changing the session stuff to putting it in the form as hidden input, but this gives the same issues.
You'll need to preserve the session cookie between then requests in your test(s).
The Symfony HTTPClient does not do this by default.
The HTTP client provided by this component is stateless but handling cookies requires a stateful storage (because responses can update cookies and they must be used for subsequent requests). That's why this component doesn't handle cookies automatically.
You can either handle cookies yourself using the Cookie HTTP header or use the BrowserKit component which provides this feature and integrates seamlessly with the HttpClient component.
Example usage:
// Request using the client
$crawler = $client->request('GET', '/');
// Get the cookie Jar
$cookieJar = $client->getCookieJar();
// Get the history
$history = $client->getHistory();
// Get a cookie by name
$sessionCookie = $cookieJar->get('PHPSESSID');
// create cookies and add to cookie jar
$cookie = new Cookie('PHPSESSID', 'XYZ', strtotime('+1 day'));
$cookieJar = new CookieJar();
$cookieJar->set($cookie);
// create a client and set the cookies
$client = new Client([], null, $cookieJar);
I need to update the ACL basically by adding or removing the allUsers entity.
I have the PHP library and what I'm doing at moment is:
$storage = new StorageClient([
'projectId' => "xxxxx",
'keyFilePath' => mykey,
]);
$bucket = $storage->bucket('mybucket');
$acl = $bucket->acl('objectAccessControls', 'path/file/on/bucket');
if(add){
$acl->add('allUsers', 'READER');
}else{
$acl->delete('allUsers');
}
With this code actually changes ALL bucket configuration, not the file only.
How can I correctly specify the path of a specific file and change permissions only on path/file/on/bucket? I'm using the wrong functions?
Here the documentation that I'm using
https://googleapis.github.io/google-cloud-php/#/docs/google-cloud/v0.90.0/storage/acl
This is the case if add:
This is the else case:
UPDATE 1:
Using this to delete seems working -> https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/delete
Tried to include the parameters listed here to the call I do, something like this:
$options = ['object' => 'path/obj'];
$acl->delete('allUsers', $options)
Still not working
Actually I've solved by using the Google_Service
$client = new Google_Client();
$client->setApplicationName('GoogleBuck/0.1');
$client->useApplicationDefaultCredentials(); // app engine env
$client->addScope('https://www.googleapis.com/auth/devstorage.full_control');
$storage = new Google_Service_Storage($client);
$acl = new Google_Service_Storage_ObjectAccessControl($client);
$acl->setEntity('allUsers');
$acl->setRole('READER');
$acl->setBucket($bucketName);
$acl->setObject($objectName);
To add
$response = $storage->objectAccessControls->insert($bucketName, $objectName, $acl);
To delete
$response = $storage->objectAccessControls->delete($bucketName, $objectName, 'allUsers');
I tried to save my pdf files into the file system of sonata media bundle and insert the correct database entry.
I created my file with dompdf as following:
$dompdf = new Dompdf($pdfOptions);
$html = $this->renderView("pdf/hrprotokoll.html.twig", [
'result' => $result,
'vals' => $vals,
'title' => 'Prüfprotokoll',
'item' => $item,
]);
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$output = $dompdf->output();
$publicDirectory = $request->server->get('DOCUMENT_ROOT') . '/uploads/hrprotokolle/'.$this->getUser()->getStandort()->getId();
$pdfFilepath = $publicDirectory . '/'. time().'.pdf';
$file = time().'.pdf';
file_put_contents($pdfFilepath, $output);
ok, now the file is saved correctly without errors. The question now is how to manage this file with Sonata MediaBundle.
Ive tried the following:
$mediaManager = new MediaManager();
$media = new Media();
$media->setBinaryContent($file);
$media->setContext('default');
$media->setProviderName('sonata.media.provider.file');
$mediaManager->save($media);
Error:
Too few arguments to function Sonata\Doctrine\Model\BaseManager::__construct(), 0 passed... ($mediaManager)
Im not able to set the correct way. Anyone have an idea to solve this problem? Thx
The problem was: $mediaManager (service sonata.media.manager.media) cant autowire so you have to do this manually.
at first check this service in your terminal and find informations about this service by typing the following:
php bin/console debug:container sonata.media.manager.media
The Result is:
Service ID sonata.media.manager.media
Class Sonata\MediaBundle\Entity\MediaManager
Ok, now go to your services.yaml and create the alias:
Sonata\MediaBundle\Entity\MediaManager: '#sonata.media.manager.media'
Its done. Now you can inject the MediaManager and it works for me:
use Sonata\MediaBundle\Entity\MediaManager;
private $mediaManager;
public function __construct(MediaManager $mediaManager)
{
$this->mediaManager = $mediaManager;
}
$media = new Media();
$this->mediaManager->save($media);
I want to get params from my PUT or DELETE request sent with Zend_Http_client like this :
$httpClient = new Zend_Http_Client();
$httpClient->setUri("http://mysite/mycontroller/");
$httpClient->setMethod(Zend_Http_Client::PUT);
$data = array("id"=>"1","label"=>"LABEL UPDATE");
$httpClient->setParameterPost($data);
$response = $httpClient->request();
For a POST request I can retrieve params without problems, but for PUT or DELETE I have nothing ...
Any idea ?
THX
Finally I found this solution :
in Zend/Controller/Plugin/ you can find PutHandler.php . It can be used to get PUT params using $this->getRequest()->param_name.
Include it in your boostrap.php file with this :
protected function _initRestRoute()
{
$this->bootstrap('frontController');
$frontController = Zend_Controller_Front::getInstance();
$frontController->registerPlugin(new Zend_Controller_Plugin_PutHandler());
$frontController->registerPlugin(new Zend_Controller_Plugin_DeleteHandler());
$restRoute = new Zend_Rest_Route($frontController);
$frontController->getRouter()->addRoute('default', $restRoute);
}
I extended the PutHandler.php script for Delete params and it works.
I want to test my application. Everything works fine to the point where i want to test my own viewHelpers (actionHelpers).
The problem is, i want to use the url-ViewHelper in my own viewHelper to generate links.
Therefore i use this statements.
$urlHelper = $serviceLocator->getServiceLocator()->get('ViewHelperManager')->get('url');
$urlHelper->__invoke('test',array(),array(),true);
This works great.
But now i want to test parts of my application where my view helper is used. Everything works fine to the point where i use the url_ViewHelper.
I get following exception:
Fatal error: Call to a member function getRouteMatch() on a non-object in ****\vendor\zendframework\zendframework\library\Zend\Mvc\Service\ViewHelperManagerFactory.php on line 70
Is there something wrong in the way i setUp my test?
$serviceManager = Bootstrap::getServiceManager();
$this->controller = new IndexController();
$this->request = new Request();
$this->routeMatch = new RouteMatch(array('controller' => 'index'));
$this->event = new MvcEvent();
$config = $serviceManager->get('Config');
$routerConfig = isset($config['router']) ? $config['router'] : array();
$router = HttpRouter::factory($routerConfig);
$this->event->setRouter($router);
$this->event->setRouteMatch($this->routeMatch);
$this->controller->setEvent($this->event);
$this->controller->setServiceLocator($serviceManager);
Thank you very much for help!