TCPDF and database: conflicts in PHP - tcpdf

Hi this my php code :
<?php require_once('tcpdf/config/lang/eng.php'); ?>
<?php require_once('tcpdf/tcpdf.php'); ?>
<?php include_once("class/class_productos.php"); ?>
<?php include_once("class/class_clientes.php"); ?>
<?php include_once("class/class_img_gen.php"); ?>
<?php include_once("class/class_acros.php"); ?> // here is MY DB CONNECTION
<?php
class MYPDF extends TCPDF {
//Page header
public function Header() {
$auto_page_break = $this->AutoPageBreak;
$this->SetAutoPageBreak(false, 0);
$img_file = 'img/pdf_fondo.jpg';
$this->Image($img_file, $x=0, $y=0, $w=210, $h=297, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0);
$this->SetAutoPageBreak($auto_page_break);
}
}
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator('ACROS');
$pdf->SetAuthor('ACROS');
$pdf->SetTitle('Lista de producto');
$pdf->SetSubject('Lista de producto');
$pdf->SetKeywords('ACROS, acros, mayorista, informática');
$pdf->setPrintHeader(true);
$pdf->setPrintFooter(false);
$pdf->SetMargins(0, 0, 0);
$pdf->SetAutoPageBreak(FALSE, PDF_MARGIN_BOTTOM);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->setLanguageArray($l);
$pdf->AddPage();
$category = $_GET['c'];
$getCategory = "SELECT * FROM prod_detalle WHERE fk_marca = '$category'";
$getCategory = mysql_query($getCategory);
$count = mysql_num_rows($getCategory);
$txt = "result ".$count;
// output the HTML content
$pdf->writeHTML($txt, true, 0, true, 0);
$pdf->SetY(-30);
$pdf->SetX(0.65);
$pdf->MultiCell(20, 0, $txtB, $border = 0,$align = 'L',$fill = 0,$ln = 1,$x = '',$y = '',$reseth = false, $stretch = 0, $ishtml = true, $autopadding = false, $maxh = 0);
$pdf->Output('lista.pdf', 'I');
?>
and i'm getting this two warnings :
Warning: mysql_num_rows() expects parameter 1 to be resource, boolean
given in /mnt/futurehome/netlogiq/public_html/acros/lista_pdf.php on
line 64
Warning: Cannot modify header information - headers already sent by
(output started at
/mnt/futurehome/netlogiq/public_html/acros/lista_pdf.php:64) in
/mnt/futurehome/netlogiq/public_html/acros/tcpdf/tcpdf.php on line
5405 TCPDF ERROR: Some data has already been output to browser, can't
send PDF file
Can anyone help me with this ?? If run the query in phpmyadmin, it returns the wanted data. So the query works fine !

The reason you are getting the error from mysql_num_rows() is because you haven't initialized the connection to the database. You are also using the old (and deprecated as og PHP 5.5) MySQL interface - you should look into using mysqli or PDO instead.
A full explanation of how to initialize the connection to the database and communicate with it using the correct resource handle is, IMO, beyond the scope of an SO answer. Maybe start here instead:
http://www.php.net/manual/en/mysqli.quickstart.connections.php
The reason you're getting the second error is simply because the first error message is being sent to the browser before your call to $pdf->Output(). Once you get your database connection working and remove the error messages that problem will go away.

