how to group similar names from database before "-" - php

hey so my database looks like this. Please only focus on the second column:
db
and for now i have done this that looks like:
what i have done
so for now as u all can see i did a view where it shows and separates and groups the same value:
approval-timing-when,
approval-violation,
cancellation-person,
cancellation-person-1,
cancellation-person-2
but what i want to do now is to group all "approval" together and all "cancellation" together and not separate them as shown in my second pictuere. How can i do that? My code is as below:
route:
Route::get('queries/{companyID}/{entityType}/{entityValue}','Chatbot\ChatbotController#queries');
controller:
public function queries($companyID, $entityType, $entityValue)
{
$data = [];
$details = DiraQuestion::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach ($details AS $datum)
{
if (!isset($data[$datum->intent])) $data[$datum->intent] = ['question' => [], 'answer' => []];
$data[$datum->intent]['question'][$datum->queries] = $datum->id;
}
$detailsAns = DiraResponses::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach ($detailsAns AS $datum)
{
if (!isset($data[$datum->intent])) $data[$datum->intent] = ['question' => [], 'answer' => []];
$data[$datum->intent]['answer'][$datum->reply] = $datum->id;
}
ksort($data);
return view('AltHr.Chatbot.queries', compact('data','entityType','entityValue','companyID'));
}
view:
#foreach($data as $intentName => $questionAnswer)
<div class="form-group edit-response-container">
<label data-toggle="collapse" data-target="#collapse-{{$intentName}}" aria-expanded="false" aria-controls="collapse-{{$intentName}}"> {{$intentName}} <i class="fa fa-chevron-down"></i></label>
<div class="collapse" id="collapse-{{$intentName}}">
</div>
</div>
#endforeach

I'd use the groupBy collection method and work off the second column like this:
// change to your model and whatever the second column is named.
$collection = Model::all();
// or DiraQuestion/DiraResponse ..
$collection = ... your query...
// then
$grouped = $collection->groupBy(function ($item, $key) {
return explode('-', $item['column_2'])[0];
});
update
// result of DiraResponses query
$grouped = $detailsAns->groupBy(function ($item, $key) {
return explode('-', $item['column_2'])[0];
});

Related

Route Controller function to welcome.blade file

