Symfony3 - how to compare properties from 2 different entities - entity-framework

I want to create a view where an event is displayed only if it is owned by the currently logged in user.
So I want to compare LoginID from the Events entity to the current user ID.
I tried with the following function:
public function showAction(Events $event, $id)
{
$em = $this->getDoctrine()->getManager();
$user=$this->getUser()->getLoginid();
$guests = $em->getRepository('VendorMyBundle:Guests')->findByEventid($id);
$events = $em->getRepository('VendorMyBundle:Events')->findByEventid($id);
// condition to display only events owned by the current user
if ($events->getLoginid()==$user){
$session = new Session();
$session->set('eventid', $id);
$deleteForm = $this->createDeleteForm($event);
return $this->render('events/show.html.twig', array(
'event' => $event,
'delete_form' => $deleteForm->createView(),
'guests' => $guests,
));
}
$this->addFlash('error', 'The event does not exist or you do not have permission to view it.');
return $this->redirectToRoute('home_page');
}
LoginID in Events entity is a Many-to-One relation property towards the Logins entity which is my user provider entity.
When I try to view with that method in my controller I get this: Error: Call to a member function getLoginid() on a non-object on the line with the IF statement.
Additional question would be, how do I compare 2 property values from 2 different entities?

Since the problem is that you are returning an array you have two choices, update the findByEventid() to return a single result
return $query->getSingleResult();
or
if ($events[0]->getLoginid()==$user){
..
}
Hope this help you.

Related

Laravel one to many relationship save method empty attributes

I am trying to save a relationship with the Laravel save method:
public function storeContact(Request $request)
{
$user = User::firstOrNew(['email' => $request->input('email')]);
$user->save();
$message = new App\Message([
'message' => $request->input('remarks')
]);
$user->message()->save($message);
}
var_dump($request->all) confirms both fields are available in the request.
All relations work. hasOne, belongsTo are configured in the models. The relation is saved like expected (but message field is empty)
When I var_dump($message), there are no attributes in the collection.
I already tried fillable and guarded on the models without any effect. These should not be necessary for the save method though because this uses a full Eloquent model instance.
What am I missing here??
I think I found the culprit.
When I use a __construct on a model it fails. When I instantiate a model with a __construct no variables are passes as attributes. Even if the __construct is empty.
Test with __construct method
class Message extends Model
{
protected $connection = 'system';
public function __construct()
{
}
// ...
}
$message = new App\Message(['remarks' => 'Test remarks']);
var_dump(message) // does NOT contain attributes!
Test2 without __construct method
class Message extends Model
{
protected $connection = 'system';
// ...
}
$message = new App\Message(['remarks' => 'Test remarks']);
var_dump(message) // does contain attributes!
This looks like a bug in Laravel to me.

capturing the login event in zendframework 2

I want to capture the loggin event in zendframework2 and then update the database when the user last logged in.
i am aware that if i do the following in the onBootstrap(MVCEvent $e) of my module i will be able to capture the event etc:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUser\Authentication\Adapter\AdapterChain',
'authenticate',
function($e)
{
$id = $e->getIdentity();
}
);
this will give me the Id of the user. however, the confusion is how i can then update my database from the bootstrap. i mean, i dont have access to the entity manager in my bootstrap and i am not sure how to transport it there. the entity manager is held in the service config file.
i.e
getServiceConfig()
'Members\Model\WorkerTable' => function($sm) {
$db = $sm->get('doctrine.entitymanager.orm_default');
$table = new Model\MemberTable($db);
return $table;
},
.
with the above settings i am able to access the entity manager in my MemberTable class
so, a simple solution would be to transfer the loggin event manager to my
** MemberTable class** where i would use my entity manager to update the database.
issue, i am not sure how to set this up:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
i mean, i dont know how to get the variable $e into the MemberTable class so that i can access the eventManger and the sharedManager.
in summary; the issues are twofold.
how do i get the entity manager into the bootstrap function
alternatively
how do i get the eventManager and shared eventmanager into a normal class so that i can call the eventmanger in a class that already contains the entity manager
Well, all you have to do is to retrieve the service manager this way:
$serviceManager = $e->getApplication()->getServiceManager();
and then get your entity manager like this:
$entityManager = $serviceManager->get('Members\Model\WorkerTable');
Does it solve your problem?
The answer to the second question
To bring a variable into the closure from outside you can use "use" operator like so:
function() use ($myVar){
// some code
}
So, in your case I would do:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUser\Authentication\Adapter\AdapterChain',
'authenticate',
function($e) use ($entityManager){
$id = $e->getIdentity();
}
);
If you are planning to have a lot of code inside your closure I would suggest to put it into a separate class and make it invokable. For instance,
class YourClosureCode
{
private $entityManager;
public function __construct($eventManager)
{
$this->eventManager = $eventManager;
}
public function __invoke(EventInterface $e)
{
// put your closure code here
}
}
Then a slight modification here:
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUser\Authentication\Adapter\AdapterChain',
'authenticate',
new YourClosureCode($entityManager);
);

