Html2pdf hindi support - pdf

I am using html2pdf in my Yii application to generate Pdf's, This is my code
Some 'Hindi' or 'Tamil' words are need to show in the pdf.
How can I get this?
sample code and generated Pdf are below, it shows either '?' or squares
$html2pdf = Yii::app()->ePdf->HTML2PDF();
$html2pdf = new HTML2PDF('L', 'A4', 'en');
$html2pdf->setDefaultFont('freesans');
$html2pdf->WriteHTML($this->renderPartial('attentancepdf', array(), true));
$html2pdf->Output($batch_name);

<span align="center"><h4><?php echo Yii::t('app','CLASS STUDENT ATTENDANCE'); ?></h4></span>
I have removed the "h4" tag then its worked , I dont know how!?
Also 'b' tag !!
<td width="150"><b><?php echo Yii::t('app','Batch'); ?></b></td>

Related

HtmlPurifier - keeps removing my tables - what is the right config?

I have a table that keeps beeing removed by html purifier
the content is an email that needs to be populated
<table>
<thead>
<th>fieldA</th>
<th>fieldB</th>
<th>fieldC</th>
<th>fieldD</th>
</thead>
<tbody>
<!--[[[order_list]]]-->
</tbody>
</table>
where < ! - - [[[order_list]]] - - > is replaced at runtime, but htmlpurifier keeps removing my table (the comments are there for ckeditor, otherwise it gets removed)
I tried to disable the AutoFormat.RemoveEmpty :
$config = \HTMLPurifier_Config::createDefault();
$config->set('AutoFormat.RemoveEmpty', false);
Validator::$purifier = new \HTMLPurifier($config);
$val=Validator::$purifier->purify($data);
it does not work at all, the table yet gets removed
how can I fix this ?
thanks
[edit: tried this so far...]
$config = \HTMLPurifier_Config::createDefault();
// $config->set('AutoFormat.RemoveEmpty', false);
// ----------------------------------------------- from stackoverflow
$def = $config->getHtmlDefinition(true);
$element = $def->addElement(
'tbody',
false,
'Flow', // <-- here is the change - we're not requiring 'tr' any more
'Common',
[
'align' => 'Enum#left,center,right,justify,char',
'charoff' => 'Length',
'valign' => 'Enum#top,middle,bottom,baseline',
]
);
$config->set('HTML.AllowedComments', array('[[[[order_list]]]'));
Validator::$purifier = new \HTMLPurifier($config);
The problem you're encountering is that tbody cannot be empty by the HTML standard ("Each row group must contain at least one row") (and much of HTML Purifier's security comes from strategically requiring the HTML to be standards-compliant), a comment does not count as content, and it's thus removed. That said, the "living" standard of HTML doesn't require this ("Zero or more tr ..."), so it should be safe to fiddle with.
In any case, you can see HTML Purifier's requirement in the file library/HTMLPurifier/HTMLModule/Tables.php:
$this->addElement('tbody', false, 'Required: tr', 'Common', $cell_align);
If you want to overwrite the way HTML Purifier treats tbody elements, check out the Customize documentation. Your solution would look a little like this (although this example does not cache the HTML definition, you may want to fiddle with yours until yours does):
require_once (__DIR__ . '/library/HTMLPurifier.auto.php');
$dirty_html = '<table>
<thead>
<th>fieldA</th>
<th>fieldB</th>
<th>fieldC</th>
<th>fieldD</th>
</thead>
<tbody>
<!--[[[order_list]]]-->
</tbody>
</table>';
$config = HTMLPurifier_Config::createDefault();
$def = $config->getHtmlDefinition(true);
$element = $def->addElement(
'tbody',
false,
'Flow', // <-- here is the change - we're not requiring 'tr' any more
'Common',
[
'align' => 'Enum#left,center,right,justify,char',
'charoff' => 'Length',
'valign' => 'Enum#top,middle,bottom,baseline',
]
);
$purifier = new HTMLPurifier($config);
$clean_html = $purifier->purify($dirty_html);
This spits out (though I removed the whitespace):
<table><thead></thead><tbody></tbody></table>
If the result still does not seem right to you because thead was emptied out, know that thead was emptied because you have "stray" th tags in it - they're not wrapped by tr. That is required to be standards-compliant even by the "living" standard (as it only permits tr children), but you could of course also change that behaviour by tweaking HTML Purifier if you want. That might have unintended consequences for browser rendering, though, be careful!
That said, this alone will still kill the <!-- [[[order_list]]] --> comment, since HTML Purifier by default disallows all comments for security reasons (there've historically been quite a few browser exploits busting out of HTML comments, although not so much in recent years).
To fix this, you can whitelist the specific comment you want to preserve like this:
...
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.AllowedComments', ['[[[order_list]]]']);
$def = $config->getHtmlDefinition(true);
...
This will spit out (though I again removed the whitespace):
<table><thead></thead><tbody><!--[[[order_list]]]--></tbody></table>

Liferay Dynamic Data Lists: How to get image URL?

I am creating a custom template in velocity for a Dynamic Data Lists and I want to get the image URL for the selected image. How can I get it?
The code is:
#set ( $DDLRecordService = $serviceLocator.findService("com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalService") )
#set ( $records = $DDLRecordService.getRecords($mathTool.toNumber($reserved_record_set_id)) )
#foreach ($record in $records)
#set( $fields = $record.getFields() )
#set( $URL = $fields.get("URL").getValue() )
#set( $Link = $fields.get("Linktitle").getValue() )
#set( $Preview = $fields.get("Vorschaubild").getValue() ) ##the image is here
$URL
$Link
$Preview
#end
The $preview output is: {"groupId":"0000000","uuid":"ccdaccec-00a0-4284-a000-589be48‌​99281","version":"1.‌​0"}
Any suggestion?
Itt will work if you replace UUID_HERE to the real UUID.
<a href='${themeDisplay.getPortalURL()}/c/document_library/get_file?uuid=UUID_HERE&groupId=${themeDisplay.getScopeGroupId()}'>MyFile OR Image</a>
I also came across similar situation and after searching on the internet for hour(s), didn't find any useful information apart from LPS-34792 ticket.
Well, you can render image on the UI from a Documents and Media field using:
<#assign hasPicture = cur_record.getFieldValue("picture")?has_content>
<#if hasPicture>
<#assign picture = jsonFactoryUtil.createJSONObject(cur_record.getFieldValue("picture"))>
<img src='/documents/${picture.getString("groupId")}/${picture.getString("uuid")}' />
</#if>
Where picture is the name of field and hasPicture will check if the image was selected.

UTF-8 characters are disappeared after Zend Form render

I use Zend Framework 2 and have this code in my view script. Name and description are Russian strings:
$brand = $form->get('brand');
$id = $brand->get('id');
$name = $brand->get('name');
$type = $brand->get('type');
$description = $brand->get('description');
\Zend\Debug\Debug::dump($name->getValue()); //correctly dumps russian letters
\Zend\Debug\Debug::dump($this->formText()->getEncoding()); //UTF-8 (by default)
But when I'm trying to render these elements, I have empty input and textarea:
<?= $this->formText($name) ?>
<?= $this->formTextarea($description) ?>
I've found, that Zend\Form\View\Helper\AbstractHelper do the following code:
$strings[] = sprintf('%s="%s"', $escape($key), $escape($value));
after which russian letters disappear. But I still have no idea how to fix this.

Yii: How to work with translate Yii::t() and hyperlinks

I have many lines similar to this in my code:
echo Yii::t('forms','Would you like to create a new item?');
where I want to hyperlink just around "create a new item", as an example.
Here are some alternatives that I've thought about:
Split the URL into 2 translated strings, surrounded by a hyperlink:
echo Yii::t('forms','Would you like to').' '.Yii::t('forms','create a new item').'?';
Use placeholders, as described in the Yii documentation ( http://www.yiiframework.com/doc/guide/1.1/en/topics.i18n Although hyperlinks aren't given as an explicit example):
echo Yii::t('forms','Would you like to {url}create a new item',array('{url}'=>"<a href='/new_item'>")).'</a>?';
There's probably an easier way to do this, but I've been unable to discover the preferred method...what's the best way to build translated strings that include URLs?
I suggest to you this solution:
echo Yii::t(
'forms',
'Would you like to {link:create}create a new item{/link}?',
array(
'{link:create}'=>'<a href="/new_item">',
'{/link}'=>'</a>',
)
);
The benefit is if you want put id, class, onclick and more anything in a tag you can do it. and so the translate string in clear.
Note that create in {link:create} is just a ideal string that pointer to hyperlink string.
Another advanced sample:
echo Yii::t(
'forms',
'Would you like to {link:create}create a new item{/link}? And you can {link:delete}delete the item{/link}.',
array(
'{link:create}'=>'<a href="/new_item" class="button">',
'{link:delete}'=>'<a href="#" id="item-21" onclick="delete(21);">',
'{/link}'=>'</a>',
)
);
The link may have different placement (beginning, middle or end) and label in the translated string depending on a target language. Therefore, you should use placeholder only for url:
echo Yii::t(
'forms',
'Would you like to create a new item?',
array('{url}' => '/new_item')
);
Use following if you have a dynamic uri:
echo Yii::t(
'forms',
'Would you like to create a new item?',
array(':url'=>'/new_item')
);
Or:
echo Yii::t(
'forms',
'Would you like to create a new item?',
);
Or if you want to pass other dynamic attributes other than the url, use the following:
echo Yii::t(
'forms',
'Would you like to <a :linkAttr>create a new item?</a>',
array('linkAttr'=>'href="/new_item" id="link-id" class="link-class"')
);
I think this is a better solution:
echo Yii::t(
'forms',
'Would you like to {action}?'
[
'action' => Html::a(
Yii::t('forms', 'create a new item'),
['controller/action']
)
]
);
Benefits of this solution
You can use helpers to generate your link
You can modify your html code without modifing the translations
Whoever will be doing translations doesn't need to know anything about html and they can't mess the html code.

Youtube api get latest upload thumbnail

I am looking to returning the video-thumbnail of the latest uploaded video from my channel, and display it on my website.
Anyone know how I can do a minimal connection trough api and get only the thumbnail?
Thanks!
-Tom
REVISED!!
Using Cakephp, this is how I did it (thanks dave for suggestions using zend);
controller:
App::import('Xml');
$channel = 'Blanktv';
$url = 'https://gdata.youtube.com/feeds/api/users/'.$channel.'/uploads?v=2&max-results=1&orderby=published';
$parsed_xml =& new XML($url);
$parsed_xml = Set::reverse($parsed_xml);
//debug($parsed_xml);
$this->set('parsed_xml',$parsed_xml);
View;
$i=0;
foreach ($parsed_xml as $entry)
{
echo '<a href="/videokanalen" target="_self">
<img width="220px" src="'.$entry['Entry']['Group']['Thumbnail'][1]['url'] .'">
</a>';
}
Now the only thing remaining is to cache the feed call someway.. Any suggestions???
-Tom
here is a quick dirty way of doing it without really touching the api at all.
I'm not suggesting it's best practice or anything and I'm sure there are smarter ways but it definitely works with the current Youtube feed service.
My solution is PHP using the Zend_Feed_Reader component from Zend Framework, if you need a hand setting this up if you're not familiar with it let me know.
Essentially you can download version 1.11 from Zend.com here and then make sure the framework files are accessible on your PHP include path.
If you are already using Zend Framework in an MVC pattern you can do this in your chosen controller action:
$channel = 'Blanktv'; //change this to your channel name
$url = 'https://gdata.youtube.com/feeds/api/users/'.$channel.'/uploads';
$feed = Zend_Feed_Reader::import($url);
$this->view->feed = $feed;
Then you can do this in your view:
<h1>Latest Video</h1>
<div>
<?php
$i=0;
foreach ($this->feed as $entry)
{
$urlChop = explode ('http://gdata.youtube.com/feeds/api/videos/',$entry->getId());
$videoId = end($urlChop);
echo '<h3>' . $entry->getTitle() . '</h3>';
echo '<p>Uploaded on: '. $entry->getDateCreated() .'</p>';
echo '<a href="http://www.youtube.com/watch?v=' . $videoId .'" target="_blank">
<img src="http://img.youtube.com/vi/' . $videoId .'/hqdefault.jpg">
</a>';
$i++;
if($i==1) break;
}
?>
</div>
otherwise you can do:
<?php
$channel = 'Blanktv'; //change this to your channel
$url = 'https://gdata.youtube.com/feeds/api/users/'.$channel.'/uploads';
$feed = Zend_Feed_Reader::import($url);
?>
<h1>Latest Video</h1>
<div>
<?php
$i=0;
foreach ($feed as $entry)
{
$urlChop = explode ('http://gdata.youtube.com/feeds/api/videos/',$entry->getId());
$videoId = end($urlChop);
echo '<h3>' . $entry->getTitle() . '</h3>';
echo '<p>Uploaded on: '. $entry->getDateCreated() .'</p>';
echo '<a href="http://www.youtube.com/watch?v=' . $videoId .'" target="_blank">
<img src="http://img.youtube.com/vi/' . $videoId .'/hqdefault.jpg">
</a>';
$i++;
if($i==1) break;
}
?>
</div>
With the latter method you'll likely need to use a php require statement for the Zend_Feed_Reader files etc....
Hope this helps, like I say let me know if you need a hand.
All the best,
Dave
UPDATE: In response to your comments about caching
Hi Tom, here is another quick and dirty solution which doesn't use cache but may be very quick to implement.
The reason I didn't go with a caching component is because I figured a simple db solution would suffice under the circumstances. I also thought having to pull the feed to compare whether it was new or not wouldn't be the most economical for you.
You could automate this process to be run automatically at specified times but if you don't want to automate the process and don't mind clicking a link to update the video manually you could trigger it that way.
My solution is again based on ZF but since you were ok hacking it into something useful with cakephp you should have no problem doing the same here.
First set up a new table (assuming a MySQL db):
CREATE TABLE `yourdbname`.`latestvid` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'Unique identifier',
`videoId` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Video id',
`videoTitle` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Video title',
`uploadDate` VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'Video upload date'
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO `yourdbname`.`latestvid` (`id`, `videoId`, `videoTitle`, `uploadDate`) VALUES (NULL, '--', '--', '--');
This will create a table for your latest video info for use in your template however the default values I've set up will not work with your template for obvious reasons.
You could then do something similar to this:
public function updateAction()
{
$this->_helper->viewRenderer->setNoRender(); // disable view
$this->_helper->layout()->disableLayout(); // disable layout
$user = 'Blanktv'; // insert your channel name
$url = 'https://gdata.youtube.com/feeds/api/users/'.$user.'/uploads';
$feed = Zend_Feed_Reader::import($url);
if(!$feed)
{
die("couldn't access the feed"); // Note: the Zend component will display an error if the feed is not available so this wouldn't really be necessary for ZF
}
else
{
$i=0;
foreach ($feed as $entry)
{
$urlChop = explode ('http://gdata.youtube.com/feeds/api/videos/',$entry->getId());
$videoId = end($urlChop);
$videoTitle = $entry->getTitle();
$uploadDate = $entry->getDateCreated();
// use your preferred method to update the db record where the id = 1
$i++;
if($i==1) break;
}
}
}
Maybe have a go and let me know how you get on?
You'd just need to tweak the template so you'd get the variables from the database instead of Youtube with the exception of the thumbnail.
I suppose you could always take that approach further and actually store images etc since the thumbnail is still being pulled from Youtube and may slow things down.
You could set up a script to copy the thumbnail to your own server and store the path in the db or use a standard thumbnail if you are running a series of videos for which you require standard branding - anyway hope it helps.
:-D
Dave