Just remove the line
require_once('tcpdf/config/lang/eng.php');
and
edit the tcpdf.php file from the tcpdf folder:
add the line ob_end_clean(); as below (3rd last line):
public function Output($name='doc.pdf', $dest='I') {
//LOTS OF CODE HERE....}
switch($dest) {
case 'I': {
// Send PDF to the standard output
if (ob_get_contents()) {
$this->Error('Some data has already been output, can\'t send PDF file');}
//some code here....}
case 'D': { // download PDF as file
if (ob_get_contents()) {
$this->Error('Some data has already been output, can\'t send PDF file');}
break;}
case 'F':
case 'FI':
case 'FD': {
// save PDF to a local file
//LOTS OF CODE HERE..... break;}
case 'E': {
// return PDF as base64 mime email attachment)
case 'S': {
// returns PDF as a string
return $this->getBuffer();
}
default: {
$this->Error('Incorrect output destination: '.$dest);
}
}
ob_end_clean(); //add this line here
return '';
}

Related

Unable to print error message in foreach in magento admin

Hi i have added a new mas action in the sales order grid which allow create batch invoices.
For this my controler file is
<?php
class Iclp_Batchupdate_IndexController extends Mage_Adminhtml_Controller_Action
public function batchinvoiceAction ()
{
$already = " already ";
$refererUrl = $this->getRequest()->getServer('HTTP_REFERER');
$this->loadLayout();
$this->renderLayout();
$orderIds = explode(",",$this->getRequest()->getParam('order_ids'));
foreach ($orderIds as $orderIdss) {
$order = Mage::getModel('sales/order')->load($orderIdss);
//echo $orderIdss ."<br/>";
//echo "already ".$order->getStatusLabel();
try
{
if(!$order->canInvoice())
{
echo Mage::getSingleton('core/session')->addError($orderIdss.$already.$order->getStatusLabel());
}
$invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
if (!$invoice->getTotalQty()) {
Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
}
$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_ONLINE);
$invoice->register();
$transactionSave = Mage::getModel('core/resource_transaction')->addObject($invoice)->addObject($invoice->getOrder());
$transactionSave->save();
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true)->save();
//echo "Invoice are created";
}
catch (Mage_Core_Exception $e) {
}
}
//A Success Message
Mage::getSingleton('core/session')->addSuccess("Some success message");
//A Error Message
Mage::getSingleton('core/session')->addError("Some error message");
//A Info Message (See link below)
Mage::getSingleton('core/session')->addNotice("This is just a FYI message...");
//These lines are required to get it to work
session_write_close();
$this->getResponse()->setRedirect($refererUrl);
}
}
every thing is working fine but the problem is it is not printing the error message in foreach in above code
if(!$order->canInvoice())
{
echo Mage::getSingleton('core/session')->addError($orderIdss.$already.$order->getStatusLabel());
}
but the bottom error message are displayed properly. MOreover if i extend the class with front-action than it also prints the foreach messages. Please suggest where i am doing the mistake
You should add your errors and messages to admintml/session and not to core/session when you are in adminhtml. That should display the message correctly. You shouldn't need session_write_close();. There is also no need to echo the message, that should be handled automatically by Magento after the redirect.
There is also no need to call $this->loadLayout(); and $this->renderLayout(); because you are redirecting at the end.
Finally, regarding the redirect, you should not read the referrer yourself, Magento can to that for you more reliably. Just use the $this->_redirectReferer(); method instead of $this->getResponse()->setRedirect($refererUrl);.

How to test file download in Behat

