Referencing variable set by application in models (a good idea?) - zend-framework

i am using zend framework 1.10 with doctrine 2. i wonder if in my (doctrine) model class, isit a good idea to reference a variable set by my application (bootstrap.php, variable stored in Zend_Registry, i think its something like a global variable)
what i want to access is the doctrine entityManager. also i want the id of the logged in user

I am building a project with similar setup (ZF 1.10 + Doctrine2) and I've used dependency injection to deal with this situation, much like takeshin said. Here goes full project repository URL: https://bitbucket.org/phpfour/zf-doctrine2. Below are some code excerpts.
Here's my controller:
<?php
require_once APPLICATION_PATH . "/models/PostManager.php";
class IndexController extends Zend_Controller_Action
{
private $_em;
public function init()
{
$this->_em = $this->getInvokeArg('bootstrap')->getResource('doctrine');
}
public function indexAction()
{
$pm = new PostManager($this->_em);
$this->view->posts = $pm->getPublicPosts();
}
My entity manager (or service class):
<?php
class PostManager
{
protected $_em;
public function __construct(Doctrine\ORM\EntityManager $em)
{
$this->_em = $em;
}
public function getPublicPosts()
{
$query = $this->_em->createQuery('SELECT p FROM Entities\Post p WHERE p.visible = true');
$posts = $query->getResult();
return $posts;
}
Hope this helps!

you should simply use Zend_Auth for the logged-in-userId problem, then could do something like the following in your model
class Model extends BaseModel
{
public function something()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$loggedInUserId = $auth->getIdentity()->id;
}
}
}

There is nothing wrong with this approach (unless you are referring to singletons). Use dependency injection where possible.
However I'd create a service (or two) for this.
class Modulename_Services_Servicename
{
public function getCurrentUser() { ... }
public function getCurrentUserModel() { ... }
public function isLogged() { ... }
public function authenticate() { ... }
public function getSomeData()
{
$user = $this->getCurrentUser()
$model = new YourModel($user);
$query = ....;
$result = $query->execute();
return $result;
}
public function getSomeMoreData($usermodel) { ... }
}

Related

What would the magento 2 equivalent of Mage::helper('core')->?

What would the magento 2 equivalent of Mage::helper('core')-> ?
The Mage static methods are not existing anymore, you will have to use dependency injection to get your helper instance, for example in your model:
<?php
namespace Mycompany\Mymodule\Model;
use Mycompany\Mymodule\Helper\Data;
class Custom {
private $helper;
public function __construct(
Data $helper
) {
$this->helper = $helper;
}
public function myMethod() {
$this->helper->helperMethod();
}
}
You can use the same system in Blocks etc.. and for existing helpers that you want to use.

Is there a way to use MongoDB without ORM in Laravel 5?

Basically, I see Eloquent (for that matter, any ORM) as overhead, as MongoDB itself deals with document objects.
I am looking to use native PHP MongoDB code with application wide database connection object, for a greater performance.
Any library or a simple way to achieve this?
I have read a few things and used PHP MongoDB driver with custom "Model" code, with base class like below:
AppModel.php
<?php
namespace App;
use MongoClient;
use MongoId;
use Log;
class AppModel {
public $collection;
public function __construct() {
$mongo = new MongoClient();
$model_name = (new \ReflectionClass($this))->getShortName();
$collection_name = str_plural(strtolower($model_name));
$this->collection = $mongo->selectCollection('proj_zabbit', $collection_name);
}
public function findById($id) {
return $this->collection->findOne(array(
'_id' => new MongoId($id)
));
}
// more wrapper functions ..
}
Extended model class:
<?php
namespace App;
class Message extends AppModel {
}
In Controller:
<?php namespace App\Http\Controllers;
use App\Message;
class MessagesController extends Controller {
public function __construct()
{
$this->Message = new Message;
}
public function get()
{
$id = Input::get('id');
$message = $this->Message->findById($id);
return $message;
}
}

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 ;
}

How to use preDispatch variables in my controller

I am creating custom plugin in zend framework using Zend_Controller_Plugin_Abstract in the disptach method i am using the following code
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
global $serversetting;
$serversetting = 'S3Server';
}
Now I want to use the value of $serversetting inside my controller
How Can i use them??
Thanks In Advance !!
class MyclassController extends Zend_Controller_Action
{
private $_serversetting;
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$this->_serversetting = 'S3Server'; //set
}
[...]
public function otherAction() {
[...]
$foo = $this->_serversetting; //get
[...]
}
}

Inject Doctrine Entity Manager to Zf2 Form

I tried to inject doctrine entity manager in zf2 form in the way that is described here
http://zf2cheatsheet.com/#doctrine (Inject the Entity Manager to Form) but it fails with error _construct() must be an instance of Doctrine\ORM\EntityManager, null given...
Anybody solved this problem ?
There are a few ways on how to do this. The dirty but easier way is to just give the form In your Controller Action The Entity Manager trough a param like so:
/**
* #var Doctrine\ORM\EntityManager
*/
protected $em;
public function getEntityManager()
{
if (null === $this->em) {
$this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
}
return $this->em;
}
public function setEntityManager(EntityManager $em)
{
$this->em = $em;
}
...
public function yourAction() {
...
$form = new YourForm($this->getEntityManger());
...
}
You then can just call entity Manager methods within your form:
public function __construct($em)
{
...
$repository = $em->getRepository('\Namespace\Entity\Namespace');
...
}
The more complex but nicer way requires you to add the getServiceconfig function within your modules Module.php:
public function getServiceConfig()
{
return array(
'factories' => array(
'YourFormService' => function ($sm) {
$form = new YourForm($sm);
$form->setServiceManager($sm);
return $form;
}
)
);
}
Within your Form you´ll need to implent the ServiceManagerAwareInterface and the setServiceManager setter.
use Zend\Form\Form as BaseForm;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;
class CategoryForm extends BaseForm implements ServiceManagerAwareInterface
{
protected $sm;
public function setServiceManager(ServiceManager $sm)
{
$this->sm = $sm;
}
public function __construct($sm)
{
...
$em = $sm->get('Doctrine\ORM\EntityManager');
...
}
You then have to call your Form within your controller differently. The usual$form = new YourForm(); constructor will not work with the factory we created.
$form = $this->getServiceLocator()->get('YourFormService');
I usually use the dirty way to get the Entitymanager but as soon as I need the Service Locator I create a factory personally I dont think its worth it to create a big overhead with the services.
I hope this helped a bit.