Set a value to null, when calling Zend_Db::update() and insert() - mysql

My question is the exact same as How to Set a Value to NULL when using Zend_Db
However, the solution given in that question is not working for me. My code looks like the following. I call updateOper on the Model class when update is clicked on the front end. Inside updateOper, I call another function trimData() where I first trim all whitespace and then I also check that if some of the fields are coming in empty or '' I want to set them to default values or NULL values. Therefore I am using new Zend_db_expr('null') and new Zend_db_expr('default') .
The code is as follows:
private function trimData(&$data ) {
//Trim whitespace characters from incoming data.
foreach($data as $key => $val)
{
$data[$key] = trim($val);
if($data['notes'] == '') {
error_log("set notes to null/default value");
$data['notes'] = new Zend_db_expr('DEFAULT');
}
}
}
public function updateOper($data, $id)
{
$result = 0;
$tData = $this->trimData($data);
error_log("going to add data as ".print_r($data, true));
$where = $this->getAdapter()->quoteInto('id = ?', $id);
$result = $this->update($data, $where);
return $result;
}
The error_log statement prints the $data array as follows:
[id] => 10
[name] => alpha
[notes] => DEFAULT
As a result, the notes column has value ='DEFAULT' instead of picking the default value given in the table definition.
I have been trying to figure out what is wrong, but have not been able to find a solution.
I would really appreciate your help.
Thanks so much!

Your $data['notes'] is being changed to the __toString() value of the Zend_Db_Expr instead of preserving the actual object.
Maybe the reference is clogging things up. Else you may need to move the expression declaration into the actual update query.

Related

Keep sort order of json columns in Laravel after inserting new Key Value pair

I have a key value pair that I am inserting into a model with the following:
public function addContactDetail(Request $request){
$data = $request->all();
$contact_id = $data['contact_id'];
$contact = Contact::find($contact_id);
$details = $contact->details;
$details[$data['label']] = $data['value'];
$contact->details = $details;
$contact->save();
return response()->json($contact);
}
After insert it sometimes puts it randomly in the middle of the object. How do I keep it at the end?
If you are using Laravel 5 or greater version,
Try casting your json column into array in eloquent using mutators. like this.
inside your Contact Model
protected $casts = [
'details' => 'array',
];
By doing so, I guess you will get what you want. Try it and let me know

Undefined offset: 1, getting this error in looping

I have the following code:
$datas = $request->all();
if (!empty($datas)){
for ($i=1; $i<count($datas); $i++){
$value = [
'questionnaire_id' => $datas[$i]->questionnaires_id,
'question_id' => $datas[$i]->id,
'answer' => $datas[$i]->key
];
return $value;
}
}
I am getting error:
Undefined offset: 1
With input form:
<input type="" name="{{$question->id}}" value="{{$key}}">
How can I receive this value in controller?
You're assuming that $datas is a numerical array starting at index 1 with no gaps. That may not be the best assumption.
Based on my knowledge of request()->all(), it's going to return an associative array of all your user input so you wouldn't be able to access an $i key on $datas. Just because it may have 1 element, doesn't mean that index on the array will be 1.
Perhaps you want to retrieve a specific user input, for example, if you had a checkbox named checkbox, you may want to use request()->input('checkbox') instead of request()->all(), but I'd still assume your array keys would start from 0 and not 1.
When all else fails, set a breakpoint and use a debugger to see the value of $datas. If you don't have a debugger (which I highly recommend) you can use dd($datas); to die and dump the value.
You could try initialize the variable i = 0. Also make a dd($datas) to see what you are evaluating.
$datas = $request->all();
if (!empty($datas)){
for ($i=0; $i<count($datas); $i++){
$value = [
'questionnaire_id' =$datas[$i]->questionnaires_id,
'question_id' =$datas[$i]->id,
'answer' =$datas[$i]->key
];
return $value;
}
}

Laravel 5.4 save NULL to database not working