I have created a function to generate the chart in a TestChart.php controller.
now i need to call that function in my welcome.blade file. but i don't know how to do that.All i get is that the genChart function is undefined(welcome.blade file)
The genChart function is what is want to call in the welcome.blade file
Controller(where the chart is created):
public function index()
{
$columns = array();
$charts = array();
foreach ($columns as $column) {
$charts[$column] = $this->genChart("ami_demo2018", $column);
}
return view('welcome')->with('charts', $charts);
}
function genChart($table, $column)
{
$labels = Array();
$data = Array();
$distinct = DB::select("select distinct `{$column}` FROM `{$table}`");
$sql = "SELECT ";
foreach ($distinct as $key => $value) {
foreach ($value as $key1 => $value1) {
$sql .= "SUM(case when `{$column}` = '{$value1}' THEN 1 END ) AS `{$value1}`,";
if (empty($value1)){
$value1 = 'Niet ingevuld';
}
array_push($labels, $value1);
}
}
$sql = rtrim($sql, ',');
$sql .= " From {$table}";
$result = DB::select($sql);
foreach ($result as $row) {
foreach ($row as $column => $value) {
array_push($data, (int)$value);
}
}
$chart = new chart();
$chart->labels($labels);
$chart->dataset('First Dataset', "bar", $data);
return $chart;
}
the welcome.blade file(where i want to call the genChart function):
<?php
if(isset($_GET['submit'])){
$selected_val = $_GET['select'];
genChart($table, $selected_val);
}
?>
</div>
<div id="container">
#foreach($charts as $chart)
{!! $chart->container() !!}
{!! $chart->script() !!}
#endforeach
</div>
You are using $this->getChart() and defining it as a normal function. You will need to define it as a class function.
Change:
function genChart($table, $column)
To:
public function getChart($table, $column)
This will define it as a class function/method.
First write a route in web.php
Route::post('/getChart/{table}/{selected_val}',ControllerName#genChart)->name('genChart');
After that in blade file on submit write the route
route('genChart',['table'=>$table,'selected_val'=>$selected_val])
Make your function genChart public to access...
i.e public function genChart()

add custom column to laravel excel

I am using maatwebsite/excel, I want to know if it's possible to add custom column when I export my data as CSV or not?
Explanation
I am successfully exporting my products data, but my products have other option which is not stored in my products table such as: specification.
my specifications are stored in 2 different tables named specifications where is parent like CPU and subscpecifications where child's are stored like: Core i5.
another table i am using to store child's id and products id in order to relate each product to their subspecifications.
Sounds Complecated right? :) here i provide ugly map to get the logic :)
Now, What I try to do is:
Add extra column to my csv file and include all specifications of each product.
sample:
Codes
here is my current export function
public function export(Request $request) {
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getRealInput[$key] = $input['defaultname'][$key];
}
}
$products = Product::select($getRealInput)->get();
Excel::create('products', function($excel) use($products, $request) {
$excel->sheet('sheet 1', function($sheet) use($products, $request){
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getCustomInput[$key] = $input['customname'][$key];
}
}
$sheet->fromArray($products, null, 'A1', false, false);
$sheet->row(1, $getCustomInput);
});
})->export('csv');
return redirect()->back();
}
Questions
Is that possible?
If yes, Base on my function above, how do I do it?
Thanks in advance.
UPDATE 1
I have added this code to my function
$allRows = array();
$data = array();
foreach($products as $product){
$specs = $product->subspecifications;
foreach($specs as $spec){
$data[] = $spec->specification->title;
$data[] = $spec->title;
}
}
array_push($allRows , $data);
and changed this line:
$sheet->fromArray($products, null, 'A1', false, false);
to
$sheet->fromArray($allRows, null, 'A1', false, false);
now here is what I have:
here is my full function currently:
public function export(Request $request) {
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getRealInput[$key] = $input['defaultname'][$key];
}
}
$products = Product::select($getRealInput)->get();
Excel::create('products', function($excel) use($products, $request) {
$excel->sheet('sheet 1', function($sheet) use($products, $request){
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getCustomInput[$key] = $input['customname'][$key];
}
}
// test code of adding subspacifications
$allRows = array();
$data = array();
foreach($products as $product){
$specs = $product->subspecifications;
foreach($specs as $spec){
$data[] = $spec->specification->title;
$data[] = $spec->title;
}
}
array_push($allRows , $data);
$sheet->fromArray($allRows, null, 'A1', false, false);
//
// $sheet->fromArray($products, null, 'A1', false, false);
$sheet->row(1, $getCustomInput);
});
})->export('csv');
return redirect()->back();
}
UPDATE 2
Well tonight I've played with my codes a lot and FINALLY :) I got what I needed, here is how:
//codes...
// Here is you custom columnn logic goes
foreach($products as $product){
$specifications = DB::table('products')
->where('products.id', $product->id)
->join('product_subspecification', 'product_subspecification.product_id', '=', 'products.id')
->join('subspecifications', 'subspecifications.id', '=', 'product_subspecification.subspecification_id')
->select('subspecifications.title')
->pluck('title');
$product['specifications'] = rtrim($specifications,',');
}
//
$sheet->fromArray($products, null, 'A1', false, false);
$sheet->row(1, $getCustomInput);
//... rest of the codes
This will give me my products specifications, however there is 3 little issues:
I do not have heading for my specifications in CSV file
Products without specification shows [] instead of nothing
products with specification also covers them with [] and ""
Here I provided screenshot for better understanding:
You need to prepare custom column Specifications by looping through products. Here is your fix,
public function export(Request $request) {
$headers[] = [
'Id',
'Title',
'Specifications',
];
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getRealInput[$key] = $input['defaultname'][$key];
}
}
$products = Product::select($getRealInput)->with('subspecifications')->get()->toArray();
Excel::create('products', function($excel) use($headers,$products, $request) {
$excel->sheet('sheet 1', function($sheet) use($headers,$products, $request){
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getCustomInput[$key] = $input['customname'][$key];
}
}
// Here is you custom columnn logic goes
foreach($products as $product){
$specs = "";
$specifications = DB::table('products')
->where('products.id', $product->id)
->join('product_subspecification', 'product_subspecification.product_id', '=', 'products.id')
->join('subspecifications', 'subspecifications.id', '=', 'product_subspecification.subspecification_id')
->select('subspecifications.title')
->pluck('title');
foreach($specifications as $spec){
$specs = $specs .','.$spec;
}
$product['specifications'] = ltrim($specs,',');
}
//
$mergedProducts = array_merge($headers, $products);
$sheet->fromArray($mergedProducts, null, 'A1', false, false);
$sheet->row(1, $getCustomInput);
});
})->export('csv');
return redirect()->back();
}
Update
As per your sheet image I can assume you have only three columns Id, Title and Specifications, you can change header array according to the columns you are getting from DB.
Yes its possible.
create array for row ie. data = array();
push cell data to array
you can fetch relation data using eloquent or join as well, here I am fetching inside loop.
Updated Function as below:
I tried to match with your data structure
public function export(Request $request) {
$input = $request->except('_token');
foreach ($input['cb'] as $key => $value) {
if ($value== 'on') {
$getRealInput[$key] = $input['defaultname'][$key];
}
}
$products = Product::select($getRealInput)->get();
Excel::create('products', function($excel) use($products, $request) {
$excel->sheet('sheet 1', function($sheet) use($products, $request){
// test code of adding subspacifications
$allRows = array();
array_push($allRows , ['id', 'title', 'specifications']); // Added title row
$data = array();
foreach($products as $product){
$data[] = $product->id; // Added product fields
$data[] = $product->title;
$specs = $product->subspecifications;
$spec_details = "";
foreach($specs as $spec){
$spec_details .= $spec->specification->title.':'. $spec->title. ' '; // appended specification:subspecification
}
$data[] = $spec_details;
}
array_push($allRows , $data);
$sheet->fromArray($allRows, null, 'A1', false, false);
//
// $sheet->fromArray($products, null, 'A1', false, false);
//$sheet->row(1, $getCustomInput); // commented
});
})->export('csv');
return redirect()->back();
}
I do not have heading for my specifications in CSV file
To solve the issue, you can define header and use use array_merge(). For I.E.
$headers[] = [
'Title',
'Specifications',
];
$products= array_merge($headers, $products);
Products without specification shows [] instead of nothing
products with specification also covers them with [] and ""
For 2nd and 3rd point you can use implode() to get rid of []
$product['specifications'] = implode(',', $specifications);
Hope this helps
It works for me. very simple
// Headings//
$headers[] = ['Id', 'Name'];
// 2 Rows //
$data[0] = ['1', 'John'];
$data[1] = ['2', 'Roger'];
Excel::create('report', function($excel) use($headers, $data) {
$excel->sheet('sheet 1', function($sheet) use($headers, $data){
$merged_records = array_merge($headers, $data);
$sheet->fromArray($merged_records, null, 'A1', false, false);
});
})->export('csv');

