I'm trying to get PHPExcel (rather, the Laravel wrapper for it: https://github.com/Maatwebsite/Laravel-Excel ) to export my view. The query I'm running returns multiple rows as a multidimensional array (I'm using DB::select and binding that way because the query is a bit complex for Fluent)
The results look like this:
array(3) {
[0]=> object(stdClass)#224 (3) {
["name"]=> string(13) "Administrator"
["TotalRequest"]=> string(6) "100.00"
["TotalGiven"]=> string(6) "150.00" }
[1]=> object(stdClass)#226 (3) {
["name"]=> string(14) "Beta Alpha Psi"
["TotalRequest"]=> string(6) "363.00"
["TotalGiven"]=> string(6) "200.00" }
[2]=> object(stdClass)#227 (3) {
["name"]=> string(30) "Student Government Association"
["TotalRequest"]=> string(7) "1225.00"
["TotalGiven"]=> string(6) "620.00" }
}
The Laravel-Excel package only takes in a $data array(), so I'm confused how to convert my multi-dimensional array into my view. I can get it to work if I use the alternative
View::make(xxxx)->with('example', $example)
Am I overlooking how to pass $data as an array when I have objects involved in this?
It's not a multi-dimensional array but an array of objects. If you pass the array to your view using something like this:
View::make('xxxx')->with('example', $example)
Then in your view you may loop it using #foreach, like this:
#foreach($example as $item)
{{ $item->name }}
{{ $item->TotalRequest }}
{{ $item->TotalGiven }}
#endforeach
Because, the array contains multiple stdClass objects and the first object is (0):
{
["name"]=> string(13) "Administrator"
["TotalRequest"]=> string(6) "100.00"
["TotalGiven"]=> string(6) "150.00"
}
So, you may also retrieve the first object from the $example array using something like $example[0] and to retrieve the second object you may use $example[1] and so on.
Well I Would suggest you simply change the Fetch Mode to return an array directly using a method like the one below
public function getQueryResult($returnQueryAs = null)'
{
$tablename = 'YourAwesomeTable';
if($returnQueryAs == 'array')
{
DB::connection()->setFetchMode(PDO::FETCH_ASSOC);
}
return DB::table($tablename)->get();
}
then do something like this
public function exportAsExcel()
{
$filename = 'nameoffile';
$data = $this->getQueryResult($as = 'array');
Excel::create($filename, function($excel) use ($filename, $data) {
// Set the title
$excel->setTitle($filename);
// Chain the setters
$excel->setCreator('Damilola Ogunmoye');
$excel->sheet('SHEETNAME', function($sheet) use ($data) {
$sheet->fromArray($data);
});
})->download('xls');
}
This Would get an associative array as opposed to an stdClass object which you can pass directly.
Related
I have a working WordPress Gutenberg Block project which uses nested blocks. I'm trying to rewrite the javascript save function in PHP to create a dynamic block.
I've modified the PHP file to include the following:
function render_html($attributes) {
var_dump($attributes);
ob_start(); ?>
<h1>Attributes</h1>
<h3>The number of columns is <?php echo esc_html($attributes['myColumns']) ?>!</h3>
<?php return ob_get_clean();
}
function cards_init() {
register_block_type_from_metadata( __DIR__, array(
'render_callback' => 'render_html'
) );
}
add_action( 'init', 'cards_init' );
This displays the top level attributes correctly (just one value):
C:\Users\Steve\Local Sites\netmonics6\app\public\wp-content\plugins\cards\cards.php:32:
array (size=1)
'myColumns' => int 3
Attributes
The number of columns is 3!
I'm just wondering how I access the attributes for the nested blocks?
I've used Innerblocks in the main edit.js as follows to enable a nested block:
<InnerBlocks
allowedBlocks={['some-name/card']}
orientation="horizontal"
template={[
['some-name/card'],
['some-name/card'],
['some-name/card'],
]}
/>
Does anyone please have any ideas?
Steve
InnerBlocks can be accessed via $block in the render_callback function. The syntax for the render callback is function($attributes, $content, $block) although commonly, only $attributes is used - unless you want to access something <InnerBlocks>, eg:
PHP
/*
* Render callback function
* #return string HTML markup
*/
function render_html($attributes, $content, $block)
{
$output = '';
// Loop through each inner block
foreach ($block->inner_blocks as $inner_block) {
// Eg. If your ['some-name/card'] block had an attribute
// called `someAttribute` (boolean), it could be accessed via:
if ($inner_block->someAttribute == true) {
// Do something different with this block
$output .= sprintf('<div class="is-some-attribute">%s</div>', $inner_block->render());
} else {
// Otherwise, render block as usual..
$output .= $inner_block->render();
}
}
/*
* Tip: Always return the content to render
* echo() should not be used in render_callback() and ob_start/ob_get_clean not needed.
* Returning valid content avoids dreaded "Invalid JSON" error in Editor.
*/
return $output;
}
When using InnerBlocks, the save() function in JavaScript is required so that the block editor saves the InnerBlock content (even if you are using a PHP render_callback), eg:
save.js
export default function save() {
const blockProps = useBlockProps.save();
return (
<div {...blockProps}>
<InnerBlocks.Content />
</div>
)
}
Depending on what you need from the InnerBlocks, block context might also be useful too..
I created a query that works on a single query but when I use ->get() it prompt
Object of class stdClass could not be converted to string
Here is my code:
$result = DB::table('users')->get(); // the data you want to download as csv
$csv = (array)$result; // stored the data in a array
return Excel::create('csvfile', function ($excel) use ($csv) {
$excel->sheet('mySheet', function ($sheet) use ($csv) {
$sheet->fromArray($csv);
});
})->download('xls');
Quick solution is decoding it
json_decode( json_encode($data), true);
Here is my code now
$data = DB::table('users')->get();
$csv= json_decode( json_encode($data), true);
return Excel::create('SalesReport', function($excel) use ($csv) {
$excel->sheet('Sales-Report', function($sheet) use ($csv)
{
$sheet->fromArray($csv);
});
})->download('xls');
I'm stuck on the following puppet code from days, can you please give me an hand?
In hiera I have the following structure:
my_list::servers:
server1.subnet.env.com:
id: 0
server2.subnet.env.com:
id: 1
server3.subnet.env.com:
id: 2
server4.subnet.env.com:
id: 3
Where the various server1..n (n=>2) are the FQDN of the servers in the specific environment. The ID is always in order, but starting from 0.
I need to create a string that contains a comma separated list of string as broker-${id}-check, where id is different from the FQDN of the server where I'm running puppet, so for example if I'm running the script on server2.subnet.env.com the string should be broker-0-check,broker-2-check,broker-3-check. If I'm running on server1.subnet.env.com it will be broker-1-check,broker-2-check,broker-3-check, etc..
My last tentative is:
$servers_list = hiera('my_list::servers', {"${::fqdn}" => {'id' => 0 } })
$list_broker=''
$servers_list.each |$key, $value| {
if $key != $::fqdn {
$list_broker="${list_broker},broker-${value['id']}-check"
}
}
notify {"******* ${list_broker}": }
but list_broker is still empty and then I will have to fix the leading comma.
Is there a better way to do that?
I'm using Puppet 4.
The problem is that although Puppet has an iteration feature, it doesn't allow the reassignment of variables (ref).
For this reason, Puppet has a lot of functional programming features that allow you to solve problems like this without needing to reassign variables.
This works (Puppet < 5.5), where join() comes from stdlib:
$list_broker = join(
$servers_list
.filter |$key, $value| { $key != $::fqdn }
.map |$key, $value| { "broker-${value['id']}-check" },
','
)
Or in Puppet >= 5.5 (as suggested in comments), where the join command is built-in, the join can be chained too:
$list_broker = $servers_list
.filter |$key, $value| { $key != $::fqdn }
.map |$key, $value| { "broker-${value['id']}-check" }
.join(',')
If you'd prefer it in more steps:
$filtered = $servers_list.filter |$key, $value| { $key != $::fqdn }
$mapped = $filtered.map |$key, $value| { "broker-${value['id']}-check" }
$list_broker = join($mapped, ',')
Explanation:
The filter function selects elements from an Array or Hash on the basis of some criteria.
The map function performs a transformation on all elements of an Array or Hash and returns an Array of transformed data.
The join function (which prior to Puppet 5.5 comes from stdlib) joins an array of strings.
As http://docs.phalconphp.com/en/latest/reference/models.html#understanding-records-to-objects says, you can edit the objects once its loaded in the memory.
$settingCategories = SettingCategory::find();
foreach($settingCategories as $settingCategory){
if($settingCategory->type == "2"){
$settingCategory->type = "asd";
$settingCategory->intersection = "asd";
}else{
$settingCategory->type = "blaa";
$settingCategory->intersection = "blaa";
}
$settingCategory->type = "test";
}
$this->view->setVar("settingCategories",$settingCategories);
type is still its default value when I loop through it with volt:
{% for settingCategory in settingCategories %}
<div class="tab-content">
<h4>{{ settingCategory.name }}</h4>
<h4>{{ settingCategory.type }}</h4> --> still (int) integer!?
<h4>{{ settingCategory.intersection }}</h4> --> undefined!?
</div>
{% endfor %}
When you are modifying a variable inside a foreach, you are modifying a "temporary variable". What it means is that since it is only a copy of the real variable, when you change it, the real value inside the array isn't changed. Now, on to what you could do to solve this:
Setters/Getters
I personally prefer this one. If what you want to do is data transformation (I.E. you change the value of a field from one thing to another, and you want to use the new value in your code everywhere), I would use setters and getters. Here is an example:
// This is inside your model
protected $type;
public function getType()
{
if ($this->type === 2) {
return "asd";
} else {
return $this->type;
}
}
public function setType($type)
{
if ($type === 2) {
$this->type = "asd";
} else {
$this->type = 1; // or $type, or anything really :)
}
}
Of course, in your code, you'll have to change $category->type to $category->getType() and $category->setType($type), based on whether you are reading the value or assigning something to it.
The Quick and Dirty Way
Well, if your use case is different, you can use your current code block with a simple modification. Change your foreach to foreach($settingCategories as &$settingCategory). The ampersand makes the variable be passed into the block as a reference (I.E. it is not a copy like your current case). That means changing it will change the real value.
In my application i have a loop that executes about 1000 times, inside it i'm creating object and saving it. This is the part of application where i populate my database with data. In common this looks like this:
foreach(...){
...
try{
$object = new Model_Whatever;
$object->whatever=$whatever;
$object->save();}
catch(Exception $e){
...}
}
}
This produces 1000 of INSERT queries. Is it possible to, in some way, made kohana produce multi inserts. Split this into 10 inserts with 100 data sets in each. Is it possible and if yes that what is the way doing so?
Whilst the Kohana ORM doesn't support multi inserts, you can still use the query builder as follows:
$query = DB::insert('tablename', array('column1', 'column2','column3'));
foreach ($data as $d) {
$query->values($d);
}
try {
$result = $query->execute();
} catch ( Database_Exception $e ) {
echo $e->getMessage();
}
you'll still need to split the data up so the above doesn't try to execute a query with 1000 inserts.
$data assumes an array of arrays with the values corresponding to the order of the columns
thanks Isaiah in #kohana
php work very slow when insert multi array very big (so that method ::values have array_merge) so more fast:
class Database_Query_Builder_Bath_Insert
extends Database_Query_Builder_Insert{
public static function doExecute($table, $data) {
$insertQuery = DB::insert($table, array_keys(current($data)));
$insertQuery->_values = $data;
$insertQuery->execute();
}
}
call_user_func_array([$query, 'values'], $data);