how to add ManyToOne property field in configureListfield in sonataAdmin - sonata-admin

i have a Fonctionnaire entity class that contains ManyToOne property to Grade entity class. when i want to add the idGrade field to ConfigureListField of FonctionnaireAdmin (using SonataAdmin) i got this error:
An exception has been thrown during the rendering of a template ("You must define an associated_property option or create a Proxies\__CG__\Examens\ExamensBundle\Entity\Grade::__toString method to the field option idGrade from service examens.examens.admin.fonctionnaire is ") in SonataDoctrineORMAdminBundle:CRUD:list_orm_many_to_one.html.twig at line 19.
Fontionnaire.php class:
<?php
namespace Examens\ExamensBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Fonctionnaire
*/
class Fonctionnaire
{
//...//
/**
* #var \Examens\ExamensBundle\Entity\Grade
*/
private $idGrade;
//...//
}
FonctionnaireAdmin.php:
<?php
namespace Examens\ExamensBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Examens\ExamensBundle\Entity\Fonctionnaire;
class FonctionnaireAdmin extends Admin
{
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'codeFonctionnaire'
);
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('nomAr','text',array('label'=>'Nom arabe'))
->add('prenomAr','text',array('label'=>'Prénom arabe'))
->add('nomFr','text',array('label'=>'Nom français '))
->add('prenomFr','text',array('label'=>'Prénom français'))
->add('nomUtilisateur','text',array('label'=>'nom Utilisateur'))
->add('motDePasse','text',array('label'=>'motDePasse'))
->add('idGrade','entity',
array('class' => 'Examens\ExamensBundle\Entity\Grade',
'property' => 'libGradeAr'))
->add('dateNominationGrade','date',
array('years' => range(1980, date('Y'))))
;
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('nomAr')
->add('prenomAr')
->add('nomFr')
->add('prenomFr')
->add('nomUtilisateur')
->add('motDePasse')
->add('idGrade')
->add('dateNominationGrade')
;
}
}

You can just add:
->add('idGrade', null, array('associated_property' => 'libGradeAr'))

You just need to add a __toString() method to your Grade class. Something like :
public function __toString() {
return $this->nomAr;
}
It will be used by SonataAdminBundle to display the name of your current object.

Don't forget you also can use it as follow to prevent Sonata from generating a name for you when creating a new object:
public function __toString {
// Show name if it exist otherwise just show a custom label
return $this->nomAr ? $this->nomAr : 'Custom new label name';
}

Related

React login screen with laravel [duplicate]

