Adding multiple object values to array with key names - php

In Laravel, I'm trying to create an array of some existing values I have that are built from values from a JSON object.
I have the 4 variables set and they dump properly but I'd like to add all 4 (username, perms, roles, access) to the array (IdentifierArray) with their own key/name so that when I add the array to the session and inspect it, I can see each value with it's key/name.
Code at this point:
$IdentifierArray = [];
$Username = $login->username;
$Perms = $login->permissions;
$Roles = $login->roles;
$Access = $login->access;
Session::put('Array of Values', $identifierArray);
So I'd like to add those object values to the array in the best way while having a key for each as well, like:
Array(
"username": $username value,
"perms":$perms value,
"Roles":$roles value,
"Access":$Access value
)

Another way of doing it, equal to #danboh:
$IdentifierArray = [
"username" => $login->username,
"permissions" => $login->permissions,
"roles" => $login->roles,
"access" => $login->access
];

Why not use a regular PHP array? Like:
$IdentifierArray["username"] = $login->username;
$IdentifierArray["permissions"] = $login->permissions;
$IdentifierArray["roles"] = $login->roles;
$IdentifierArray["access"] = $login->access;

You can use the array_only helper to make your life easy:
$identifierArray = array_only(
json_decode($login, true),
['username', 'permissions', 'roles', 'access']
);
Another option would be to use the only() Collection method:
collect(json_decode($login, true))
->only(['username', 'permissions', 'roles', 'access'])
->all();

Related

Adding values to array in a loop

Iam working on a laravel project which stores values to a DB entry in loop on meeting certain conditions.
This first creates an array if the entry is for the first time and adds a value to it. Henceforth, it recalls the array and keeps adding values to it.
if(is_null($lead->shown_to)) {
$a = array();
array_push($a, "lead 1");
$lead->shown_to = serialize($cart);
$lead->save();
} else {
$a=unserialize($lead->shown_to);
array_push($a, "lead 2");
$lead->shown_to = serialize($a);
$lead->save();
}
To be able to create an array and add distinct elements to it repeatedly.
Is there a way to first check if the element exists in it or not. If it does, just move ahead, else add it?
Thanks in advance.
There're a couple of methods you can use.
You can first look for the value on the DB if exists using a column from the database like:
$result = Model::where( 'column', 'value' );
if ( $result ) {
// update already exists
} else {
// create one
}
// Retrieve flight by name, or create it if it doesn't exist...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);
// Retrieve by name, or instantiate...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
Also it depends what you are looking for as firstOrCreate persists the value into the DB where firstOrNew just creates a new instance where you need to call save()
to check a value exists in an array you can use array_search(). this will return the value if exists. if not it returns false.
if(!array_search('lead 2', $a)) {
// array does't has 'lead 2' so,
array_push('lead 2', $a);
}
In Laravel I would take advantage of the Collections because they have a lot of helpful methods to work with.
I would do something like this:
OPTION 1
//Depending on the value of $lead->show, initialize the cart variable with the serialization of the attribute or and empty array and transform it to a collection.
$cart = collect($lead->shown_to ? unserialize($lead->shown_to) : []);
//Ask if the collection doesn't have the given value. If so, added it.
if (!$cart->contains($your_value)) {
$cart->push($your_value);
}
//Convert to array, serialize and store
$lead->shown_to = serialize($cart->toArray());
$lead->save();
OPTION 2
//Depending on the value of $lead->show, initialize the cart variable with the serialization of the attribute or and empty array and transform it to a collection.
$cart = collect($lead->shown_to ? unserialize($lead->shown_to) : []);
//Always push the value
$cart->push($your_value);
//Get the unique values, convert to an array, serialize and store
$lead->shown_to = serialize($cart->unique()->toArray());
$lead->save();
You can get more creative using the collections and they read better on Laravel
I think you can use updateOrCreate, if not exists it will create now, if exists, it will update it, so you can keep assigning value to shown_to property
$lead= App\Lead::updateOrCreate(
['name' => 'Lead 1'],
['shown_to' => serialize($a)]
);
if you wan to keep the existing shown_to better to use json data, so that you can do like
$lead= App\Lead::updateOrCreate(
['name' => 'Lead 1'],
['shown_to' => json_encode(array_push(json_decode($a), $newData))]
);

