Safari prints extra pages - php

I am working on a site where user can print Quiz or Flashcards. Print functionality is working fine on all browsers (IE9, Firefox, Chrome) except Safari. On Safari, when user prints any quiz, extra blank pages are getting printed. I have found out that the logic for calculating pixel to point ratio is creating an issue. Here is the sample of my code.
function getHeight(elem) {
var elem_height = 0;
if (typeof elem.innerHeight != 'undefined') {
elem_height = elem.innerHeight;
} else {
elem_height = elem.clientHeight;
}
return parseInt(elem_height);
}
var dpiBoxHeight = getHeight(document.getElementById('dpiBox'));
if (dpiBoxHeight < 1) dpiBoxHeight = 96;
var pixelPointRatio = 72 / dpiBoxHeight;
'dpiBox' is an empty div and in CSS we have defined the deafult height as 1 inch.
The value 72 represents points per inch. In safari, I am getting 'dpiBoxHeight' as 96.
If I change, the points per inch Value to above 85 OR change the 'dpiBoxHeight' to less than 85. No blank pages get printed. But, this increases the number of overall printed pages.
Please suggest if you have a solution/workaround which can be used to prevent blank pages getting printed on Safari and is compatible on all the browsers
Thanks in advance,
Neha

Related

FPDF/FPDI and Microsoft Internet Explorer and Edge

I am currently utilising FPDF for the first time and everything works great so far in Chrome, Firefox, Safari, Mobile Chrome, Mobile Safari but both Internet Explorer and Microsoft Edge give me issues.
I have a page where a user can fill in a form with their own company name and adress information.
They are also required to upload their company logo.
I use FPDF combined with FPDI for the use of templates/PDFs
Our designers made the PDF in InDesign and that is all good.
I start by declaring a new FPDI and importing in the base PDF (it has 8 pages) as the first source and template.
The first 5 pages in the PDF are as followed
Cover 1
Cover 2
Cover 3
Cover 4
Cover 5
In my HTML form I have a select input where the user can choose between the five.
Which I then pick up in PHP and load the correct page as follow:
$pdf = new FPDI();
$pagecount = $pdf->setSourceFile('../pdf/source-brochure.pdf');
// Add the Cover
$tplCover = $pdf->importPage($cover_versie, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tplCover, 0, 0, 210);
$pdf->Image($newFile, $baseOffsetX, $baseOffsetY);
$cover_versie; // Outputs the integer 1, 2, 3, 4 or 5 for the covers
$newFile; // Is the uploaded logo resised and uploaded to the server
The logo is resized and edited through a php script
Now the 5th option is a custom cover where the user can upload their own cover image to the form (this input field is shown when Cover 5 is chosen)
So in my Switch Statement where I check which cover the user has chosen I have this following code:
if ($custimg->uploaded) {
$custimg->image_resize = true;
$custimg->image_x = 741;
$custimg->image_y = 792;
$custimg->image_ratio = true;
$custimg->image_ratio_fill = true;
$custimg->image_ratio_crop = 'TL';
$custimg->image_ratio_no_zoom_in = false;
$custimg->image_ratio_no_zoom_out = false;
$custimg->image_convert = 'png';
$custimg->process('uploads/');
if ($custimg->processed) {
$customcoverimage = $custimg->file_dst_pathname;
$custimg->clean();
}
}
The rest of the form is not required and fall back using ternary operators like so:
$filename = (!empty($companyname)) ? $companyname : time();
So after the cover is chosen and done I add the 6th page from the source PDF which is a Spread page and requires no edits so I import that as the new page:
// Add the content of the brochure
$tplContent = $pdf->importPage(6, '/MediaBox');
$pdf->addPage('L', 'A4');
$pdf->useTemplate($tplContent, 0, 0, 297);
Alright nothing too hard here.
Next up is the last page.
For this I also have a input select option in my form.
There are 2 flavors to choose from.
// Add the Back
$tplBack = $pdf->importPage($achter_versie, '/MediaBox');
$pdf->addPage();
$pdf->useTemplate($tplBack, 0, 0, 210);
$achter_versie; // Outputs the integer 7 or 8 based on the chosen back
Now here we get a little tricky.
On the last page there is a spot where I need to loop through 5 checkboxes in the form to see which sponsors the company uses and output their respective logo's next to eachother:
So I first count the amount of checkboxes are checked.
I get the values of the checkboxes in a loop and through a for loop I add the logo's (which are uploaded to a default folder) to the page:
// Get the checkbox values
if ($nrofkeurmerken != 1) {
for ($x1 = 0; $x1 <= $nrofkeurmerken-1; $x1++) {
$brandBaseX = 10;
$baseImgWidth = 29.897916667;
if ($keurmerken[$x1] != 'eigen') {
$keurmerkname[] = "../img/keurmerken/logo-" . $keurmerken[$x1] . ".png";
$pdf->Image($keurmerkname[$x1], $brandBaseX + ($baseImgWidth * $x1) + 5, 270);
} else {
$keurimg = new upload($_FILES['keurmerkfile']);
if ($keurimg->uploaded) {
$keurimg->image_resize = true;
$keurimg->image_x = 113;
$keurimg->image_y = 71;
$keurimg->image_ratio = true;
$keurimg->image_ratio_no_zoom_in = true;
$keurimg->image_ratio_no_zoom_out = false;
$keurimg->image_convert = 'png';
$keurimg->process('uploads/');
if ($keurimg->processed) {
$customkeurmerkimage = $keurimg->file_dst_pathname;
$pdf->Image($customkeurmerkimage, $brandBaseX + ($baseImgWidth * $x1) + 5, 270);
$keurimg->clean();
}
}
}
}
} else if ($nrofkeurmerken == 1) {
$brandBaseX = 10;
$baseImgWidth = 29.897916667;
$keurmerkname = "../img/keurmerken/logo-snf.png";
$pdf->Image($keurmerkname, $brandBaseX + ($baseImgWidth * 0) + 5, 270);
}
Now In All modern browsers (except IE11 and MS Edge) this works.
But both IE11 and Edge have the error that the PDF does not start with %PDF
At first my error was incorrect type of file but I added the
header('Content-type: application/pdf');
which solved that problem.
If anyone understands this that would be awesome haha.
Thanks for the time to look though!

