i want to provide the possibility to login on my website by passing the username and password in the url. Something like this:
http://vabdat.local/rest/bpid/34.xml?User=Mustermann&password=abcdef123
But i have no idea how to solve that problem. I `m actually using CakePHP 2.x
public function beforeFilter() {
if(in_array(strtolower($this->params['controller']),array('rest'))){
$user = $this->Auth->identify($this->request, $this->response);
$this->Auth->login($user);
$this->Auth->authenticate = array('Basic' => array (
'fields' => array('User.username' => 'Username', 'User.password' => 'Password'),
'userModel' => 'User',
'passwordHasher' => 'Blowfish',
'scope' => array (
'User.active' => 1,
)
) );
$this->Security->unlockedActions = array();
}
else{
}
}
Can someone tell me how to find a solution to this?
Thanks a lot.
This is my first question, so I would also appreciate hints on how to ask properly.
So, In my Laravel app, I have a database table with users. For start, I wanted to have a model factory for it. So I took a standard code from laravel doc page:
$factory->define(App\User::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
And I changed it to:
$factory->define(App\User::class,
function(Faker\Generator $faker) {
return [
'name' => $faker->name(),
'email' => $faker->safeEmail(),
'password' => bcrypt(str_random(10)),
'phone_number' => $faker->phoneNumber(),
'remember_token' => str_random(10),
'account_type' => 0,
];
});
So far, everything works. But I wanted it to be more sophisticated, and I decided to use more specific kind of Faker class, to generate Italian data. I changed it to:
$factory->define(App\User::class,
function(Faker\Generator $faker,
Faker\Provider\it_IT\PhoneNumber $fakerITPN,
Faker\Provider\it_IT\Person $fakerITPER,
Faker\Provider\it_IT\Internet $fakerITInt) {
return [
'name' => $fakerITPER->name(),
'email' => $fakerITInt->safeEmail(),
'password' => bcrypt(str_random(10)),
'phone_number' => $fakerITPN->phoneNumber(),
'remember_token' => str_random(10),
'account_type' => 0,
];
});
In seeder class I wrote:
factory(App\User::class)->create();
And then, after I used Artisan, command:
artisan migrate:refresh --seed -vvv
I get following error (just the head, for clearance):
[ErrorException]
Argument 2 passed to Illuminate\Database\Eloquent\Factory::{closure}() must be an instance of Faker\Provider\it_IT\PhoneNumber, array given
Exception trace:
() at /home/vagrant/php/housing/database/factories/ModelFactory.php:19
Illuminate\Foundation\Bootstrap\HandleExceptions->handleError() at /home/vagrant/php/housing/database/factories/ModelFactory.php:19
Illuminate\Database\Eloquent\Factory::{closure}() at n/a:n/a
call_user_func() at /home/vagrant/php/housing/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:130
Illuminate\Database\Eloquent\FactoryBuilder->Illuminate\Database\Eloquent\{closure}() at /home/vagrant/php/housing/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2308
Illuminate\Database\Eloquent\Model::unguarded() at /home/vagrant/php/housing/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:133
Illuminate\Database\Eloquent\FactoryBuilder->makeInstance() at /home/vagrant/php/housing/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:105
Illuminate\Database\Eloquent\FactoryBuilder->make() at /home/vagrant/php/housing/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:83
Illuminate\Database\Eloquent\FactoryBuilder->create() at /home/vagrant/php/housing/database/seeds/UsersTableSeeder.php:24
UsersTableSeeder->run() at /home/vagrant/php/housing/vendor/laravel/framework/src/Illuminate/Database/Seeder.php:42
Clearly, there is something wrong with dependency injection, but I don't know what. I know, that in this case I could just manually create instances of classes I need, but I want to know, how to do it properly. Can anyone help?
If you take a look at the documention of faker # https://github.com/fzaninotto/Faker#localization, you'll see that you can simply assign the proper localization as a parameter to create.
In your case, just use:
Faker\Factory::create('it_IT');
You don't need to add more parameters in the anonymous function when you define the factory.
Edit:
Just to add on the issue on dependency injection. If you trace the source code, it does not do any dependency injection underneath.
$factory->define(...)
Only sets an array of definitions
public function define($class, callable $attributes, $name = 'default')
{
$this->definitions[$class][$name] = $attributes;
}
Calling
Faker\Factory::create();
or
factory(App\User::class)->create();
$factory->of($class)
calls "of" method that instantiate FactoryBuilder
(see lines 169-172 of Illuminate\Database\Eloquent\Factory.php)
public function of($class, $name = 'default')
{
return new FactoryBuilder($class, $name, $this->definitions, $this->faker);
}
after that, it chains "create" method of FactoryBuilder that calls "make" method which also calls "makeInstance"
protected function makeInstance(array $attributes = [])
{
return Model::unguarded(function () use ($attributes) {
if (! isset($this->definitions[$this->class][$this->name])) {
throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}].");
}
$definition = call_user_func($this->definitions[$this->class][$this->name], $this->faker, $attributes);
return new $this->class(array_merge($definition, $attributes));
});
}
Notice "call_user_func" inside "makeInstance", that is the one responsible for calling the anonymous function created as the 2nd argument to define (inside ModelFactory.php). It specifically pass only 2 arguments to the callable function, these are:
...$this->faker, $attributes);
Only 1 faker is passed on the first argument and an array of attributes on the 2nd argument (this is the one you saw on your ErrorException earlier)
That means you can only define your factory in this way:
$factory->define(App\User::class,
function (Faker\Generator $faker, $attributes=array()) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
If you really need other classes, you can initialize it outside of "define" and use it in the function like this:
$sampleInstance = app(App\Sample::class);
$factory->define(App\User::class,
function (Faker\Generator $faker, $attributes=array()) use($sampleInstance){
//...do something here
//...or process the $attributes received
//...or call a method like
$sampleData = $sampleInstance->doSomething();
return [
'someField' => $sampleData,
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
You can put this setting in register() of AppServiceProvider:
$this->app->singleton(\Faker\Generator::class, function () {
return \Faker\Factory::create('it_IT');
});
I want to create an url with this format :
domain.com/list?sortBy=number&sortDir=desc
in my View (blade). I'm using this approach which I don't really prefered :
{{ url("list")."?sortBy=".$sortBy."&sortDir=".$sortDir }}
because using
{{ url("list", $parameters = array('sortBy' => $sortBy, 'sortDir' => $sortDir) }}
didn't produce as I hoped. Is there a better way?
Have you tried the URL::route method.
Example Route:
Route::get('/list', array('as' => 'list.index', 'uses' => 'ListController#getIndex'));
Retrieve the URL to a specific route with query string:
URL::route('list.index', array(
'sortBy' => $sortBy,
'sortDir' => $sortDir
));
If your using a closure on the route:
Route::get('/list', array('as' => 'list.index', function()
{
return URL::route('account-home', array(
'sortBy' => 1,
'sortDir' => 2
));
}));
I'm trying to set a drop down to 'required' but the form still goes through. What am I doing wrong?
Here is the code:
this->exportForm = new sfForm();
$widgets['sheet_type'] = new sfWidgetFormDoctrineChoice(array('model' => 'ExportSheet', 'add_empty' => true));
$this->exportForm->setWidgets($widgets);
$this->exportForm->setValidators(array('sheet_type' => new sfValidatorDoctrineChoice(array('model' => 'ExportSheet', 'required' => true), array('required' => 'Please select a sheet type to export.') )));
UPDATE:
I've made the changes suggested.
actions.class.php:
$this->exportForm = new sfForm();
$this->exportForm->getWidgetSchema()->setNameFormat('exportForm[%s]');
$widgets['sheet_type'] = new sfWidgetFormDoctrineChoice(array('model' => 'ExportSheet', 'add_empty' => true));
$this->exportForm->setWidgets($widgets);
$this->exportForm->setValidators(array('sheet_type' => new sfValidatorDoctrineChoice(array('model' => 'ExportSheet', 'required' => true), array('required' => 'Please select a sheet type to export.') )));
if ($request->isMethod('post'))
{
$this->exportForm->bind($request->getParameter('exportForm'));
if ($this->exportForm->isValid())
{
...
}
}
Template:
<form method="post" action="<?php echo url_for('#export'); ?>">
<div id="export" style="display: block">
<?php echo $exportForm['sheet_type']->renderRow(); ?>
</form>
I can see when I submit that the echoing $request->getParameter('sheet_type') does return a value. If this is the case, why is the validation still failing?
There are 2 parts to validating a form ... the first is adding the validators the second is checking if its valid ....
take this example :
public function executeSomeaction(sfWebRequest $request)
{
// Define the form
this->exportForm = new sfForm();
$widgets['sheet_type'] = new sfWidgetFormDoctrineChoice(array('model' => 'ExportSheet', 'add_empty' => true));
$this->exportForm->setWidgets($widgets);
$this->exportForm->setValidators(array('sheet_type' => new sfValidatorDoctrineChoice(array('model' => 'ExportSheet', 'required' => true), array('required' => 'Please select a sheet type to export.') )));
// Deal with the request
if ($request->isMethod('post'))
{
$this->exportForm->bind($request->getParameter(<your form>));
if ($this->exporForm->isValid())
{
// Handle the form submission
// ...
$this->redirect('foo/bar');
}
}
}
Its only the second part within if ($request->isMethod('post')) that applies your validation and checks the user submitted data. See here in the symfony docs about handling forms with validation
If you use the following to add a naming schema for your form output then getting all of the results is easy ....
$this->exportForm->getWidgetSchema()->setNameFormat('exportForm[%s]');
then you can get use :
$this->exportForm->bind($request->getParameter('exportForm'));
this will then get the array with all of the field values in it and bind it to your form - ready for checking to see if its valid.
Update
you need to specify
$this->exportForm->getWidgetSchema()->setNameFormat('exportForm[%s]');
after
$this->exportForm->setWidgets($widgets);
as the setWidgets method resets the naming format
I have an ImportController with a function admin_getcontents.
function admin_getcontents($url = null)
{
$contents = json_decode(file_get_contents(($url)),true);
//some stuff
}
Through ajax I call /admin/import/getcontents/ with:
$.get('/admin/import/getcontents/'+ encodeURIComponent($('#urlcheck').val()) ,function(data) {
$('#importtable').html(data);
$('#busy-indicator').fadeOut('high');
});
so I call the page: /admin/import/getcontents/http%3A%2F%2Flocalhost%2Feclipse%2Fanarxeio%2Fexport%2Fcontents%2F
Apache gives me an 404 error. If I call /admin/import/getcontents/1 the page loads correctly. So I figured to pass a ? before the parameter like:
admin/import/getcontents/?http%3A%2F%2Flocalhost%2Feclipse%2Fanarxeio%2Fexport%2Fcontents%2F
Now I don't get a 404 error but $url param in admin_getcontents() is empty. How can I achieve the above?
Thanks
A quick fix would be to triple url encode your url:
// javascript
$.get('/admin/import/getcontents/'+ encodeURIComponent(encodeURIComponent(encodeURIComponent($('#urlcheck').val()))) ,function(data) {
$('#importtable').html(data);
$('#busy-indicator').fadeOut('high');
});
Then url decode it in your php before you use it:
// php
function admin_getcontents($url = null)
{
$url = urldecode(urldecode($url));
$contents = json_decode(file_get_contents(($url)),true);
//some stuff
}
EDIT following comments:
You will need to set up your routing to pass the url parameter. Looking at your setup, it should looking something like:
Router::connect('/admin/import/getcontents/:url', array(
'controller' => 'import',
'action' => 'getcontents',
'admin' => true),
array(
'url' => '(.*)',
'pass' => array('url')
)
);