How to merge data in elasticsearch

i want to merge some data in Elasticsearch, but every time it is replacing my previous data and not merging it.
Suppose when i new is created it should add with the previous data, not replacing previous data. So Suppose there is a user exists in the "update_field" named "Christofer" so when i array_merge($usernames) where $usernames contains one or couple of usernames it is always replacing previous data.
I am working on PHP.
$usernames= array ("Johanna", "Maria");
$doc = array();
$doc['update_field'] = array_merge($usernames);
$u_params = array();
$u_params['id'] = 'my_id';
$u_params['index'] = 'my_index';
$u_params['type'] = 'my_type';
$u_params['body'] = array('doc' => $doc);
$client->update($u_params);
For being more clear, as a example let's say in the usernames field there are couple of username exists- like - "Christofer", "Henrik", "Eric".
So now i want to add more user like - "Johanna", "Maria", ...
Now every time i merge and update documents it is replacing the data, like ("Christofer", "Henrik", "Eric") is getting replace by ("Johanna", "Maria").
I want them to be added not replaced.
Do any body knows how can i merge the new data, or just the new data in other process. Thanks in advanced.
You need to use partial update. Try this instead, i.e. you need to send a doc hash in the body with the fields to marge (i.e. update_fields):
$params = [
'index' => 'my_index',
'type' => 'my_type',
'id' => 'my_id',
'body' => [
'doc' => [
'update_field' => array_merge($usernames)
]
]
];
$client->update($params);
UPDATE
That's right, core values and arrays are getting replaced.
You may want to try scripted partial update then
$usernames= array ("Johanna", "Maria");
$script = array();
$script['script'] = 'ctx._source.update_field += new_value';
$script['params'] = array('new_value' => array_merge($usernames));
$u_params = array();
$u_params['id'] = 'my_id';
$u_params['index'] = 'my_index';
$u_params['type'] = 'my_type';
$u_params['body'] = $script;
$client->update($u_params);
And make sure that scripting is enabled in your elasticsearch.yml config file:
script.disable_dynamic: false

Laravel: Add data to the Input::all()

I am grabbing the values from the parameters in the URL domain.com?para=value in the controller using
Input:all()
Is there a way to add more values to the Input:all() in the controller?
I have tried $_POST['para'] = "value and $_GET['para'] = "value" but no luck.
I've gone through the docs but cannot find anything.
Thanks
More Info
Here is what is returned
{
"param_1" => "value",
"param_2" => "value",
"param_3" => "value",
}
I would like to add another param into the Input:all()
{
"param_1" => "value",
"param_2" => "value",
"param_3" => "value",
"NEW_PARAM" => "NEW VALUE",
}
In laravel 5, you can use
Request::merge(['New Key' => 'New Value']);
or by using request() helper
request()->merge(['New Key' => 'New Value']);
You should never need to add anything to Input. You should assign Input like so...
$arr = Input::all();
And then add to $arr like so...
$arr['whatever'] = 'whatever';
If you need to get that value in another part of the stack, try to pass it through yourself.
Cheers.
Best way to add data into the input::all() in laravel.
Solution 1
add Request package at the top of the page.
use Request;
Then add following code into your controller.
Request::merge(['new_key' => 'new_value']);
Solution 2
You can assign all the Input::all(); to a variable and then you can add new data to the variable. Like below.
$all_input = Input::all();
$all_input['new_key'] = 'new_value';
Add an input value on the fly inside a request instance
public function store(Request $request){
$request->request->add(['new_key' => 'new_value']);
}
Remove data from an input value on the fly inside a request instance
public function store(Request $request){
$request->request->remove('key');
}

MongoDB search $in _id php

