Parsing information from TrueType font - php

This is PHP code I have so far:
https://gist.github.com/2eeba2ff31ebecb526e2
This is the result:
https://gist.github.com/cf07fe90922ac3dfcd22
Now say I need to get information that is referenced in this table:
object(ttfTableDirectoryEntry)#6 (4) {
["tag"]=>
string(4) "cmap"
["checksum"]=>
int(2553734765)
["offset"]=>
int(1556)
["length"]=>
int(1190)
}
How do I do that?
In general, I need to parse info for every of these tables.
This is what you get if you simply try to parse the data from offset with length.
object(ttfTableDirectoryEntry)#12 (4) {
["tag"]=>
string(4) "name"
["checksum"]=>
int(3955157420)
["offset"]=>
int(400)
["length"]=>
int(1153)
}
string(1153) "���>��������:����������:��������F�������"�L��������n�������
������������������5����������������� �#��������
�:������������������ ���t#�� ����� ����� ��D��� ��$��� ��#�� ��$��� ��j=�� ����� � �F��� �
�t#�� ��: �� ��: Copyright (c) 2010 by YouWorkForThem. All rights reserved.YWFT HLLVTKANormalYouWorkForThem: YWFT HLLVTKA: 2010YWFT HLLVTKA NormalVersion 1.000YWFTHLLVTKA-NormalYWFT HLLVTKA Normal is a trademark of YouWorkForThem.YouWorkForThemEric Carlson & Taechit Jiropaskosolhttp://www.youworkforthem.com�C�o�p�y�r�i�g�h�t� �(�c�)� �2�0�1�0� �b�y� �Y�o�u�W�o�r�k�F�o�r�T�h�e�m�.� �A�l�l� �r�i�g�h�t�s� �r�e�s�e�r�v�e�d�.�Y�W�F�T� �H�L�L�V�T�K�A�N�o�r�m�a�l�Y�o�u�W�o�r�k�F�o�r�T�h�e�m�:� �Y�W�F�T� �H�L�L�V�T�K�A�:� �2�0�1�0�Y�W�F�T�H�L�L�V�T�K�A�-�N�o�r�m�a�l�V�e�r�s�i�o�n� �1�.�0�0�0�Y�W�F�T� �H�L�L�V�T�K�A� �N�o�r�m�a�l� �i�s� �a� �t�r�a�d�e�m�a�r�k� �o�f� �Y�o�u�W�o�r�k�F�o�r�T�h�e�m�.�Y�o�u�W�o�r�k�F�o�r�T�h�e�m�E�r�i�c� �C�a�r�l�s�o�n� �&� �T�a�e�c�h�i�t� �J�i�r�o�p�a�s�k�o�s�o�l�h�t�t�p�:�/�/�w�w�w�.�y�o�u�w�o�r�k�f�o�r�t�h�e�m�.�c�o�m"