There is this new Export functionality developed on this application and I'm trying to test it using Behat/Mink.
The issue here is when I click on the export link, the data on the page gets exported in to a CSV and gets saved under /Downloads but I don't see any response code or anything on the page.
Is there a way I can export the CSV and navigate to the /Downloads folder to verify the file?
Assuming you are using the Selenium driver you could "click" on the link and $this->getSession()->wait(30) until the download is finished and then check the Downloads folder for the file.
That would be the simplest solution. Alternatively you can use a proxy, like BrowserMob, to watch all requests and then verify the response code. But that would be a really painful path for that alone.
The simplest way to check that the file is downloaded would be to define another step with a basic assertion.
/**
* #Then /^the file ".+" should be downloaded$/
*/
public function assertFileDownloaded($filename)
{
if (!file_exists('/download/dir/' . $filename)) {
throw new Exception();
}
}
This might be problematic in situations when you download a file with the same name and the browser saves it under a different name. As a solution you can add a #BeforeScenario hook to clear the list of the know files.
Another issue would be the download dir itself – it might be different for other users / machines. To fix that you could pass the download dir in your behat.yml as a argument to the context constructor, read the docs for that.
But the best approach would be to pass the configuration to the Selenium specifying the download dir to ensure it's always clear and you know exactly where to search. I am not certain how to do that, but from the quick googling it seems to be possible.
Checkout this blog: https://www.jverdeyen.be/php/behat-file-downloads/
The basic idea is to copy the current session and do the request with Guzzle. After that you can check the response any way you like.
class FeatureContext extends \Behat\Behat\Context\BehatContext {
/**
* #When /^I try to download "([^"]*)"$/
*/
public function iTryToDownload($url)
{
$cookies = $this->getSession()->getDriver()->getWebDriverSession()->getCookie('PHPSESSID');
$cookie = new \Guzzle\Plugin\Cookie\Cookie();
$cookie->setName($cookies[0]['name']);
$cookie->setValue($cookies[0]['value']);
$cookie->setDomain($cookies[0]['domain']);
$jar = new \Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar();
$jar->add($cookie);
$client = new \Guzzle\Http\Client($this->getSession()->getCurrentUrl());
$client->addSubscriber(new \Guzzle\Plugin\Cookie\CookiePlugin($jar));
$request = $client->get($url);
$this->response = $request->send();
}
/**
* #Then /^I should see response status code "([^"]*)"$/
*/
public function iShouldSeeResponseStatusCode($statusCode)
{
$responseStatusCode = $this->response->getStatusCode();
if (!$responseStatusCode == intval($statusCode)) {
throw new \Exception(sprintf("Did not see response status code %s, but %s.", $statusCode, $responseStatusCode));
}
}
/**
* #Then /^I should see in the header "([^"]*)":"([^"]*)"$/
*/
public function iShouldSeeInTheHeader($header, $value)
{
$headers = $this->response->getHeaders();
if ($headers->get($header) != $value) {
throw new \Exception(sprintf("Did not see %s with value %s.", $header, $value));
}
}
}
Little modified iTryToDownload() function with using all cookies:
public function iTryToDownload($link) {
$elt = $this->getSession()->getPage()->findLink($link);
if($elt) {
$value = $elt->getAttribute('href');
$driver = $this->getSession()->getDriver();
if ($driver instanceof \Behat\Mink\Driver\Selenium2Driver) {
$ds = $driver->getWebDriverSession();
$cookies = $ds->getAllCookies();
} else {
throw new \InvalidArgumentException('Not Selenium2Driver');
}
$jar = new \Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar();
for ($i = 0; $i < count($cookies); $i++) {
$cookie = new \Guzzle\Plugin\Cookie\Cookie();
$cookie->setName($cookies[$i]['name']);
$cookie->setValue($cookies[$i]['value']);
$cookie->setDomain($cookies[$i]['domain']);
$jar->add($cookie);
}
$client = new \Guzzle\Http\Client($this->getSession()->getCurrentUrl());
$client->addSubscriber(new \Guzzle\Plugin\Cookie\CookiePlugin($jar));
$request = $client->get($value);
$this->response = $request->send();
} else {
throw new \InvalidArgumentException(sprintf('Could not evaluate: "%s"', $link));
}
}
In project we have problem that we have two servers: one with web drivers and browsers and second with selenium hub. As result we decide to use curl request for fetching headers. So I wrote function which would called in step definition. Below you can find a function which use a standard php functions: curl_init()
/**
* #param $request_url
* #param $userToken
* #return bool
* #throws Exception
*/
private function makeCurlRequestForDownloadCSV($request_url, $userToken)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = [
'Content-Type: application/json',
"Authorization: Bearer {$userToken}"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
$output .= "\n" . curl_error($ch);
curl_close($ch);
if ($output === false || $info['http_code'] != 200 || $info['content_type'] != "text/csv; charset=UTF-8") {
$output = "No cURL data returned for $request_url [" . $info['http_code'] . "]";
throw new Exception($output);
} else {
return true;
}
}
How you can see I have authorization by token. If you want to understand what headers you should use you should download file manual and look request and response in browser's tab network

The youtube API sometimes throws error: Call to a member function children() on a non-object

