Unknown method SfGuardUserTable::retrieveByUsername Symfony1.4 - php

I'm wondering why I got this error when installing sfDoctrineGuard plugin in symfony 1.4 project
stack trace:
SF_ROOT_DIR/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Table.php line 2856 ...
return call_user_func_array(array($this->getRecordInstance(), $method . 'TableProxy'), $arguments);
} catch (Doctrine_Record_UnknownPropertyException $e) {}
throw new Doctrine_Table_Exception(sprintf('Unknown method %s::%s', get_class($this), $method));
}
}

The problem occurs when you run doctrine build all or build model command from the command line.
If the sf_guard_user table exists in your database, running either of these commands generates an empty SfGuardUserTable class in your \lib\model folder and this gets used instead of the sfGuardUserTable class sitting in your plugin folder, which does contain a retrieveByUsername method.
Removing the SfGuard____ classes from inside your lib folder would fix the problem.
I used the build commands quite often and got a bit fed up with doing this each time. I eventually moved the code from within the plugin folder into the lib directory which isn't really recommended. But I don't think the sfGuardUser plugin is maintained any more, so if you know what you're doing you could give it a try.

Related

PHP error calling a function from a package

I am new to php and have just installed my first package via composer. I'm now trying to call a function from the package I installed as follows:
<?php
require_once 'vendor/autoload.php';
$value = 1;
$aws = AmazonGiftCode::make()->buyGiftCard($value);
echo $aws;
?>
But I get the following error:
PHP Fatal error: Uncaught Error: Class 'AmazonGiftCode' not found in
/public_html/php/test.php:4 Stack trace:
#0 {main} thrown in /public_html/php/test.php on line 4
Based on my (albeit limited) experience with other languages, I'm guessing I have to load the package that contains the class first. The package folder is in the same directory as the test.php file, in the subfolder vendor/kamerk22/AmazonGiftCode/. But I think this is where I don't know enough to troubleshoot it based on the information I could find.
Your directory structure should look like this.
test.php
composer.json
vendor
└───autoload.php
└───kamerk22
└───AmazonGiftCode
Make sure you installed the package using composer, and not by downloading it.
I'm guessing I have to load the package that contains the class first.
Unlike what you would normally expect when importing stuff, when using composer you only have to import the autoload.php file, and composer will take care of loading other packages as needed. By as needed what I mean is that as soon as composer sees you use the AmazonGiftCode class it will import the AmazonGiftCode package, but if one of your REST endpoints doesn't use anything from the AmazonGiftCode package it won't ever load it. This allows you to not have to worry about slowing down the entire application when you want to use a composer package for only a few endpoints. At least that's the way I understand how composer works.
Just run composer dump-autoload once and the class should known then.
You could also get verbose and use kamerk22\AmazonGiftCode\AmazonGiftCode;
But that AmazonGiftCode looks quite Laravel specific... that's why it may still fail, even if it may be found by auto-load. One needs to setup Laravel framework in the first place; just see this query (just in case if you may wonder where all these missing classes may come from).

PHPUnit does not find a class

I am working on a new tokenizer class for PHP_CodeSniffer. This also requires making a new Standard since the valid tokenizers are specified within each standard.
My new classes are using the same namespaces as the “sibling” classes from the original codebase.
If I use composer to install my project, and run phpcs, the auto loader seems to pick up my new classes just fine. PHP_CodeSniffer will load my tokenizer by calling:
$className = ‘PHP_CodeSniffer\\Tokenizers\\’ . $type;
$class = new $className(<stuff>);
Similarly, my custom standard has a use statement for a class in the original codebase. When running phpcs, no error are thrown.
When I try to run a test file through phpcs in a unit test, I get an error that my custom sniff file is unable to find the class in the use statement. My guess is this is auto-loading related. The bootstrap.php file for phpunit requires __DIR__ . ‘/../vendor/autoload.php’.My project composer.json has:
“autoload”: {
“psr-4”: { “PHP_CodeSniffer\\”: “src\” }
},
“autoload-dev”: {
“psr-4”: { “PHP_CodeSniffer\\Tests\\”: “tests\” }
}
Is there an issue with using the same namespace as the original code? With registering the same namespace to a different location in composer? Why does it work in runtime but not in testing?
It turns out PHPUnit has its own custom bootloader. When I added a require_once() for that in my PHPUnit bootloader, it loaded successfully. Thanks to a user on the PHP subreddit.