I tried to achieve this and went close to making it. However, at the end, I decided to use Python instead when parsing data. Anyway, if anyone decide that they want to go PHP way, here is what I have until this moment. It is one step close to getting glyph map. For a documentation on how to read the data, refer to http://developer.apple.com/fonts/ttrefman/RM06/Chap6.html.
<?php
$ttr = new TrueTypeReader;
$ttr->open('font.otf');
class TrueTypeReader
{
private $position = 0;
private $offset = 0;
private $file;
public function open($file)
{
$this->file = file_get_contents($file);
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6.html
// The offset subtable
$number_of_tables = $this->getUint16(4);
$this->tables = array();
for($i = 0; $i < $number_of_tables; $i++)
{
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6.html
// The table directory
$table = array();
$tag = $this->getTag(12 + $i * 16);
$table = array
(
'tag' => $tag,
'check_sum' => $this->getUint32(12 + $i * 16 + 4),
'offset' => $this->getUint32(12 + $i * 16 + 8),
'length' => $this->getUint32(12 + $i * 16 + 12),
);
if($tag == 'cmap')
{
$this->parseCmapTable($table);
}
$this->tables[] = $table;
}
}
private function getTag($pt = FALSE)
{
if($pt === FALSE)
{
$pt = $this->position;
$this->position += 4;
}
return substr($this->file, $pt, 4);
}
private function getUint32($pt = FALSE)
{
if($pt === FALSE)
{
$pt = $this->position;
$this->position += 4;
}
$r = unpack("N", substr($this->file, $pt, 4) );
return $r[1];
}
private function getUint16($pt = FALSE)
{
if ($pt === FALSE)
{
$pt = $this->position;
$this->position += 2;
}
$r = unpack("n", substr($this->file, $pt, 2) );
return $r[1];
}
private function parseCmapTable($table)
{
$this->position = $table['offset'];
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6cmap.html
// General table information
$data = array
(
'version' => $this->getUint16(),
'number_subtables' => $this->getUint16(),
);
$sub_tables = array();
for($i = 0; $i < $data['number_subtables']; $i++)
{
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6cmap.html
// The 'cmap' encoding subtables
$sub_tables[] = array
(
'platform_id' => $this->getUint16(),
'specific_id' => $this->getUint16(),
'offset' => $this->getUint32(),
);
}
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6cmap.html
// The 'cmap' formats
$formats = array();
foreach($sub_tables as $t)
{
// http://stackoverflow.com/questions/5322019/character-to-glyph-mapping-table/5322267#5322267
$this->position = $table['offset'] + $t['offset'];
$format = array
(
'format' => $this->getUint16(),
'length' => $this->getUint16(),
'language' => $this->getUint16(),
);
if($format['format'] == 4)
{
$format += array
(
'seg_count_X2' => $this->getUint16(),
'search_range' => $this->getUint16(),
'entry_selector' => $this->getUint16(),
'range_shift' => $this->getUint16(),
'end_code[segCount]' => $this->getUint16(),
'reserved_pad' => $this->getUint16(),
'start_code[segCount]' => $this->getUint16(),
'id_delta[segCount]' => $this->getUint16(),
'id_range_offset[segCount]' => $this->getUint16(),
'glyph_index_array[variable]' => $this->getUint16(),
);
$backup = $format;
$format['seg_count_X2'] = $backup['seg_count_X2']*2;
$format['search_range'] = 2 * (2 * floor(log($backup['seg_count_X2'], 2)));
$format['entry_selector'] = log($backup['search_range']/2, 2);
$format['range_shift'] = (2 * $backup['seg_count_X2']) - $backup['search_range'];
}
$formats[$t['offset']] = $format;
}
die(var_dump( $sub_tables, $formats ));
die(var_dump( $this->getUint16(), $this->getUint16(), $this->getUint16(), $this->getUint16(), $this->getUint16() ));
die(var_dump( $sub_tables[0] ));
$cmap = array
(
'format' => $this->getUint16(),
#'length' => $this->getUint16(),
#'language' => $this->getUint16(),
);
die(var_dump( $cmap ));
die(var_dump( $table, $data, $table, $cmap ));
}
private function parseNameTable($table)
{
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6name.html
// Name Table Format
$data = array
(
'format' => $this->getUint16($table['offset']),
'count' => $this->getUint16($table['offset'] + 2), // $num_of_name_tables
'string_offset' => $this->getUint16($table['offset'] + 4),
);
$offset = $table['offset'] + $data['string_offset']; // $name_tables_offset
$name_tables = array();
for($i = 0; $i < $data['count']; $i ++)
{
$this->position = $table['offset'] + 6 + $i * 12;
$d = array
(
'platform_id' => $this->getUint16(),
'specific_id' => $this->getUint16(),
'lang_id' => $this->getUint16(),
'name_id' => $this->getUint16(),
'length' => $this->getUint16(),
'offset' => $this->getUint16() + $offset,
);
$key = "{$d['platform_id']}::{$d['specific_id']}::{$d['lang_id']}";
if(isset($d['name_id']) && empty($name_tables[$key][$d['name_id']]))
{
$text = substr($this->file, $d['offset'], $d['length']);
$name_tables[$key][$d['name_id']] = str_replace(chr(0), '', $text);
}
}
die(var_dump( $name_tables ));
}
}

