Unable to save select box options in Laravel 5.1 - php

I am working on my first project using Laravel 5.1. Uses a selectbox in a form.
{!!Form::select('animal_parent[]', array('1' => 'opt1', '2' => 'opt2', '3' => 'opt3', '4' => 'opt4',), null, ['id' => 'animal_parent', 'disabled' => 'disabled', 'multiple' => 'multiple', 'class' => 'form-control'])!!}
Selection limited to two options which need to saved in two columns, male_parent and female_ parent of the animal table.
There are no male_parent and female_ parent element names in the form. Similarly no animal_parent field in animal table.
Values are set as expected in the code given below. However, the insert command does not reflect the newly set values and throws an error.
"ErrorException in helpers.php line 671: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array."
Any help would be much appreciated.
First attempt using mutators
public function setMaleParentAttribute()
{
$parent = Input::get('animal_parent');
$this->attributes['male_parent'] = intval($parent[0]);
}
public function setFemaleParentAttribute(AddAnimalRequest $request)
{
$parent = Input::get('animal_parent);
if (isset($parent[1])) {
$this->attributes['female_parent'] = intval($parent[1]);
} else {
$this->attributes['female_parent'] = intval($parent[0]);
}
unset($request->animal_parent);
}
Second attempt using the store() method in the controller.
$animal = new Animal($request->all());
$parent = Input::get('animal_parent');
$animal['male_parent'] = intval($parent[0]);
if (isset($parent[1])) {
$animal['female_parent'] = intval($parent[1]);
} else {
$animal['female_parent'] = intval($parent[0]);
}
unset($request->animal_parent);
Auth::user()->animals()->save($animal);
return redirect('animals');

The problem was then solved with a change in UI. I feel the problem could have been solved using the below method. Hope that helps someone.
$input = $request->all();
$parent = $input['animal_parent'];
$input['male_parent'] = intval($parent[0]);
if (isset($parent[1])) {
$input['female_parent'] = intval($parent[1]);
} else {
$input['female_parent'] = intval($parent[0]);
}
unset($input['animal_parent']);
$animal = new Animal($input);
$animal->save();`

Related

In CakePhp, how can I retrieve the value of only one column from my database?

I am new to CakePHP but I have been using PHP for a while. I am trying to create a helper that would provide the level of access of a user (ACL).
Here is my ACLHelper.php so far
<?php
namespace App\View\Helper;
use Cake\View\Helper;
use Cake\ORM\TableRegistry;
class ACLHelper extends Helper{
public function getACL($id, $acl_field, $level){
$members = TableRegistry::get('groups_member');
$group = $members->find()->where(['user_id' => $id]);
$acls = TableRegistry::get('acls');
$acl = $acls->find('all', [ 'fields' => $acl_field ])->where(['group_id' => $group->first()->group_id]);
return $acl->first();
}
}
I call this function in my view this way
<?= $this->ACL->getACL($user->id, 'is_items', '4') ?>
And this is the output
{ "is_items": "4" }
What I need is the function to return true or false if the value of the field equals or is higher then the value of $level provided to the function. Now if I do this :
<?= $this->ACL->getACL($user->id, 'is_items', '4')->is_item ?>
it will return just the value. My problem is that I do not want to specify the field twice.
Thanks in advance for any help
public function getACL($id, $acl_field, $level){
$members = TableRegistry::get('groups_member');
$group = $members->find()->where(['user_id' => $id]);
$acls = TableRegistry::get('acls');
// Get the first ACL record right here
$acl = $acls->find('all', [ 'fields' => $acl_field ])->where(['group_id' => $group->first()->group_id])->first();
// Compare the requested field against the provided level
return $acl->$acl_field >= $level;
}

Updating table fields on submit button

I am very much new to laravel framework.
I have one form , which i need to update on submit button click.
when submit button clicks control goes to controller.php 's update() function .
But I am unable to edit any field's value.
here is my code.
public function update($id)
{
//echo "<pre>";print_r(Input::all());exit;
$product = $this->product->find($id);
$input = Input::only('designer', 'sku', 'name', 'display_name', 'description', 'price', 'main_category', 'sub_category', 'lead_time', 'sizing', 'woven', 'body_fabric', 'lining_fabric', 'fit', 'primary_color', 'secondary_color', 'care_label', 'neck_type', 'closure', 'trims', 'special_finishings', 'image1', 'image2', 'image3', 'image4', 'image5','top', 'combo_products', 'keywords', 'visibility', 'featured');
//echo "<pre>";print_r($input);exit;
try
{
$this->adminNewProductForm->validate($input);
} catch(\Laracasts\Validation\FormValidationException $e)
{
return Redirect::back()->withInput()->withErrors($e->getErrors());
}
$slug = Str::slug(Input::get('name'));
$slug = $this->product->getSlug($slug);
$input = array_add($input, 'slug', $slug);
DB::transaction(function() use($product, $input)
{
$product->fill($input)->save();
$stock_count = 0;
if(!empty(Input::get('xsmall_size')))
{
$rows = DB::table('products_variants')->where('product_id', $product->id)->where('variant_name', 'XS')->get();
$stock_count += Input::get('xsmall_stock');
if(!empty($rows))
{
DB::table('products_variants')->where('product_id', $product->id)->where('variant_name', 'XS')->update(array('variant_specs' => Input::get('xsmall_size'), 'price_change' => Input::get('xsmall_price'), 'total_stock' => Input::get('xsmall_stock'), 'stock_used' => 0));
} else {
DB::table('products_variants')->insert(array('product_id' => $product->id, 'variant_name' => 'XS', 'variant_specs' => Input::get('xsmall_size'), 'price_change' => Input::get('xsmall_price'), 'total_stock' => Input::get('xsmall_stock'), 'stock_used' => 0));
}
}
$input = array();
$input['flagship_status'] = Input::get('flagship_status');
if(Input::get('flagship_status'))
{
$input['stock_count'] = Input::get('small_stock');
}else {
$input['stock_count'] = $stock_count;
}
$product->fill($input)->save();
});
//echo "<pre>";print_r(Input::all());exit;
return Redirect::back()->withFlashMessage('Product Updated Successfully!');
}
Also I cant understand , what is going on by this line ? because i did not find validate function anywhere in my code.
$this->adminNewProductForm->validate($input);
I need to update table products not products_variants.
validate is inherited from the FormRequst class.
https://laravel.com/api/5.0/Illuminate/Foundation/Http/FormRequest.html#method_validate
You've provided too much code and too little information. You said you need to update a specific table, but yet there are two lines where you are very intentionally manually updating a database entry.
This is one of them:
DB::table('products_variants')->where('product_id', $product->id)->where('variant_name', 'XS')->update(array('variant_specs' => Input::get('xsmall_size'), 'price_change' => Input::get('xsmall_price'), 'total_stock' => Input::get('xsmall_stock'), 'stock_used' => 0));
When you call this:
$product->fill($input)->save();
It also saves 'dirty' (modified) models that also belong to it, which can include products_variants relationships. From the sound of it, you are incorrectly applying changes directly through SQL, and then the model's save method is overwriting it.
You seem unclear about what your code is actually doing, and I would strongly suggest simplifying it down and adding in code as you begin to understand what each line does. I think your question is the byproduct of copying an example and adding your own work without understanding how Laravel handles relationships and models. There is almost never a good reason to use raw SQL or DB statements.

Laravel: Updating hasMany/BelongTo relation

I have a master table jobs with multiple location in separate table job_location. Now I am not able to update/delete, if extra rows found from job_location. Now why I am saying DELETE is because sync() did this, but it's related to many-to-many relation. I am new to laravel, just trying to get eloquent approach to achieve this, otherwise deleting all rows and inserting can be done easily OR updating each and delete remaining is also an option but I wonder Laravel has something for this.
In every request I get multiple job locations(with unchanged/changed city,phone_number,address) which is creating trouble.
Some codeshots:
Model: [Job.php]
class Jobs extends Model
{
protected $fillable = [
'job_id_pk', 'job_name','salary'
];
public function joblocation() {
return $this->hasMany('\App\JobLocation', 'job_id_fk', 'job_id_pk');
}
}
Model:[JobLocation.php]
class JobLocation extends Model
{
protected $fillable = [
'jobl_id_pk', 'job_id_fk','city', 'address', 'phone_number'
];
public function job() {
return $this->belongsTo('\App\Jobs', 'job_id_fk', 'job_id_pk');
}
}
Controller:[JobController.php]
function jobDetail() {
if($params['jid']) {
// update
$obj = \App\Jobs::find($params['jid']);
$obj->job_name = $params['name'];
$obj->salary = $params['salary'];
$obj->save();
} else {
// create new
$data = array(
'job_name' => $params['name'],
'salary' => $params['salary'],
);
$obj = \App\Jobs::create($data);
}
// don't bother how this $objDetail has associative array data, it is processed so
foreach ($params['jobLocations'] AS $key => $objDetail) {
$jobLoc = new \App\JobLocation;
$jobLoc->city = $objDetail['city'];
$jobLoc->phone_number = $objDetail['phone_number'];
$jobLoc->address = $objDetail['address'];
$jobLoc->job()->associate($obj);
$obj->jobLoc()->save($jobLoc);
}
}
In this approach I am able to save all job locations, but I am using same function to update also. Please tell how I can update jobLocations if present. I am ok to loose previous entries, but it would be good if previous gets updated and new get entered OR if we have extra entries they get deleted. I know sounds weird but still guide me a way.
Yea, you cannot use the same function, do this
$jobs = \App\Jobs::find($params['jid']);
foreach ($params['jobLocations'] as $key => $objDetail) {
$joblocation = $jobs->joblocation->where('jobl_id_pk', $objDetail['some_id'])->first();
//here update you job location
$joblocation->save();
}
Something like this:
Controller:[JobController]
public function jobDetail() {
if( !empty($params['jid']) ) {
// update
$job = \App\Jobs::find($params['jid']);
$job->job_name = $params['name'];
$job->salary = $params['salary'];
$job->save();
} else {
// create new
$data = array(
'job_name' => $params['name'],
'salary' => $params['salary'],
);
$job = \App\Jobs::create($data);
}
$locationDetails = !empty($params['jobLocations']) ? $params['jobLocations'] : [];
$jobLocations = array_map(function($location) use($job) {
$location = array_merge($location, [ 'job_id_fk' => $job->job_id_pk ]);
return \App\JobLocation::firstOrNew($location);
}, $locationDetails);
$job->jobLocations()->saveMany($jobLocations);
}

Yii 1.1 create relationships automatically

Pago, model exists in Yii. As I create relationships automatically?..
Example:
$pago = new Pago();
Now I want to show information:
echo $pago->iDTIPOTRAMITE->id;
It is assumed that the information must be loaded by default
thanks.
I think I found the solution here: model init()
With this method, set initial property values.
Example. Pago model.
public function init()
{
$documentos = DocumentacionT::model()->findAll(array(
'condition' => 'ID_TIPOSOLICITUD = :idTipo',
'params' => array(':idTipo' => 5)
));
$pagoDocumento = [];
foreach($documentos as $documento)
{
$pagoDocumento[] = new PagoDocumento();
}
$this->pagoDocumentos = $pagoDocumento;
}

Custom Widget doesn't display the same amount of choices

I try to create a customWidget with a special tablemethod to only display the pre selected choices of the user, this is the form :
$this->widgetSchema['Books_list'] = new MyWidgetFormThematicSelector(array(
'multiple' => true,
'model' => 'Books',
'table_method' => array('method' => 'getOnlySelected', 'parameters' => array($this->getObject()->getId())),
'expanded' => true,
));
this is the method getOnlySelected:
$q = Doctrine::getTable('BooksAuthors')
->createQuery('ba')
->select('ba.position,ba.name')
->leftJoin('ba.Books b')
->where('ba.BooksAuthors_id = ?', $id);
echo count($q); //return 4
return $q;
this method return 4 elements which is normal then if i try to echo the values of the getChoices method from the widget I get only 1 in return !?
class MyWidgetFormThematicSelector extends sfWidgetFormDoctrineChoiceWithParams {
public function configure($options = array(), $attributes = array())
{
parent::configure($options, $attributes);
}
public function getChoices() {
$choices = parent::getChoices();
echo count($choices); // return 1
return $choices;
}
public function render($name, $value = null, $attributes = array(), $errors = array()) {
return parent::render($name, $value, $attributes, $errors);
}
}
What's going on here ?
I create a similar widget in the same form where the probleme does not occurs, and it s quite the same code...
thx
I solve this problem by setting the attribute 'key_method' => 'myUniqueId', in the form where the widget is called...
Cause Ive got two primary keys in my table and the sfWidgetFormDoctrineChoiceWithParams widget use the one which was identic for all the results as the key for the array choices, so the size of the array was always one...By setting the other primary key as the main key of the getChoices method I get the correct result.

Categories