Remember Page Position Using Two Lines of Script

In all major browsers, except Internet Explorer, the following script returns the page to its previous vertical position on reload:
<?php $y = $_COOKIE["y"]; ?> //in head tag before any output
and
<?php
print "<body onScroll=\"document.cookie='y=' + window.pageYOffset\" onLoad='window.scrollTo(0,$y)'>";
Can someone please tell me how I would modify this code to remember the page's vertical position in IE? Thanks.
From w3Schools :
IE 8 and earlier does not support this property, but may use "document.body.scrollLeft" and "document.body.scrollTop" instead.
I use the following code to do basic IE/not-IE browser detection:
if(document.all) { //if IE
//code
} else { //if not IE
//code
}
You should be able to combine this with AlecTMH's document.body.scrollLeft and document.body.scrollTop suggestion to get where you're going. But you're likely going to have to write a function for it and then call that in onScroll().
I'm not exactly a JavaScript wiz, but...
function blah() {
if(document.all) { //if IE
document.cookie='y=' + document.body.scrollTop
} else { //if not IE
document.cookie='y=' + window.pageYOffset
}
}
...might almost be functional code.

An issue with a dropdown menu w/ embedded php content in a seperate location of the document

An issue with a dropdown menu. The problem isn't the menu code itself ie ul..etc, but a php chat program im currently embedding. After inserting this code to embed the chat box which appears with no errors the ability to use the ul dropdown link is disabled. The embedded php is in an entirely seperate div from the menu which is located in the #zonebar div.
the embedded code <?php $chat->printChat(); ?> which is in a specific div.
The thing is when i remove this code the dropdown menu buttons work again..
To be more specific the only php code in my html file with appropriate htaccess which allows me to use php in an html document is..
the code below is located at the very top of my page above all tags
<?php
require_once dirname(__FILE__)."/src/phpfreechat.class.php";
$params = array();
$params["serverid"] = md5(__FILE__); // calculate a unique id for this chat
$params["title"] = "A simple chat with user's parameters";
$params["frozen_nick"] = true; // do not allow to change the nickname
$params["shownotice"] = 0; // 0 = nothing, 1 = just nickname changes, 2 = connect/quit, 3 = nick + connect/quit
$params["max_nick_len"] = 20; // nickname length could not be longer than 10 caracteres
$params["max_text_len"] = 300; // a message cannot be longer than 50 caracteres
$params["max_channels"] = 1; // limit the number of joined channels tab to 3
$params["refresh_delay"] = 2000; // chat refresh speed is 10 secondes (10000ms)
$params["max_msg"] = 15; // max message in the history is 15 (message seen when reloading the chat)
$params["height"] = "230px"; // height of chat area is 230px
$params['admins'] = array('daddo' => '1234', 'berthill' => '1234');
$params["debug"] = false; // activate debug console
$chat = new phpFreeChat( $params );
?>
and then the code in the specific div
<?php $chat->printChat(); ?>
link directly the html file without any php content
edited out address after fix
link with the php code embedded
I am going to wager a guess at this since looking through about a dozen javascript files is not something I really want to do.
Your dropdown menu uses jQuery... which is great.
Your chat uses Prototype... also great.
They are most likely not playing well together. You can try doing this:
var $j=jQuery.noConflict();
$j(document).ready(function(){
$j("#zone-bar li em").click(function() {
var hidden = $j(this).parents("li").children("ul").is(":hidden");
$j("#zone-bar>ul>li>ul").hide()
$j("#zone-bar>ul>li>a").removeClass();
if (hidden) {
$j(this)
.parents("li").children("ul").toggle()
.parents("li").children("a").addClass("zoneCur");
}
});
});
It may or may not work, but using $j instead of $ may fix the issue.