Related

which algorithm php to create a secret Santa program

I'm trying to make a draw for a secret Santa.
I collect in a table the information of the person and the name of the person on whom it should not fall (to avoid couples).
However during my PHP loop I can't take into account my exclusions
foreach ($supplier as $sup){
$exclude = $sup['blacklist'];
$data = $recipient;
$temp = array_diff($data[], array($exclude));
echo $temp[rand(0, sizeOf($temp))];
foreach ($recipient as $key=>$recip){
if ($sup['surname'] !== $recip['surname']){
$result[] = ['recipient' => $recip, 'supplier' => $sup];
unset($recipient[$key]);
}
}
}
How can I take into account this blacklist please?
shuffle($supplier);
shuffle($recipient);
// dump($supplier, $recipient);
$result = [];
foreach ($supplier as $sup){
$assign = false;
dump($sup);
foreach ($recipient as $key=>$recip){
dump($recip['surname']);
if ($sup['surname'] !== $recip['surname'] && $sup['blacklist'] !== $recip['surname'] && $sup['surname'] !== $recip['blacklist']){
$result[] = ['recipient' => $recip, 'supplier' => $sup];
dump($sup['surname']);
unset($recipient[$key]);
$assign = true;
}
if ($assign === true){
break;
}
}
}
return $result;
}
this is my code with shuffle
Your solution is fine, but with that nested loop it's going to start behaving poorly as the list of participants grows. You can accomplish the task with a single array and two linear passes over it:
$people = [
[ 'name' => 'alice', 'blacklist' => ['bob'] ],
[ 'name' => 'bob', 'blacklist' => ['alice'] ],
[ 'name' => 'carl', 'blacklist' => ['david'] ],
[ 'name' => 'david', 'blacklist' => ['carl'] ],
[ 'name' => 'elise', 'blacklist' => ['frank'] ],
[ 'name' => 'frank', 'blacklist' => ['elise'] ],
[ 'name' => 'georg', 'blacklist' => ['herb'] ],
[ 'name' => 'herb', 'blacklist' => ['george'] ]
];
function wrap_index($count, $index) {
$cur = $index;
if( $index == 0 ) {
$prev = $count - 1;
$next = $index + 1;
} else if( $index == $count - 1) {
$prev = $index - 1;
$next = 0;
} else {
$prev = $index - 1;
$next = $index + 1;
}
return [$prev, $cur, $next];
}
function array_swap(&$array, $a, $b) {
$tmp = $array[$a];
$array[$a] = $array[$b];
$array[$b] = $tmp;
}
function santify($people) {
shuffle($people);
$count = count($people);
for( $i=0; $i<$count; ++$i ) {
list($prev, $cur, $next) = wrap_index($count, $i);
if( in_array($people[$cur]['name'], $people[$next]['blacklist']) ) {
printf("%s in blacklist for %s\n", $people[$cur]['name'], $people[$next]['name']);
array_swap($people, $cur, $prev);
}
}
$pairs = [];
for( $i=0; $i<$count; ++$i ) {
list($prev, $cur, $next) = wrap_index($count, $i);
$pairs[] = [ $people[$cur]['name'], $people[$next]['name'] ];
}
return $pairs;
}
foreach( santify($people) as $pair ) {
printf("%s\n", json_encode($pair));
}
Output:
david in blacklist for carl
elise in blacklist for frank
["david","georg"]
["georg","carl"]
["carl","bob"]
["bob","herb"]
["herb","elise"]
["elise","alice"]
["alice","frank"]
["frank","david"]
There is a caveat to this approach, though. It will only work with strict 1:1 blacklist arrangements. Once there is a love triangle [or quardrangle or above] or any polyamory, neither of our solutions is equipped for these extra dimensions.