Usually when I search for one related ID I do it like this:
$thisSearch = $collection->find(array(
'relatedMongoID' => new MongoId($mongoIDfromSomewhereElse)
));
How would I do it if I wanted to do something like this:
$mongoIdArray = array($mongoIDfromSomewhereElseOne, $mongoIDfromSomewhereElseTwo, $mongoIDfromSomewhereElseThree);
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => new MongoId(mongoIdArray)
)));
I've tried it with and without the new MongoId(), i've even tried this with no luck.
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
how do I search '$in' "_id" when you need to have the new MongoID() ran on each _id?
Hmm your rtying to do it the SQL way:
foreach($mongoIdArray as $seprateIds){
$newMongoString .= new MongoId($seprateIds).', ';
}
$mongoIdArray = explode(',', $newMongoString).'0';
Instead try:
$_ids = array();
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
That should produce a list of ObjectIds that can be used to search that field - relatedMongoID.
This is what I am doing
Basically, as shown in the documentation ( https://docs.mongodb.org/v3.0/reference/operator/query/in/ ) the $in operator for MongoDB in fact takes an array so you need to replicate this structure in PHP since the PHP driver is a 1-1 with the documentation on most fronts (except in some areas where you need to use an additional object, for example: MongoRegex)
Now, all _ids in MongoDB are in fact ObjectIds (unless you changed your structure) so what you need to do to complete this query is make an array of ObjectIds. The ObjectId in PHP is MongoId ( http://php.net/manual/en/class.mongoid.php )
So you need to make an array of MongoIds.
First, I walk through the array (could be done with array_walk) changing the values of each array element to a MongoId with the old value encapsulated in that object:
foreach($mongoIdArray as $seprateIds){
$_ids[] = $serprateIds instanceof MongoId ? $seprateIds : new MongoId($seprateIds);
}
I use a ternary operator here to see if the value is already a MongoId encapsulated value, and if not encapsulate it.
Then I add this new array to the query object to form the $in query array as shown in the main MongoDB documentation:
$thisSearch = $collection->find(array(
'relatedMongoID' => array( '$in' => $_ids)
));
So now when the query is sent to the server it forms a structure similar to:
{relatedMongoId: {$in: [ObjectId(''), ObjectId('')]}}
Which will return results.
Well... I came across the same issue and the solution might not be relevant anymore since the API might have changed. I solved this one with:
$ids = [
new \MongoDB\BSON\ObjectId('5ae0cc7bf3dd2b8bad1f71e2'),
new \MongoDB\BSON\ObjectId('5ae0cc7cf3dd2b8bae5aaf33'),
];
$collection->find([
'_id' => ['$in' => $_ids],
]);

Yii gridview use outside variable in value

I have a function in my Teacher model which returns categories array.
getCaterogies() {
return array('1' => 'short tempered', '2' => 'funny', '3' => 'visionary', ...);
}
I am storing indexes in database and displaying values everywhere using the value of the array corresponding to that..
$categories = $teacher->categories;
$category = $categories[$teacher->category];
I am doing this because once somebody suggested to me not to store strings in a database which are statuses, instead store integer values, and either store the conversion in the database or define it in ht model. The problem with strings is that they are more prone to human errors in comparisons. Maybe because of case sensitiveness.
Now the problem I am facing is that while displaying values in gridview, I need to write the 2 lines in a value field, but it is an expression, and outside variables also it doesn't take.
How can I get this working for gridview?
You can use anonymous function as value which can take $row, $data params where $row holds the row number (zero-based) and $data contains the data model for the row.
That way you can have it defined inside only.
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'name'=>'..',
'value'=>function($data,$row){
$categories = $teacher->categories;
return $categories[$data->category];
},
),
),
));
And if you want to use it from outside, you can rely on PHP's use:
$categories = $teacher->categories;
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataProvider,
'columns'=>array(
array(
'name'=>'..',
'value'=>function($data,$row) use ($categories){
return $categories[$data->category];
},
),
),
));
I would personally recommend second one, because that way the calculation of the array will be only once and will be used in all cases.
You can write
$categories = $teacher->categories;
$category = $categories[$teacher->category];
in one line:
$category = $teacher->categories[$teacher->category];
Also, I suggest you to use another solution:
class ModelClass
{
const STATUS_SHORT_TEMPERED = 1;
const STATUS_FUNNY = 2;
const STATUS_VISIONARY = 3;
}
This allow you to use a more semantic
ModelClass::STATUS_FUNNY;
instead of less semantic
2;
Also, you can compose your array in this way:
getCaterogies() {
return array(
ModelClass::STATUS_FUNNY => 'status funny',
...
);
}
'urlCreator' => function ($action, $model, $key, $index) use($under_category) {

Categories