Error in using my own Curl class in laravel - class

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

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

Using my own service with Laravel4

In my app, I was testing Google Directions API with ajax, but since I was just testing all the logic was in the routes.php file. Now I want to do things the proper way and have three layers: route, controller and service.
So in the routes I tell Laravel which method should be executed:
Route::get('/search', 'DirectionsAPIController#search');
And the method just returns what the service is supposed to return:
class DirectionsAPIController extends BaseController {
public function search() {
$directionsSearchService = new DirectionsSearchService();
return $directionsSearchService->search(Input::all());
}
}
I created the service in app/libraries/Services/Directions and called it DirectionsSearchService.php and copied all the logic I developed in routes:
class DirectionsSearchService {
public function search($input = array()) {
$origin = $input['origin'];
$destination = $input['destination'];
$mode = $input['mode'];
// do stuf...
return $data;
}
}
I read the docs and some place else (and this too) and did what I was supposed to do to register a service:
class DirectionsAPIController extends BaseController {
public function search() {
App::register('libraries\Services\Directions\DirectionsSearchService');
$directionsSearchService = new DirectionsSearchService();
return $directionsSearchService->search(Input::all());
}
}
// app/libraries/Services/Directions/DirectionsSearchService.php
use Illuminate\Support\ServiceProvider;
class DirectionsSearchService extends ServiceProvider {
}
I also tried adding libraries\Services\Directions\DirectionsSearchService to the providers array in app/config/app.php.
However, I am getting this error:
HP Fatal error: Class
'libraries\Services\Directions\DirectionsSearchService' not found in
/home/user/www/my-app-laravel/bootstrap/compiled.php on line 549
What am I doing wrong? And what is the usual way to use your own services? I don't want to place all the logic in the controller...
2 main things that you are missing:
There is a difference between a ServiceProvider and your class. A service provider in Laravel tells Laravel where to go look for the service, but it does not contain the service logic itself. So DirectionsSearchService should not be both, imho.
You need to register your classes with composer.json so that autoloader knows that your class exists.
To keep it simple I'll go with Laravel IoC's automatic resolution and not using a service provider for now.
app/libraries/Services/Directions/DirectionsSearchService.php:
namespace Services\Directions;
class DirectionsSearchService
{
public function search($input = array())
{
// Your search logic
}
}
You might notice that DirectionsSearchService does not extend anything. Your service becomes very loosely coupled.
And in your DirectionsAPIController.php you do:
class DirectionsAPIController extends BaseController
{
protected $directionsSearchService;
public function __construct(Services\Directions\DirectionsSearchService $directionsSearchService)
{
$this->directionsSearchService = $directionsSearchService;
}
public function search()
{
return $this->directionsSearchService->search(Input::all());
}
}
With the code above, when Laravel tries to __construct() your controller, it will look for Services\Directions\DirectionsSearchService and injects into the controller for you automatically. In the constructor, we simply need to set it to an instance variable so your search() can use it when needed.
The second thing that you are missing is to register your classes with composer's autoload. Do this by adding to composer.json's autoload section:
"autoload": {
"classmap": [
... // Laravel's default classmap autoloads
],
"psr-4": {
"Services\\": "app/libraries/Services"
}
}
And do a composer dump-autoload after making changes to composer.json. And your code should be working again.
The suggestion above can also be better with a service provider and coding to the interface. It would make it easier to control what to inject into your controller, and hence easier to create and inject in a mock for testing.
It involves quite a few more steps so I won't mention that here, but you can read more in Exploring Laravel’s IoC container and Laravel 4 Controller Testing.

How to integrate non Laravel related classes in framework?

I have a class which I would like to use inside of my Laravel App. Where do I place this and how do I integrate in Laravel workflow
what I tried
creating
/app/libraries
--myClass.php
than in composer
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/services",
"app/facades",
"app/libraries",
"public/site"
]
},
composer dump-autoload
Than I would like to initiate inside of a custom Model How would I do that?
under vendor/composer/autoloaded the class is present
than in my model I init autoloaded
public function MyMethod(){
$instance = new MyClass();
var_dump($instance);
// pulled Error : Class 'App\Models\MyClass' not found
}
The work is almost done, now you have to make sure your class appears in
vendor/composer/autoload_classmap.php
Then you just need to use it anywhere:
class Post extends Eloquent {
public function doThing()
{
$instance = new MyClass;
}
}
If you are somehow using namespaces, you have to use them in the top of your class:
use MyClass;
use App\Classes\MyOtherClass;
class Whatever {
public function MyMethod()
{
$instance = new MyClass();
$other = new MyOtherClass();
var_dump($instance);
}
}

Zend: Action helper not found

I am trying to create a helper of my own. The Safecheck folder is located in the library folder and contains a Helper folder. The class is called Safecheck_Helper_Authority.php (inside library/Safecheck/Helper).
In Bootstrap.php:
protected function _initHelper()
{
Zend_Controller_Action_HelperBroker::addPrefix('Safecheck_Helper');
}
In Safecheck_Helper_Authority.php:
class Safecheck_Helper_Authority extends Zend_Controller_Action_Helper_Abstract
{
public function hasAuthority($userId, array $ids)
{
}
}
I want to user the functions inside this class. But I get the error "Message: Action Helper by name Authority not found", triggered by the following code:
$this->_helper->authority('hasAuthority');
Maybe I am not calling it with the right code? Am I missing something?
in order to call an action helper in this manner $this->_helper->authority('hasAuthority'); you need to define the direct() method in your helper.
class Safecheck_Helper_Authority extends Zend_Controller_Action_Helper_Abstract
{
public function direct($userId, array $ids)
{
// do helper stuff here
}
}
an easy way to register the helper path and prefix is to use the application.ini:
resources.frontController.actionhelperpaths.Safecheck_Helper = APPLICATION_PATH "/../library/Safecheck/Helper"
to do it in bootstrap (not sure if addPrefix() works with library namespaces):
protected function _initHelper()
{
//addPath(path_to_helper, helper_prefix)
Zend_Controller_Action_HelperBroker::addPath('/../library/Safecheck/Helper', 'Safecheck_Helper');
}
a Simple example of an action helper:
class Controller_Action_Helper_Login extends Zend_Controller_Action_Helper_Abstract
{
//prepares a login form for display
public function direct()
{
$form = new Application_Form_Login();
$form->setAction('/index/login');
return $form;
}
}
Have in your application.ini something similar to
resources.frontController.actionhelperpaths.Application_Action_Helper = APPLICATION_PATH "/../classes/Application/Action/Helper"
The path should be changed to reflect your file path.

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.