How to get if data exist in array in php

I am making laravel project.
I need to get data list from request.
So should get this data if data exist next.
I used below code...
for($i = 0; $i < count($request->post('pickup_location')); $i++)
{
if($request->post('meeting_ids')[$i])
{
$meeting_profile = MeetingPoint::findOrFail($request->post('meeting_ids')[$i]);
$meeting_data = array(
'pickup_location' => $request->post('pickup_location')[$i],
'pickup_type' => $request->post('pickup_type')[$i],
'pickup_time' => $request->post('pickup_time')[$i],
);
$meeting_profile->fill($meeting_data);
$meeting_profile->save();
} else {
$meeting_profile = new MeetingPoint;
$meeting_data = array(
'holiday_id' => $profile->id,
'pickup_location' => $request->post('pickup_location')[$i],
'pickup_type' => $request->post('pickup_type')[$i],
'pickup_time' => $request->post('pickup_time')[$i],
);
$meeting_profile->fill($meeting_data);
$meeting_profile->save();
}
}
But there is this error:
How can I get next data list with that logic?
Please do like below...
for($i = 0; $i < count($request->post('pickup_location')); $i++)
{
if(isset($request->post('meeting_ids')[$i]))
{
$meeting_profile = MeetingPoint::findOrFail($request->post('meeting_ids')[$i]);
$meeting_data = array(
'pickup_location' => isset($request->post('pickup_location')[$i]) ? $request->post('pickup_location')[$i] : null,
'pickup_type' => isset($request->post('pickup_type')[$i]) ? $request->post('pickup_type')[$i] : null,
'pickup_time' => isset($request->post('pickup_time')[$i]) ? $request->post('pickup_time')[$i] : null,
);
$meeting_profile->fill($meeting_data);
$meeting_profile->save();
} else {
$meeting_profile = new MeetingPoint;
$meeting_data = array(
'holiday_id' => $profile->id,
'pickup_location' => isset($request->post('pickup_location')[$i]) ? $request->post('pickup_location')[$i] : null,
'pickup_type' => isset($request->post('pickup_type')[$i]) ? $request->post('pickup_type')[$i] : null,
'pickup_time' => isset($request->post('pickup_time')[$i]) ? $request->post('pickup_time')[$i] : null,
);
$meeting_profile->fill($meeting_data);
$meeting_profile->save();
}
}
You could use Arr Helper function to more clean and organized code.
$values = $request->all();
for($i = 0; $i < count(Arr::get($values, 'pickup_location')); $i++)
{
if($id = Arr::get($values, "meeting_ids.{$i}"))
{
$meeting_profile = MeetingPoint::findOrFail($id);
$meeting_data = array(
'pickup_location' => Arr::get($values, "pickup_location.{$i}"),
'pickup_type' => Arr::get($values, "pickup_type.{$i}"),
'pickup_time' => Arr::get($values, "pickup_time.{$i}"),
);
$meeting_profile->fill($meeting_data);
$meeting_profile->save();
} else {
...
}
}
Please do like below
<?php
$array1 = [
"Orange" => 100,
"Apple" => 200,
"Banana" => 300,
"Cherry" => 400
];
if ( array_key_exists("Banana", $array1) )
echo "Array Key exists...";
else
echo "Array Key does not exist...";
?>

Parsing returns an empty value