In my LoginController under Auth, I have used the following codes:
namespace App\Http\Controllers\Auth;
use App\Model\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Redirect;
use Hash;
use Auth;
use DB;
use App\Model\UserAdmin;
class LoginController extends Controller {
use AuthenticatesUsers;
public function __construct() {
$this->middleware('guest')->except('logout');
}
public function doLogin(Request $request) {
$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'status' => '1',
);
if (Auth::guard('admin')->attempt($userdata)) {
return Redirect::intended('/administrator/dashboard')->with('successMessage', 'You have successfully logged in.');
}
}
}
And in UserAdmin (model) under app/Model is as follows:
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Config;
class UserAdmin extends Authenticatable {
protected $table = 'adminusers';
public $timestamps = false;
protected $fillable = ['firstName', 'lastName', 'email', 'company', 'website'];
public function __construct() {
parent::__construct(); // Don't forget this, you'll never know what's being done in the constructor of the parent class you extended
}
}
After submitting the login details, it shows me the error:
Type error: Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Model\UserAdmin given, called in /var/www/html/XXXXXX/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php on line 379
I suppose that you required to add implements \Illuminate\Contracts\Auth\Authenticatable to your UserAdmin model class definition.
class UserAdmin extends Model implements
\Illuminate\Contracts\Auth\Authenticatable
You must use Authenticatable in User model
for example:
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
//your code
}
You must declared use AuthenticableTrait for Authenticatable interface.
For example :
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Auth\Authenticatable as AuthenticableTrait;
use Illuminate\Database\Eloquent\Model;
class Company extends Model implements Authenticatable
{
use AuthenticableTrait;
Try and run 'composer dump-autoload' to check for "ambiguous User class resolution". It is likely you have two classes Defined as User Class.
use Illuminate\Foundation\Auth\AuthenticatesUsers;
Then in your model class, extends AuthenticatesUsers instead of Model.
You must extends Authenticatable class and implements JWTSubject in User model
For example :
class User extends Authenticatable implements JWTSubject {
Go to your Model and instead of extending Model, extend User
<?php
namespace App;
class Staff extends \Illuminate\Foundation\Auth\User
{
}

Cannot declare class App\User, because the name is already in use in my browser

when I run the program. there something error in my model user. the path App\Models\User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Presence;
use App\Models\Project;
use App\Productivity;
use App\Sick_leave;
use App\Annual_leave;
use App\Models\Team;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'level',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function presence()
{
return $this->hasOne(Presence::class, 'astrowatch', 'user_id', 'presence_id');
}
public function role()
{
return $this->belongsTo(Role::class, 'role_id');
}
public function permission()
{
return $this->hasMany(Permission::class);
}
public function teams()
{
return $this->belongsToMany(Team::class, 'user_teams');
}
}
the error is
"Cannot declare class App\User, because the name is already in use" in my browser.
I've tried use Illuminate\Database\Eloquent\User as EloquentUser but nothing change, still errors.
this error
change you namespace
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Presence;
use App\Models\Project;
use App\Productivity;
use App\Sick_leave;
use App\Annual_leave;
use App\Models\Team;
class User extends Model implements Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'level',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function presence()
{
return $this->hasOne(Presence::class, 'astrowatch', 'user_id','presence_id');
}
public function role()
{
return $this->belongsTo(Role::class, 'role_id');
}
}
this will fix you namespace problem
In the new version of Laravel (version 8+) The models are kept inside a new folder namely Models inside Http.
You are getting this error because your file is inside that folder but the namespace is not leading to that folder and cannot find the required file as it is inside the folder.
Simply changing
namespace App;
to
namespace App\Models;
will solve your problem.
Maybe you try to change your namespace into namespace App\Models; to your User model?
A bit late answer, but I had the same problem and solved it using composer dump autoload.
I had moved the models in the Models folder and the autoload file was not up to date.
Replace your code from below code in auth.php file
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
],

How to extend entity classes with custom functions (business logic) in cakephp v3