how to foreach data from same database with two tables laravel

I have written a code to view data but I'm having some problems.
From the code, I wrote it's viewing the data from one table which is the $details. But I also wanna view the data from the $detailsAns.
How can I do that? also, can I foreach two data from that two tables?
my code below:
public function queries($companyID, $entityType, $entityValue)
{
$data = [];
$details = DiraQuestion::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
$detailsAns = DiraResponses::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach($details as $key => $detailsValue)
{
if(!array_key_exists($detailsValue->intent, $data))
{
$data[$detailsValue->intent] = [];
}
if(!array_key_exists($detailsValue->reply, $data[$detailsValue->intent]))
{
$data[$detailsValue->intent]['answer'][$detailsValue->reply] = $detailsValue->id;
}
if(!array_key_exists($detailsValue->queries, $data[$detailsValue->intent]))
{
$data[$detailsValue->intent]['question'][$detailsValue->queries] = $detailsValue->id;
}
}
ksort($data);
return view('AltHr.Chatbot.queries', compact('data','entityType','entityValue','companyID'));
}
so as you can see I can return the data from foreach for $details but now I want to return data for $detailsAns also. how can I do that?
my database structure:
table1:
table2:
so to get the data it first has to select the company id, eType, eVal, and intent so from that now i need to display the reply and queries.
The output that i want is as below:
So as you can see i can output the questions table in the foreach that i did. and if i change the foreach to $detailsAns then i display the reply.. but i want to view the both now
It isn't very clear from the data provided how the tables relate to each other. If the answer has the same id value as the question, it is easy to relate them by structuring the arrays so that they are keyed by the common value.
$data = [];
$details = DiraQuestion::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach ($details AS $datum) {
if (!isset($data[$datum->intent])) $data[$datum->intent] = ['question' => [], 'answer' => []];
$data[$datum->intent]['question'][$datum->id] = $datum->queries;
}
$detailsAns = DiraResponses::where('company_id', $companyID)->where('eType', $entityType)->where('eVal', $entityValue)->get();
foreach ($detailsAns AS $datum) {
if (!isset($data[$datum->intent])) $data[$datum->intent] = ['question' => [], 'answer' => []];
$data[$datum->intent]['answer'][$datum->id] = $datum->reply;
}
At this point, since you said that there is no relation between the data sets, just pass the data array to the view the way you already are:
return view('AltHr.Chatbot.queries', compact('data','entityType','entityValue','companyID'));
And loop through both elements of data, printing out values in the view:
#foreach ($data['approval-document']['question'] as $id=>$question)
<p>Question #{{ $id }}: {{ $question }}</p>
#endforeach
#foreach ($data['approval-document']['answer'] as $id=>$answer)
<p>Answer #{{ $id }}: {{ $answer }}</p>
#endforeach