I make a parser of items from DotA 2 user inventory in the Steam service. Every time I try to parse user data, I get an empty value:
{"success":true,"items":[]}, but there are items in my Steam inventory.
My function to parse items:
public function loadMyInventory() {
if(Auth::guest()) return ['success' => false];
$prices = json_decode(Storage::get('prices.txt'), true);
$response = json_decode(file_get_contents('https://steamcommunity.com/inventory/'.$this->user->steamid64.'/570/2?l=russian&count=5000'), true);
if(time() < (Session::get('InvUPD') + 5)) {
return [
'success' => false,
'msg' => 'Error, repeat in '.(Session::get('InvUPD') - time() + 5).' сек.',
'status' => 'error'
];
}
//return $response;
$inventory = [];
foreach($response['assets'] as $item) {
$find = 0;
foreach($response['descriptions'] as $descriptions) {
if($find == 0) {
if(($descriptions['classid'] == $item['classid']) && ($descriptions['instanceid'] == $item['instanceid'])) {
$find++;
# If we find the price of an item, then move on.
if(isset($prices[$descriptions['market_hash_name']])) {
# Search data
$price = $prices[$descriptions['market_hash_name']]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($descriptions['tradable'] == 0) || ($descriptions['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
# Adding to Array
$inventory[] = [
'name' => $descriptions['market_name'],
'price' => floor($price),
'color' => $this->getRarity($descriptions['tags']),
'tradable' => $descriptions['tradable'],
'class' => $class,
'text' => $text,
'classid' => $item['classid'],
'assetid' => $item['assetid'],
'instanceid' => $item['instanceid']
];
}
}
}
}
}
Session::put('InvUPD', (time() + 5));
return [
'success' => true,
'items' => $inventory
];
}
But should return approximately the following value:
{"success":true,"items":[{"classid":"2274725521","instanceid":"57949762","assetid":"18235196074","market_hash_name":"Full-Bore Bonanza","price":26}]}
Where my mistake?
First of all, you are iterating on descriptions for every assets, which is assets*descriptions iteration, it's quite a lot, but you can optimize this.
let's loop once for descriptions and assign classid and instanceid as object key.
$assets = $response["assets"];
$descriptions = $response["descriptions"];
$newDescriptions=[];
foreach($descriptions as $d){
$newDescriptions[$d["classid"]][$d["instanceid"]] = $d;
}
this will give as the ability to not loop over description each time, we can access the description of certain asset directly $newDescriptions[$classid][$instanceid]]
foreach($assets as $a){
if(isset($newDescriptions[$a["classid"]]) && isset($newDescriptions[$a["classid"]][$a["instanceid"]])){
$assetDescription = $newDescriptions[$a["classid"]][$a["instanceid"]];
$inventory = [];
if(isset($prices[$assetDescription["market_hash_name"]])){
$price = $prices[$assetDescription['market_hash_name']]["price"]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($assetDescription['tradable'] == 0) || ($assetDescription['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
$inventory["priceFound"][] = [
'name' => $assetDescription['market_name'],
'price' => floor($price),
'color' => $this->getRarity($assetDescription['tags']),
'tradable' => $assetDescription['tradable'],
'class' => $class,
'text' => $text,
'classid' => $a['classid'],
'assetid' => $a['assetid'],
'instanceid' => $a['instanceid']
];
}else{
$inventory["priceNotFound"][] = $assetDescription["market_hash_name"];
}
}
}
About your mistake:
are you Sure your "prices.txt" contains market_hash_name?
I don't see any other issue yet, operationg on the data you have provided in comment, I got print of variable $assetDescription. Please doublecheck variable $prices.

Save as PDF in portrait orientation using Yii pdfGrid extension

Good Afternoon
I am using the pdfGrid extension in Yii in which i am using the class EPDFGrid..
I am really confused on how to make the orientation in PORTRAIT mode. currently the rendered PDF file is in Landscape.. i tried changing this line public $orientation = 'L'; to 'P' but it did nothing..
i followed it here..
http://www.yiiframework.com/extension/pdf-grid/
is there an option in config that dictates the orientation into PORTRAIT.?
can anybody help me..
this is the code in my EPDFGrid.php
<?php
Yii::import('zii.widgets.grid.CDataColumn');
Yii::import('ext.pdfGrid.fpdf.PDF');
class EPDFGrid extends CWidget {
private $_debug = false;
protected $_pdf;
protected $_fill = false;
protected $_columnWidths = array();
protected $_visibleColumns = 0;
public $dataProvider;
public $fileName;
public $config = array();
public $columns = array();
public $labels = array();
public $orientation = 'L';
public $showTableOnEmpty = true;
public $nullDisplay = ' ';
public $emptyText;
public $hideHeader = false;
public function init() {
if ($this->columns === array()) {
if ($this->dataProvider instanceof CActiveDataProvider)
$this->columns = $this->dataProvider->model->attributeNames();
else if ($this->dataProvider instanceof IDataProvider) {
// use the keys of the first row of data as the default columns
$data = $this->dataProvider->getData();
if (isset($data[0]) && is_array($data[0]))
$this->columns = array_keys($data[0]);
}
}
$id = $this->getId();
foreach ($this->columns as $i => $column) {
if (is_string($column))
$column = $this->createDataColumn($column);
else {
if (!isset($column['class']))
$column['class'] = 'CDataColumn';
$column = Yii::createComponent($column, $this);
}
if (!$column->visible) {
unset($this->columns[$i]);
continue;
}
$this->_visibleColumns++;
if ($column->id === null)
$column->id = $id . '_c' . $i;
$this->columns[$i] = $column;
}
$default = array(
'pdfSize' => 'A4',
'title' => '',
'subTitle' => '',
'headTitle' => '',
'amount' => '',
'tableWidth' => 275,
'rowHeight' => 6,
'colAligns' => null,
'colWidths' => null,
'showLogo' => false,
'imagePath' => YiiBase::getPathOfAlias('webroot') . '/images/logo.jpg',
'headerDetails' => false,
);
$this->config = array_merge($default, $this->config);
$this->_pdf = new PDF('L', 'mm', $this->config['pdfSize']);
$this->_pdf->title = $this->config['title'];
$this->_pdf->subTitle = $this->config['subTitle'];
$this->_pdf->headTitle = $this->config['headTitle'];
$this->_pdf->amount = $this->config['amount'];
$this->_pdf->tableWidth = $this->config['tableWidth'];
$this->_pdf->rowHeight = $this->config['rowHeight'];
$this->_pdf->imagePath = $this->config['imagePath'];
$this->_pdf->showLogo = $this->config['showLogo'];
$this->_pdf->headerDetails = $this->config['headerDetails'];
$this->_pdf->SetAligns($this->config['colAligns']);
$this->_pdf->SetFont('Arial', 'B', 10);
$this->_pdf->SetLineWidth(0.5);
$this->_columnWidths = $this->_calcWidths();
$this->_pdf->SetWidths($this->_columnWidths);
$this->_pdf->AliasNbPages();
$this->_pdf->AddPage();
foreach ($this->columns as $column)
$column->init();
$this->renderItems();
}
protected function createDataColumn($text) {
if (!preg_match('/^([\w\.]+)(:(\w*))?(:(.*))?$/', $text, $matches))
throw new CException(Yii::t('zii', 'The column must be specified in the format of "Name:Type:Label",
where "Type" and "Label" are optional.'));
$column = new CDataColumn($this);
$column->name = $matches[1];
if (isset($matches[3]) && $matches[3] !== '')
$column->type = $matches[3];
if (isset($matches[5]))
$column->header = $matches[5];
return $column;
}
protected function renderItems() {
if ($this->dataProvider->getItemCount() > 0 || $this->showTableOnEmpty) {
$this->renderTableHeader();
$this->renderTableBody();
}
else
$this->_renderEmptyText();
if ($this->_debug)
Yii::app()->end();
else {
// $this->_pdf->Output($this->fileName . ' (' . date('Y-m-d') . ').pdf', 'D');
$this->_pdf->Output($this->fileName . '.pdf', 'D');
exit();
}
}
protected function renderTableHeader() {
if (!$this->hideHeader) {
// Colores y fuente en negrita
$this->_pdf->SetFillColor(245, 185, 120);
$this->_pdf->SetTextColor(0);
$this->_pdf->SetBold();
$rowHeader = array();
if ($this->labels != array()) {
$rowHeader = $this->labels;
} else {
foreach ($this->columns as $i => $column) {
if ($column->name == 'Id') {
$rowHeader[] = strtoupper($column->name);
} else {
$rowHeader[] = $column->name;
}
// $rowHeader[] = $column->grid->dataProvider->model->getAttributeLabel($column->name);
//$this->_pdf->Cell($this->_columnWidths[$i],$this->headerHeight,$data,0,0,'C',true);
}
}
$this->_pdf->Row($rowHeader, array('fill' => true, 'header' => true));
}
}
protected function renderTableBody() {
$data = $this->dataProvider->getData();
$n = count($data);
// Restauraci�n de colores y fuentes
$this->_pdf->SetFillColor(255, 242, 208);
$this->_pdf->SetTextColor(0);
$this->_pdf->SetFont('');
if ($n > 0) {
for ($row = 0; $row < $n; ++$row)
$this->renderTableRow($row);
}
else
$this->_renderEmptyText();
}
protected function renderTableRow($row) {
//var_dump($this->dataProvider);
$rowData = array();
foreach ($this->columns as $i => $column) {
$data = $this->dataProvider->data[$row];
if ($column->value !== null)
$value = $column->evaluateExpression($column->value, array('data' => $data, 'row' => $row));
else if ($column->name !== null)
$value = CHtml::value($data, $column->name);
// $rowData[] = $value===null ? $this->nullDisplay : $this->_formatString($value);
$rowData[] = $value === null ? $this->nullDisplay : utf8_decode($value);
}
$this->_pdf->Row($rowData, array('fill' => $this->_fill));
$this->_fill = !$this->_fill;
}
protected function _renderEmptyText() {
$emptyText = $this->emptyText === null ? Yii::t('zii', 'No results found.') : $this->emptyText;
$this->_pdf->Cell(array_sum($this->_columnWidths), $this->config['rowHeight'], $emptyText, 0, 0, 'L');
}
protected function _calcWidths() {
$widths = array();
$params = $this->config['colWidths'];
$visibleCols = $this->_visibleColumns;
if (!$params) {
$w = $this->_pdf->tableWidth / $visibleCols;
for ($i = 0; $i < $visibleCols; $i++)
$widths[] = $w;
} else if (is_array($params)) {
if (count($params) > $visibleCols)
throw new Exception('La cantidad de parametros supera a las columnas visibles');
if (array_sum($params) > $this->_pdf->tableWidth)
throw new Exception('La suma de los parametros supera a la longitud max de la tabla');
$nulls = 0;
$confWidth = 0;
for ($i = 0; $i < $visibleCols; $i++) {
if (empty($params[$i]))
$nulls++;
else
$confWidth += $params[$i];
}
$w = $nulls ? ($this->_pdf->tableWidth - $confWidth) / $nulls : 0;
for ($i = 0; $i < $visibleCols; $i++) {
$widths[] = empty($params[$i]) ? $w : $params[$i];
}
}
else
throw new Exception('El parametro $config[widths] debe ser un array');
return $widths;
}
protected function _formatString($string) {
$string = strtolower(utf8_decode($string));
return ucwords($string);
}
protected function _combineColumns($print = '', $config = array()) {
$default = array(
'from' => 0,
'to' => $this->_visibleColumns - 1,
'border' => 0,
'align' => 'L',
'fill' => $this->_fill,
'ln' => 1,
);
$config = array_merge($default, $config);
$b = $this->$config['border'];
$a = $this->$config['align'];
$f = $this->$config['fill'];
$ln = $this->$config['ln'];
$w = 0;
for ($i = $this->$config['from']; $i <= $this->$config['to']; $i++) {
$w += $this->_columnWidths[$i];
}
$this->_pdf->Cell($w, $this->config['rowHeight'], $print, $b, $ln, $a, $f);
if ($f)
$this->_fill = !$this->_fill;
}
}
this is the generated pdf file.
<?php
$data_provider = $model->viewEmployees($search, $from, $to);
$data_provider->pagination = false;
$this->widget('ext.pdfGrid.EPDFGrid', array(
'id' => 'employee-pdf',
'fileName' => 'Employees',
'dataProvider' => $model->viewEmployees($search, $from, $to),
'columns' => array(
array('name' => 'ID Number','value' => '$data->company_id', 'htmlOptions'=>array('width'=>'10%'),),
array('name' => 'Name', 'header' => 'Name', 'value' => '$data->getNameWithMiddleInitial()', 'htmlOptions' => array('width'=>'10%')),
array('name' => 'Date Employed', 'value' => '$data->date_employed' ,'htmlOptions'=>array('width'=>'10%')),
),
'config' => array(
'title' => 'Sprasia Philippines Information Management System',
'subTitle' => 'List of Employees',
'headerDetails' => true,
'showLogo' => true,
'colAligns' => array('C', 'C', 'C'),
),
));
?>
please help..
so silly of me..
i have found it. in this line..
$this->_pdf->AddPage();
i indicated P for portrait.. in which i have solved it by using this
$this->_pdf->AddPage('P');

Can't find the error behind the undefined index

I have the following code, and i keep getting undefined index error, the code is failing on test5() but i'm unable to find the error.
<?php
function test1() {
$vars = [0, 1, 2, 4, 3];
for ($i = 0; $i < count($vars); $i++) {
print $vars[$i] . "\n";
}
}
function test2() {
$flavors = ['vanilla', 'pistachio', 'banana', 'caramel', 'strawberry'];
$favorite = 'banana';
foreach ($flavors as $key => $flavor) {
if ($flavor === $favorite) {
print $key . "\n";
break;
}
}
}
function test3() {
$stuff = ['shoes', 33, null, false, true];
$selected = 0;
foreach ($stuff as $key => $thing) {
if ($thing == $selected) {
print $key . "\n";
break;
}
}
}
function test4() {
$four = 4;
$five = test4_helper($four);
print "four: $four\n";
print "five: $five\n";
}
function test4_helper(&$arg) {
$return = $arg++;
return $return;
}
function test5() {
$products = [
'Trek Fuel EX 8' => [
'price' => 2000,
'quantity' => 1
],
'Trek Remedy 9' => [
'price' => 2600,
'quantity' => 2
],
'Trek Scratch 8' => [
'price' => 3500,
'quantity' => 1
]
];
$total = 0;
$callback = function ($product, $name) {
//$total = 0;
$tax = 1.2;
$price = $product[$name]['price'];
$total += ($price * $product[$name]['quantity']) * $tax;
return $total;
};
array_walk($products, $callback);
print "$total\n";
}
/* * **********************************
* *** DO NOT EDIT BELOW THIS LINE ****
* *********************************** */
$tests = 5;
for ($i = 1; $i <= $tests; $i++) {
$function = "test$i";
print "\n\n==== Test $i ====\n";
$function();
print "==== END of test $i ====\n <br>";
}
what is the problem with this code?
it looks that it's failing on test 5
PHP closures are not like JavaScript ones in that they do not inherit the parent scope. You need to pass in any dependencies via the use construct. In your example...
$callback = function ($product, $name) use ($total) {
// etc
See http://php.net/manual/functions.anonymous.php#example-166
Arrays in PHP are defined like this:
$products = array(
'Trek Fuel EX 8' => array(
'price' => 2000,
'quantity' => 1
),
'Trek Remedy 9' => array(
'price' => 2600,
'quantity' => 2
),
'Trek Scratch 8' => array(
'price' => 3500,
'quantity' => 1
)
);
Which means you also need to look at $vars = [0, 1, 2, 4, 3]; and $flavors = ['vanilla', 'pistachio', 'banana', 'caramel', 'strawberry']; and fix them too.

Categories