getting javascript error object required

Iam getting offsetwidth of an div tag. Below is code.
<body>
<div id="marqueeborder" onmouseover="pxptick=0" onmouseout="pxptick=scrollspeed">
<div id="marqueecontent">
<?php
// Original script by Walter Heitman Jr, first published on http://techblog.shanock.com
// List your stocks here, separated by commas, no spaces, in the order you want them displayed:
$stocks = "idt,iye,mill,pwer,spy,f,msft,x,sbux,sne,ge,dow,t";
// Function to copy a stock quote CSV from Yahoo to the local cache. CSV contains symbol, price, and change
function upsfile($stock) { copy("http://finance.yahoo.com/d/quotes.csv?s=$stock&f=sl1c1&e=.csv","stockcache/".$stock.".csv"); }
foreach ( explode(",", $stocks) as $stock ) {
// Where the stock quote info file should be...
$local_file = "stockcache/".$stock.".csv";
// ...if it exists. If not, download it.
if (!file_exists($local_file)) { upsfile($stock); }
// Else,If it's out-of-date by 15 mins (900 seconds) or more, update it.
elseif (filemtime($local_file) <= (time() - 900)) { upsfile($stock); }
// Open the file, load our values into an array...
$local_file = fopen ("stockcache/".$stock.".csv","r");
$stock_info = fgetcsv ($local_file, 1000, ",");
// ...format, and output them. I made the symbols into links to Yahoo's stock pages.
echo "<span class=\"stockbox\">".$stock_info[0]." ".sprintf("%.2f",$stock_info[1])." <span style=\"";
// Green prices for up, red for down
if ($stock_info[2]>=0) { echo "color: #009900;\">↑"; }
elseif ($stock_info[2]<0) { echo "color: #ff0000;\">↓"; }
echo sprintf("%.2f",abs($stock_info[2]))."</span></span>\n";
// Done!
fclose($local_file);
}
?>
<span class="stockbox" style="font-size:0.6em">Quotes from Yahoo Finance</span>
</div>
</div>
</body>
below is the javascript function which will be called onlaod of the page.
<script type="text/javascript">
// Original script by Walter Heitman Jr, first published on http://techblog.shanock.com
// Set an initial scroll speed. This equates to the number of pixels shifted per tick
var scrollspeed=2;
var pxptick=scrollspeed;
function startmarquee(){
alert("hi");
// Make a shortcut referencing our div with the content we want to scroll
var marqueediv=document.getElementById("marqueecontent");
alert("marqueediv"+marqueediv);
alert("hi"+marqueediv.innerHTML);
// Get the total width of our available scroll area
var marqueewidth=document.getElementById("marqueeborder").offsetWidth;
alert("marqueewidth"+marqueewidth);
// Get the width of the content we want to scroll
var contentwidth=marqueediv.offsetWidth;
alert("contentwidth"+contentwidth);
// Start the ticker at 50 milliseconds per tick, adjust this to suit your preferences
// Be warned, setting this lower has heavy impact on client-side CPU usage. Be gentle.
var lefttime=setInterval("scrollmarquee()",50);
alert("lefttime"+lefttime);
}
function scrollmarquee(){
// Check position of the div, then shift it left by the set amount of pixels.
if (parseInt(marqueediv.style.left)>(contentwidth*(-1)))
marqueediv.style.left=parseInt(marqueediv.style.left)-pxptick+"px";
// If it's at the end, move it back to the right.
else
marqueediv.style.left=parseInt(marqueewidth)+"px";
}
window.onload=startmarquee();
</script>
when iam running the above code on server, iam getting javascript error as "object required" at line 46 also the alert("marqueediv"+marqueediv); is "marqueedivnull" after that alert iam getting the javascript error.
Here my question is, did the div tag is not getting recognized?why?
so that only it is getting as null object, how can i resolved this?
Thanks.
You are calling startmarquee immediately and trying to assign its return value (undefined) to window.onload.
Presumably the script appears in the <head> and this the div does not exist at the time you run it.
Assign the function to onload, not its return value.
window.onload=startmarquee;
You could copy the script and put it before the body closing tag and remove window.onload=startmarquee(); thus making sure all elements have been loaded and accessible
Just like #Quentin said, that element with the id might not have been loaded into the DOM when you referenced it