In cakephp 3 (3.3.5, that is) I want to extend my entity classes with custom functions (business logic). For example:
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Something extends Entity {
public function isFoo() {
return true;
}
}
The corresponding table object looks like this:
namespace App\Model\Table;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
use App\Model\Entity\Something; // produces an `unused import' warning
class SomethingsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
...
}
...
}
In the controller, I use this code to retrieve the entity from the database and call the custom function:
class SomeOtherController extends AppController {
...
$this->loadModel('Somethings');
$thing = $this->SomethingsTable->get($id);
if ($thing->isFoo()) { ... }
...
}
However, this fails with a fatal error:
Error: Call to undefined method Cake\ORM\Entity::isFoo()
Note, when I do a
<?= var_dump($thing,true); ?>
in the corresponding view, $thing is shown as of type Cake\ORM\Entity.
How can I change the table's get() function to return entities with the correct type "Something" ?
It should be:
$thing = $this->Somethings->get($id);
// not
$thing = $this->SomethingsTable->get($id);
Thats why the Something entity is not used, but the default Entity class.
CakePHP autotables, since it can not find the SomethingsTableTable the default table class is used. Therefore also the default entity class is loaded.
If your test method would contain a query to the db, there would have been an error thrown, saying that somethings_table does not exist.
The problem is probably here:
class SomeOtherController extends AppController {
$this->loadModel('Somethings');
$thing = $this->SomethingsTable->get($id); // <-- Here
if ($thing->isFoo()) { ... }
}
Controller::loadModel does not set $this->SomethingsTable (which was probably set somewhere else in your code... ), but $this->Somethings, so this should be:
$this->loadModel('Somethings');
$thing = $this->Somethings->get($id);
if ($thing->isFoo()) { }
This code works, you do not need use App\Model\Entity\Something in SomethingsTable.php.
When trying to debug such thing, use debug() instead of var_dump:
Configure::write('debug', true); // If you are not already in debug mode
$this->loadModel('Somethings');
debug($this->Somethings);
Output:
object(App\Model\Table\SomethingsTable) {
'registryAlias' => 'Somethings',
'table' => 'somethings',
'alias' => 'Somethings',
'entityClass' => 'App\Model\Entity\Something', // Good!
'associations' => [],
'behaviors' => [],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
This is an old post but I faced this issue today and the solution for me was slightly different. I was loading the model the right way, but my class name was not following naming conventions.
My Table: JobProfitsTable.php
My Entity: JobProfits.php (plural)
CakePhp is automatically looking for class named JobProfit.php (singular), and seems to fallback on Cake\ORM\Entity
So I had 2 options:
Rename my entity into JobProfit.php
Update my Table class with $this->setEntityClass('JobProfits')

Respond as XML not working since cakePHP 3.1

I need to render an XML+XSL template in my application, and it used to work with cakePHP 3.0. I have made the switch to 3.1 recently and it has stopped working. The problem is that I was having a formatted view of my XML, while now I just get a plain string.
The migration guide says something about some changes in the RequestHandlerComponent, but nothing helpful (or maybe it's just me and I don't get the point :)).
This is my controller (it is exactly as it was with Cake3.0):
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Utility\Xml;
use Cake\Event\Event;
use Cake\Routing\Router;
use Cake\ORM\TableRegistry;
use Cake\Filesystem\Folder;
use Cake\Filesystem\File;
use Cake\Network\Email\Email;
use Cake\Core\Configure;
use Cake\I18n\Time;
/**
* Invoices Controller
*
* #property App\Model\Table\InvoicesTable $Invoices
*/
class InvoicesController extends AppController
{
public $components = [
'Browser',
'Reorder11'
];
public $helpers = [
'Multiple'
];
public $paginate = [];
public function initialize()
{
parent::initialize();
$this->loadComponent('Paginator');
$this->loadComponent('RequestHandler');
}
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['demo']);
}
/*
* ... several other functions ...
*/
public function viewxml($id = null)
{
$this->viewBuilder()->layout('xml');
$invoice = $this->Invoices->myInvoice($id, $this->Auth->user('id'));
$this->RequestHandler->respondAs('xml');
$this->set('invoice', $invoice);
}
}
The xml.ctp layout, which is really simple
echo $this->fetch('content');
and the viewxml.ctp template just echoes the xml as a string.
How can I obtain the formatted XML+XSL again?
Try add: $this->response->header(['Content-type' => 'application/xml']);
I had the same error but my output was pdf
working 3.0.14 using this code:
$this->RequestHandler->respondAs("pdf");
$this->layout = 'pdf/default';
$this->view = 'pdf/report1_pdf';
for 3.1.x (this works if u save the file and open later, if you try to open it directly on browser its print the plain file content as a txt/html):
$this->viewBuilder()->layout('pdf/default');
$this->viewBuilder()->template('pdf/report1_pdf');
$this->RequestHandler->respondAs('pdf');
$this->response->header(['Content-type' => 'application/pdf']);

CakePHP 3 Custom helper not working

Hello i am trying to implement a helper extends the Html helper.
I created based on the documentation the below empty custom helper
<?php
namespace App\View\Helper;
use Cake\View\Helper;
use Cake\View\Helper\HtmlHelper;
use Cake\View\View;
/**
* MyHtml helper
*/
class MyHtmlHelper extends HtmlHelper
{
public function __construct(View $view, $config = []) {
parent::__construct($view, $config);
}
/**
* Default configuration.
*
* #var array
*/
protected $_defaultConfig = [];
}
I load both of them on AppController but when i use them on the view I receive the expected result from Html helper but not from custom helper why ? (the second helper doesn't return an error but just an empty result)
<?php echo $this->Html->tag('div','oti na einai2'); ?>
<?php echo $this->MyHtml->tag('div','oti na einai'); ?>
You broke it by overriding the parents default settings.
protected $_defaultConfig = [];
See the API documentation.
Merge whatever you need in the constructor for example instead of overriding the whole property with an empty array.

Resources