Convert array to list of params for Eloquent - php

I'm trying to use the Eloqunt avg function. When I pass in my columns as a list of params, it works;
$this->avg('column_two','column_one');
But when I pass in an $array it doesn't;
$this->avg($array);
Here is a dd (like a var_dump of that array so you know what I'm talking about;
array:6 [▼
0 => "column_0"
1 => "column_1"
2 => "column_2"
3 => "column_3"
4 => "column_4"
5 => "column_5"
]
I get a really bizarre error;
ErrorException in Grammar.php line 58:
strtolower() expects parameter 1 to be string, array given
This might seem like a basic array problem, but how can I convert that array to a list of params?
The best I can do is implode;
$array = implode(',', $array);
But that will just return an SQL error;
ERROR: column "example_0,example_1" does not exist

Try with -
function quote($el){
return '"'.$el.'"';
}
$quotedArr[] = array_map('quote', $array);
$paramStr = implode(',', $quotedArr);
$this->avg($paramStr);

You're looking for the PHP call_user_func_array() function.
You would use it like this:
$result = call_user_func_array([$this, 'avg'], $array);
The first parameter is a callable. The second parameter is the array of parameters to send to the callable.
Having said that, I'm not sure if your code is working the way you expect. Taking a look at the code, it seems like the avg() method only accepts one column in the first place. Are you sure you're getting what you want?

Related

Laravel make array and use strtolower

I have data like this:
array:1 [
0 => "No Brand,ddfg"
]
First of all this data is wrong, what I want is to have something like this:
array:2 [
0 => "No Brand"
1 => "ddfg"
]
So now its really an array :)
Then I need my array data transform to lower case like:
array:2 [
0 => "no brand"
1 => "ddfg"
]
Code
$sibarBrandsArray = SidebarManager::first()->pluck('brands')->toArray();
This return data like:
array:1 [
0 => "No Brand,ddfg"
]
And this is how my data looks like in database:
Any idea?
Solved
// get my table row
$sibarBrandsArray = SidebarManager::first();
// get my row column
$getBrandColumn = $sibarBrandsArray->brands;
// separate data in that column with comma
$separateBrands = explode(',', $getBrandColumn);
// lowercase each separated data
$brandsArray = array_map('strtolower', $separateBrands);
// dump the result
dd($brandsArray);
Result
array:2 [
0 => "no brand"
1 => "ddfg"
]
Laravel has a very efficient and easy way to work with arrays. It's called a collection. Click here to learn more. Don't convert your response to the array, use collection directly.
$sibarBrandsCollection = SidebarManager::first()->pluck('brands');
Laravel eloquent by default gives you collection instance when you get a response. so pluck in above call is nothing but calling pluck on collection instance. We can chain method to the collection and do manipulation as needed.
$sibarBrandsCollection = $sibarBrandsCollection->map(function ($name) {
return strtolower($name);
});
Above code will automatically convert all of your values to lowercase. Similarly, you can explode the value to get your intended result. At last, if you have to send data as array to the browser just add toArray() method at the end of your collection.
I would not use core PHP array function unless needed, Laravel collection is great way to work with arrays.
$yourArray = array_map('strtolower', $yourArray);
$yourArray = array_map('nestedLowercase', $yourArray);
function nestedLowercase($value) {
if (is_array($value)) {
return array_map('nestedLowercase', $value);
}
return strtolower($value);
}
or you can use:
$query->whereRaw('LOWER(`newsTitle`) LIKE ? ',[trim(strtolower($newsTitle)).'%']);

Modx xPDO getMany not returning expected results

I'm not sure what is going on here, but I'm trying to retrieve some budgets from a modx/xpdo object and getting unexpected results. From the code below, both foreach loops return the same results [that of the first getMany call. 2 items] if I switch the order of the getmany calls I get only one result for both foreach loops.
$tipa = $this->modx->getObject('Tipa', array('id' => $id, 'token' => $token));
// should retrieve two objects
$tipa_sub_budgets = $tipa->getMany('TipaBudget', array('budget_type_id:!=' => '999'));
foreach($tipa_sub_budgets as $sb){
echo $sb->get('id');
}
// should retrieve one object
$tipa_primary_budgets = $tipa->getMany('TipaBudget', array('budget_type_id' => '999'));
foreach($tipa_primary_budgets as $tb){
echo $tb->get('id');
}
I'm not sure what is happening here. What is the correct way to grab 2 sets of objects from the $tipa object?
I think whereas xPDO::getObject() can be passed the criteria either as an array or an instance of xPDOCriteria, xPDOObject::getMany() expects only an instance of xPDOCriteria meaning the array will not work.
Try passing an instance of xPDOCriteria like so...
$criteria = $this->modx->newQuery("TipdaBudget"); // classname, not the alias
$criteria->where(array("budget_type_id:!=" => 999));
$tipa_sub_budgets = $tipa->getMany("TipaBudget", $criteria);

executePrepared throws Phalcon\Db\Exception with message Invalid bind type parameter

