How can I use different layouts in one module in Zend2 - templates

How can I use different layouts in one module in Zend2
I write as in my code down and there is no effect
I need to use different layouts for different actions in one controller
class IndexController extends AbstractActionController
{
public function indexAction()
{ $this->layout('layout/layout');
$view = new ViewModel();
$menu = new ViewModel();
$menu->setTemplate('application/menu');
$view->addChild($menu, 'menu');
return $view;
}
public function portfolioAction()
{
$this->layout('layout/portfolio');
$view = new ViewModel();
$menu = new ViewModel();
$menu->setTemplate('application/menu');
$view->addChild($menu, 'menu');
return $view;
}
}
and this is my viewManager
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/portfolio' => __DIR__ . '/../view/layout/layout_portfolio.phtml',
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),

I think the layout is set up by the event MvcEvent::EVENT_DISPATCH.
So I wrote a listener to change the layout. You can see my solution at https://github.com/dafap/DafapLayout and adapt it for your needs.

Related

Symfony2: PHPUnit Testing-> #dataProvider sends no multipleArray

I make UnitTesting for my application.
I have a save saveArticleIds() Method and I wrote a testing for it -> testSaveArticelIds(). I have an dataProvider articelIdsArray() whith a multiple array. The function need that array exact like this.
/**
*
* #dataProvider articleIdsArray
*
*/
public function testSavearticleIds($articleIds) {
$articleIdObjekt = new ArticleIdHandler();
$result = $articleIdObjekt->saveArticleIds($articleIds,false);
$this->assertTrue($result);
}
public function articleIdsArray() {
return array(
array(
10552 => 10552,
14314 => 14314,
21034 => 21034,
22739 => 22739,
34568 => 34568,
34572 => 34572,
35401 => 35401,
38292 => 38292,
55141 => 55141,
161764 => 161764,
181589 => 181589
)
);
}
When I run my test, I get this Error:
There was 1 error: 1) My\Bundle\ArticleBundle\Tests\Article\ArticleIdHandlerTest::testSaveArticleIds
with data set #0 (10552, 14314, 21034, 22739, 34568, 34572, 35401, 38292, 55141, 161764, 181589)
Invalid argument supplied for foreach()
Why does it show the array like I have no keys in the array? I need the array exact like in my dataProvider! Any idea?? THANKS A LOT FOR YOU HELP!!!
maybe try this:
public function articleIdsArray()
{
return
array(
array(
array(
10552 => 10552,
14314 => 14314,
21034 => 21034,
22739 => 22739,
34568 => 34568,
34572 => 34572,
35401 => 35401,
38292 => 38292,
55141 => 55141,
161764 => 161764,
181589 => 181589
)
)
);
}
The reason is that the first level of the array nesting is the set of data provided for each round of tests, the second level represents the arguments provided to testSavearticleIds, in the same order as in the parameter list of the function (in your example there is only one argument), the last level is just the test array itself.
Hope this helps...
Try this :
/**
* #dataProvider articleIdsArray
*/
public function testSavearticleIds($articleIds)
{
$articleIdObjekt = new ArticleIdHandler();
$result = $articleIdObjekt->saveArticleIds($articleIds,false);
$this->assertTrue($result);
}
public function articleIdsArray()
{
return array(
'scenario_one' => 10552,
'scenario_two' => 14314,
...,
);
}
You doesn't need to use #dataProvider in your example.
Define your method like this
public function getArticleIdsArray() {
return array(
10552 => 10552,
14314 => 14314,
21034 => 21034,
22739 => 22739,
34568 => 34568,
34572 => 34572,
35401 => 35401,
38292 => 38292,
55141 => 55141,
161764 => 161764,
181589 => 181589
);
}
and use it in your test
public function testSavearticleIds($articleIds) {
$articleIdObjekt = new ArticleIdHandler();
$result = $articleIdObjekt->saveArticleIds($this->getArticleIdsArray(),false);
$this->assertTrue($result);
}

SF2: How to custom the form type messages?

I want to know how I can modify the error message on my ContactType.
It's possible directly in the Type ?
My current code:
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$collectionConstraint = new Collection(array(
'name' => array(
new NotBlank(array('message' => 'My custon message.')),
new Length(array('min' => 2), array('message' => 'My custon message.'))
),
'email' => array(
new NotBlank(array('message' => 'My custon message.')),
new Email(array('message' => 'My custon message.'))
),
'subject' => array(
new NotBlank(array('message' => 'My custon message.')),
new Length(array('min' => 10), array('message' => 'My custon message.'))
),
'message' => array(
new NotBlank(array('message' => 'My custon message')),
new Length(array('min' => 5))
)
));
$resolver->setDefaults(array(
'constraints' => $collectionConstraint
));
}
public function getName()
{
return 'contact';
}
}
Thanks you all for your helping.
Best regards,
It's recommend to change the message of the assertion instead, but you can also use the invalid_message setting of a form type.

