When importing and modifying a PDF file inside a Joomla component using the FPDF and FPDI libraries, after sending the file to the browser, the PDF viewer claims the XREFS table to be broken.
Here's part of what I have:
<?php
...
use \setasign\Fpdi\Fpdi;
include "fpdf/fpdf.php";
include "fpdi2/src/autoload.php";
class MycompoViewMycompo extends JViewLegacy
{
protected $pdf;
function display($tpl = null) {
...
$this->pdf = new Fpdi();
$this->pdf->AddPage();
$this->pdf->setSourceFile('components/com_mycompo/views/mycompo/template.pdf');
$tplIdx = $this->pdf->importPage(1);
$this->pdf->useImportedPage($tplIdx, 0, 0, null, null, true);
$this->pdf->SetFont('Arial', '', 13);
$this->pdf->SetTextColor(0, 0, 0);
$this->pdf->SetXY(175, 49);
$pdf->Cell(0, 0, 'some Text', 0, 0, 'R');
// This actually happens in the layout...
// But I'd like to simplify here
$doc =& JFactory::getDocument();
$doc->setMimeEncoding('application/pdf');
$this->pdf->Output('gift_coupon_generated.pdf', 'D', true);
}
...
}
?>
The document is sent to the browser.
It also can be downloaded and opened by a PDF viewer (I use PDF Exchange Editor).
All the file's conents seem to be correct. No visible problems.
But a warning is shown that the XREFS table is broken.
(The exact message reads like "One or more XREF data streams were not found". I don't know the exact English message, as I use a different language version)
When working with the same code OUTSIDE of Joomla (i. e. in a standard PHP environment and a simple php web page), the file is also created perfectly fine and this error is not shown.
Any ideas on what might be the reason for this error message?
Or how I could debug it further?
Or is using FPDF/FPDI not supported with Joomla?
Please find the generated file here: https://file.re/2021/10/16/banktransferform/
Best regards
Tom
Related
if anybody konws this,please help me.how to give name to pdf.
i generated pdf using mpdf codeigniter. on click of a button the pdf wil be viewed. but how can give name for that pdf? it shows 1 on the top of the pdf.how can i give name to that pdf?
My controller
public function viewpdf($key,$option) {
if($option=='1')
{
$searchdata['fetchproduct']=$this->b2bproduct_model->fetch_productdata1($key);
}
if($option=='2')
{
$searchdata['fetchproduct']=$this->b2bproduct_model->fetch_productdata2($key);
}
if($option=='3')
{
$searchdata['fetchproduct']=$this->b2bproduct_model->fetch_productdata3($key);
}
$html=$this->load->view('moderator/pdf_data', $searchdata,true);
//this the the PDF filename that user will get to download
$pdfFilePath = "shany.pdf";
//load mPDF library
$this->load->library('m_pdf');
//generate the PDF from the given html
$this->m_pdf->pdf->WriteHTML($html);
//download it.
$this->m_pdf->pdf->Output($pdfFilePath, "I");
}
Use this code.
$mpdf=new mPDF();
$mpdf->SetTitle('My Title');
$mpdf->WriteHTML('<p>Hallo World</p>');
$mpdf->Output('filename.pdf');
Set the title for the document. The title is displayed at the top of the Adobe Reader screen when viewing the PDF file
Use code as bellow
public function mypdf() {
$this->load->library('pdf');
$pdf = $this->pdf->load();
$html=$this->load->view('welcome_message',null,true);
$pdf->WriteHTML($html);
// write the HTML into the PDF
$output = 'your_given_name.pdf'; //You can give a name of your generated pdf file or you can create it auto on timestamp by using $output = time().'.pdf'.
$pdf->Output("$output", 'I');
}
If you send data to view page then replace the variable with null in line 4.
For more details please see the tutorial from here.
If you are interested on DOMPDF please see from here.
Need some help with images.
As the topic says, I want to create an image with live updating text on it.
This is mainly used by game servers and players to show off their stats and info. Server-wise, to show if the server is online and how many players are online and such.
I haven no idea how to do it and figured this would be the best place to find out. Since I don't have any idea what this is even called, i did not know what to search for.
Thanx in advance.
This is an html+css+ajax solution. Make the image an html element's background image. Let's use a div. Then position the text in the div. Use ajax to update the text. The image will remain the same while the text can be updated.
Was possible with the use of API. Created an API of the database I want to use, connected to the database and everything worked!
After using $API_GET to get the data, I set it into an array-format.
Used PHP for everything.
From there on I used imagecreatefrompng, obviously to select an image.
Set a few colors using imagecolorallocate and from there on it was purely adding the text on the image as to where I want them using imagettftext.
Creating an image, with live updating stats on it.
But we still have to tell the browser to load it as an image and not a page with an image on it, so therefor...
header( "Content-type: image/png" );
And imagesetthickness to 5, followed by imagepng and imagedestroy.
Code Extracts:
$API_GET = file_get_contents("API URL");
$API_GET = json_decode($API_GET);
$API = array();
foreach ($API_GET as $key => $value) {
$API[$key] = $value;
}
if (file_exists($imagefile)) {
$bg_img = imagecreatefrompng ( "IMAGE URL");
$color_red = imagecolorallocate( $bg_img, 250, 0, 0 );
imagettftext($bg_img, 20, 0, 19, 36, $color_red, 'FONT URL.tff',"Text On Image");
imagesetthickness ( $my_img, 5 );
header( "Content-type: image/png" );
imagepng( $my_img );
imagedestroy( $my_img );
} else {
echo 'Image does not exist.';
}
That is the basic structure of the code.
Thank You for your reply to the question.
This is code from the Dizi-images module (plugin/content/images/images.php) for Joomla. This works, it publishes a image or image gallery at the end of a specific article.
But if I want to publish the image/image gallery to another position (by changing its position in Joomla admin and the getModules-value in the code below) it looses its "connection" to the article. It shows up on every article on the site.
Is it possible to make this code below to be able to publish the image/image gallery to another position without loosing its connection to the specific article?
/*
* load front end images module
*/
public function onContentAfterDisplay( $context, &$row, &$params, $limitstart = null )
{
$jinput = JFactory::getApplication()->input;
$option = $jinput->get('option', '', '');
$view = $jinput->get('view', '', '');
if( $context == 'com_content.article' && ( $modules = JModuleHelper::getModules( 'images' ) ) )
{
return JModuleHelper::renderModule( $modules[ 0 ] );
}
return '';
}
Thanks
Magnus
Screenshot of the modules that I change position on (Joomla Admin/Extensions/Module Manager/)
The plug-in I use is "Dizi images gallery"-extension.
This shows the Dizi-images Tab. Where you add images/image gallery to the article your in.
These three lines of code will allow you load and render any existing modules as needed.
jimport( 'joomla.application.module.helper' );
$module = JModuleHelper::getModule('mod_myimagemodulename', 'Images Gallery');
echo JModuleHelper::renderModule($module, array('style' => 'xhtml'));
If you want to manage from the back end, you will need to make a duplicate of the existing module with different menu position assignments. It sounds like the only limitation is the source images folder, so the module should not mind!
** EDIT **
To create a new position like "right", you would need to add a new jdoc element to your templates index.php where you would like the new position:
<jdoc:include type="moduels" name="right" style="xhtml" />
Then in your templates manifest XML file, add the new position to list of existing positions:
<position>right</position>
Now if you navigate to the module copy you want to place there, you would be able to select the newly created "right" position.
** EDIT **
Noticed something in how the module instance is being loaded, the name should reflect the the module type and name.
$modules = JModuleHelper::getModules( 'images', 'Images gallery' )
And definitely migrate away from JRequest.
Why not just create a new instance of the module for the other position? That way this module stays just as it is and the new module is published elsewhere without conflicting with the code you have.
Also agree with Lodder, use JInput.
var currentDialog = CKEDITOR.dialog.getCurrent();
currentDialog._.editor.insertHtml("<customTag myAttr='var'></customTag>");
Throws an error, TypeError: Cannot read property 'isBlock' of undefined
If I try .insertHtml("<span>hello</span>") it works just fine.
How can I change ckeditor to allow me to specify my own custom html tags via .insertHtml()? I'd love to just change it to be something like <span class='custom'... or something like that, but I'm having to deal with legacy CMS articles. Using latest ckeditor. Thanks.
You need to modify CKEDITOR.dtd object so editor will know this tag and correctly parse HTML and process DOM:
CKEDITOR.dtd.customtag = { em:1 }; // List of tag names it can contain.
CKEDITOR.dtd.$block.customtag = 1; // Choose $block or $inline.
CKEDITOR.dtd.body.customtag = 1; // Body may contain customtag.
You need to allow for this tag and its styles/attrs/classes in Advanced Content Filter:
editor.filter.allow( 'customtag[myattr]', 'myfeature' );
Unfortunately, due to some caching, in certain situations you cannot modify DTD object after CKEditor is loaded - you need to modify it when it is created. So to do that:
Clone the CKEditor repository or CKEditor presets repository.
Modify core/dtd.js code.
And build your minified package following instructions in README.md - the only requirements are Java (sorry - Google Closure Compiler :P) and Bash.
PS. That error should not be thrown when unknown element is inserted, so I reported http://dev.ckeditor.com/ticket/10339 and to solve this inconvenience http://dev.ckeditor.com/ticket/10340.
I worked around this issue with a combination of createFromHtml() and insertElement()
CKEDITOR.replace('summary', { ... });
var editor = CKEDITOR.instances.summary;
editor.on('key', function(ev) {
if (ev.data.keyCode == 9) { // TAB
var tabHtml = '<span style="white-space:pre"> </span>';
var tabElement = CKEDITOR.dom.element.createFromHtml(tabHtml, editor.document);
editor.insertElement(tabElement);
}
}
I have recently asked where global stylesheets are for editing Cognos 10 styles (Here).
After some discussions with our team we would like to find the CGI or base imported file that Cognos uses to construct it's report viewer pages and dashboard widget holders.
The reason we want to do this is so that we can include all our custom style and javascript in one location. When/If we upgrade Cognos we can be sure of one point of failure with our reports. This would solve our problem of having to re-edit multiple stylesheets (and javascript).
I'm normally familiar with ASP.NET and not CGI-BIN. Is there something akin to a Master page where styles and basic imports are done for a Cognos page? Ideally editing this file would allow us to continue our customizations.
Can this be done? Or are we just insane? We understand the risks concerning upgrades, but are OK with the risks (unless someone can provide a good example of how this technique would not be replicated via version changes).
I think it's fairly common that BI professionals with more traditional web development backgrounds like me and you have no qualms with making changes to the global CSS files and bringing in more JS.
I've explained to you how I run JS in a report - I'd love to add jQuery to our global libraries, but I haven't drummed up enough support for it yet. I can help with the CSS portion though.
In 8.4.1, there's a ton of CSS files referenced by the report viewer. If I were you, I'd render a sample report with the default styling and use Firebug or similar to trace the CSS files being called. You'll find that server/cognos8/schemas/GlobalReportStyles.css is commonly referenced, with some help from server/cognos8/skins/corporate/viewer/QSRVCommon.css - there's also some other files in there that are imported.
I'd imagine you could grep -R '<link rel=\"stylesheet\" type=\"text/css\" href=\"../schemas/GlobalReportStyles.css\"> in the COGNOS directory to see where the file is being called, and either edit that file directly, or create a link to your own JS. Personally, I'd just backup the existing stylesheet and modify the one that is already there.
I'd imagine you could do something similar for the JS - find where it's being called in the template (using grep) and just create a new reference to the file you'd like to create. In my case, I'd do a backflip if I could get jQuery loaded into every report.
Just realized this is a year old. :-( Sorry, first time here. I'll leave it in case anyone is still interested in the topic.
Here is the documentation on customizing Cognos on several levels:
We used an alternative to modifying the system files. We have a shared component "report" containing an HTML object with our particular CSS overrides on it, and/or a link to a custom stylesheet. We then add this on each report with a "Layout Component Reference" from the toolbox. If we want a global change, just change the one item in the component report or custom stylesheet. This works very well for us.
I up-voted both the previous answers to this question. I'll admit I kind of forgot about this question till someone put some activity on it.
We ended up doing a combination of the above techniques. I was able to find the global stylesheets as suggested. What I ended up doing was copying out all the styles that were in that stylesheet and created a new sheet suffixed with *_SystemSytles.css*. I created a second sheet and suffixed it with *_Custom.css*. Then in the original sheet I placed two imports, first importing the system styles and then the custom styles.
For certain reports we have a custom object that is dropped on that brings in its own styles (and JavaScript). This utilizes a similar technique to the second question.
However, what I had to do for import the JavaScript for general use within the entire Cognos site was difficult.
In the core webcontent folder I created a js folder that contained the jQuery and our custom JavaScript files. Then in a series of JavaScript files I included code similar to the following:
/************************
JQUERY UTIL INCLUDE
************************/
function loadjscssfile(filename, filetype, id) {
if (filetype == "js") { //if filename is a external JavaScript file
var fileref = document.createElement('script')
fileref.setAttribute("type", "text/javascript")
fileref.setAttribute("src", filename)
if (id)
fileref.setAttribute("OurCompanyNameAsAnID", id)
}
else if (filetype == "css") { //if filename is an external CSS file
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref != "undefined") {
var headTag = document.head || document.getElementsByTagName('head')[0];
headTag.appendChild(fileref);
}
}
function _PortalLoadJS() {
if (!window._PortalScriptsLoaded) {
var pathParams = [];
var path = location.href;
(function () {
var e,
r = /([^/]+)[/]?/g,
p = path;
while (e = r.exec(p)) {
pathParams.push(e[1]);
}
})();
var baseURL = location.protocol + '//';
for(var i = 1; i < pathParams.length; i++) {
if(pathParams[i] == 'cgi-bin')
break;
baseURL += pathParams[i] + '/';
}
loadjscssfile(baseURL + "js/jquery-1.6.1.min.js", "js");
loadjscssfile(baseURL + "js/Custom.js?pageType=COGNOS_CONNECTION", "js", "SumTotalUtil");
window._PortalScriptsLoaded = true;
}
}
if(!window.$CustomGlobal) {
window.$CustomGlobal= function(func) {
if (!window.$A) {
if (!window.__CustomExecStack) {
window.__CustomExecStack= new Array();
}
window.__CustomExecStack.push(func);
}
else
$A._executeCustomItem(func);
}
}
try {
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if (document.readyState === "complete") {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout(_PortalLoadJS, 10);
}
// Mozilla, Opera and webkit nightlies currently support this event
if (document.addEventListener) {
// Use the handy event callback
document.addEventListener("DOMContentLoaded", function() { _PortalLoadJS(); }, false);
// A fallback to window.onload, that will always work
window.addEventListener("load", _PortalLoadJS, false);
// If IE event model is used
} else if (document.attachEvent) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", function() { _PortalLoadJS(); });
// A fallback to window.onload, that will always work
window.attachEvent("onload", _PortalLoadJS);
}
}
catch (ex) { }
The $A item is an item that I create when the Custom.js file is loaded.
Here are the list of files that I've included this code (at the vary end of the JavaScript):
webcontent\icd\bux\js\bux\bux.core.js
webcontent\ps\portal\js\cc.js
webcontent\rv\CCognosViewer.js
webcontent\rv\GUtil.js
webcontent\rv\viewer.standalone.core.js
These files should cover the Cognos Connection, Report Viewer, and the Dashboards area. If any more are found please let me know and I can update this list.
When linking to the Custom.js file I put a query string on the external resource that the Custom.js file picks up: pageType=COGNOS_CONNECTION. This allows me to do specific load code for the Cognos Connection, Report Viewer, or the Dashboards.
Here is the code in the Custom.js class that inits the $A object:
function _CustomUtilInit() {
try {
if (!window.$j) {
window.setTimeout(_CustomUtilInit, 1);
return;
}
var jScriptTags = $j('SCRIPT[' + Analytics.SCRIPT_ATTR_NAME + '= ' + Analytics.SCRIPT_ATTR_VALUE + ']');
jScriptTags.each( function(i, scriptElem) {
var tag = $j(scriptElem);
if(tag.attr(Analytics.LOADED_SCRIPT_KEY))
return;
var scriptURL = new URI(tag.attr('src'));
var analyticsPageType = scriptURL.getQueryStringValue(Analytics.PAGE_TYPE_QUERY_KEY, Analytics.PageType.REPORT_VIEWER);
if(!window.$A) {
window.$A = new Analytics();
}
window.$A.init(analyticsPageType);
tag.attr(Analytics.LOADED_SCRIPT_KEY, 'true');
});
} catch (e) {
}
}
_CustomUtilInit();
Of course this expects that the jQuery libraries were included before the Custom.js files in each of the previously mentioned JavaScript files.
The URI class is something that I've found on the internet and tweaked for our use. If you have any questions regarding the custom JavaScript loading please leave a comment and I'll do my best to elaborate some more.