Have search using foreach loop not return on first match

I want to get all records with the same refid but my foreach loop is just searching until it find the first record and halts.
$data = Projekt1Db::select('refid', 'userid', 'passwd', 'uid', 'gid', 'homedir')->get();
$inputs = \Request::all();
foreach ($data as $id) {
if ($id->refid == $inputs['refid']){
return view('searchfound', [
'id' => $id]);
}
}
if($inputs !== $id){
return redirect()->back()->with('message', 'Refid not found');
}
}
There are more records with the same refid, but it just gives me the first record with that refid.
In the view:
<b>Refid:</b> {{$id->refid}}<br>
<b>Userid:</b> {{$id->userid}}<br>
<b>Password:</b> {{$id->passwd}}<br>
<b>UID:</b> {{$id->uid}}<br>
<b>GID:</b> {{$id->gid}}<br>
<b>homedir:</b> {{$id->homedir}}<br><br>
Use the code below for your php code:
$data = Projekt1Db::select('refid', 'userid', 'passwd', 'uid', 'gid', 'homedir')->get();
$inputs = Request::all();
$id_array = [];
foreach ($data as $id) {
if ($id->refid == $inputs['refid']){
$id_array[] = $id;
}
}
if(count($id_array) == 0){
return redirect()->back()->with('message', 'Refid not found');
}
else{
return view('searchfound', ['id' => $id_array]);
}
and the layout code below:
#foreach($id as $val)
<b>Refid:</b> {{$val->refid}}<br>
<b>Userid:</b> {{$val->userid}}<br>
<b>Password:</b> {{$val->passwd}}<br>
<b>UID:</b> {{$val->uid}}<br>
<b>GID:</b> {{$val->gid}}<br>
<b>homedir:</b> {{$val->homedir}}<br><br>
#endforeach
Basic, change
foreach ($data as $id) {
if ($id->refid == $inputs['refid']){
return view('searchfound', [
'id' => $id]);
}
}
to
$data = array();
foreach ($data as $id) {
if ($id->refid == $inputs['refid']){
$data[] = $id;
}
}
if (length($data) > 0) {
var_dump($data);
} else {
// nothing found
}
Try this:
$newData = [];
foreach ($data as $id) {
if ($id->refid == $inputs['refid']){
$newData[] = $id;
}
}
return view('searchfound', [
'newData' => $newData]);
#foreach($newData as $val)
<b>Refid:</b> {{$val->refid}}<br>
<b>Userid:</b> {{$val->userid}}<br>
<b>Password:</b> {{$val->passwd}}<br>
<b>UID:</b> {{$val->uid}}<br>
<b>GID:</b> {{$val->gid}}<br>
<b>homedir:</b> {{$val->homedir}}<br><br>
#endforeach
Better you can use where condition if you have many records of same refidid
$data=Projekt1Db::where('refid','=', $inputs->refid);
foreach ($data as $id) {
}
then you can loop easily right