Authentication using Doctrine 2 MongoDbODM Module

I'm trying to set a login(Authentication) using Zend2 and DoctrineODMModule but I am getting an error.
I have followed the tutorial to setup the Authentication of Zend2 with doctorineODMModule on github
any suggestion what I am doing wrong? or what I have to do?
i have done it in the following way.
in doctrine mdule.config.php
'authentication' => array(
'odm_default' => array(
'object_manager' => 'doctrine.documentmanager.odm_default',
'identity_class' => 'Admin\Document\User',
'identity_property' => 'username',
'credential_property' => 'password',
),
),
'odm_driver' => array(
'class' => 'Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver',
'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Document')
),
'odm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Document' => 'odm_driver'
)
)
in Admin/Document/User.php created two methods getUsername and getPassword.
public function getUsername(){
return $this->username;
}
public function getPassword(){
return $this->password;
}
created controller in index controller.php
public function loginAction(){
$this->layout('layout/login-layout.phtml');
$login_error=false;
$loginForm = new LoginForm();
if ($this->request->isPost())
{
$loginForm->setData($this->request->getPost());
if ($loginForm->isValid())
{
// try {
// throw new \Exception("My exception");
$data = $loginForm->getData();
$authService = $this->getServiceLocator()
->get('doctrine.authenticationservice.odm_default');
$adapter = $authService->getAdapter();
$adapter->setIdentityValue($data['username']); // i am using username
$adapter->setCredentialValue(md5($data['password']));
$authResult = $authService->authenticate();
if ($authResult->isValid()) {
$this->redirect()->toRoute('admin_index'); // or last viewed page
}
/*} catch (Exception $e) {
echo "Caught exception $e\n";
echo $e->getPrevious();
$login_error=false;
return new ViewModel(array(
'loginForm' => $loginForm,
'login_error' => $login_error,
));
//exit;
}/
return array(
'loginForm' => $loginForm,
'errors' => 'username or password is not valid',
);
$this->redirect()->toRoute('admin_index');
} else {
//
// LOG Event ( login|password not valide )
//
//Zend\Debug\Debug::dump("not valid data");
//Zend\Debug\Debug::dump($loginForm->getMessages());
$login_error=true;
}//* */
}
}
//
return new ViewModel(array(
'loginForm' => $loginForm,
'login_error' => $login_error,
));
}
With the message you give,
A value for the identity was not provided prior to authentication with ObjectRepository authentication adapter
I'd say that either you didn't give the field to use as identity on you're User Document or during authentication process (in your action) you didn't populate the value for identity (aka login)
Please give more informations about your app (odm module configuration, Identity class...) to provide you a better help
as configuration you should have stg like :
...
'doctrine' => array(
'driver' => array(
__NAMESPACE__ . '_orm_driver' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
),
'orm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_orm_driver'
)
),
__NAMESPACE__ . '_odm_driver' => array(
'class' => 'Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver',
'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Document')
),
'odm_default' => array(
'drivers' => array(
__NAMESPACE__ . '\Document' => __NAMESPACE__ . '_odm_driver'
)
)
),
'authentication' => array(
'odm_default' => array(
'objectManager' => 'doctrine.documentmanager.odm_default',
'identityClass' => 'Application\Document\User',
'identityProperty' => 'username',
'credentialProperty' => 'password',
'credentialCallable' => 'Application\Utils::hashPassword' // Not needed if you don't hash passwords
),
),
),
...
This was working great for some of my projects

zend framework 2 Unable to render template resolver could not resolve to a file