Symfony2 Form Dropping Entity Data

This questions is NOT about how to embed an entity that is simple and straightforward my question is about an abnormality I am seeing and can't reconcile.
I have an Entity (Contact) I have an "Email" relation on this and want to have the ability to embed Emails in my create new method.
So I do the usual embed steps:
1) Add my collection to my form (contactType.php)
->add('emails', 'collection', array(
'type' => new EmailType()
))
2) In the Controller I add a new empty Email entity and set that as my default data for my form
$entity = new Contact();
$email = new Email();
$entity->addEmail($email);
$form->createForm(new ContactType(), $entity);
This is where the issue occurs, going into "createForm" my $entity has a collection called Emails, coming out the $form is a blank ContactType, no Email attached to it... it's as if the defaultData is just being ignored.
If you have seen this or have any idea why this would happen I would love some input.
We have modified our getter to return an Associative Array and this seems to break the Form builder, The following breaks the Form Builder:
public function getContacts()
{
$array = new ArrayCollection();
$property = (is_array($this->contacts)) ? $this->contacts : $array;
foreach($property as $entity)
{
$array[$entity->getType()->getName()] = $entity;
}
return $array;
}
the basic getter is just
return $this->contacts;
Which works, it seems ArrayCollection() isn't a simple Associative Array as we assumed it could be.

How to fetch Objects from Model/Service layer

