I wanted to use Doctrine in my project, but I am not able to use Entity Manager.
I have created entites, repositories, config files and dbconnect but it seems that it's not done correctly.
Can you please check this code? Maybe I'm missing something really small.
My dbconnect file(it is bootstrapped in init.php):
<?php
namespace Projekt\Config;
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;
$paths = array("Entity");
$isDevMode = false;
// the connection configuration
$dbParams = array(
'driver' => 'pdo_mysql',
'user' => 'root',
'password' => '',
'dbname' => 'projekt',
);
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, null, null, false);
$em = EntityManager::create($dbParams, $config);
My Repository example:
<?php
namespace Projekt\Repository;
use Doctrine\ORM\EntityRepository;
/**
* Message
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class Message extends EntityRepository
{
public function getMessage($id)
{
$message = $this->find($id);
return $message;
}
public function getAllMessages()
{
}
public function createMessage()
{
}
public function updateMessage()
{
}
public function deleteMessage()
{
}
}
Now when I'm trying to access a default or custom repository method I get this error:
Warning: Missing argument 1 for Doctrine\ORM\EntityRepository::__construct(),
called in F:\xampp\htdocs\mvc\app\Controllers\Messages.php
on line 15 and defined in F:\xampp\htdocs\mvc\vendor\doctrine\orm\lib\Doctrine\ORM\EntityRepository.php on line 64
line 64 in EntityRepository.php is a __construct function that declares entitymanager, but it seems to not be working properly:
public function __construct($em, Mapping\ClassMetadata $class)
{
$this->_entityName = $class->name;
$this->_em = $em;
$this->_class = $class;
}
Two things that i noticed:
Your path is relative. Im not sure but i always use complete path to the Entity folder. You can use __DIR__ to achieve that easily. Depending on your namespace it should look Like:
$paths = array(__DIR__ . "/../Repository");
Doctrine needs to know where to find your entities and repositories. Depending on your namespace i would think your Repository file exists in a folder named "Repository" and not "Entity".
Have you correctly defined an Entity Class? Your Repository class looks ok to me but it can only work if you have a valid Entity class.
You should not name your repository "Message". The Entity should be named "Message" and the repository should be named "MessageRepository".
Related
I am migrating a project from Zend framework 1.4 to 2.4, I have a class in "vendor/custom/classes/User.php"
<?php
namespace Classes;
use Zend\Db\TableGateway\TableGateway;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Db\Adapter\Adapter;
class User
{
public function getItemById($id)
{
//$config = $this->getServiceLocator()->get('config');
//This only work in controller
$configs = array();
$adapter = new Adapter($configs);
$projectTable = new TableGateway('project', $adapter);
$rowset = $projectTable->select(array('type' => 'PHP'));
echo 'Projects of type PHP: ';
foreach ($rowset as $projectRow) {
echo $projectRow['name'] . PHP_EOL;
}
}
}
?>
I need to load merged configurations in my files in "config/autoload" , global.php and local.php. $config = $this->getServiceLocator()->get('config'); Can someone guide me how can I get these configurations from a custom class. Basically I am trying to do is writing set of classes like User, Project, Customer outside of Models and use them commonly in all modules like CMS, Admin Panel, Web site. Appreciate your guidance.
An approach could be using a factory.
You create a class UserFactory implementing Zend\ServiceManager\FactoryInterface. This class will have a method createService with a $serviceLocator parameter. You use this service locator to retrieve your dependencies and pass them to your User class.
In your User class you need to use a controller that accepts as parameters the dependencies that you need to pass to it
Since there is no direct way to access those configurations. I have wrote constants with DB access information in the local and global php files in config/autoload and used it in my class.
class DBManager
{
protected $adapter ;
protected $connection ;
/**
* Constructor
*/
public function __construct()
{
$configs = array(
'hostname' => DB_SERVER_NAME,
'driver' => 'Pdo_Mysql',
'database' => DB_DATABASE_NAME,
'username' => DB_USER_NAME,
'password' => DB_PASSWORD ,
);
$this->adapter = new Adapter($configs);
}
}
I'm creating a module X that will be instantiated inside a controller module. How can I get the name of that controller in a method of module X?
This module is not a controller, nor a view or layout.
An example. This is an action in the controller:
public function indexAction {
$parser = new Parser();
}
And this my new module Parser, where I need to know the controller's name.
public function __construct() {
$controller_name = ???
}
For such dependencies you should use a factory to create your service instance. Then you can inject whatever you want in there, also a controller name. Your ParserFactory could for example look like this:
<?php
namespace Application\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Application\Service\Parser
class ParserFactory implements FactoryInterface
{
/**
* #param ServiceLocatorInterface $serviceLocator
* #return Parser
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$routeMatch = $serviceLocator->get('Application')->getMvcEvent()->getRouteMatch();
$controllerName = $routeMatch->getParam('controller');
$parser = new Parser($controllerName);
return $parser;
}
}
Your Parser class:
<?php
namespace Application\Service;
class Parser
{
/**
* #param string $controllerName
*/
public function __construct($controllerName)
{
//... use your controller name ...
}
}
Register your factory in module.config.php like this:
'service_manager' => array(
'factories' => array(
'Parser' => 'Application\Factory\ParserFactory',
)
)
Get your service where you need it from the ServiceManager like this:
$parser = $serviceManager->get('Parser');
I think this has been asked before but I think you do:
$this->getEvent()->getRouteMatch()->getParam('controller', 'index');
You should just be able to grab it all from the router.
EDIT:
Yeah, check these out:
How to get the controller name, action name in Zend Framework 2
ZF2 - Get controller name into layout/views
ZF2: Get module name (or route) in the application layout for menu highlight
I have been racking my brain now for the better part of two days. I'm using Zend Apigility to create a RESTful web API application. Apigility builds its application using ZF2.
I created a custom class that I use throughout my API.
I would like to read in some autoloaded configuration information to make a connection to an memcache server. The file that is being autoloaded into the service manager is:
memcache.config.local.php:
return array(
'memcache' => array(
'server' => '10.70.2.86',
'port' => '11211',
),
);
My custom class that my REST services are calling is called checkAuth:
checkAuth.php:
namespace equiAuth\V1\Rest\AuthTools;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class checkAuth implements ServiceLocatorAwareInterface{
protected $services;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->services = $serviceLocator;
}
public function getServiceLocator()
{
return $this->services;
}
public function userAuths() {
//** Some Code
$config = $this->getServiceLocator()->get('config');
// **
}
}
I believe I'm injecting the service manager into the class from my module.config.php with the following code:
'service_manager' => array(
'invokables' => array(
'checkAuth' => 'equiAuth\V1\Rest\AuthTools\checkAuth',
),
),
When I hit the code when I'm trying to read the 'config' from the get method of the ServiceLocator I get the following error:
Fatal error: Call to a member function get() on a non-object
I know I'm missing something, but I cant for the life of me figure out what.
Give your class an API that allow's you to 'set' the configuration from client code. This could be via the constructor or
a public setter.
namespace equiAuth\V1\Rest\AuthTools;
class CheckAuth
{
protected $config;
public function __construct(array $config = array())
{
$this->setConfig($config);
}
public function setConfig(array $config)
{
$this->config = $config;
}
public function doStuff()
{
$server = $this->config['server'];
}
}
In order to 'set' the configuration you would also need to also create a service factory class. The idea in the factory is to give you an area to inject the configuration in to the service; with the updates to CheckAuth above we can now do so very easily.
namespace equiAuth\V1\Rest\AuthTools;
use equiAuth\V1\Rest\AuthTools\CheckAuth;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\FactoryInterface;
class CheckAuthFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('config');
return new CheckAuth($config['memcache']);
}
}
Lastly, change the registered service with the service manager; the change here is service key form invokables to factories as we need to register the
above factory to create it.
// module.config.php
'service_manager' => array(
'factories' => array(
'checkAuth' => 'equiAuth\V1\Rest\AuthTools\CheckAuthFactory',
),
),
ZF2 use ServiceManager Container as well.
Your code is right at all, but
To auto-inject the servicelocator on your class you just need to use
$checkAuth = $this->getServiceLocator()->get('checkAuth');
then you can call
$checkAuth->userAuths();
and should work.
If you try to use:
$checkAuth = new \equiAuth\V1\Rest\AuthTools\checkAuth();
$checkAuth->userAuths(); //error
Will not work because what inject the serviceLocator into your class is just the
ServiceManager, once you use serviceManager you need to be evangelist with them.
But if you try:
$checkAuth = new \equiAuth\V1\Rest\AuthTools\checkAuth();
$checkAuth->setServiceLocator($serviceLocator)
//get $serviceLocator from ServiceManager Container
$checkAuth->userAuths();
Will work too.
Good job!
I have the problem with doctrine console. I have a MailServiceFactory.php containing this code:
namespace Application\Service;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class MailServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$I_render = $serviceLocator->get('ViewRenderer');
$a_config = $serviceLocator->get('config');
return new MailService($I_render, $a_config);
}
}
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class MailServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$I_render = $serviceLocator->get('ViewRenderer');
$a_config = $serviceLocator->get('config');
return new MailService($I_render, $a_config);
}
}
and all functions works, but when i execute the vendor/bin/doctirne-module I get the error below:
Fatal error: Uncaught exception
'Zend\ServiceManager\Exception\ServiceNotFoundException' with message
'Zend\ServiceManager\ServiceManager::get was unable to fetch or create
an instance for ViewRenderer' in
/Users/Daniele/Apps/corradini.com/www/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:529
Why i'm getting this error?
You cannot get ViewRenderer directly from ServiceLocator on console requests because its not in stage since request is not an HttpRequest.
Instead of ViewRenderer, you can easily try to passing a PhpRenderer instance to your service and render a ViewModel using that. For example:
use Zend\View\Renderer\PhpRenderer;
class MailServiceFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$renderer = new PhpRenderer();
$a_config = $serviceLocator->get('config');
return new MailService($renderer, $a_config);
}
Now in your MailService:
use Zend\View\Renderer\RendererInterface;
use Zend\View\Model\ViewModel;
class MailService
{
protected $renderer;
public function __construct(RendererInterface $renderer, $config)
{
$this->renderer = $renderer;
// set your config etc..
}
public function fooMethod()
{
$model = new ViewModel();
$model->setTemplate('path/to/template.phtml');
$result = $this->renderer->render($model);
// The $result contains rendered html markup
}
Hope it helps.
Thanks foozy now doctrine console funciton! but the i can't read the tempalte for render mail.
My tempate is locatend in module/Application/view/email/template.phtml
In my module.config.php there is configuration:
'template_path_stack' => array(
'application' => __DIR__ . '/../view',
),
And error:
Zend\View\Renderer\PhpRenderer::render: Unable to render template "email/template.phtml"; resolver could not resolve to a file
where mistake ?
thanks
I had the same problem after I added a view_manager config to the console config. The solution is to just pull the renderer from the ViewManager:
$renderer = $serviceLocator->get('ViewManager')->getRenderer();
This will also register the ViewRenderer service, so any calls to get('ViewRenderer') after this should work too.
in ZF3 also a TemplateMapResolver can help you to fix some issues like:
"PhpRenderer::render: Unable to render template"
$resolver = new \Zend\View\Resolver\TemplateMapResolver();
$resolver->setMap([
'mailTemplate' => __DIR__ . '/../../view/email/testmail.phtml'
]);
$renderer->setResolver($resolver);
$viewContent = new \Zend\View\Model\ViewModel($contentArray);
$viewContent->setTemplate('mailTemplate');
I am moving my old password encrypt class from ZF1 to ZF2. In my original code I used the zend registry to store the encryption salt value pulled from the application.ini file. In ZF2 the logical place for this setting to go would be the local.php file in config/autoload folder.
My question is how do I access the salt setting specified in the local.php file?
I have tried
$this->getServiceLocator()->get('Config');
but all this does is produce the error
Call to a member function get() on a non-object
in C:\Users\Garry Childs\Documents\My Webs\freedomw\vendor\freedom\Zend\Filter\EncryptPassword.php on line 59
I have also tried to add the following function to my module.php file
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
and used
$this->getConfig();
to no avail.
Please can someone point me in the right direction, many thanks.
would say that you have to make a factory for your password encrypt class and get the salt from ServiceLocator in the factory and inject the salt from the config into your class (either in constructor or by using some setter).
So something like this:
In your module.config.php:
'service_manager' => array(
'factories' => array(
'My\Filter\EncryptPassword' => 'My\Filter\EncryptPasswordFactory',
)
)
And then in your My\Filter\EncryptPasswordFactory.php:
<?php
namespace My\Filter;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class EncryptPasswordFactory implements FactoryInterface
{
/**
* #param ServiceLocatorInterface $serviceLocator
* #return EncryptPasswordService
*/
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('config');
$salt = ...get salt from config...
$encryptPasswordService = new EncryptPasswordService($salt);
return $encryptPasswordService;
...or make a setSalt method or whatever you think is nicest...
}
}
Your My\Filter\EncryptPasswordService.php:
<?php
namespace My\Filter;
class EncryptPasswordSevice
{
/**
* #param ServiceLocatorInterface $serviceLocator
* #return EncryptPasswordService
*/
public function __construct($salt)
{
use your $salt
}
}
Now you can get your My\Filter\EncryptPassword anywhere where you have access to a serviceManager instance (or serviceLocator instance) like this:
$encryptPasswordService = $serviceManager->get('My\Filter\EncryptPassword');