Show name of the project in the table list of event - laravel-backpack

I want to show the "Project" Name. Under the project, I have created an event, and on the listing page, I want to show the name of the project not the id of the project.
Both tables share the relationship between them.
I am using a laravel-backpack.
1)The below is the event model.
public function eventProject()
{
return $this->belongsTo('App\Models\Project','project_id','id');
}
2) And the project model like this.
public function projectEvent()
{
return $this->hasMany('App\Models\Event', 'project_id', 'id');
}
how can I show in the grid list like this, 'Project name', 'Event name', etc?

I hope this will help.
You put a setColumnDetails into the setupListOperation in your crud controller.
$this->crud->setColumnDetails( 'project_id', [
'label' => "Project", // Table column heading
'type' => 'text',
'name' => 'project.project_name', // the column that contains the ID of that connected entity;
// 'entity' => 'project', // the method that defines the relationship in your Model
'attribute' => "project.name", // foreign key attribute that is shown to user
'model' => "App\Models\Project", // foreign key model,
'orderable' => true,
'orderLogic' => function ( $query, $column, $column_direction ) {
return $query->join( 'projects', 'projects.id', '=', 'events.project_id' )
->orderBy( 'project.id', 'desc' );
},
'searchLogic' => function ( $query, $column, $searchTerm ) {
$query->orWhereHas( 'project', function ( $q ) use ( $column, $searchTerm ) {
$q->where( 'projects.name', 'like', '%' . $searchTerm . '%' );
} );
}
] );
This basically just changes it from the id to the name field, assuming the project name is stored in the "name" field.

Related

Laravel Backpack attribute accessor causing bug on update command

I am working on Laravel Backpack. I have two fields like this:
$this->crud->addField([ // SELECT2
'label' => 'Type',
'type' => 'select_from_array',
'name' => 'type',
'options' => [
'' => 'select type',
'Movie' => 'Movies',
'Series' => 'Series'
],
]);
$this->crud->addField([ // select2_from_ajax: 1-n relationship
'label' => "Entity", // Table column heading
'type' => 'select2_from_ajax',
'name' => 'entity_id', // the column that contains the ID of that connected entity;
'entity' => 'entity', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'data_source' => url('api/entity'), // url to controller search function (with /{id} should return model)
'placeholder' => 'Select', // placeholder for the select
'include_all_form_fields' => true, //sends the other form fields along with the request so it can be filtered.
'minimum_input_length' => 0, // minimum characters to type before querying results
'dependencies' => ['type'], // when a dependency changes, this select2 is reset to null
// 'method' => 'GET', // optional - HTTP method to use for the AJAX call (GET, POST)
]);
The second field options are dependent on the first one.
In my model, I have:
public function getEntityIdAttribute()
{
$id = $this->attributes['entity_id'];
$type = $this->attributes['type'];
if ($type == "Movie") {
$attribute = Movie::find($id);
} else {
$attribute = Series::find($id);
}
return $attribute->name;
}
Create and List operations work perfectly. But on update, it throws this error:
Undefined array key "entity_id"
Why is this accessor not working on the update? or can we somehow skip the accessor on the update command?

Gravityview - Show payment status of another form

I currently have Gravityview view which is getting the source from form A. However, I want to show if the current user has made a payment on form B. Obviously this can be fetched from the {payment_status} merge tag of form B. But How can I pull the data of form B onto the Gravity view custom content field of form A?
I've looked at the gform_entry_id_pre_save_lead hook but I think there's a better way. Thanks for your help in advance..
add_filter( 'gform_entry_id_pre_save_lead', 'my_update_entry_on_form_submission', 10, 2 );
function my_update_entry_on_form_submission( $entry_id, $form ) {
$update_entry_id = rgpost( 'my_update_entry_id' );
return $update_entry_id ? $update_entry_id : $entry_id;
}
You can either use the Gravityview Multiple Forms Add-on or you can try adding the following code to your functions.php:
function gf_check_form($atts = array()) {
$details = shortcode_atts( array(
'form_id' => "",
'user' => ""
), $atts );
$form_id = $details['form_id'];
$search_criteria = array(
'status' => 'active',
'field_filters' => array(
'mode' => 'all',
array(
'key' => 'created_by',
'operator'=> 'is',
'value' => $details['user']
)
)
);
$entries = GFAPI::get_entries( $form_id, $search_criteria);
foreach($entries as $entry){
$paid .= 'Paid on '.date("F d, Y", strtotime($entry['date_created'])).'<br><br>';
}
return $paid;
}
add_shortcode( 'check_form', 'gf_check_form' );
You can then add the following shortcode to your Gravityview in a custom content field:
[check_form form_id="Add the form ID of form B here" user="{created_by:ID}"]

