Laravel 5.1 - Cannot access relationship via ORM - eloquent

I have two model classes as defined as below:
class Event extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
public function user()
{
return $this->belongsTo('App\User');
}
public function transfers()
{
return $this->hasMany('App\Transfer');
}
}
class Transfers extends Model
{
use SoftDeletes;
/**
* The attributes that should be mutated to dates.
*
* #var array
*/
protected $dates = ['deleted_at'];
public function event()
{
return $this->belongsTo('App\Event');
}
}
I am trying access Transfers from an Event object using following code.
public function filter()
{
$id = request()->input('id');
$event = \App\Event::where([['id', '=', $id],
['deleted_at', '=', NULL],
['user_id', '=', auth()->user()->id]])->first();
echo $event->transfers->count();
}
However, it resulted in an exception as follows
Fatal error: Class 'App\Transfer' not found in
D:\work\HC\hcserver\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php
on line 876
Please advice on how to get rid of this exception
Thanks in advance.

Related

In magento 2, how to store observer value in session

Example:
I have 2 observer classes.
1- category.php
2- product.php
I want to store the category.php data in a session variable, like $_SESSION['category']= $data; and call that session in product.php class.
Like this:
<?php
namespace Vendor\Module\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Checkout\Model\Session as CheckoutSession;
class MyOberver implements ObserverInterface
{
protected $checkoutSession;
public function __construct(
CheckoutSession $checkoutSession
) {
$this->_checkoutSession = $checkoutSession;
}
/**
* #param EventObserver $observer
* #return $this
*/
public function execute(EventObserver $observer)
{
$setValue = $this->_checkoutSession->setVar('dit is een sessie test hoppa');
$getValue = $this->_checkoutSession->getVar();
return $this;
}
}

Laravel Mailable | ->from($this->input->mail)

I have created a
php artisan make:mail ContactFormFilledOut
which works nicely. But the only issue I have is that I cant access the the users mail to insert it to
->from('users-mail')
Im trying to get the users mail by doing this
$this->input->mail
but I get the error
Trying to get property 'mail' of non-object
so I tried also doing
$this->input['mail'].
This did not help either.
public function build()
{
return $this->view('mail.kontaktform')
->from($this->input->mail) // HERE IS THE ISSUE
->subject('Test subject');
}
Here we have all the code
class ContactFormFilledOut extends Mailable
{
use Queueable, SerializesModels;
public $input;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($input)
{
$this->input = $input;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->view('mail.kontaktform')
->from($this->input->mail) // HERE IS THE ISSUE
->subject('Test subject');
}
}
You can specify data which you want Laravel inject in in your constructor, In this case you want to have access to the email address of the user who is suppose to be the sender of that email. you can do that like this
use App\User;
class ContactFormFilledOut extends Mailable
{
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
/* ... */
}
Laravel will automaticaly inject the user who is authenticated and save it in the property user of the mailable.
You have that issue because Laravel doesn't know which object to inject when you add $input as parameter in the constructor of your mailable.
But you can overcome that is you instantiate munually the mailable and pass in the $input which can be any thing you want
$mailable = new ContactFromFilledOut($some_data);
$user = User::find(1);
Mail::to($user)
->send($mailable);

Zend Framework 2 call TableGateway in Service