The following code results in an empty value inside the database and when I get it out of the database its an empty String.
$customer->update(['company' => NULL]);
You should consider 3 things:
1) Make sure company column in nullable in your table. If it's not it won't be possible to put null in there.
2) Make sure you have in $fillable property of Customer model column company
3) Verify you don't have any mutator in your Customer model - so verify you don't have setCompanyAttribute method that might change value automatically to empty string if it's set to null
SOLUTION
If you want a field inside the database to be null and you do not use a mutator everything is fine.
Are you using a mutator, in my case the following snippet.
public function setCompanyAttribute($value)
{
$this->attributes['company'] = ucfirst($value);
}
Then you need to check if $value is null and then set it manually to null otherwise it will be an empty string.
To do that automatically on every model you can set the empty string back to null inside your EventServiceProvider.
Event::listen('eloquent.saving: *', function ($eventName, array $data) {
$attributes = [];
foreach ($data as $model) {
foreach( $model->getAttributes() as $key => $value ) {
$attributes[$key] = (is_string($value) && $value === '') ? null : $value;
}
$model->setRawAttributes($attributes);
}
return true;
});
It's important to first check all attributes from the model and set it to a temporary array. Now inside the setAttribute() method on the model instance the checks are done if a mutator exists. But thats exactly what you do not want, because it would set all fields with a definied mutator to an empty sting. Instead use setRawAttribute so the old attributes are overwritten with the ones from the temporary array.
This is safe to do because if the checked value isn't an empty string the already existing value is taken for that field. Otherwise if it's an empty string then null is set.
Hope it helps!

mySQL query for building dynamically populated model

I have some code below which demonstrates a hard-coded example of what I would like to accomplish dynamically.
At a high level, I wish to do something like select * from view_data_$app_state and then get all of the data from that views table into my mustache templates dynamically.
The code I currently must use to group multiple rows of data for a specific column along with the views data is:
<?php
error_reporting(E_ALL);
class Example {
function __construct(){
try {
$this->db = new PDO('mysql:host=localhost;dbname=Example', 'root','drowssap');
}
catch (PDOException $e) {
print($e->getMessage());
die();
}
}
function __destruct(){
$this->db = null;
}
function string_to_array($links_string){
return explode(",", $links_string);
}
function get_view_data(){
$q = $this->db->prepare('select *, GROUP_CONCAT(`links`) as "links" from `view_data_global` ');
$q->execute();
$result = $q->fetchAll(PDO::FETCH_ASSOC);
return $result;
}
}
$Example = new Example();
$result = $Example->get_view_data();
$result[0]["links"] = $Example->string_to_array($result[0]["links"]);
echo json_encode($result);
This gives me the perfect object while
GROUP_CONCAT seems to be doing the trick this way, however I MUST know the column name that will contain multiple rows before writing the query. I am trying to figure out an approach for this and wish to make a custom query + code example that will transform cols with multiple rows of null null and not empty data into an array like above - but return the data.. again like the code above.
Below is an output of the actual data:
[{"id":"1","title":"This is the title test","links":["main","about","store"]}];
How can I replicate this process dynamically on each view table?
Thank you so much SO!
You can use PDOStatement::fetch to retrieve your results, with fetch_style set to PDO::FETCH_ASSOC (some other values will also provide the same information). In this case, the result set will be array indexed by column name. You can access this information with foreach (array_expression as $key => $value)
See the documentation for additional information.

Zend Framework - join query

I build a function
public function getBannedByLogin($commentId)
{
$sql = $this->getDbAdapter()->select()
->from(array('comments' => 'comments'), array())
->join(array('users' => 'qengine_users'),
'comments.bannedBy = users.userId',
array())
->where('commentId = ?', $commentId)
;
$row = $this->fetchRow($sql);
return $row['login'];
}
And there are problems, that does'nt work! :D
Let's I explain you. Column 'bannedBy' from comments returns id of user, who give a ban. I need to join this with table users to load a login field. Where i have mistakes?
I assume the code works in the sense of not throwing an exception. If so, your code is OK, you just specifically tell Zend_Db not to select any columns.
public function getBannedByLogin($commentId)
{
$sql = $this->getDbAdapter()->select()
->from(array('comments' => 'comments'))
->join(array('users' => 'qengine_users'),
'comments.bannedBy = users.userId')
->where('commentId = ?', $commentId)
;
$row = $this->fetchRow($sql);
return $row['login'];
}
The last argument to from() and join() functions is an array of columns you wish to select. If you pass in an empty array, no columns are selected. No argument = select everything. You can, of course, specify only the columns you need too.