Creating a new ServiceProvider / Facade as a package in Laravel 5

Introduction
I've never worked with a framework before (Zend, CakePHP, etc) and finally decided to sit down and learn one. I'm starting with Laravel because the code looks pretty and unlike some other frameworks I tried to install, the "Hello, World!" example worked on the first try.
The Goal
For the time being, I want my app to do something very simple:
User submits a request in the form of: GET /dist/lat,lng
The app uses the remote IP address and MaxMind to determine $latitude1 and $longitude1
This request path is parsed for $latitude2 and $longitude2
Using these two positions, we calculate the distance between them. To do this I'm using Rafael Fragoso's WorldDistance PHP class
Since I plan to re-use this function in later projects, it didn't seem right to throw all of the code into the /app directory. The two reusable parts of the application were:
A service provider that connects to MaxMind and returns a latitude and longitude
A service provider that takes two points on a globe and returns the distance
If I build facades correctly then instead of my routes.php file being a mess of closures within closures, I can simply write:
Route::get('dist/{input}', function($input){
$input = explode( "," , $input );
return Distance::getDistance( GeoIP::getLocation(), $input );
});
What I've tried
Initial Attempt
For the first service provider, I found Daniel Stainback's Laravel 5 GeoIP service provider. It didn't install as easily as it should have (I had to manually copy geoip.php to the /config directory, update /config/app.php by hand, and run composer update and php artisan optimize) however it worked: A request to GET /test returned all of my information.
For the second service provider, I started by trying to mimic the directory structure and file naming convention of the GeoIP service provider. I figured that if I had the same naming convention, the autoloader would be able to locate my class. So I created /vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:
<?php namespace Stevendesu\WorldDistance;
use Illuminate\Support\ServiceProvider;
class WorldDistanceServiceProvider extends ServiceProvider {
protected $defer = false;
public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}
public function provides()
{
return ['distance'];
}
}
I then added this to my /config/app.php:
'Stevendesu\WorldDistance\WorldDistanceServiceProvider',
This fails with a fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
Using WorkBench
Since this utterly failed I figured that there must be some other file dependency: maybe without composer.json or without a README it gives up. I don't know. So I started to look into package creation. Several Google searches for "create package laravel 5" proved fruitless. Either:
They were using Laravel 4.2, in which case the advice was "run php artisan workbench vendor/package --resources"
Or
They were using Laravel 5, in which case the docs were completely useless
The official Laravel 5 docs give you plenty of sample code, saying things like:
All you need to do is tell Laravel where the views for a given namespace are located. For example, if your package is named "courier", you might add the following to your service provider's boot method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
This makes the assumption that you have a service provider to put a boot method in
Nothing in the docs says how to create a service provider in such a way that it will actually be loaded by Laravel.
I also found several different resources all of which assume you have a repository and you just want to include it in your app, or assume you have "workbench". Nothing about creating a new package entirely from scratch.
PHP Artisan did not even have a "workbench" command, and there was no "workbench.php" file in /config, so anything I found related to workbench was worthless. I started doing some research on Workbench and found several different questions on StackOverflow.
After a long time and some experimentation, I managed to get laravel/workbench into my composer.json, composer update, composer install, manually build a workbench.php config file, and finally use the PHP Artisan Workbench command to make a new package:
php artisan workbench Stevendesu/WorldDistance --resources
This created a directory: /workbench/stevendesu/world-distance with a number of sub-directories and only one file: /workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php
This service provider class looked essentially identical to the file I created before, except that it was in the /workbench directory instead of the /vendor directory. I tried reloading the page and I still got the fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
I also tried php artisan vendor:publish. I don't really know what this command does and the description wasn't helpful, so maybe it would help? It didn't.
Question
How do I create a new service provider as a package so that in future projects I can simply include this package and have all the same functionality? Or rather, what did I do wrong so that the package I created isn't working?
After two days of playing with this I managed to find the solution. I had assumed that the directory structure mapped directly to the autoloader's path that it checked (e.g. attempting to access a class Stevendesu\WorldDistance\WorldDistanceServiceProvider would look in vendor/stevendesu/world-distance/WorldDistanceServiceProvider)... This isn't the case.
Reading through the composer source code to see how it actually loads the files, it builds a "classmap" - essentially a gigantic array mapping classes to their respective files. This file is built when you run composer update or composer install - and it will only be built correctly if composer knows the details of your package. That is - if your package is included in your project's composer.json file
I created a local git repository outside of my app then added my package to my app's composer.json file then ran composer update -- suddenly everything worked perfectly.
As for the:
It didn't install as easily as it should have
the secret sauce here was first add the service provider to /config/app.php then, second run php artisan vendor:publish