I'm learning how to use Zend Framework2. According to some tutorials available on the Net I've wrote some pieces of code . The most important tutorial for me is this one: https://github.com/psamatt/zf2-doctrine-example It covers most of the basics that i've planned to write. I've stuck on one problem that looks strange to me. On my summary page, that display all the records from DB I have a links to add new record, edit existing record, and delete record. Routing is covered by module.config.php:
'router' => array(
'routes' => array(
'incident' => array(
'type' => 'segment',
'options' => array(
'route' => '/incident[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Helpdesk\Controller\Incident',
'action' => 'index',
),
),
),
),
),
When I use a link to a new record (h.t.t.p://helpdesk/incident/add) everything works correctly. But when I use a link to edit my record (h.t.t.p://helpdesk/incident/edit/1 - where 1 is example record ID) I receive an error:
Zend\View\Renderer\PhpRenderer::render: Unable to render template "helpdesk/incident/edit"; resolver could not resolve to a file
This is my IncidentController.php:
<?php
namespace Helpdesk\Controller;
use Application\Controller\EntityUsingController;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject;
use Doctrine\ORM\EntityManager;
use Zend\View\Model\ViewModel;
use Helpdesk\Form\IncidentForm;
use Helpdesk\Entity\Incident;
class IncidentController extends EntityUsingController
{
/**
* Index action
*
*/
public function indexAction()
{
$em = $this->getEntityManager();
$incidents = $em->getRepository('Helpdesk\Entity\Incident')->findAll();
return new ViewModel(array(
'incidents' => $incidents
));
}
/**
* Edit action
*
*/
public function editAction()
{
$incident = new Incident();
if ($this->params('id') > 0) {
$incident = $this->getEntityManager()->getRepository('Helpdesk\Entity\Incident')->find($this->params('id'));
}
$form = new IncidentForm($this->getEntityManager());
$form->bind($incident);
$form->setHydrator(new DoctrineObject($this->getEntityManager(),'Helpdesk\Entity\Incident'));
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($incident->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$em = $this->getEntityManager();
$em->persist($incident);
$em->flush();
$this->flashMessenger()->addSuccessMessage('Incident saved');
// Redirect to list of incidents
return $this->redirect()->toRoute('incident');
}
}
return array(
'incident' => $incident,
'form' => $form,
);
}
/**
* Add action
*
*/
public function addAction()
{
return $this->editAction();
}
/**
* Delete action
*
*/
public function deleteAction()
{
$id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
if (!$id) {
return $this->redirect()->toRoute('incident');
}
$request = $this->getRequest();
if ($request->isPost()) {
$del = $request->post()->get('del', 'No');
if ($del == 'Yes') {
$id = (int)$request->post()->get('id');
$incident = $this->getEntityManager()->find('Helpdesk\Entity\Incident', $id);
if ($incident) {
$this->getEntityManager()->remove($incident);
$this->getEntityManager()->flush();
}
}
// Redirect to list of incidents
return $this->redirect()->toRoute('default', array(
'controller' => 'incident',
'action' => 'index',
));
}
return array(
'id' => $id,
'incident' => $this->getEntityManager()->find('Helpdesk\Entity\Incident', $id)->getArrayCopy()
);
}
}
What is the difference between these two? Why one works fine, while the second one generates an error?
Thanks for your help
Smok.
Most likely helpdesk/incident/edit.phtml does not exist, while add action is rendering an existing helpdesk/incident/add.phtml.
You can reuse the existing helpdesk/incident/add.phtml or create a new one.

Doctrine2 + Zend Framework 2 - EntitiesManager as variable in Controller

I want to set EntitiesManager instance available on my Controller. I want the Instance available with $this->em on Controller. This is my configuration :
module.config.php
[...]
'doctrine' => array(
'driver' => array(
'application_entities' => array(
'class' =>'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'cache' => 'array',
'paths' => array(__DIR__ . '/../src/Application/Entity')
),
'orm_default' => array(
'drivers' => array(
'Application\Entity' => 'application_entities'
),
),
),
),
'di' => array(
'instance' => array(
'alias' => array(
'application' => 'Application\Controller\IndexController',
),
'Application\Controller\IndexController' => array(
'parameters' => array(
'em' => 'doctrine_em',
),
),
),
),
IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use \Doctrine\ORM\EntityManager;
class IndexController extends AbstractActionController
{
protected $em;
public function setEm(EntityManager $em) {
$this->em = $em;
return $this;
}
public function indexAction() {
$user1 = $this->em->find('\Application\Entity\User', 1);
var_dump($user1->getFullname());
}
I got this error : "Fatal error: Call to a member function find() on a non-object". It seem than EntityManager is not correctly instantiate.
What Am I missing?
Thank you!
You dont need anything in the module config
You edit the Module.php, onbootstrap function
public function onBootstrap(\Zend\EventManager\EventInterface $e) {
$serviceManager = $e->getApplication()->getServiceManager();
$em = $serviceManager;
$controllerLoader = $serviceManager->get('ControllerLoader');
$controllerLoader->addInitializer(function ($controller) use ($em) {
if (method_exists($controller, 'setEm')) {
$controller->setEm($em);
}
});
}
the controller stays as you have it, with the $em field, and the setEm method
//..
protected $em;
public function setEm(EntityManager $em) {
$this->em = $em;
return $this;
}
//..