I'm trying something really simple and yet doesn't work. I have one controller where selecting from one database to show some info for user. Now I'm trying in this same controller to select from second table to show some other info but I get Undefined variable...
This is the part of controller which is problematic
public function orderView( $orderId, $userId ) {
$order = self::$user->orders()->where('order_id', $orderId)->first();
$keys = Keys::all();
if (!$order) {
App::abort(404);
}
$userID = $order['user_id'];
$orderID = $order['order_id'];
$public_key = $keys['public_key'];
$private_key = $keys['private_key'];
$options = array(
"public_key" => $public_key,
"private_key" => $private_key,
"orderID" => $orderID,
"userID" => $userID
);
What I have added here is
$keys = Keys::all();
$public_key = $keys['public_key'];
$private_key = $keys['private_key'];
....
"public_key" => $public_key,
"private_key" => $private_key,
The error is Undefined index: public_key
Keys::all() returns an Illuminate\Database\Eloquent\Collection.
In order to access a single item of the Collection, you either must iterate the collection and access them singularly, or take one item specifically with Collection's functions, such as first().
For example:
public function orderView($orderId, $userId)
{
$order = self::$user->orders()->where('order_id', $orderId)->first();
$keys = Keys::all();
if (! $order) {
App::abort(404);
}
$options = [];
foreach ($keys as $key)
{
$options[] = [
'public_key' => $key->public_key,
'private_key' => $key->private_key,
'userID' => $order->user_id,
'orderID' => $order->order_id
];
}
return $options;
}
You can find more information about Illuminate Collection methods here.
Related
In my Laravel project, I've got a job set up which runs and attempts to notify a user based on their threshold and chosen alert metrics. I'm using the php end() method to get the last item in an array and then attempting to get whatever metric the user has chosen.
However, upon dumping the data, this isn't returning the last array item, it's returning every item and I'm not sure why?
When I dump my data, I'm getting this format instead of the last item in the array:
[2021-04-13 13:30:45] production.DEBUG: array (
0 =>
(object) array(
'event_category' => 'My Category',
'event_action' => 'My Event',
'event_count' => '2190',
'period_from' => '2021-04-13 00:00:00',
'period_to' => '2021-04-13 13:30:02',
'created_at' => '2021-04-13 13:30:06',
),
1 =>
(object) array(
'event_category' => 'My Category',
'event_action' => 'My Event',
'event_count' => '5184',
'period_from' => '2021-04-12 00:00:00',
'period_to' => '2021-04-12 23:57:02',
'created_at' => '2021-04-12 23:57:07',
),
2 =>
(object) array(
'event_category' => 'My Category',
'event_action' => 'My Event',
'event_count' => '3820',
'period_from' => '2021-04-11 00:00:00',
'period_to' => '2021-04-11 23:57:02',
'created_at' => '2021-04-11 23:57:07',
),
)
I should just be seeing the last item, amongst all of my code, the following is of significant value here:
/**
* Notify if data meets threshold & alert rules
*
* #return void
*/
public function notifyAlertThreshold($alerts, $data)
{
$newestDataPart = end($data) ?? null;
// alerts for data source
foreach ($alerts as $key => $alert) {
Log::debug($newestDataPart);
$metric = !isset($newestDataPart->{$alert->metric}) ? $newestDataPart : $newestDataPart->{$alert->metric};
}
}
In context, here's some mode of the code, but the primary question here, is why is my end() method not returning the last item?
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$filters = json_decode($this->report->discovery_filters, true);
$this->reportStatus = 'complete';
$data = [];
foreach ($filters as $findableKey => $findable) {
/*
** If there are datasets on the findable objec, then we assume
** that we can build up a chart or some data structure.
*/
if (isset($findable['datasets'])) {
$pushableDatasets = [];
foreach ($findable['datasets'] as $datasetKey => $dataset) {
// query data
if (isset($dataset['query'])) {
$chartLabel = $findable['name'] ?? 'Untitled Chart';
$this->setDynamicChartOptions($chartLabel);
$additionFromField = $dataset['query']['additionFromField'] ?? '';
$resultData = [];
if ($dataset['query']['prefersConversionCalculation'] == 'yes') {
$totals = DB::table($dataset['query']['table'])
->select($dataset['query']['columns'])
->where($dataset['query']['calculateConversionFromTotals'])
->orderBy($dataset['query']['orderBy']['field'], $dataset['query']['orderBy']['direction'])
->get()
->chunk(100);
$goal = DB::table($dataset['query']['table'])
->select($dataset['query']['columns'])
->where($dataset['query']['calculateConversionByGoal'])
->orderBy($dataset['query']['orderBy']['field'], $dataset['query']['orderBy']['direction'])
->get()
->chunk(100);
$totals = $totals->flatten();
$goal = $goal->flatten();
$totalsGrouped = $this->groupData(
$totals,
$dataset['query']['groupBy'],
$dataset['query']['groupByFormat'],
$additionFromField
);
$goalsGrouped = $this->groupData(
$goal,
$dataset['query']['groupBy'],
$dataset['query']['groupByFormat'],
$additionFromField
);
$totalsGroupedFlattened = $totalsGrouped->flatten();
$goalsGroupedFlattened = $goalsGrouped->flatten();
$resultData = $this->getStructure($findable, $datasetKey, $goalsGroupedFlattened, $totalsGroupedFlattened);
array_push($pushableDatasets, $resultData);
} else {
$res = DB::table($dataset['query']['table'])
->select($dataset['query']['columns'])
->where($dataset['query']['filterBy'])
->orderBy($dataset['query']['orderBy']['field'], $dataset['query']['orderBy']['direction'])
->get()
->chunk(100);
$res = $res->flatten();
if (isset($dataset['query']['useGrouping']) && $dataset['query']['useGrouping'] == 'yes') {
$results = $this->groupData(
$res,
$dataset['query']['groupBy'],
$dataset['query']['groupByFormat'],
$additionFromField
);
// if we're using an addition function our array is already flattened
if (!empty($additionFromField)) {
$resultData = $results;
} else {
$resultData = $results->flatten();
}
array_push($pushableDatasets, $this->getStructure($findable, $datasetKey, $resultData));
}
}
$dataForAlerts = $resultData;
if ($dataset['query']['prefersConversionCalculation'] == 'yes') {
$dataForAlerts = $dataForAlerts['data'];
}
// alerting
$alerts = $this->getAlertThresholds($dataset['query']['table']);
$this->notifyAlertThreshold($alerts, $dataForAlerts);
}
}
$findable['datasets'] = $pushableDatasets;
}
array_push($data, $findable);
}
// no data or it's empty
if (!isset($data) || empty($data)) {
$this->reportStatus = 'error';
}
// create our report data entry
$this->updateReportData(false, $data);
}
I'm connecting to 3 databases which are stored in array $firmy
For now they are hard coded into array but they will be set via Axios request.
public function show(Request $request, $division, $id)
{
$firmy = array('connection1', 'connection2', 'connection3');
$data = [];
foreach ($firmy as $firma) {
DB::setDefaultConnection($firma);
$calendar = new CalendarEvent();
$data[] = CalendarEventResource::collection($calendar->with('calendarCategories')->where('start', '>', '2020-05-21')->get());
DB::purge($firma);
}
foreach ($data as $firma_event) {
foreach ($firma_event as $event) {
$eventT[] = $event;
}
}
return $eventT;
}
I set the connection, get collection and close the connection.
3 times in this case.
Then I loop through the data to get all records in one go.
Here's the API response returned by $eventT array:
[{"id":17549,"title":"Test","description":"test","contact":"test","email":"test","cat":1,"approved":0,"kto_dodal":450,"calendarCategories":{"id":1,"name":"Ogolna","color":"blue"},"start":"2020-09-30","end":"2020-09-30","private":0,"created_at":null,"updated_at":null},
{"id":17580,"title":"Test","description":"test","contact":"test","email":"test","cat":1,"approved":0,"kto_dodal":450,"calendarCategories":{"id":1,"name":"Ogolna","color":"blue"},"start":"2020-09-30","end":"2020-09-30","private":0,"created_at":null,"updated_at":null},
{"id":17545,"title":"Test","description":"test","contact":"test","email":"test","cat":1,"approved":0,"kto_dodal":450,"calendarCategories":{"id":1,"name":"Ogolna","color":"blue"},"start":"2020-09-30","end":"2020-09-30","private":0,"created_at":null,"updated_at":null}]
One per each connection/table which is fine.
I would like to add a name of the connection to each record. So the API response would look like this:
{"id":17545,"title":"Test","description":"test","contact":"test","email":"test","cat":1,"approved":0,"kto_dodal":450,"calendarCategories":{"id":1,"name":"Ogolna","color":"blue"},"start":"2020-09-30","end":"2020-09-30","private":0,"created_at":null,"updated_at":null, "firma":connection1}]
So "firma":nameOfConnection added to each record.
I tried looping through the data[] and using array_push but I can't place the value of connection inside each record.
Value ends up outside of object:
0: {id: 17549, title: "Test", description: "Test ",…} 1: {firma: "connection1"} firma: "connection1"
I managed to sort it.
First I added a value of firma to Resource class so it gets added to collection although it will be null because there is no column in DB with that name:
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'contact' => $this->contact,
'email' => $this->email,
'cat' => $this->cat,
'approved' => $this->approved,
'kto_dodal' => $this->kto_dodal,
'calendarCategories' => new CalendarCategoryResource($this->whenLoaded('calendarCategories')),
'start' => $this->start,
'end' => $this->end,
'private' => $this->private,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'firma' => $this->firma,
];
}
Then I access Event collection,loop through the results and set value of firma to whatever value the loop is currently at.
public function show(Request $request, $division, $id)
{
$firmy = array('connection1', 'connection2', 'connection3');
$data = [];
foreach ($firmy as $firma) {
DB::setDefaultConnection($firma);
$calendar = new CalendarEvent();
$data = CalendarEventResource::collection($calendar->with('calendarCategories')
->where('start', '>', '2020-09-21')
->where('private', '=', '0')
->get());
// Loop over data in collection and set value of firma
foreach ($data as $value) {
$value->firma = $firma;
$total[] = $value;
}
DB::purge($firma);
}
return $total;
}
Here's the returned value with the attribute firma inside the object:
{"id":17545,"title":"Test","description":"test","contact":"test","email":"test","cat":1,"approved":0,"kto_dodal":450,"calendarCategories":{"id":1,"name":"Ogolna","color":"blue"},"start":"2020-09-30","end":"2020-09-30","private":0,"created_at":null,"updated_at":null,"firma":"connection1"},
i have a relationship that i try to insert with the relationship into the model every thing is fine when i just add phone numbers but when i add the secound field which is type_id i cant handle it because it wont insert the secound field into table here is how i do it in my controller store i want my user to be able to send unlimited phone numbers and each of them have a type_id how can i achive that
:
public function store(StoreHome $request)
{
$validated = $request->all();
if (!$validated) {
return $this->sendError('Validation Error.', $validated->errors());
}
$home = Home::create($validated);
$phones = [];
$type_id = [];
$numbers = $request->input('phones');
$type_id = $request->input('type_id');
foreach($numbers as $number => $item){
$phones[] = [
'phone' => $number
];
$types[] = [
$type_id[] = [
'type_id' => $type_id[$item]
]
];
}
$home->phones()->createMany($phones);
return new HomeResource($home);
You pass $phones to createMany, this variable does not contain any type_id because you put them into $types variable which, moreover is not declared (I suppose you mispelled $type_id = []; instead of $types = [];
Example solution;
$datas = [];
foreach($numbers as $number => $item){
array_push($datas, [$number => $type_id[$item]]);
}
foreach ($datas as $key => $value) {
Home::create([
'phone' => $key,
'type_id' => $value
]);
}
I am building out a website that has about 7500 users. What i wanted was to grab all of my users and their meta data and return it to me through a rest api call that I built myself. Currently I am having a hard time returning all of our users meta data and not just one single user's meta data.
I have already built out the custom endpoint and can successfully return users
add_action( 'rest_api_init', 'my_register_route' );
function my_register_route() {
register_rest_route( 'map/v1', 'test', array(
'methods' => 'GET',
'callback' => 'custom_phrase',
)
);
}
function custom_phrase() {
$users = get_users( array( 'fields' => array( 'ID' ) ) );
foreach($users as $user_id){
return (get_user_meta ( $user_id->ID));
}
}
I expect that the endpoint will return all of my users meta_data & user_data together instead of just the final user in the index.
UPDATE: I feel like I am almost there but each index in the array comes back with the exact same information. Not to mention i am somehow unsuccessful at grabbing the Active_Memberships values which is an array before it gets to me.
function custom_phrase($request_data) {
$parameters = $request_data->get_params();
$state = $parameters['state'];
$users = get_users(array(
'meta_key' => 'active state membership',
'meta_value' => $state,
));
$stack = array();
foreach($users as $user_id) {
$user_meta = get_user_meta ($user_id -> ID);
$obj->display_name = $user_id -> display_name;
$obj->memberships = $user_meta -> active_memberships;
array_push($stack, $obj);
}
return $stack;
}
You use return in your loop, so it will return at the first iteration.
Just create a variable to store meta :
function custom_phrase() {
$users = get_users( array( 'fields' => array( 'ID' ) ) );
$data = [];
foreach($users as $user_id){
$data []= get_user_meta ( $user_id->ID);
}
return $data;
}
How can I keep the matched item's key with array_search and array_column?
$items = array(
'meta-title' => [
"code" => 'meta-title'
],
'meta-keywords' => [
"code" => 'meta-keywords'
],
);
$key = array_search('meta-title', array_column($items, 'code'));
var_dump($key); // 0
The result I am after:
'meta-title'
Any ideas?
Your array_columns() call returns a numerically indexed array of strings (based on the keys from the 1st level), not the array that you're wanting to search (i.e. an array of the 'code' values from the 2nd level). You might be better off iterating through $items and building an array (key/value pairs) based on searching the arrays you're iterating through:
$items = array(
'meta-title' => [
'code' => 'meta-title'
],
'meta-keywords' => [
'code' => 'meta-keywords'
],
);
$results = array();
foreach ($items as $key => $value) {
$result = array_search('meta-title', $value);
if ($result !== false) {
array_push($results, array($key => $result));
}
}
http://sandbox.onlinephpfunctions.com/code/71934db55c67657f0336f84744e05097d00eda6d
Here is an object oriented approach that allows the column and search value to be set at run time. As a class it's more reusable and somewhat self documenting.
<?php
$items = array(
'meta-title' => [
"code" => 'meta-title'
],
'meta-keywords' => [
"code" => 'meta-keywords'
],
);
/**
* Search all records of a recordset style array for a column containing a value
* Capture the row into matches member for later use.
*/
class ColumnSearch {
private $key;
private $search;
public $matches=array();
public function __construct( $key, $search ){
$this->key = $key;
$this->search = $search;
}
public function search( array $items ){
// #todo validate $items is like a recordset
$matches = array_filter( $items, array( $this, "_filter"), ARRAY_FILTER_USE_BOTH );
$this->matches = $matches;
return count($matches);
}
private function _filter( $row, $rowKey ){
return ( $row[$this->key] == $this->search );
}
}
$search = new ColumnSearch( 'code', 'meta-title' );
$occurances = $search->search( $items );
// return value indicates how many were found, in case of multiples...
echo $occurances ." ". PHP_EOL;
// the matched row will be in matches member.
var_dump($search->matches);
// there might be more than 1, not in your example but this is very generic code.
// grab just the keys, then get the current
echo current( array_keys($search->matches) ) . PHP_EOL;
echo "New Search for value that doesn't exist.". PHP_EOL;
$newSearch = new ColumnSearch( 'code', 'title' );
$count = $newSearch->search( $items );
if( 0 == $count ){
echo "Nothing found.". PHP_EOL;
}
echo current( array_keys( $newSearch->matches) );
http://sandbox.onlinephpfunctions.com/code/83b306bfc30ef2a055cf49501bdeb5cb2e5b5ed7