I'm trying to use \Phalcon\Db\Adapter\Pdo\Mysql->executePrepared() with Phalcon (1.2.5 - 1020540)
exectePrepared expects three arguments:
public PDOStatement executePrepared (
PDOStatement $statement,
array $placeholders,
array $dataTypes)
But I can't found in the documentation how to fill $dataTypes.
I try with:
$dataType[] = \PDO::PARAM_INT;
and with:
$dataType[] = \Phalcon\Db\Column::TYPE_INTEGER;
but with the same 'Invalid bind type parameter' message
the same happens on 1.2.4, I upgrade trying to fix it.
Any suggestion are welcomed.
Usually phalcon expects db parameters in the following syntax:
array("columnName => ':value:'", 'bind' => array('value' => 'foo'));
Did you try
array('column_name' => \Phalcon\Db\Column::TYPE_INTEGER);
Think this should work as phalcon works internally a lot with keys (e.g. https://github.com/phalcon/cphalcon/blob/master/ext/db/adapter/pdo.c search for dataType)
you can also request the PDO-Adapter (eg Phalcon\Db\Adapter\Pdo\Mysql) for a given table with describeColumns($table) and get back Phalcon\Db\Column's, then you can ask for getBindType()
$fields = $this->db->describeColumns($table);
foreach ($fields as &$field) {
$objectFields[$field->getName()] = $field->getBindType();
}

How to change data of reference passed Array in Closure

I have an Eventbus that takes a filter name as its first parameter and a Closure as second parameter. Like this:
$this->EventBus->subscribe('FilterTestEvent', function(){/*Do Something*/});
It's called like this:
$filteredValue = $this->EventBus->filter('FilterTestEvent', $anyValue);
What I want now is to pass an array as reference to the Closure that then is changed in any way (here: add elements) and then return something as the filtered value:
$item_to_change = array('e1' => 'v1', 'e2' => 'v2');
$this->EventBus->subscribe('FilterTestEvent', function(&$item){
$item['new'] = 'LoremIpsum';
return true;
});
$filtered = $this->EventBus->filter('FilterTestEvent', $item_to_change);
Now I would a print_r($item_to_change) expect to look like the following:
Array
(
[e1] => v1
[e2] => v2
[new] => LoremIpsum
)
But instead it looks like the original array:
Array
(
[e1] => v1
[e2] => v2
)
The eventbus internally stores all closures and calls them if needed through call_user_func_array() with the closure as first argument and the value as the only argument array element.
How can I achieve what it's meant to do?
Source Code to the Eventbus: http://goo.gl/LAAO7B
Probably this line:
$filtered = $this->EventBus->filter('FilterTestEvent', $item_to_change);
is supposed to return a new filtered array, not modify the original one.
So check it:
print_r($filtered);
Passing by reference is possible by modifying a function (adding &):
function filter(&$array){ //Note & mark
$array['new_index'] = "Something new" ;
}
$array = array("a"=> "a");
filter($array); //The function now receives the array by reference, not by value.
var_dump($array); //The array should be modified.
Edit:
Make your callback return the filtered array:
$this->EventBus->subscribe('FilterTestEvent', function(&$item){
$item['new'] = 'LoremIpsum';
return $item ;
});
Passing by reference should not work here, because in the source code that $value variable is swapped with another value and returned after.
Ok. I found the answer. The filter function needs to be changed so that it accepts arrays as value, in which I can save the reference. For details see difference Revision 1 and Revision 2 of the Eventbus source code, here: goo.gl/GBocgl

mongodb limit the fields to return PHP

I have a PHP script that gathers data from MongoDB and prints it. Some options are gathered from $_POST supergoblal. Everything works fine but I can't limit the fields to return using an array.
$results = $db->$table->find($param); //This line works and returns all fields
$results = $db->$table->find($param, array('Descripción','Ocurrencias relacionadas'));//This line works and limit the returned fields to the ones specified.
The following code constructs an array to use as a field limiter parameter:
$fields=implode(',', $_POST[field]);
$fd = array($fields);
print_r($fd) shows:
Array ( [0] => 'Descripción','Ocurrencias relacionadas' )
$results = $db->$table->find($param,$fd);` //This line works and returns all documents but only _id field.
Any ideas? It's driving me mad!
Thanks in advance.
You are running your query in the wrong way. First of all, you don't show what $param is, but let's assume it is a query like:
$param = array( 'field1' => 'foo' );
Then as second argument you pass in an array with two values, but that is not what this method wants. The second argument is an array of fields to return, in the following format:
array( 'Descripción' => 1, 'Ocurrencias relacionadas' => 1 );
You pass in the following:
array( 0 => 'Descripción', 1 => 'Ocurrencias relacionadas');
Which means to only show the fields with the names 0 and 1 (which likely don't exist). The _id field is always return so that's why it shows up.
What you need to do, is to pass in the field names as keys in the second argument to find():
$fields=implode(',', $_POST[field]);
$fd = array($fields);
$fd = array_flip($fd); // << important to make the values keys and they keys values: php.net/array_flip
$results = $db->$table->find($param, $fd);

Categories