I'm new to ZF2. After few days of trying to figure out how all this stuff should work I was unable to figure out how should I call TableGateway Model from Service.
So I have Controller:
class SubscriberController extends AbstractActionController
{
/**
* #var \Subscriber\Service\SubscriberServiceInterface
*/
private $subscriberService;
/**
* #param $subscriberService
*/
public function __construct(SubscriberServiceInterface $subscriberService)
{
$this->subscriberService = $subscriberService;
}
Factroy for this Controller:
class SubscriberControllerFactory implements FactoryInterface
{
/**
* Returns ArchiveController instance.
*
* #param ServiceLocatorInterface $serviceLocator
* #return SubscriberController
* #override
**/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$sm = $serviceLocator->getServiceLocator();
return new SubscriberController(
$sm->get('Subscriber\Service\SubscriberServiceInterface')
);
}
Some SubscriberTable:
class SubscriberTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
And Service in which I want to get SubscriberTable instance and make some logic. But I can't figure out how should I call this instance in SubscriberService and set the DbAdapter for SubscriberTable
First implement servicelocator interface and define get and set locator functions to your service like this.
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class Yourservice implements ServiceLocatorAwareInterface{
function test(){
$this->getSubscriberTable->fetchAll(); // call to subscriber table functions
}
/**
* #table gateway Call
**/
public function getSubscriberTable()
{
if (!$this->SubscriberTable) {
$sm = $this->getServiceLocator();
$this->SubscriberTable = $sm->get('Application\Model\SubscriberTable');
}
return $this->SubscriberTable;
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
Hope it will help you.

MongoDB & MySQL relationships in jenssegers/laravel-mongodb

Let's begin with some plain code. I have two following models.
First is using MySQL:
class Phrase extends \Eloquent {
public function positions()
{
return $this->hasMany('Position');
}
public function getIdAttribute($id)
{
return (int) $id;
}
}
and second is using MongoDB:
use Jenssegers\Mongodb\Model as Eloquent;
class Position extends Eloquent {
protected $collection = 'positions';
protected $connection = 'mongodb';
public function phrase()
{
return $this->belongsTo('Phrase');
}
}
In my controller I want to get phrase positions:
Phrase::find(1)->positions
which is generating query
positions.find({"positions.phrase_id":1}, [])
instead of
positions.find({"phrase_id":1}, [])
How I can fix it? The problem is inside HasMany method (http://laravel.com/api/source-class-Illuminate.Database.Eloquent.Model.html#_hasMany).
I managed to get the functionality by creating my own function inside the model
class Phrase extends \Eloquent {
public function positions()
{
return Position::where('phrase_id', '=', (int) $this->id)->get();
return $this->hasMany('Position');
}
}
$positions = Phrase::find(1)->positions();
Anyway, this solution is not a great replacement, because it's breaking convention. Third programmers may not know how to use this relationship.
use this trait in both models and u can use basic relationships
use Jenssegers\Mongodb\Eloquent\HybridRelations;
class User extends Model
{
protected $connection = "mysql" ;
use HybridRelations ;
}
class Orders extends Model
{
protected $connection = "mongo" ;
use HybridRelations ;
}

Injecting the Service Manager to Build a Doctrine Repository in ZF2

How do I inject the service manager into a Doctrine repository to allow me to retrieve the Doctrine Entity Manager?
I using the ZF2-Commons DoctrineORMModule and are trying to implement the repository example listed in the Doctrine Tutorial (bottom of tutorial in link below):
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html
However, I keep getting a message "Fatal error: Call to a member function get() on a non-object in C:\zendProject\zf2 ... ", which suggests that I do not have a working instance of the service locator.
My Doctrine repository looks like this:
namespace Calendar\Repository;
use Doctrine\ORM\EntityRepository,
Calendar\Entity\Appointment,
Calendar\Entity\Diary;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class ApptRepository extends EntityRepository implements ServiceLocatorAwareInterface
{
protected $services;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->services = $serviceLocator;
}
public function getServiceLocator()
{
return $this->services;
}
public function getUserApptsByDate()
{
$dql = "SELECT a FROM Appointment a";
$em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$query = $em()->createQuery($dql);
return $query->getResult();
}
}
I then want to call this in my controller using the following pattern:
$diary = $em->getRepository('Calendar\Entity\Appointment')->getUserApptsByDate();
EDIT: The attached link suggests that I may need to convert the class to a service,
https://stackoverflow.com/a/13508799/1325365
However, if this is the best route, how would I then make my Doctrine Entity aware of the service. At the moment I include an annotation in the doc block pointing to the class.
#ORM\Entity (repositoryClass="Calendar\Repository\ApptRepository")
The way i approach things is this:
First i register a Service for each entity. This is done inside Module.php
public function getServiceConfig()
{
return array(
'factories' => array(
'my-service-entityname' => 'My\Factory\EntitynameServiceFactory',
)
);
}
Next thing would be to create the factory class src\My\Factory\EntitynameServiceFactory.php. This is the part where you inject the EntityManager into your Entity-Services (not into the entity itself, the entity doesn't need this dependency at all)
This class looks something like this:
<?php
namespace My\Factory;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
use My\Service\EntitynameService;
class EntitynameServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$service = new EntitynameService();
$service->setEntityManager($serviceLocator->get('Doctrine\ORM\EntityManager'));
return $service;
}
}
Next thing in line is to create the src\My\Service\EntitynameService.php. And this is actually the part where you create all the getter functions and stuff. Personally i extend these Services from a global DoctrineEntityService i will first give you the code for the EntitynameService now. All this does is to actually get the correct repository!
<?php
namespace My\Service;
class EntitynameService extends DoctrineEntityService
{
public function getEntityRepository()
{
if (null === $this->entityRepository) {
$this->setEntityRepository($this->getEntityManager()->getRepository('My\Entity\Entityname'));
}
return $this->entityRepository;
}
}
This part until here should be quite easy to understand (i hope), but that's not all too interesting yet. The magic is happening at the global DoctrineEntityService. And this is the code for that!
<?php
namespace My\Service;
use Zend\EventManager\EventManagerAwareInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
class DoctrineEntityService implements
ServiceManagerAwareInterface,
EventManagerAwareInterface
{
protected $serviceManager;
protected $eventManager;
protected $entityManager;
protected $entityRepository;
/**
* Returns all Entities
*
* #return EntityRepository
*/
public function findAll()
{
$this->getEventManager()->trigger(__FUNCTION__ . '.pre', $this, array('entities' => $entities));
$entities = $this->getEntityRepository()->findAll();
$this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array('entities' => $entities));
return $entities;
}
public function find($id) {
return $this->getEntityRepository()->find($id);
}
public function findByQuery(\Closure $query)
{
$queryBuilder = $this->getEntityRepository()->createQueryBuilder('entity');
$currentQuery = call_user_func($query, $queryBuilder);
// \Zend\Debug\Debug::dump($currentQuery->getQuery());
return $currentQuery->getQuery()->getResult();
}
/**
* Persists and Entity into the Repository
*
* #param Entity $entity
* #return Entity
*/
public function persist($entity)
{
$this->getEventManager()->trigger(__FUNCTION__ . '.pre', $this, array('entity'=>$entity));
$this->getEntityManager()->persist($entity);
$this->getEntityManager()->flush();
$this->getEventManager()->trigger(__FUNCTION__ . '.post', $this, array('entity'=>$entity));
return $entity;
}
/**
* #param \Doctrine\ORM\EntityRepository $entityRepository
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setEntityRepository(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
return $this;
}
/**
* #param EntityManager $entityManager
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setEntityManager(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
return $this;
}
/**
* #return EntityManager
*/
public function getEntityManager()
{
return $this->entityManager;
}
/**
* Inject an EventManager instance
*
* #param EventManagerInterface $eventManager
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setEventManager(EventManagerInterface $eventManager)
{
$this->eventManager = $eventManager;
return $this;
}
/**
* Retrieve the event manager
* Lazy-loads an EventManager instance if none registered.
*
* #return EventManagerInterface
*/
public function getEventManager()
{
return $this->eventManager;
}
/**
* Set service manager
*
* #param ServiceManager $serviceManager
* #return \Haushaltportal\Service\DoctrineEntityService
*/
public function setServiceManager(ServiceManager $serviceManager)
{
$this->serviceManager = $serviceManager;
return $this;
}
/**
* Get service manager
*
* #return ServiceManager
*/
public function getServiceManager()
{
return $this->serviceManager;
}
}
So what does this do? This DoctrineEntityService pretty much is all what you globally need (to my current experience). It has the fincAll(), find($id) and the findByQuery($closure)
Your next question (hopefully) would only be "How to use this from my controller now?". It's as simple as to call your Service, that you have set up in the first step! Assume this code in your Controllers
public function someAction()
{
/** #var $entityService \my\Service\EntitynameService */
$entityService = $this->getServiceLocator()->get('my-service-entityname');
// A query that finds all stuff
$allEntities = $entityService->findAll();
// A query that finds an ID
$idEntity = $entityService->find(1);
// A query that finds entities based on a Query
$queryEntity = $entityService->findByQuery(function($queryBuilder){
/** #var $queryBuilder\Doctrine\DBAL\Query\QueryBuilder */
return $queryBuilder->orderBy('entity.somekey', 'ASC');
});
}
The function findByQuery() would expect an closure. The $queryBuilder (or however you want to name that variable, you can choose) will be an instance of \Doctrine\DBAL\Query\QueryBuilder. This will always be tied to ONE Repository though! Therefore entity.somekey the entity. will be whatever repository you are currently working with.
If you need access to the EntityManager you'd either only instantiate only the DoctrineEntityService or call the $entityService->getEntityManager() and continue from there.
I don't know if this approach is overly complex or something. When setting up a new Entity/EntityRepository, all you need to do is to add a new Factory and a new Service. Both of those are pretty much copy paste with two line change of code in each class.
I hope this has answered your question and given you some insight of how work with ZF2 can be organized.
As long as you extend the Doctrine\ORM\EntityRepository, you have immediate access to the entity manager by calling EntityRepository::getEntityManager() or the $_em attribute. The inheritence from the Doctrine\ORM\EntityRepository class allow you to do so.
Your method should now look like this:
public function getUserApptsByDate()
{
$dql = "SELECT a FROM Appointment a";
$em = $this->getEntityManager();// Or $em=$this->_em;
$query = $em()->createQuery($dql);
return $query->getResult();
}
I always keep in mind that access to my data should go from the web front (Zend MVC, Service Manager) to the persistence layer (Doctrine). My persistence (entities, repositories...) layer should not refer to the web front or neither know that it exists. If my system is doing the inverse at some level, then probably I'm doing something wrong.
Happy end of year