Really it's complicated situation for me right now.
Here I have to export multidimensional array data into excel which is looks like below image, but I'm unable to make it possible.
Please help me to export the multidimensional array data to export in excel.
I have an array from relational query like:
$array = [
0 => [
'name' => 'Devat Karetha',
],
1 => [
'name' => 'John Doe',
'schools' => [
0 => [
'school_name' => 'ABC School',
'school_address' => 'ABC Address',
],
1 => [
'school_name' => 'XYZ School',
'school_address' => 'XYZ Address',
]
],
'sports' => [
0 => [
'id' => 8,
'sport_type' => [
'id' => 2
'sport_type_name' => 'ABC Sport'
],
],
1 => [
'id' => 8,
'sport_type' => [
'id' => 3
'sport_type_name' => 'ABC Sport'
],
],
],
],
2 => [
'name' => 'Utkarsh Raval',
'schools' => [],
'sports' => [
0 => [
'id' => 8,
'sport_type' => [
'id' => 2
'sport_type_name' => 'DEKTS Sport'
],
],
],
'centre' => [
0 => [
'id' => 4,
'centre_name' => 'ABC Centre',
'centre_mobile' => '9898989898',
],
1 => [
'id' => 5,
'centre_name' => 'XYZ Centre',
'centre_mobile' => '7878787878',
],
]
],
];
Thank You...:)
Here I putting my own answer of this question - may be it'll help someone to understand the export functionality with multidimensional array:
$newArr = [];
$arr = [];
foreach($result as $key => $value) {
$count = [count($value['schools']),count($value['centre']),count($value['sports'])];
$arrMax = max($count);
if($arrMax > 0){
for($i=0; $i < $arrMax; $i++){
$arrIndex = $i;
$arr['sr_no'] = '';
$arr['name'] = '';
if($arrIndex == '0'){
$arr['sr_no'] = $key + 1;
$arr['name'] = isset($value['name']) ? $value['name'] : '';
}
$arr['school_name'] = isset($value['schools'][$arrIndex]['school_name']) ? $value['schools'][$arrIndex]['school_name'] : '';
$arr['school_address'] = isset($value['schools'][$arrIndex]['school_address']) ? $value['schools'][$arrIndex]['school_address'] : '';
$arr['sport_type_name'] = isset($value['sports'][$arrIndex]['sport_type']['sport_type_name']) ? $value['sports'][$arrIndex]['sport_type']['sport_type_name'] : '';
$arr['centre_name'] = isset($value['centre'][$arrIndex]['centre_name']) ? $value['centre'][$arrIndex]['centre_name'] : '';
$arr['centre_mobile'] = isset($value['centre'][$arrIndex]['centre_mobile']) ? $value['centre'][$arrIndex]['centre_mobile'] : '';
$newArr[] = $arr;
}
} else {
$arr['sr_no'] = $key + 1;
$arr['name'] = isset($value['name']) ? $value['name'] : '';
$arr['school_name'] = '';
$arr['school_address'] = '';
$arr['sport_type_name'] = '';
$arr['centre_name'] = '';
$arr['centre_mobile'] = '';
$newArr[] = $arr;
}
}
/**
* #param $excel
*/
\Excel::create('advance-report-'.date('d-m-YTH-i-s'), function($excel) use($newArr) {
$excel->sheet('Sheet 1', function($sheet) use($newArr) {
$sheet->fromArray($newArr);
// Freeze first row
$sheet->freezeFirstRow();
// Set height for header
$sheet->setHeight(1, 30);
// Modify properties of header
$sheet->cells('A1:AS1', function($cells) {
$cells->setBackground('#345fbc');
$cells->setFontColor('#ffffff');
$cells->setValignment('center');
});
for( $intRowNumber = 1; $intRowNumber <= count($newArr) + 1; $intRowNumber++){
laravelExcel($sheet, $intRowNumber); //helper function
}
});
})->export('xls');
In Helper File:
/**
* #param null $sheet
* #param null $intRowNumber
*/
function laravelExcel($sheet = null, $intRowNumber = null)
{
try {
$sheet->setSize('A' . $intRowNumber, 10, 18);
$sheet->setSize('B' . $intRowNumber, 20, 18);
$sheet->setSize('C' . $intRowNumber, 20, 18);
$sheet->setSize('D' . $intRowNumber, 20, 18);
$sheet->setSize('E' . $intRowNumber, 35, 18);
$sheet->setSize('F' . $intRowNumber, 15, 18);
$sheet->setSize('G' . $intRowNumber, 15, 18);
} catch (\Exception $e) {
return $e->getMessage();
}
}
Related
I am getting array_key_exists() expects parameter 2 to be array, null given
in the following code. I know it's because $this->items; is null but I am not sure how to fix it.
Warning: array_key_exists() expects parameter 2 to be array, null given
public function __construct($cart = null)
{
if ($cart) {
$this->items = $cart->items;
$this->totalPrice = $cart->totalPrice;
$this->totalQty = $cart->totalQty;
} else {
$this->items = [];
$this->totalQty = 0;
$this->totalPrice = 0;
}
}
public function add($product)
{
$item = [
'id' => $product->id,
'name' => $product->name,
'price' => $product->price,
'qty' => 0,
'image' => $product->image
];
if (!array_key_exists($product->id, $this->items)) {
$this->items[$product->id] = $item;
$this->totalQty += 1;
$this->totalPrice += $product->price;
} else {
$this->totalQty += 1;
$this->totalPrice += $product->price;
}
$this->items[$product->id]['qty'] += 1;
}
It would be helpful to see the full class and your usage of the add() function.
If $this->items is null, I would expect that the $cart object you are passing into the constructor has null items.
Let's assume this is your whole class;
class Cart
{
public function __construct($cart = null)
{
if ($cart) {
$this->items = $cart->items;
$this->totalPrice = $cart->totalPrice;
$this->totalQty = $cart->totalQty;
} else {
$this->items = [];
$this->totalQty = 0;
$this->totalPrice = 0;
}
}
public function add($product)
{
$item = [
'id' => $product->id,
'name' => $product->name,
'price' => $product->price,
'qty' => 0,
'image' => $product->image,
];
if (!array_key_exists($product->id, $this->items)) {
$this->items[$product->id] = $item;
$this->totalQty += 1;
$this->totalPrice += $product->price;
} else {
$this->totalQty += 1;
$this->totalPrice += $product->price;
}
$this->items[$product->id]['qty'] += 1;
}
}
If you consider the snippet below, this code will give the same error you are experiencing.
$product = (object) [
'id' => 1,
'name' => 'product',
'price' => 100,
'qty' => 0,
'image' => 'image.jpg',
];
$existingCart = (object) [
'items' => null, // this is most likely your issue
'totalPrice' => 1000,
'totalQty' => 1,
];
$cart = new Cart($existingCart);
$cart->add($product); // TypeError: array_key_exists(): Argument #2 ($array) must be of type array, null given
If you have items in the $cart->items property, the error won't be thrown;
$product = (object) [
'id' => 1,
'name' => 'product',
'price' => 100,
'qty' => 0,
'image' => 'image.jpg',
];
$existingCart = (object) [
'items' => [
'product-1' => $product, // we actually have an array here of products. An empty array would also be fine
],
'totalPrice' => 1000,
'totalQty' => 1,
];
$cart = new Cart($existingCart);
$cart->add($product); // null
Double check your constructor input by using dd() or print_r() in your constructor to check the $cart argument.
Arr::add doesn't work with dot notation. Arr::set will create a new element only if it does not exist, otherwise, it will overwrite the existing one. There is data_set, it works similar to Arr::set, but it accepts the overwrite flag which does not do what I need (if it's set to false instead of adding a new item, it will just skip setting new value).
My code:
$array = [['name' => 'Test', 'link' => 'test_link'], ['name' => 'Test1', 'link' => 'test1_link']];
$result = [];
$position = 1;
foreach($array as $element) {
Arr::set($result, 'itemListElement.type', 'ListItem');
Arr::set($result, 'itemListElement.position', $position);
Arr::set($result, 'itemListElement.item.name', $element['name']);
Arr::set($result, 'itemListElement.item.link', $element['link']);
$position++;
}
And I would like to have multiple list elements within the itemListElement parent, instead of having one list element which is being overwritten all the time.
Here is what it should look like:
[
"itemListElement" => [
[
"type" => "ListItem",
"position" => 1,
"item" => [
"name" => "Test",
"url" => "test_url",
]
],
[
"type" => "ListItem",
"position" => 1,
"item" => [
"name" => "Test1",
"url" => "test1_url",
]
],
]
]
Can you try this:
$array = [['name' => 'Test', 'link' => 'test_link'], ['name' => 'Test1', 'link' => 'test1_link']];
$result = [];
foreach($array as $key=>$element) {
Arr::set($result["itemListElement"][$key], 'type', 'ListItem');
Arr::set($result["itemListElement"][$key], 'position', $key + 1);
Arr::set($result["itemListElement"][$key], 'item.name', $element['name']);
Arr::set($result["itemListElement"][$key], 'item.link', $element['link']);
}
$result;
I'm having some issues with some Loop for Custom Catalog Listing.
The goal: have Simple Products and some Variant Products (depend on the attribute) listed on the catalog page;
I created a custom product loop using wc_get_products with the type array('simple', 'variation') but attribute filters like size or color don't work with this listing.
This is the code:
$category = get_queried_object();
$currentCat = "";
if ( $category->slug != NULL ){
$currentCat = array($category->slug);
}
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1;
$ordering = WC()->query->get_catalog_ordering_args();
$ordering['orderby'] = array_shift(explode(' ', $ordering['orderby']));
$ordering['orderby'] = stristr($ordering['orderby'], 'price') ? 'meta_value_num' : $ordering['orderby'];
$products_per_page = apply_filters('loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page());
$list_products = wc_get_products(array(
'meta_key' => '_price',
'status' => 'publish',
'category' => $currentCat,
'type' => array('simple', 'variation'),
'limit' => $products_per_page,
'page' => $paged,
'paginate' => true,
'return' => 'ids',
'orderby' => $ordering['orderby'],
'order' => $ordering['order'],
));
$totalProducts = (array) $list_products->products;
wc_set_loop_prop('current_page', $paged);
wc_set_loop_prop('is_paginated', wc_string_to_bool(true));
wc_set_loop_prop('page_template', get_page_template_slug());
wc_set_loop_prop('per_page', $products_per_page);
wc_set_loop_prop('total', $list_products->total);
wc_set_loop_prop('total_pages', $list_products->max_num_pages);
if($totalProducts) {
do_action('woocommerce_before_shop_loop');
woocommerce_product_loop_start();
foreach($totalProducts as $productID) {
$post_object = get_post($productID);
setup_postdata($GLOBALS['post'] =& $post_object);
wc_get_template_part('content', 'product');
}
wp_reset_postdata();
woocommerce_product_loop_end();
do_action('woocommerce_after_shop_loop');
} else {
do_action('woocommerce_no_products_found');
}
Anyone can give me an hand, so that filters start working??
Just got the way to put it to work:
1st I have a loop to get all the product ID's with a condition in the variations to confirm if a custom field (checkbox) is checked. This is mainly to get the total number of products to set up pagination.
The Goal is to include only the Variations Checked on the Catalog Page.
After, I'm doing a second loop, to get all products retrieved from the previous loop.
Here is the working solution:
if(!function_exists('wc_get_products')) {
return;
}
function get_issues($term) {
$hlterms = get_terms($term);
foreach($hlterms as $term){
// var_dump($term->taxonomy);
return true;
}
}
// Get all Attribute Filters
$outputFilters = "";
foreach($_GET as $key => $querystring){
if (strpos($key, 'filter') !== false) {
$outputFilters = array();
$newkey = str_replace("filter", "pa", $key);
if (get_issues($newkey) === true){
$outputFilters[$newkey] = $querystring;
}
}
}
// Check if in some Category
$category = get_queried_object();
$currentCat = "";
if ( $_GET['product_cat'] != NULL ){
$currentCat = $_GET['product_cat'];
} else if ($category->slug != NULL){
$currentCat = array($category->slug);
}
// 1st Loop to get total IDs
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1;
$products_per_page = apply_filters('loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page());
$ordering['orderby'] = 'id';
$args = array(
'meta_key' => '_price',
'status' => 'publish',
'category' => $currentCat,
'type' => array('simple', 'variation'),
'limit' => 1000,
'paginate' => true,
'return' => 'ids',
);
if ($outputFilters != ""){
$args = array_merge($args, $outputFilters);
}
$list_products = wc_get_products($args);
$totalProducts = (array) $list_products->products;
$productsIDS = array();
foreach($totalProducts as $productID) {
$product_s = wc_get_product( $productID );
if ($product_s->product_type == 'simple') {
array_push($productsIDS, $productID);
} else {
if ($product_s->product_type == 'variation') {
$showCatalog = get_post_meta( $productID, '_showoncatalog', true );
if ($showCatalog == "yes"){
array_push($productsIDS, $productID);
}
}
}
}
// Final loop
$args = array(
'meta_key' => '_price',
'status' => 'publish',
'category' => $currentCat,
'type' => array('simple', 'variation'),
'limit' => $products_per_page,
'page' => $paged,
'paginate' => true,
'return' => 'ids',
'orderby' => $ordering['orderby'],
'order' => $ordering['order'],
'include' => $productsIDS,
);
if ($outputFilters != ""){
$args = array_merge($args, $outputFilters);
}
$list_products = wc_get_products($args);
$totalProducts = (array) $list_products->products;
wc_set_loop_prop('current_page', $paged);
wc_set_loop_prop('is_paginated', wc_string_to_bool(true));
wc_set_loop_prop('page_template', get_page_template_slug());
wc_set_loop_prop('per_page', $products_per_page);
wc_set_loop_prop('total', $list_products->total);
wc_set_loop_prop('total_pages', $list_products->max_num_pages);
if($totalProducts) {
do_action('woocommerce_before_shop_loop');
woocommerce_product_loop_start();
foreach($totalProducts as $productID) {
$post_object = get_post($productID);
setup_postdata($GLOBALS['post'] =& $post_object);
wc_get_template_part('content', 'product');
}
wp_reset_postdata();
woocommerce_product_loop_end();
do_action('woocommerce_after_shop_loop');
} else {
do_action('woocommerce_no_products_found');
}
/**
* Hook: woocommerce_after_shop_loop.
*
* #hooked woocommerce_pagination - 10
*/
#do_action( 'woocommerce_after_shop_loop' );
}
I have a set of checkboxes with a belongs to many relationship. I couldnt use a multiple checkbox option for various reasons. The table Tutors has a belongsToMany relationship with subjects table. I get the correct checkboxes checked when it loads and when I update the checboxes I get the correct checkbox data returned but how do i save this? The docs say i need to put the id's in an array for the correct Subjects to be checked . I tried a few things but I couldnt save the data. I dont get an error, just not saving.
//view
foreach ($subjects as $key => $item) {
$sub=$item->name;
$val=0;
foreach ($tutor->subjects as $key2 => $item2) {
$sub2=$item2->name;
if ($sub==$sub2){
$val=1;
break;
}
}
echo $this->Form->hidden('subjects.'.$key.'.id', ['value'=>$item->id]);
echo $this->Form->input('subjects.'.$key.'.checkedvalue', ['label'=>$sub,
'checked'=> $val,'type'=>'checkbox']);
}
//controller
public function edittest5($id = null)
{
$tutor = $this->Tutors->get($id, [
'contain' => ['AvailabilityForTutors','Subjects']
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$tutor = $this->Tutors->patchEntity($tutor, $this->request->data(),['associated' => ['AvailabilityForTutors','Subjects']] );
// $tutor->dirty('availability_for_tutors', true);
debug($tutor);
$this->Tutors->save($tutor,[
// 'atomic'=>false,
'validate' => false,
'associated' => ['Subjects']
]);
return $this->redirect(['action' => 'edittest5',$id]);
}
$subjects = $this->Tutors->Subjects->find('all', ['limit' => 200]);
returned data
'first_name' => 'drew',
'subjects' => [
(int) 0 => [
'id' => '1',
'checkedvalue' => '1'
],
(int) 1 => [
'checkedvalue' => '0'
],
(int) 2 => [
'checkedvalue' => '0'
],
(int) 3 => [
'checkedvalue' => '0'
],
(int) 4 => [
'id' => '5',
'checkedvalue' => '1'
//create anew schedule pane at checkout
function uc_pizza_uc_checkout_pane() {
$panes[] = array(
'id' => 'schedule',
'callback' => 'uc_checkout_pane_schedule',
'title' => t('Pickup/Delivery Date & Time'),
'desc' => t("Show Pickup/Delivery Date & Time Pane"),
'weight' => 1,
'process' => TRUE,
'collapsible' => FALSE,
);
return $panes;
}
function uc_checkout_pane_schedule($op, $order, $form = NULL, &$form_state = NULL) {
require_once(drupal_get_path('module', 'uc_cart') . '/uc_cart_checkout_pane.inc');
switch($op) {
case 'view': //create a date-popup field and a separate field for time.
$format = 'Y-m-d';
if(isset($_REQUEST['panes']['schedule']['date']['date'])) {
$date = $_REQUEST['panes']['schedule']['date']['date'];
} else {
$date = date($format);
}
$descriptions = t("NOTE: You may schedule your pizza pickup or delivery below. The shop is only open from 5pm until 11pm, you may still place your order beyond store hours but it will be delivered the next working hour or your required schedule.");
$contents ['sched_date'] = array(
'#type' => 'date_popup',
'#title' => t('select a date'),
'#default_value' => $date,
'#date_format' => $format,
'#datepicker_options' => array('minDate' => 'today', 'maxDate' => variable_get("uc_pizza_max_days", '+6 days')),
'#date_label_position' => 'within',
'#date_increment' => 15,
'#date_year_range' => '-0:+0',
);
$base_hour= 5;
for($i=0; $i<25; $i++) {
$mins = str_pad((int) (($i % 4) * 15),2,"0",STR_PAD_LEFT);
$hour = str_pad((int) $base_hour,2,"0",STR_PAD_LEFT);
$options_time[$hour.$mins] = t($hour . ":" . $mins . " PM");
if($mins == 45) {
$base_hour++;
}
}
if(isset($_REQUEST['panes']['schedule']['time'])) {
$default_option = $_REQUEST['panes']['schedule']['time'];
} else {
$default_option = 0000;
}
$contents['sched_time'] = array(
'#type' => 'select',
'#title' => 'Time',
'#options' => $options_time,
'#default_value' => $default_option,
);
return array('description' => $descriptions, 'contents' => $contents);
break;
case 'prepare':
break;
case 'review': //**/THIS IS WHERE THE PROBLEM IS** please check process
dprint_r("order: ", $order); // only var with data
dprint_r("form: ", $form); //no data
dprint_r("form_state: ", $form_state); //no data
//$sched_date = $arg1->schedule_date;
//$sched_time = $arg1->schedule_time;
//$review[] = '<div class="giftwrap">' . t('You want #type as gift wrap medium', array('#type' => $gift_wrap_type)) . '</div>';
//$review[] = array('title' => t('Schedule'), 'data' => check_plain("$sched_date # $sched_time"));
//return $review;
break;
case 'process':
//here in process i put the var to $order->schedule_date but unable to see it in $order at view
$order->schedule_date = $form_state['panes']['schedule']['sched_date']['#value']['date'];
$order->schedule_time = $form_state['panes']['schedule']['sched_time']['#value'];
return TRUE;
break;
case 'settings':
$max_days = variable_get("uc_pizza_max_days", '+6 days');
variable_set("uc_pizza_max_days", $max_days);
$contents['max_days'] = array(
'#type' => 'textfield',
'#title' => t('Calendar Max Days Limit'),
'#default_value' => $max_days,
'#maxlength' => 60,
'#size' => 32,
);
return $contents;
break;
}
}
I'm trying to add a pane to checkout process of ubercart,
$op = view and settings works perfect.
I have problem with review i tried setting the variable at $op=process but i cannot find it in $op=review
tried this in process
$order->schedule_date = $form_state['panes']['schedule']['sched_date']['#value']['date'];
$order->schedule_time = $form_state['panes']['schedule']['sched_time']['#value'];
but
in review it seems $order->schedule_date and $order->schedule_time is not in $order;
Can anyone help out what im missing please... this is in D7
Use $order->data instead of trying to apply your custom settings directly to $order.
Try this under 'process'
case 'process':
// display arrays for devel testing
dpm($form);
dpm($order);
// use $order->data to store your submission data
$order->data['schedule_time'] = $form['panes']['schedule']['sched_time']['#value'];
break;
Then use $order under 'review' to get the data you need.