When i launch the php script, sometime works fine, but many other times it retrieve me this errror
Fatal error: Call to a member function children() on a non-object in
/membri/americanhorizon/ytvideo/rilevametadatadaurlyoutube.php on line
21
This is the first part of the code
// set feed URL
$feedURL = 'http://gdata.youtube.com/feeds/api/videos/dZec2Lbr_r8';
// read feed into SimpleXML object
$entry = simplexml_load_file($feedURL);
$video = parseVideoEntry($entry);
function parseVideoEntry($entry) {
$obj= new stdClass;
// get nodes in media: namespace for media information
$media = $entry->children('http://search.yahoo.com/mrss/'); //<----this is the doomed line 21
UPDATE: solution adopted
for ($i=0 ; $i< count($fileArray); $i++)
{
// set feed URL
$feedURL = 'http://gdata.youtube.com/feeds/api/videos/'.$fileArray[$i];
// read feed into SimpleXML object
$entry = simplexml_load_file($feedURL);
if (is_object($entry))
{
$video = parseVideoEntry($entry);
echo ($video->description."|".$video->length);
echo "<br>";
}
else
{
$i--;
}
}
In this mode i force the script to re-check the file that caused the error
You are first of all calling a function:
$entry = simplexml_load_file($feedURL);
That function has a return value. You find it documented on the manual page of that function:
http://php.net/simplexml_load_file
Then you use that return value in form of a variable $entry without verifying that the function call was successful.
Because of that, you run into an error next. However your error/mistake is how you treat the return value of the function.
Not dealing with return values properly is like calling for trouble. Read about the function you use, check the return value(s) and proceed according to success or error conditions.
$entry = simplexml_load_file($feedURL);
if (FALSE === $entry)
{
// youtube not available.
}
else
{
// that's what I love!
}
Sometimes? Really?
Take a look at this:
<?php
$dummy; //IN FACT, this var is NULL now
// Will throw exactly the same error you get
$dummy->children();
Why? Because, we can call method from an object type.
So, if you wanna avoid errors like this one, next time you would call the method ensure that it's "possible".
<?php
if ( is_object($dummy) && method_exists($dummy, 'children') ){
//sure it works
$dummy->children();
}

Working with XML in a Firefox Add-on(ex Jetpack)

I'm currently developing a Firefox add-on(using https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/ ) that consumes an API where the return data is in xml.
My problem is that I need to parse the returned data, and would like to do that using a xml object.
Since the request module only supports JSON and Text ( https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/packages/addon-kit/docs/request.html#Response ) I need to convert the response.text to XML.
The code looks like this:
var Request = require('request').Request
.......
var req = Request({
url: https://to-the-api.com,
content: {
op: 'get-the-data-op',
password: "super-sec",
user: "username"
},
onComplete: function (response) {
dataAsText = response.text;
console.log("output: " + dataAsText);
}
});
req.post();
I have tried to user (new DOMParser).parseFromString(response.text, 'text/xml') but unfortunately it just fails with a error like ReferenceError: DOMParser is not defined
The question is if anyone of you guys have been able to create a Xml object inside a Firefox add-on, and if so, how?
Looks like the capability to parse response as xml was present, but has been removed. check out this bugzilla reference
Can't you use a normal XMLHttpRequest if you want to process the response as XML?
If DOMParser is unavailable you can try E4X:
var xml = new XML(response.text);
alert(xml.children().length());
You want to use the XMLHttpRequest object to handle your xhr request. Then when you get a response back access the responseXML object of the request variable. In the responseXML you'll have the documentElement and can use the querySelectorAll or querySelector to find elements you want. In each element you want just grab the textContent you need.
Here's an example to get you going (this looks for the 'xmls' element in the response):
var request = new require("xhr").XMLHttpRequest();
request.open('GET', 'https://to-the-api.com', true);
request.onreadystatechange = function (aEvt) {
if (request.readyState == 4) {
if(request.status == 200) {
var xmls = request.responseXML.documentElement.querySelectorAll("xmls");
for (var i = 0; i < xmls.length; i++) {
console.log("xml", i, xmls[i], xmls[i].textContent);
}
}
else {
console.log('Error', request.responseText);
}
}
};
request.send(null);

MediaWiki Local Extension Link

I installed MediaWiki locally. Everything worked but I needed a functionality to link files from our file server. I stumbled upon an extension called Extension:NetworkLink which provides this functionality. You just have to add filepath in your wikipage and it should work. My problem is that I the path of my local wiki installation "http://localhost/w/index.php/" is addedd to filepath and then the link does not work. I tried to edit the url manipulation in the PHP file to cut it out but it does not work. Here is the edited code:
<?php
function linkExtension() {
global $wgParser;
$wgParser->setHook( "link", "renderlink" );
}
# The callback function for converting the input text to HTML output
function renderlink( $loc='', $argv=array() ) {
global $wgOut, $wgTitle, $wgParser;
$loc = htmlspecialchars($loc);
$pos = strrpos($loc, "/");
if ($pos != false)
{
$loc = substr($loc, $pos + 1);
}
switch( strtoupper( $argv['TARGET'] ) ) {
case "SELF":
$out = "$loc";
break;
case "TOP":
$out = "$loc";
break;
case "PARENT":
$out = "$loc";
break;
default:
$out = "$loc";
}
return $out;
}
I found another better solution. First install the FF-plugin LocalLink. Then add the MediaWiki Extension:FileProtocolLinks. After this you can add links in your wiki to local files or shares on your network like this:
LAN: <file>\\Fileserver\Directory1\Directory2\MyFile.zip</file>
Local: <file>C:/Directory1/Directory2/MyFile.zip</file>

Resources