Symfony2 service not found - service

I have a custom service class:
namespace Acme\OpsBundle\Lib;
use Doctrine\ORM\EntityManager;
use Monolog\Logger;
class ProductManager
{
private $m_logger;
private $m_em;
public function __construct(EntityManager $em, Logger $logger)
{
$this->m_logger = $logger;
$this->m_em = $em;
}
...
}
Defined in config.yml as:
services:
opsbundle.prod_manager:
class: Acme\OpsBundle\Lib\ProductManager
arguments: [#doctrine.orm.entity_manager, #monolog.logger]
And Im accessing it in a controller via:
$repoman = $this->get('opsbundle.prod_manager');
But I get the following error:
Fatal error: Class 'Acme\OpsBundle\Lib\ProductManager' not found
in C:\apache\Symfony\app\cache\dev\appDevDebugProjectContainer.php on
line 1555
This worked at one point but I cant figure out what has changed since then to break it. I have tried clearing the cache and restarting apache.
Can anyone suggest why this would happen?

Related

Symfony 4.2 Creating Repository as service in vendor/acme/demo-bundle

I am working on a third party bundle which is in the vendor/ directory.
I have an Entity class which looks like this:
/**
* #ORM\Entity(repositoryClass="Acme\DemoBundle\Repository\ArticleRepository")
* #ORM\Table(name="acme_demo_article")
*/
class Article
And a Repository class like this:
class ArticleRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Article::class);
}
}
This generates the following error:
The "Acme\DemoBundle\Repository\ArticleRepository" entity repository
implements
"Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface",
but its service could not be found. Make sure the service exists and
is tagged with "doctrine.repository_service".
If i remove the repositoryClass from the entity definition, I dont have the error anymore and i can use doctrine as such from my controller:
this->getDoctrine()->getRepository(Article::class)->findBy([], null, $limit, ($page - 1) * $limit);
I tried adding the repository as a service in the bundle service definition but it does not change anything:
vendor/Acme/demo-bundle/Resources/config/services.yaml
services:
Acme\DemoBundle\Repository\:
resource: '../../Repository/ArticleRepository.php'
autoconfigure: true
tags: ['doctrine.repository_service']
bin/console debug:autowire or debug:container wont show the service.
I also tried adding the extension:
namespace Acme\BlogBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class AcmeBlogExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.xml');
}
}
Did not work either. I dont have the impression that the extension is being called. I tried adding a constructor to it and dump, die in the constructor, but there are no results of the dump.
So my question is how do i define my repositories as a service from the vendor directory ?
The source code is overhere: https://github.com/khalid-s/sf4-bundle-test
After much struggling, i succedded in my task. I dont think that's it should be done like this, but if this can help someone...
I added in my DependencyInjection folder of the bundle:
class AcmeBlogExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.yaml');
}
}
I created a compiler (this is the part which i struggled to figure out) to register my service
class RepositoryCompiler implements CompilerPassInterface
{
/**
* #inheritdoc
*/
public function process(ContainerBuilder $container)
{
$container->register('acme_blog.repository', ArticleRepository::class);
}
}
I added in my Bundle class:
class AcmeBlogBundle extends Bundle
{
/** #info this function normally is useless */
public function getContainerExtension()
{
// This is only useful if the naming convention is not used
return new AcmeBlogExtension();
}
/**
* #inheritDoc
*/
public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new RepositoryCompiler());
parent::build($container);
}
}
And finally the service itself:
services:
Acme\BlogBundle\Repository\:
resource: '../../Repository/*Repository.php'
autoconfigure: true
autowire: true
tags: ['doctrine.repository_service']
The autoconfigure and autowire are useless since they are not taken into consideration when i debug:container which looks like this:
php bin/console debug:container acme
Information for Service "acme_blog.article.repository"
=======================================================
---------------- -----------------------------------------------
Option Value
---------------- -----------------------------------------------
Service ID acme_blog.article.repository
Class Acme\BlogBundle\Repository\ArticleRepository
Tags doctrine.repository_service
Public yes
Synthetic no
Lazy no
Shared yes
Abstract no
Autowired no
Autoconfigured no
---------------- -----------------------------------------------
One very important note which made me loose a lot of time:
Do clear your cache after every change to your services. Even in dev
mode they are not reloaded after every refresh