Handle Request: ChoicesType

So I have this ChoiceType Form that will sort the items:
$sort = $this->createForm(ChoiceType::class, NULL, array(
'choices' => array(
'...' => 'default',
'A-Z' => 'title_up',
'Z-A' => 'title_down',
'Price low to high' => 'price_up',
'Price high to low' => 'price_down',
),
));
I want to use the Choices so that when one of them is selected from the dropdown menu will do this: $products = "SELECT a FROM AppBundle:Product a ORDER BY a.title ASC".
I tried this:
$sort->handleRequest($request);
if($sort->isSubmitted() && $sort->isValid()) {
if (isset($default)) {
$products = "SELECT a FROM AppBundle:Product a ORDER BY a.title ASC";
return $this->render('AppBundle:main:index.html.twig', array('products' => $products, ));
}
}
But $default is not working, since is not defined. I dont know how to access the choices, so I can pass them to an if statement.
I think you need to write something like this:
$sort = $this->createFormBuilder()
->setAction($this->generateUrl('your_process_route_here'))
->setMethod('POST')
->add('select', ChoiceType::class, [
'placeholder' => 'Please select',
'choices' => [
'...' => 'default',
'A-Z' => 'title_up',
'Z-A' => 'title_down',
'Price low to high' => 'price_up',
'Price high to low' => 'price_down',
]
])
To get the value inside the <select> element:
$select = $request->request->get('select'); // this will contain whatever value you've selected from the dropdown
Check if the value is what you expect, and then create the query:
if ('default' == $select){ // or you can use a switch
// create a custom method inside your Repository class containing the SELECT, and call it here
}
That select from ->add('select', ...) will be the name attribute for your <select> html element.

Cakephp automatically filled form select for two word named belongTo model