Using foreach in codeigniter view to generate select options

I ma using codeigniter to generate some html options,but i only get one result,first result from the table.
This is my controller
public function edit_event($id = 0){
$id = $this->uri->segment(3);
$current_id = $this->ion_auth->get_user_id();
$data['data'] = $this->as->the_event_edit($id);
$data['groups'] = $this->as->the_groups_list($current_id);
$this->load->view('editevent',$data);
}
This is my model
public function the_groups_list($current_id){
$query = $this->db->get_where('all_groups', array('group_owner' => $current_id));
foreach ($query->result() as $row)
{
$data = array(
'group_title' => $row->group_title,
'group_name' => $row->group_name,
'group_owner' => $row->group_owner
);
return $data;
}
}
This is the other model
public function as_event_edit($id){
$query = $this->db->get_where('all_scheduled_messages', array('id' => $id));
foreach ($query->result() as $row)
{
$data = array(
'as_title' => $row->as_title,
'as_event_name' => $row->as_event_name,
'as_owner' => $row->as_owner,
'as_type' => $row->as_type,
'as_target_dataset' => $row->as_target_dataset,
'as_timestamp' => $row->as_timestamp,
'as_time' => $row->as_time,
'as_day' => $row->as_day
);
return $data;
}
}
I am then using $groups['group_title'] in view and only the first group title gets displayed even though i have like 4 group titles from the other rows.
How can i return and pass an array that i can then to the view so as to use foreach to iterate and display the group titles?.
In your model you're not creating a multi-dimensional array. You need to add keys either using a counter:
$data = array();
$i=0;
foreach ($query->result() as $row){
$data[$i]['as_title'] = $row->as_title;
$data[$i]['as_event_name'] = $row->as_event_name;
$data[$i]['as_owner'] = $row->as_owner;
$data[$i]['as_type'] = $row->as_type;
$data[$i]['as_target_dataset'] = $row->as_target_dataset;
$data[$i]['as_timestamp'] = $row->as_timestamp;
$data[$i]['as_time'] = $row->as_time;
$data[$i]['as_day'] = $row->as_day;
$i++;
);
return $data;
or use the key of the incoming array
$data = array();
foreach ($query->result() as $id => $row){
$data[$id]['as_title'] = $row->as_title;
$data[$id]['as_event_name'] = $row->as_event_name;
$data[$id]['as_owner'] = $row->as_owner;
$data[$id]['as_type'] = $row->as_type;
$data[$id]['as_target_dataset'] = $row->as_target_dataset;
$data[$id]['as_timestamp'] = $row->as_timestamp;
$data[$id]['as_time'] = $row->as_time;
$data[$id]['as_day'] = $row->as_day;
);
return $data;
Change the model from $data = to $data[] = to insert each row and not only one.
In your view loop over the groups, like so:
foreach ($data as $group) {
echo "Title" . $groups['group_title'];
}
RTM: Adding Dynamic Data to the View
In the controller: rename your $data['data'] to $data['event']
$data['event'] = $this->as->the_event_edit($id);
$data['groups'] = $this->as->the_groups_list($current_id);
$this->load->view('editevent',$data);
In your view:
foreach ($event as $items) {
var_dump($items);
}
foreach ($groups as $group) {
var_dump($group);
}

Categories