Symfony2 get public services in controller

Much ink has flowed about Sf2 controller/container. I face with follow situation:
app/console container:debug security
...
> 4
[container] Information for service security.token_storage
Service Id security.token_interface
Class Symfony\Component\Security\Core\Authentication\Token ...
...
Public yes
LoginBundle\DefaultController.php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
dump(Controller::get('security.token_storage'));
...
works OK, obviously.
LoginBundle\UserUtilsController
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserUtilsController extends Controller
{
public function getRoleById()
{
dump(Controller::get('security.token_storage'));
...
throw: Error: Call to a member function get() on a non-object
In Sf2 Book - Service container I found:
In this example, the controller extends Symfony's base Controller, which gives you access to the service container itself. You can then use the get method to locate and retrieve the my_mailer service from the service container.
The misunderstanding is:
- Both controllers extends basic controller which itself extends ContainerAware which implements ContainerAwareInterface which set container.
- Both controllers access same public service container.
So, why the second controller it doesn't work?
I know that the question is old but I don't want to inject a controller as service and I think it is redundant and wrong to redeclare a public service in services.yml
Thank you in advance.
I found the answer myself and I want to share for every one is in same situation...
The UserUtilsController doesn't work because it's not working in this manner. The Symfony architecture is interesting if you get to know it.
LoginBundle\Controller\UserUtilsController
// For this job we don't need to extends any class..
class UserUtilsController
{
// but we need a property for injecting the service in it
private $token;
// Now let's inject service into our property $token
public function __construct($token)
{
$this->token = $token;
}
// It's not done but let pretend it is and let's use it
public function getRoleById()
{
...
return $this->token->getToken()->getRoles();
...
services.yml
#here it's the magic
services:
# this is a new services container
user.loggeduser_utils:
# this is my class (second class)
class: LoginBundle\Controller\UserUtilsController
# this is how I feed my _construct argument
arguments: ["#security.token_storage"]
So I just inject an existing service in my new class.
Now, to use this we must to call in first class:
LoginBundle\Controller\DefaultController.php
class DefaultController extends Controller
{
public function indexAction()
{
// because my class is now a service container we call in this way
$userRoleId = $this->get('user.loggeduser_utils');
...
This solution above is almost trivial simple AFTER understanding the Sf2 DI model.

Error in using my own Curl class in laravel

i have laravel 4 installed in my wamp server. this what i did :
1-add this "app/classes" to composer.json.
2-create folder classes in app and put Curl.php class in that folder.
3-add this app_path().'/classes', to global.php inside app/start.
4-run composer dump-autoload in command in www directory.
5-for using like Curl::help() must add this alias to app/config/app.php aliases section 'Curl'=>'Curl' .
after doing this when i return return Curl::hello(); in router this page comes :
http://www.mediafire.com/view/h9489jr5s2699ty/err.PNG
my Curl's class : Curl class
any help??
This is not how Laravel aliases works, you need more code (create Facades and Service Providers) to make it work.
So you have some options:
1) Remove the Alias from app/config/app.php and instantiate your class:
$curl = new Curl;
$curl->help();
2) Instantiate your class and bind it to the IoC container, in global.php, filters.php or create a file for that:
App::bindShared('mycurl', function($app)
{
return new Curl;
});
And create a Facade:
<?php namespace MyClasses\Facades;
use Illuminate\Support\Facades\Facade;
class MyCurlFacade extends Facade {
protected static function getFacadeAccessor()
{
return 'mycurl';
}
}
Your Alias has to point to this Facade script file, like all the others you see in app.php.
'Curl' => 'MyClasses\MyCurlFacade',
And it should work like this Curl::hello();.
3) Create the usual (correct?) Laravel structure, which also includes a ServiceProvider to instantiate your class and bind it to the IoC container in the application Boot:
<?php namespace MyClasses;
use Illuminate\Support\ServiceProvider;
class MyCurlServiceProvider extends ServiceProvider {
protected $defer = false;
public function boot()
{
}
public function register()
{
{
$this->app['mycurl'] = $this->app->share(function($app)
{
return new MyCurl;
});
}
public function provides()
{
return array('mycurl');
}
}
THIS IS UNTESTED CODE, SO DO NOT EXPECT IT TO WORK IN THE FIRST RUN

FuelPHP how to load model in test? and how to load and test controller?

how to load model in test? and how to load and test controller ?
Fatal Error : Model Not Found!
this works in the controller: #but does not work in the test
<?php
# PATH app\modules\adm\classes\model
namespace Adm\Model;
class Medico extends \Orm\Model
{
protected static $_primary_key = array('id');
protected static $_table_name = 'medico';
}
# PATH app\modules\adm\classes\controller
# WORKS!!!
namespace Adm;
use Adm\Model\Medico; # <- WORKS!!!
class Controller_Medicos extends \Controller_Template
{
public function action_index()
{
$data['medicos'] = Medico::find()->select('id','segundo_nome')->limit(1)->get_one();
print_r($data['medicos']->segundo_nome);
$this->template->content = \View::forge('medicos/index');
}
}
# app\modules\tests\adm\classes\model
# DOES NOT WORK!!
namespace Adm;
use Adm\Model\Medico; # <- Adm\Model\Medico NOT FOUND why ?
class Test_Model_Medico extends \TestCase
{
public function test_autocomplete()
{
$medico = Medico::find(1);
$this->assertEquals(2,2);
}
}
When you request the controller through the URL, the routing engine will autoload the module.
This does not happen when you run tests through oil, so you to load it manually in the setup section of your test class:
\Module::load('adm');

Probable reasons why autoloading wont work in Zend Framework 1.10.2?

Iam writing an application using Zend Framework 1.10.2.
I created few model classes and a controller to process them.
When Iam executing my application and accessing the admin controller. Iam seeing this error.
Fatal error: Class 'Application_Model_DbTable_Users' not found in C:\xampp\htdocs\bidpopo\application\controllers\AdminController.php on line 16
The error clearly shows its an autoloading error.
Hence I wrote this code in the bootstrap file.
protected function initAutoload()
{
$modeLoader = new Zend_Application_Module_AutoLoader(array
('namespace'=>'','basePath'=>APPLICATION_PATH ));
//echo(APPLICATION_PATH);
return $modeLoader;
}
Still the error remains :( . Can anyone suggest me what Iam missing out here?
This is the location of the Model Users class.
C:\xampp\htdocs\bidpopo\application\models\DbTable\Users.php
This is its code.
class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
//put your code here
protected $_name='users';
public function getUser($id)
{
$id = (int)$id;
$row = $this->fetchrow('id='.$id);
if(!$row)
{throw new Exception("Could not find row id - $id");}
return $row->toArray();
}
public function addUser($userDetailArray)
{
$this->insert($userDetailsArray);
}
public function updateUser($id,$userDetailArray)
{
$this->update($userDetailArray,'id='.(int)$id);
}
public function deleteUser($id)
{
$this->delete('id='. (int)$id);
}
}
This is the Admin Controller's code
class AdminController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
$this->view->title= "All Users";
$this->view->headTitle($this->view->title);
$users = new Application_Model_DbTable_Users();
$this->view->users = $users->fetchAll();
}
public function addUserAction()
{
// action body
}
public function editUserAction()
{
// action body
}
public function deleteUserAction()
{
// action body
}
You application classes don't follow the proper naming convention for the namespace you've set. The Zend_Application_Module_AutoLoader is a little different than the normal autoloader in that it doesn't simply change the '_' in the class name with '/'. It looks at the second part of the class name and then checks a folder for the existence of the class based on that.
You need to change the line:
$modeLoader = new Zend_Application_Module_AutoLoader(array(
'namespace'=>'Application',
'basePath'=>APPLICATION_PATH
));
This means it will autoload all module classes prefixed with 'Application_'. When it the second part of the class is 'Model_' it will look in "{$basePath}/models" for the class. The '_' in the rest of the class name will be replaced with '/'. So the file path of the file will be "{$basePath}/models/DbTable/Users.php".
Read more here.