What is right naming or what am I missing to get automagic run for two word named Model. Actual model belong to the two words named model.
Exact example:
Tour belongs to Accommodation type.
in database there is table tours and table accommodation_types
foreign key from tours is tours.accommodation_type_id
Snapshots of code below.
ToursController.php
public function add() {
//...
$accommodation_types = $this->Tour->AccommodationType->find('list');
//...
$this->set(compact('accommodation_types', ...));
}
Tour.php
//...
public $belongsTo = array(
//...
'AccommodationType' => array(
'className' => 'AccommodationType',
'foreignKey' => 'accommodation_type_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
//...
);
Tours/add.ctp (inside a form)
echo $this->Form->input('accommodation_type_id', array('label' => 'Accommodation type'));
As per convention the view vars names should be camelBacked. So rename the view var from $accommodation_types to $accommodationTypes. If you don't follow convention you have to explicitly specify the options var to use like this:
echo $this->Form->input('accommodation_type_id', array('options' => $accommodation_types, 'label' => 'Accommodation type'));

Zend_Validate_Db_RecordExists against 2 fields

I usualy use Zend_Validate_Db_RecordExists to update or insert a record. This works fine with one field to check against. How to do it if you have two fields to check?
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => $this->_name,
'field' => 'id_sector,day_of_week'
)
);
if ($validator->isValid($fields_values['id_sector'],$fields_values['day_of_week'])){
//true
}
I tried it with an array and comma separated list, nothing works... Any help is welcome.
Regards
Andrea
To do this you would have to extend the Zend_Validate_Db_RecordExists class.
It doesn't currently know how to check for the existence of more than one field.
You could just use two different validator instances to check the two fields separately. This is the only work around that I can see right now besides extending it.
If you choose to extend it then you'll have to find some way of passing in all the fields to the constructor ( array seems like a good choice ), and then you'll have to dig into the method that creates the sql query. In this method you'll have to loop over the array of fields that were passed in to the constructor.
You should look into using the exclude parameter. Something like this should do what you want:
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => $this->_name,
'field' => 'id_sector',
'exclude' => array(
'field' => 'day_of_week',
'value' => $fields_values['day_of_week']
)
);
The exclude field will effectively add to the automatically generated WHERE part to create something equivalent to this:
WHERE `id_sector` = $fields_values['id_sector'] AND `day_of_week` = $fields_values['day_of_week']
Its kind of a hack in that we're using it for the opposite of what it was intended, but its working for me similar to this (I'm using it with Db_NoRecordExists).
Source: Zend_Validate_Db_NoRecordExists example
Sorry for the late reply.
The best option that worked for me is this:
// create an instance of the Zend_Validate_Db_RecordExists class
// pass in the database table name and the first field (as usual)...
$validator = new Zend_Validate_Db_RecordExists(array(
'table' => 'tablename',
'field' => 'first_field'
));
// reset the where clause used by Zend_Validate_Db_RecordExists
$validator->getSelect()->reset('where');
// set again the first field and the second field.
// :value is a named parameter that will be substituted
// by the value passed to the isValid method
$validator->getSelect()->where('first_field = ?', $first_field);
$validator->getSelect()->where('second_field = :value', $second_field);
// add your new record exist based on 2 fields validator to your element.
$element = new Zend_Form_Element_Text('element');
$element->addValidator($validator);
// add the validated element to the form.
$form->addElement($element);
I hope that will help someone :)
Although, I would strongly recommend a neater solution which would be to extend the Zend_Validate_Db_RecordExists class with the above code.
Enjoy!!
Rosario
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
'validators' => array('EmailAddress', $obj= new Zend_Validate_Db_NoRecordExists(array('adapter'=>$dbAdapter,
'field'=>'email',
'table'=>'user',
'exclude'=>array('field'=>'email','value'=>$this->_options['email'], 'field'=>'is_deleted', 'value'=>'1')
))),
For those using Zend 2, If you want to check if user with given id and email exists in table users, It is possible this way.
First, you create the select object that will be use as parameter for the Zend\Validator\Db\RecordExists object
$select = new Zend\Db\Sql\Select();
$select->from('users')
->where->equalTo('id', $user_id)
->where->equalTo('email', $email);
Now, create RecordExists object and check the existence this way
$validator = new Zend\Validator\Db\RecordExists($select);
$validator->setAdapter($dbAdapter);
if ($validator->isValid($username)) {
echo 'This user is valid';
} else {
//get and display errors
$messages = $validator->getMessages();
foreach ($messages as $message) {
echo "$message\n";
}
}
This sample is from ZF2 official doc
You can use the 'exclude' in this parameter pass the second clause that you want to filter through.
$clause = 'table.field2 = value';
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => 'table',
'field' => 'field1',
'exclude' => $clause
)
);
if ($validator->isValid('value') {
true;
}
I am using zend framework v.3 and validation via InputFilter(), it uses same validation rules as zend framework 2.
In my case I need to check, if location exists in db (by 'id' field) and has needed company's id ('company_id' field).
I implemented it in next way:
$clause = new Operator('company_id', Operator::OP_EQ, $companyId);
$inputFilter->add([
'name' => 'location_id',
'required' => false,
'filters' => [
['name' => 'StringTrim'],
['name' => 'ToInt'],
],
'validators' => [
[
'name' => 'Int',
],
[
'name' => 'dbRecordExists',
'options' => [
'adapter' => $dbAdapterCore,
'table' => 'locations',
'field' => 'id',
'exclude' => $clause,
'messages' => [
'noRecordFound' => "Location does not exist.",
],
]
],
],
]);
In this case validation will pass, only if 'locations' table has item with columns id == $value and company_id == $companyId, like next:
select * from location where id = ? AND company_id = ?