In an app we are developing, we have Services, Mappers and Entities. We are not using an ORM. In the app, we have Group, GroupMember & Member entities. The GroupMember entity has the groupId, memberId & memberAccess properties. The memberAccess fields tells us the access level of the Member within the Group. Now we need to fetch
all the Groups where a member has specific level of access. (by providing a memberId)
all the Groups where a member is a member along with his access. (by providing a memberId)
all the Members within a group with their access. (by providing a groupId)
any ideas which service(s) should be used for each of the following. and how they will interact to fetch the specific data.
1) MembershipMapper: implement your queries here returning arrays of entities (have a look at ZfcBase\Mapper\AbstractDbMapper as base class)
function getGroupsForMember($member, $access = null)
function getMembersForGroup($group, $access = null)
2) MembershipServive: in Module.php under getServiceConfig you add this service to the service manager. Use a closure to create a new MembershipService and inject a MembershipMapper into it. The groups/members functions will probably just be proxies to the mapper.
function setMembershipMapper($membershipMapper)
function getMembershipMapper()
function getGroupsForMember($member, $access = null)
function getMembersForGroup($group, $access = null)
3) Controller: inject your MembershipService into your controller (you can do this in the same way you create your services with a closure). Then call the methods on the service.
Example for creating a service/mapper/controller in the service/controller manager (goes in Module.php)
public function getServiceConfig()
{
return array(
'factories' => array(
'MembershipService' => function (Zend\ServiceManager\ServiceManager $sm) {
$service = new YourNS\Service\Membership();
$service->setMembershipMapper($sm->get('MembershipMapper'));
return $service;
},
'MembershipMapper' => function ($sm) {
$mapper = new \YourNS\Mapper\Membership();
return $mapper;
},
);
}
public function getControllerConfig()
{
return array(
'factories' => array(
'YourNS\Controller\Something' => function (Zend\Mvc\Controller\ControllerManager $cm) {
$controller = new YourNS\Controller\Something();
$controller->setMembershipService($cm->getServiceLocator()->get('MembershipService'));
return $controller;
},
}

How to write a custom row class (extends Zend_Db_Table_Row) for a Db_Table class in Zend Framework

I have separate db_table classes for books, book_sections and users (system end users). in book table has columns for book_title, section_id(book_section) , data_entered_user_id(who entered book info).
go to this url to see the image(I'm not allow to post images bacause I'm new to stackoverflow)
img685.imageshack.us/img685/9978/70932283.png
in the backend of the system I added a form to edit existing book (get book id from GET param and fill the relevant data to the form). form has elements for book_title, book_section and data_entered_user.
to get exciting book data to "edit book form" I join book_section and user tables with book table to get book_section_name and username(of data_entered_user: read only- display on side bar)
go to this url to see the image(I'm not allow to post images bacause I'm new to stackoverflow)
img155.imageshack.us/img155/2947/66239915.jpg
In class App_Model_Book extends Zend_Db_Table_Abstract
public function getBookData($id){
$select = $this->select();
$select->setIntegrityCheck(false);
$select->from('book', array('id','section_id','data_entered_user_id',...));
$select->joinInner('section','book.section_id = section.id',array('section_name' =>'section.name' ));
$select->joinInner(array('date_entered_user' => 'user'),'book.date_entered_user_id = date_entered_user.id',array('date_entered_user_name' =>'date_entered_user.user_name' ));
$select->where("book.id = ?",$id);
return $this->fetchRow($select);
}
public function updateBookData($id,$title,$section_id,...)
{
$existingRow = $this->fetchRow($this->select()->where('id=?',$id));
$existingRow->title = $title;
$existingRow->section_id = $section_id;
//....
$existingRow->save();
}
In Admin_BookController -> editAction()
$editForm = new Admin_Form_EditBook();
$id = $this->_getParam('id', false);
$bookTable = new App_Model_Book();
$book_data = $bookTable ->getBookData($id);
//set values on form to print on form when edit book
$editForm->book_title->setValue($book_data->title);
$editForm->book_section->setValue($book_data->section_name);
//........
//If form data valid
if($this->getRequest()->isPost() && $editForm->isValid($_POST)){
$bookTable = new App_Model_Book();
$bookTable ->updateBookData(
$id,
//get data from submitted form
$editForm->getValue('title'),
//....
);
when editing an exsiting book
get data from getBookData() method on App_Model_Book class
If form data is valid after submiting edited data, save data with updateBookData() method on App_Model_Book class
but I saw that if I created a custom
Db_Table_Row(extends Zend_Db_Table_Row)
class for book table with
book_section_name and
data_entered_user_name I can use it
for get existing book data and save it
after editing book data without
creating new Book(db_table) class and without calling updateBookData() to save updated data.But I don't know which code I should write on custom
Db_Table_Row(extends Zend_Db_Table_Row)
class.
I think you can understand my problem, in simple
how to write a custom db_table_row class to create a custom row with data
form 2 joined tables for a perticular db_table class ?
I'm new to zend framewok and to stackoverflow. forgive me if you confused with my first question.
Thanks again.
1) at your db_table class create field which contain row class, for example:
protected $_rowClass = 'App_Model_Db_Books_Row';
and add reference map for parent tables:
protected $_referenceMap = array(
'Section' => array(
'columns' => 'sectionId',
'refTableClass' => 'App_Model_Db_Sections',
'refColumns' => 'id'
),
'User' => array(
'columns' => 'userId',
'refTableClass' => 'App_Model_Db_Users',
'refColumns' => 'id'
)
);
2) at row class you must define variables for parent tables:
protected $section;
protected $user;
In such cases i create method called "load":
public function load()
{
$this->section = $this->findParentRow('App_Model_Db_Sections');
$this->user = $this->findParentRow('App_Model_Db_Users');
}
And in constructor i call this method:
public function __construct(array $config = array())
{
parent::__construct($config);
$this->load();
}
As a result after:
$book_data = $bookTable ->getBookData($id);
you can access data from reference table, for example:
$book_data->section->name = "Book Section";
$book_data->section->save();