php, laravel, log4php: Class 'Apache\Log4php\Hierarchy' not found error

I'm new to php and i'm using log4php with laravel.
My project structure is
->Root
->Laravel
->app
->folderx
->abc.php
->otherfolders
.
.
->vendor
->composer.json (contains log4php and laravel)
->logconfig.xml
I'm trying to initialize the logger from inside abc.php,
Logger::configure('../../../logconfig.xml');
but it gives the error message
Class 'Apache\Log4php\Hierarchy' not found
I verified that the class Hierarchy.php exists in the vendor/apache/log4php/src under Root folder. Also, if I open Logger.php and go to the line where Hierarchy in initialized and ctrl+click(in eclipse) on Hierarchy, it takes me to Hierarchy.php.
I'm trying to figure out why php is not able to find that class.
Any help/suggestions would be greatly appreciated.
Thanks
That error message shows that your PHP is looking for a namespaced class. Log4PHP has never been released until now with namespaces (up to version 2.3.0), so this is definitely weird.
If you accidentially use the development branch of the 3.0 version, I must currently suggest not to use it. It barely got any significant commits in the last year, and should be considered work in progress (very slow progress unfortunately).

symfony2 CLI [Symfony\Component\Debug\Exception\ContextErrorException]

I'm having a problem whilst trying to create a command with Symfony2's Console component, in a full Symfony stack app.
If i try to pass my services in via DI, the command throws the following error when i try to run it:
[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Trying to get property of non-object
If I create the command with ContainerAwareCommand and try to get my service with
$this->getContainer()->get('mtgu.api.card.list.response.data');
I get
[LogicException]
The container cannot be retrieved as the application instance is not yet set.
My service is defiantly being loaded, as its used in a front end controller. This problem gets stranger, as if I pass a repository service - I don't get this problem!
Is there some trick to setting up a service to be passible by this? Or have I messed up my configuration somehow?
Im "autoloading" all my services by doing this in my DI Extension rather than including them all through the the main services.yml. I thought this or the ordering of the yml includes maybe effecting it - but I have tried manually including everything but still no joy!
$finder = new Finder();
$finder->name('services.yml');
/**
* #var $file SplFileInfo
*/
foreach($finder->in(__DIR__.'/../') as $file) {
$loader = new Loader\YamlFileLoader($container, new FileLocator($file->getPath()));
$loader->load('services.yml');
}
Vendor/Bundle/Command/services.yml
services:
mtgu.command.slugify:
class: MightyStudios\MtguBundle\Command\SlugifyCommand
tags:
- { name: console.command }
arguments:
- #mtgu.api.card.list.response.data
I think this maybe just some config issue, but Google has failed me to find the answer! Has anyone else run into this problem and can they shed any light!?
Many thanks
A better structure would be to put your services files in the Resources/config directory of your bundle (See also all core bundles). However, that's aside.
The problem is described by the exception: The container cannot be retrieved as the application instance is not yet set. Which is thrown in the ContainerAwareCommand#getContainer() method when $this->application is null. The application is set in the first line of the Application#add() method.
This means that you call $this->getContainer() before you add the command to the application. Maybe you use it in your constructor?
If so, remove it and only use the container in Command#execute(), Command#interact() or Command#initialize().

Categories