creating multiple table using phpword - php

I am working with PHPWord and am building my table from php using this instruction:
$table = new Table([
'borderSize' => 4,
'borderColor' => 'black',
'width' => 15200,
'unit' => TblWidth::TWIP
]);
I would like to display three dates per table so if I have more than three dates I should have more than one table. I added ${table} in my word file and in php I added this code:
while (count($dates)) {
$numberTable++;
$tableDates = array_splice($dates, 0, 3);
$this->InsertSingleComplexTable($templateOfficer, $data, $tableDates, $numberTable);
}
What I should add to have table per page when I export file, and in every table three dates.

Related

Save all record records using request->all in Laravel

Laravel provides a great help for developers to save all input fields of a form which is one record with one line of code.
like if I want to save a form which has multiple input fields and one record to database like:
then I can save it with below code and it works great:
SaveOrder:: create($request->all());
Now I have a question. If I have multiple records (multiple rows) in a form and I can add new rows with a button pressed. Then how can I save all records with above code?
Like:
It's easy to do that using Eloquent :
$data = array(
array('field1'=>'value1', 'field2'=> value2),
array('field1'=>'value1', 'field2'=> value1),
//...
);
Model::insert($data);
Assuming your input names look something like name[], since you can add rows on the fly, you can retrieve the input as an array, and insert them using something like this:
$data = [];
$names = request('name');
$product_names = request('product_name');
$product_colour = request('product_colour');
$product_size = request('product_size');
for ($i = 0; $i < count($names); $i++) {
// Add checks to make sure indices actually exist, probably using preprocessing in JS
$data[] = [
'name' => $names[$i],
'product_name' => $product_names[$i],
'product_colour' => $product_colour[$i],
'product_size' => $product_size[$i],
];
}
Model::insert($data);
The best answer for this question is using foreach statement. Like:
$CustomerName= $request -> input('CustomerName');
$ProductId= $request -> input('ProductId');
$ProductName= $request -> input('ProductName');
$ProductColor= $request -> input('ProductColor');
foreach( $ProductId as $key => $n ) {
SaveOrder::insert(
array(
'CustomerName' => $CustomerName[$key],
'ProductId' => $ProductId[$key],
'ProductName' => $ProductPrice[$key],
'ProductColor' => $ProductQuantity[$key],
)
);}
Use upsert
If you use Laravel 8 or above, you can make use of upsert. Such an useful function to insert or update matching records at the same time.
SaveOrder::upsert($request->all(), ['id'], ['CustomerName', 'ProductName', 'ProductColor', 'ProductID']);
The method's first argument consists of the values to insert or update, while the second argument lists the column(s) that uniquely identify records within the associated table. The method's third and final argument is an array of the columns that should be updated if a matching record already exists in the database. The upsert method will automatically set the created_at and updated_at timestamps if timestamps are enabled on the model:
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
Read the documentation on Laravel Upsert

cant get the group of an int field from a query in cakephp3

I have a table with a field called 'year'. It has many repetitions in the column so I want to find the distinct group. I have 4 different 'years' in about 20 rows and I dont get these values from the query. Instead what is returned are 4 numbers which are not the years (5,14,4,70). The same code worked fine when I used this with suburb field in another table where there were multiple values of this field. I dont get why this isnt working.
//in view
echo $this->Form->input('year', ['label' => 'Year','options' => $allyears]);
//controller
$allyears = $this->TimesheetDates->find('list')
->select(['TimesheetDates.id', 'TimesheetDates.year'])
->group(['TimesheetDates.year'])->autoFields(true)
->order(['TimesheetDates.year'=> 'ASC'])
->hydrate(false);
$this->set('allyears',$allyears);
//another controller and this code worked fine
$suburb = $this->Students->find('list')->where(['Students.address_suburb !=' => '','Students.student_inactive' => 0])
->select(['Students.id','Students.address_suburb'])
->group(['Students.address_suburb'])->autoFields(true)
->order(['Students.address_suburb' => 'ASC'])
->hydrate(false);
take a look at the documentation about how find('list') works
$allyears = $this->TimesheetDates->find('list', [
'keyField' => 'id',
'valueField' => 'year']
)
->group(['year'])
->order(['year'=> 'ASC']);
Note that it has no meaning selecting the id of the TimesheetDates Table as you are grouping by year and the id is choosen randomly between all the records that share the same year

project the sum of values in a mongo subdocument

