I currently have this code and now I would need some help in making it to work based on what the user have selected.
public function downloadResponse(Request $request)
{
$inputs = $request->input();
$eType = $inputs['chapter_category'];
Excel::create('Export data', function($excel,$eType)
{
$excel->sheet('Sheet 1', function($sheet)
{
$products = Dialog::where('eType', 'claim_type')->get();;
foreach($products as $product)
{
$data[] = array(
$product->eType,
$product->eVal,
$product->intent,
$product->reply,
);
}
$sheet->fromArray($data, null, 'A1', false, false);
$headings = array('Entity Type', 'Entity Value', 'Intent', 'Reply');
$sheet->prependRow(1, $headings);
});
})->export('csv');
}
This line I have hard corded it:
$products = Dialog::where('eType', 'claim_type')->get();
So how do I get the $eType and replace it with 'claim_type'? If I straight put there will be error like below:
Type error: Too few arguments to function
App\Http\Controllers\xxxx\xxxx\xxxx::App\Http\Controllers\xxx\xxxx{closure}(),
1 passed and exactly 2 expected
I'm not sure what field names you have in your Dialog table, but...
$products = Dialog::where('eType', $eType)->get();
or
$products = Dialog::where('claim_type', $eType)->get();
Related
I have a problem wanting to pass the id of Products in the subqueries.
The first code is what I have so far. The second is the way I want to do with Eloquent, but I can't.
$result = [];
Product::with(['locals.presentations'])->each(function ($product) use (&$result) {
$body['id'] = $product->id;
$body['nombre'] = $product->nombre;
$sedes = [];
$product->locals->each(function ($local) use (&$sedes, $product) {
$presentations = [];
$local->presentations->each(function ($presentation) use (&$presentations, $local, $product) {
if ($presentation->local_id == $local->id && $presentation->product_id == $product->id) {
$presentations[] = [
'local_id' => $presentation->local_id,
'product_id' => $presentation->product_id,
'presentacion' => $presentation->presentation,
'precio_default' => $presentation->price
];
}
});
...
});
return $result;
I want transform the previous code into this with Eloquent, but I can't pass the product_id into the subqueries:
$products = Product::with(['locals' => function ($locals) {
//How to get the id from Product to pass in the $presentations query ??????
$locals->select('locals.id', 'descripcion')
->with(['presentations' => function ($presentations) {
$presentations
// ->where('presentations.product_id', $product_id?????)
->select(
'presentations.local_id',
'presentations.product_id',
'presentations.id',
'presentation',
'price'
);
}]);
}])->select('products.id', 'nombre')->get();
return $products;
Product
public function locals()
{
return $this->belongsToMany(Local::class)->using(LocalProduct::class)
->withPivot(['id', 'is_active'])
->withTimestamps();
}
Local
public function presentations()
{
return $this->hasManyThrough(
Presentation::class,
LocalProduct::class,
'local_id',
'local_product_id'
);
}
You can simply use the has() method if you have set the relations correctly on the Product and Local models. This will return ONLY the products which has locals AND presentations.
If you want every product but only the locals and presentations with the product_id equals to the products.id, then you don't have to do anything. The relationship you set in your models already checks if the id matches.
$products = Product::has('locals.presentations')
->with(['locals' => function ($locals) {
$locals
->select('locals.id', 'descripcion')
->with(['presentations' => function ($presentations) {
$presentations->select(
'presentations.local_id',
'presentations.product_id',
'presentations.id',
'presentation',
'price'
);
}]);
}])->select('products.id', 'nombre')->get();
i am on trouble on one issue. in sidebar filter feature, when i click on checkbox it will shown properly list.but when i unchecked checkbox it will shown "array_merge(): Argument #2 is not an array" this error showing while inspect element.
when i click on checkbox it will generate this url "http://abc.local/genre-tags/?id%5B%5D=31" .
and when i unchecked checkbox it will shown url "http://abc.local/genre-tags/" with error.
following are controller and js code.
public function genresFilter ()
{
$sortBy = Input::get('sortBy', 'id');
$dir = Input::get('direction', 'desc');
$orderBy = [
'tracks'=>[ 'order_by'=>$sortBy, 'direction'=>$dir ]
];
$id = Input::get('id');
$category = Category::where('slug','music-genre')->first();
$tag = Tag::with('tracks','elements')->where('category_id', $category->id)->whereIn('id', $id)->get();
echo "<pre>";
print_r($tag->toArray());
die();
$this->layout->content = View::make('public.tags.genres', compact('tag'));
}
//Sidebar Filter Genre Tracks
$(document).ready(function () {
$('.genreTag').on('change', function (e)
{
$('input.filter-playlist, .popularGenreTag, .mood-emotion, .production-type, .vocals, .all-tracks, .last-year, .last-month, .last-week, .last-day').each(function() {
var $this = $(this);
$this.prop('checked', false);
$this.parent().find('> div').removeClass('chk-checked').addClass('chk-unchecked');
});
e.preventDefault();
id = [];
$('.genreTag:checked').each(function()
{
id.push($(this).attr('id'));
});
$.get("/genre-tags/", {id: id}, function(data)
{
hideLoader();
refreshedPage = $(data);
newDemo = refreshedPage.find(".libraryWrapper, .albumWrapper, .composersWrapper, .albumsListWrapper, .albumsWrapper, .accountWrapper, .distributionsWrapper, .PaymentsWrapper, .contactWrapper, .contractsWrapper, .toolsWrapper, .blogWrapper, .pageWrapper, .cartWrapper, .pageWrapper").html();
$('.libraryWrapper, .albumsWrapper, .albumWrapper, .composersWrapper, .albumsListWrapper, .accountWrapper, .distributionsWrapper, .PaymentsWrapper, .contactWrapper, .contractsWrapper, .toolsWrapper, .blogWrapper, .pageWrapper, .cartWrapper, .pageWrapper').html(newDemo);
activatePlayer()
initTrackInfo();
});
});
});
Route::get('genre-tags/', ['as' => 'tag.popular-genres', 'uses' => 'SideFilterController#genresFilter']);
//checkbox blade file
<li class="lib">
<label><input class="genreTag" id="{{ $genreTag->id}}" type="checkbox" name="" value="{{ $genreTag->name }}">{{{ $genreTag->name }}} ({{count(json_decode($genreTag->elements, true))+ count(json_decode($genreTag->tracks, true))}}) </label>
</li>
I think problem in your controller:
you have whereIn query that need to pass array on 2nd args. but your id is null that why it give error like that. try to change code to below will work.
public function genresFilter ()
{
$sortBy = Input::get('sortBy', 'id');
$dir = Input::get('direction', 'desc');
$orderBy = [
'tracks'=>[ 'order_by'=>$sortBy, 'direction'=>$dir ]
];
$id = Input::get('id');
// check if id is not array, then give empty array
if(!is_array($id)) $id = [];
$category = Category::where('slug','music-genre')->first();
$tag = Tag::with('tracks','elements')->where('category_id', $category->id)->whereIn('id', $id)->get();
echo "<pre>";
print_r($tag->toArray());
die();
$this->layout->content = View::make('public.tags.genres', compact('tag'));
}
solution 2
public function genresFilter ()
{
$sortBy = Input::get('sortBy', 'id');
$dir = Input::get('direction', 'desc');
$orderBy = [
'tracks'=>[ 'order_by'=>$sortBy, 'direction'=>$dir ]
];
$id = Input::get('id');
$category = Category::where('slug','music-genre')->first();
$tag = Tag::with('tracks','elements')->where('category_id', $category->id);
// if id is not null and and array then we do filter
if($id != null && is_array($id)) {
$tag->whereIn('id', $id);
}
$tag->get();
echo "<pre>";
print_r($tag->toArray());
die();
$this->layout->content = View::make('public.tags.genres', compact('tag'));
}
I am using Laravel for controller and blade file for a webpage. My code is something like:
PropertiesController
$properties = Property::where('status', 1);
$properties = $properties->orderBy('properties.created_at', 'DESC')->paginate(8);
return view('properties.index')->with('properties', $properties);
in index.blade.php
#foreach ($properties as $property)
<div class="geo">
<span class="lat">{{ $property->title }}</span>,
<span class="lng">{{ $property->description }}</span>
</div>
what I want to achieve is to get categories w.r.t. counts along with properties, for that, I am doing
$properties = Property::where('status', 1);
$categories = array();
if (is_null($req->c)) {
$search = $properties;
foreach (Category::all() as $category) {
array_push(
$categories,
array(
'id' => $category->id,
'name' => $category->category,
'counts' => count($search->where('properties.category', $category->id)->get()),
)
);
}
}
$properties = $properties->orderBy('properties.created_at', 'DESC')->paginate(8);
return view('properties.index')->with('properties', $properties)->with('categories', $categories);
$search = $properties; and
'counts' => count($search->where('properties.category', $category->id)->get()),
with this it gives me
Trying to get property of non-object
<span class="lat"><?php echo e($property->title); ?></span>,
What I think is you want to pass your data to blade view and get counts of categorized data with each category... For that, you can use duplicated functions to count your data separately. e.g.:
public function properties() {
$properties = Property::where('status', 1);
$categories = array();
foreach (Category::all() as $category) {
$count = $this->count($category->id);
array_push(
$categories,
array(
'id' => $category->id,
'name' => $category->category,
'counts' => $count,
)
);
}
$properties = $properties->orderBy('properties.created_at', 'DESC')->paginate(8);
return view('properties.index')->with('properties', $properties)->with('categories', $categories);
}
public function count($id) {
$count = count(Property::where('category_id', $id)); // or any variable you are using to connect categories table with
return $count;
}
$count = $this->count($category->id);
This is the line which did the trick.
If the relationships are made in the models you should only use with () in this way.
This is how the controller should be.
$properties = Property::where('status', 1)->with('category')->orderBy('properties.created_at', 'DESC')->paginate(8);
return view('properties.index', compact('propierties'));
This will give you the list of Properties next to the assigned category.
But if you need to list the categories and have in each category the properties you must do this.
$categories = Category::with('properties')->paginate(8);
return view('properties.index', compact('categories'));
I want to make export data into excel in my project, i have made it, but after I check the results, the results doesnt like what I want. here I would like to make a result there is a title table.
This code my controller:
public function getExport(){
Excel::create('Export data', function($excel) {
$excel->sheet('Sheet 1', function($sheet) {
$products=DB::table('log_patrols')
->join("cms_companies","cms_companies.id","=","log_patrols.id_cms_companies")
->join("securities","securities.id","=","log_patrols.id_securities")
->select("log_patrols.*","cms_companies.name as nama_companies","securities.name as nama_security")
->get();
foreach($products as $product) {
$data[] = array(
$product->date_start,
$product->date_end,
$product->condition_status,
$product->nama_security,
$product->nama_companies,
);
}
$sheet->fromArray($data);
});
})->export('xls');
}
this my problem result :
and it should be :
my problem is how to change the number into text what i want in the header table.
what improvements do i have to make to the code to achieve my goal?
NB : i use maatwebsite/excel
From the official docs:
By default the export will use the keys of your array (or model
attribute names) as first row (header column). To change this
behaviour you can edit the default config setting
(excel::export.generate_heading_by_indices) or pass false as 5th
parameter:
Change:
$sheet->fromArray($data); to $sheet->fromArray($data, null, 'A1', false, false);
how to change the number into text what i want in the header table.
Then you can define your own heading and prepend it to the first row of the sheet.
$headings = array('date start', 'date end', 'status condition', 'security', 'company');
$sheet->prependRow(1, $headings);
That should make it work.
Try this in your controller
$data=Insertion::get()->toArray();
return Excel::create('yourfilename', function($excel) use ($data) {
$excel->sheet('mySheet', function($sheet) use ($data)
{
$sheet->cell('A1:C1',function($cell)
{
$cell->setAlignment('center');
$cell->setFontWeight('bold');
});
$sheet->cell('A:C',function($cell)
{
$cell->setAlignment('center');
});
$sheet->cell('A1', function($cell)
{
$cell->setValue('S.No');
});
$sheet->cell('B1', function($cell)
{
$cell->setValue('Name');
});
$sheet->cell('C1', function($cell)
{
$cell->setValue('Father Name');
});
if (!empty($data)) {
$sno=1;
foreach ($data as $key => $value)
{
$i= $key+2;
$sheet->cell('A'.$i, $sno);
$sheet->cell('B'.$i, $value['name']);
$sheet->cell('C'.$i, $value['fathername']);
$sno++;
}
}
});
})->download(xlsx);
I am using MySQL as the database connection adapter for all my models. I have a downloads model and controller with an index function that renders either an HTML table or a CSV file depending on the type passed from the request. I also have a CSV media type to handle an array of data, which is working as expected (outputs array keys as headers then array values for each row of data).
I wish to do the same find query but then remove ID fields from the record set if a CSV file is going to be rendered. You'll notice that the download ID is being fetched even though it is not in the fields array, so simply changing the fields array based on the request type will not work.
I have tried the following in the index action of my downloads controller:
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
if ($this->request->params['type'] == 'csv') {
$downloads->each(function ($download) {
// THIS DOES NOT WORK
unset($download->id, $download->user_id);
// I HAVE TRIED THIS HERE AND THE ID FIELDS STILL EXIST
// var_dump($download->data());
// exit;
return $download;
});
return $this->render(array('csv' => $downloads->to('array')));
}
return compact('downloads');
}
}
?>
I thought there was an __unset() magic method on the entity object that would be called when you call the standard PHP unset() function on an entity's field.
It would be great if there was a $recordSet->removeField('field') function, but I can not find one.
Any help would be greatly appreciated.
Perhaps you should do $downloads = $downloads->to('array');, iterate the array with a for loop, remove those fields from each row, then return that array. If you have to do this same thing for a lot of actions, you could setup a custom Media handler that could alter the data without needing logic for it in your controller.
Take a look at this example in the Lithium Media class unit test.
You can also avoid having much logic for it in your controller at all through the use of a custom handler. This example also auto-generates a header row from the keys in your data.
In config/bootstrap/media.php:
Media::type('csv', 'application/csv', array(
'encode' => function($data, $handler, $response) {
$request = $handler['request'];
$privateKeys = null;
if ($request->privateKeys) {
$privateKeys = array_fill_keys($request->privateKeys, true);
}
// assuming your csv data is the first key in
// the template data and the first row keys names
// can be used as headers
$data = current($data);
$row = (array) current($data);
if ($privateKeys) {
$row = array_diff_key($row, $privateKeys);
}
$headers = array_keys($row);
ob_start();
$out = fopen('php://output', 'w');
fputcsv($out, $headers);
foreach ($data as $record) {
if (!is_array($record)) {
$record = (array) $record;
}
if ($privateKeys) {
$record = array_diff_key($record, $privateKeys);
}
fputcsv($out, $record);
}
fclose($out);
return ob_get_clean();
}
));
Your controller:
<?php
namespace app\controllers;
use app\models\Downloads;
class DownloadsController extends \lithium\action\Controller {
public function index() {
$this->request->privateKeys = array('id', 'user_id');
// Dynamic conditions
$conditions = array(...);
$downloads = Downloads::find('all', array(
'fields' => array('user_id', 'Surveys.name'),
'conditions' => $conditions,
'with' => 'Surveys',
'order' => array('created' => 'desc')
));
return compact('downloads');
}
}
?>
Why not then just dynamically set your $fields array?
public function index() {
$type = $this->request->params['type'];
//Exclude `user_id` if request type is CSV
$fields = $type == 'csv' ? array('Surveys.name') : array('user_id', 'Surveys.name');
$conditions = array(...);
$with = array('Surveys');
$order = array('created' => 'desc');
$downloads = Downloads::find('all', compact('conditions', 'fields', 'with', 'order'));
//Return different render type if CSV
return $type == 'csv' ? $this->render(array('csv' => $downloads->data())) : compact('downloads');
}
You can see in this example how I send the array for your CSV handler, otherwise it's the $downloads RecordSet object that goes to the view.