PHP session not working with JQuery Ajax?

Update, Solved:
After all this I found out that I was calling an old version of my code in the update ajax.
'boardControl.php' instead of 'boardUpdate.php' These are the kinds of mistakes that make programing fun.
I'm writing a browser gomoku game. I have the ajax statement that allows the player to play a piece.
$(document).ready(function() {
$("td").live('click',function(){
var value = $(this).attr('id');
$.get('includes/boardControl.php',{play: value, bid: bid});
});
});
value = board square location
bid = board ID
Before creating a user login for player identification, the server side php had a temporary solution. It would rotate the piece state for the squares when clicked instead of knowing what player to create them for.
After creating login stuff I set a session variable for the player's ID. I was hoping to read the session ID from the php during the ajax request and figure out what player they are from there.
session_start();
...
$playerId = $_SESSION['char'];
$Query=("SELECT p1, p2 FROM board WHERE bid=$bid");
$Result=mysql_query($Query);
$p1 = mysql_result($Result,0,"p1");
$p2 = mysql_result($Result,0,"p2");
$newPiece = 0; //*default no player
if($playerId == $p1)
$newPiece = 1;
if($playerId == $p2)
$newPiece = 2;
For some reason when I run the full web app, the pieces still cycle though, even after I deleted the code to make them cycle.
Furthermore, after logging in If i manually load the php page in the browser, it modifies the database correctly (where it only plays pieces belonging to that player) and outputs the correct results.
It seems to me that the session is not being carried over when used with Ajax. Yet Google searches tell me that, sessions do work with Ajax.
Update: I'm trying to provide more information.
Logging in works correctly. My
ID is recognized and I printed it
out next to the board to ensure that
I was retrieving it correctly.
The ajax request does update the
board. The values passed are
correct and confirmed with firebug's
console. However instead of placing
pieces only for the player they
belong to it cycles though the piece
states (0,1,2).
When manually browsing to
boardUpdate.php and putting in the
same values sent from the Ajax the
results seen in the echo'ed response
indicates that the corresponding
piece is played each time as
intended.
Same results on my laptop after
fresh load of firefox.
Manually browsing to
boardUpdate.php without logging in
before hand leave the board
unchanged (as intended when no user
is found in the session).
I've double checked the that
session_start() is on the php files
and double checked the session ID
variables.
Hope this extra information helps, i'm running out of ideas what to tell you. Should I load up the full code?
Update 2:
After checking the Ajax responce in fire-bug I realized that the 'play' request does not get a result, and the board is not updated till the next 'update'. I'm still looking into this but I'll post it here for you guys too.
boardUpdate.php
Notable places are:
Refresh Board(line6)
Place Piece(line20)
function boardUpdate($turnCount) (line63)
<?php
session_start();
require '../../omok/dbConnect.php';
//*** Refresh Board ***
if(isset($_GET['update']))
{
$bid = $_GET['bid'];
$Query=("SELECT turn FROM board WHERE bid=$bid");
$Result=mysql_query($Query);
$turnCount=mysql_result($Result,0,"turn");
if($_GET['turnCount'] < $turnCount) //** Turn increased
{
boardUpdate($turnCount);
}
}
//*** Place Piece ***
if(isset($_GET['play'])) // turn order? player detect?
{
$squareID = $_GET['play'];
$bid = $_GET['bid'];
$Query=("SELECT turn, boardstate FROM board WHERE bid=$bid");
$Result=mysql_query($Query);
$turnCount=mysql_result($Result,0,"turn");
$boardState=mysql_result($Result,0,"boardstate");
$turnCount++;
$playerId = $_SESSION['char'];
$Query=("SELECT p1, p2 FROM board WHERE bid=$bid");
$Result=mysql_query($Query);
$p1 = mysql_result($Result,0,"p1");
$p2 = mysql_result($Result,0,"p2");
$newPiece = 0; //*default no player
if($playerId == $p1)
$newPiece = 1;
if($playerId == $p2)
$newPiece = 2;
// if($newPiece != 0)
// {
$oldPiece = getBoardSpot($squareID, $bid);
$oldLetter = $boardState{floor($squareID/3)};
$slot = $squareID%3;
//***function updateCode($old, $new, $current, $slot)***
$newLetter = updateCode($oldPiece, $newPiece, $oldLetter, $slot);
$newLetter = value2Letter($newLetter);
$newBoard = substr_replace($boardState, $newLetter, floor($squareID/3), 1);
//** Update Query for boardstate & turn
$Query=("UPDATE board SET boardState = '$newBoard', turn = '$turnCount' WHERE bid = '$bid'");
mysql_query($Query);
// }
boardUpdate($turnCount);
}
function boardUpdate($turnCount)
{
$json = '{"turnCount":"'.$turnCount.'",'; //** turnCount **
$bid = $_GET['bid'];
$Query=("SELECT boardstate FROM board WHERE bid='$bid'");
$Result=mysql_query($Query);
$Board=mysql_result($Result,0,"boardstate");
$json.= '"boardState":"'.$Board.'"'; //** boardState **
$json.= '}';
echo $json;
}
function letter2Value($input)
{
if(ord($input) >= 48 && ord($input) <= 57)
return ord($input) - 48;
else
return ord($input) - 87;
}
function value2Letter($input)
{
if($input >= 10)
return chr($input += 87);
else
return chr($input += 48);
}
//*** UPDATE CODE *** updates an letter with a new peice change and returns result letter.
//***** $old : peice value before update
//***** $new : peice value after update
//***** $current : letterValue of code before update.
//***** $slot : which of the 3 sqaures the change needs to take place in.
function updateCode($old, $new, $current, $slot)
{
if($slot == 0)
{// echo $current,"+((",$new,"-",$old,")*9)";
return letter2Value($current)+(($new-$old)*9);
}
else if($slot == 1)
{// echo $current,"+((",$new,"-",$old,")*3)";
return letter2Value($current)+(($new-$old)*3);
}
else //slot == 2
{// echo $current,"+((",$new,"-",$old,")";
return letter2Value($current)+($new-$old);
}
}//updateCode()
//**** GETBOARDSPOT *** Returns the peice value at defined location on the board.
//****** 0 is first sqaure increment +1 in reading order (0-254).
function getBoardSpot($squareID, $bid)
{
$Query=("SELECT boardstate FROM board WHERE bid='$bid'");
$Result=mysql_query($Query);
$Board=mysql_result($Result,0,"boardstate");
if($squareID %3 == 2) //**3rd spot**
{
if( letter2Value($Board{floor($squareID/3)} ) % 3 == 0)
return 0;
else if( letter2Value($Board{floor($squareID/3)} ) % 3 == 1)
return 1;
else
return 2;
}
else if($squareID %3 == 0) //**1st spot**
{
if(letter2Value($Board{floor($squareID/3)} ) <= 8)
return 0;
else if(letter2Value($Board{floor($squareID/3)} ) >= 18)
return 2;
else
return 1;
}
else //**2nd spot**
{
return floor(letter2Value($Board{floor($squareID/3)}))/3%3;
}
}//end getBoardSpot()
?>
Please help, I'd be glad to provide more information if needed.
Thanks in advance =)
From the small snippet of code we have, it's difficult to tell what your problem might be. What I can say is that session_start should be one of the first things you do on each page where you're expecting to use the session. After that, I would just immediately do a var_dump of $_SESSION to see that the data is in there (put a die right after that). It is quite possible that your true problem lies somewhere else, and that the session is in fact working. Is there a problem with your login code, for example, that is causing it to wipe out the session?
You can use Firebug to look at the raw results of your AJAX calls, which should be helpful, since your script appears to work if you directly visit the page.
Cases where I've seen sessions not work as expected have generally been that session_start is being called too often or too late. The other possibility is that you have an insanely short timeout, but that sounds unlikely.
Finally, you can make sure that your PHP install is set to use cookie sessions. It's very unlikely at this point that it wouldn't be, but you could look.
One potential problem in this code is the use of $.get - it is cached by IE, so your server code doesn't run every time. Try using $.ajax with cache set to false:
$.ajax({
type: 'GET',
url: 'includes/boardControl.php',
cache: false,
data: {play: value, bid: bid}
});
Just happened to me, in my case was that i was importing a config file with the session_start and since i had deactivated errors i couldn't see that the import was never happening. Just triple check this, I know it's the basic.

Categories