I have a Mongo Collection that I'm trying to aggregate in which I need to be able to filter the results based on a sum of values from a subdocument. Each of my entries has a subdocument that looks like this
{
"_id": <MongoId>,
'clientID': 'some ID',
<Other fields I can filter on normally>
"bidCompData": [
{
"lineItemID": "210217",
"qtyBid": 3,
"priceBid": 10.25,
"qtyComp": 0
"description": "Lawn Mowed"
"invoiceID": 23
},
{
<More similar entries>
}
]
}
What I'm trying to do is filter on the sum of qtyBid in a given record. For example, my user could specify that they only want records that have a total qtyBid across all of the bidCompData that's greater than 5. My research shows that I can't use $sum outside of the $group stage in the pipeline but I need to be able to sum just the qtyBid values for each individual record. Presently my pipeline looks like this.
array(
array('$project' => $basicProjection), //fields to project calculated earlier using the input parameters.
array('$match' => $query),
array('$group' => array(
'_id' =>
array('clientID' => '$clientID'),
'count' => array('$sum' => 1)
)
)
I tried having another group and an unwind before the group I presently have in my pipeline so that I could get the sum there but it doesn't let me keep my fields besides the id and the sum field. Is there a way to do this without using $where? My database is large and I can't afford the speed hit from the JS execution.

MySQL result multiple arrays

i.e : i have 2 tables
Product ( id, name )
Photo ( id, name, photo_id )
And I need to get result in array like this:
array(
'id' => 1,
'name' => product,
'photos' => array(
array('id' => 1, 'name' => 'photo1')
array('id' => 2, 'name' => 'photo2')
)
}
Is it possible in PHP using clear SQL?
I know that is possible to get 2 arrays and connect it but I have many records and I dont want to wase time to quering.
You have to add a foreign_key in your photo table "product_id".
Then create a method getPhotos() in your Product class with will collect all photos for your product.
Is it possible in PHP using clear SQL?
Not in a single SQL call. With a single call, this is the closest you can get:
array(
'id' => 1,
'name' => product,
'photo_id' => 1,
'photo_name' => 'photo1')
),
array(
'id' => 1,
'name' => product,
'photo_id' => 2,
'photo_name' => 'photo2')
)
Your only choice for the format you want is to run queries separately or to combine them into the data structure you want.
As mentioned, this is not possible with SQL. SQL is based on the relational model which is a 1-Normal-Form data model. That means, the result relation is also flat (no nested relations in a relation).
However, there are good frameworks which generate intermediary models in your corresponding target language (e.g. Python, Java, ...) that circumvent the impression of a flat data model. Check for example Django.
https://docs.djangoproject.com/en/1.8/topics/db/models/
Moo

PHPWord fixed cell width

I am trying to create a table with cells width a fixed width.
Let's say I have this code:
$table->addCell(300)->addText('first');
$table->addCell(300)->addText('text that is very looooooooong');
The first cell's 300 width is ignored and is crushed against the left side of the page like this:
first
My second cell is going to contain large texts, but I want that cell to maintain it's width.
I couldn't find it anywhere on the web so I am asking if somebody knows what I will have to do here.
Remeber that these values are TWIPS and 300 Twips are mere 5mm.
Not enough room to hold more than 1 character.
Here is a calculator that helps you to convert values:
Topgrapy Calculator
Also you might use the built in conversion functions in Shared\Font.php like this:
$helper= new PHPWord_Shared_Font();
//convert 5cm to Twips
$inTwips=$helper->centimeterSizeToTwips(5);
I have not tried this so far.
I just found out that you have to set style "layout" fixed on your table like below
$fancyTableStyle = [
'borderSize' => 6,
'borderColor' => '000000',
'cellMargin' => 80,
'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER,
'layout' => \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED,
];
$table = $section->addTable($fancyTableStyle);
and then the long word will wrap itself inside the cell.
If you preset a table style on your phpword object, the layout style won't work.
$fancyTableStyleName = 'Fancy Table';
$fancyTableStyle = [
'borderSize' => 6,
'borderColor' => '000000',
'cellMargin' => 80,
'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER,
'layout' => \PhpOffice\PhpWord\Style\Table::LAYOUT_FIXED,
];
//table will not be fixed
$table = $section->addTable($fancyTableStyleName);
In ms word you also need to set the autofit option directly on each table, maybe that's why.

Categories