offset error in PHP when converting data to word document - php

Getting an Undefined offset: 1 error when try the following code that outputs some data to word document...
Using CodeIgniter in the controller I have:
$htmltodoc= new HTML_TO_DOC();
$htmltodoc->createDoc("<h1>Testing data </h1>", "testfile.doc");
In the helper directory I am using the following functions in a class called HTML_TO_DOC below...
class HTML_TO_DOC
{
var $docFile="";
var $title="";
var $htmlHead="";
var $htmlBody="";
/**
* Constructor
*
* #return void
*/
function HTML_TO_DOC()
{
$this->title="Untitled Document";
$this->htmlHead="";
$this->htmlBody="";
}
/**
* Set the document file name
*
* #param String $docfile
*/
function setDocFileName($docfile)
{
$this->docFile=$docfile;
if(!preg_match("/\.doc$/i",$this->docFile))
$this->docFile.=".doc";
return;
}
function setTitle($title)
{
$this->title=$title;
}
/**
* Return header of MS Doc
*
* #return String
*/
function getHeader()
{
$return = <<<EOH
<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 9">
<meta name=Originator content="Microsoft Word 9">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<title>$this->title</title>
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Print</w:View>
<w:DoNotHyphenateCaps/>
<w:PunctuationKerning/>
<w:DrawingGridHorizontalSpacing>9.35 pt</w:DrawingGridHorizontalSpacing>
<w:DrawingGridVerticalSpacing>9.35 pt</w:DrawingGridVerticalSpacing>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
#font-face
{font-family:Verdana;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:536871559 0 0 0 415 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:7.5pt;
mso-bidi-font-size:8.0pt;
font-family:"Verdana";
mso-fareast-font-family:"Verdana";}
p.small
{mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:1.0pt;
mso-bidi-font-size:1.0pt;
font-family:"Verdana";
mso-fareast-font-family:"Verdana";}
#page Section1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1032">
<o:colormenu v:ext="edit" strokecolor="none"/>
</o:shapedefaults></xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1"/>
</o:shapelayout></xml><![endif]-->
$this->htmlHead
</head>
<body>
EOH;
return $return;
}
/**
* Return Document footer
*
* #return String
*/
function getFotter()
{
return "</body></html>";
}
/**
* Create The MS Word Document from given HTML
*
* #param String $html :: URL Name like http://www.example.com
* #param String $file :: Document File Name
* #param Boolean $download :: Wheather to download the file or save the file
* #return boolean
*/
function createDocFromURL($url,$file,$download=false)
{
if(!preg_match("/^http:/",$url))
$url="http://".$url;
$html=#file_get_contents($url);
return $this->createDoc($html,$file,$download);
}
/**
* Create The MS Word Document from given HTML
*
* #param String $html :: HTML Content or HTML File Name like path/to/html/file.html
* #param String $file :: Document File Name
* #param Boolean $download :: Wheather to download the file or save the file
* #return boolean
*/
function createDoc($html,$file,$download=false)
{
if(is_file($html))
$html=#file_get_contents($html);
$this->_parseHtml($html);
$this->setDocFileName($file);
$doc=$this->getHeader();
$doc.=$this->htmlBody;
$doc.=$this->getFotter();
if($download)
{
#header("Cache-Control: ");// leave blank to avoid IE errors
#header("Pragma: ");// leave blank to avoid IE errors
#header("Content-type: application/octet-stream");
#header("Content-Disposition: attachment; filename=\"$this->docFile\"");
echo $doc;
return true;
}
else
{
return $this->write_file($this->docFile,$doc);
}
}
/**
* Parse the html and remove <head></head> part if present into html
*/
function _parseHtml($html)
{
$html=preg_replace("/<!DOCTYPE((.|\n)*?)>/ims","",$html);
$html=preg_replace("/<script((.|\n)*?)>((.|\n)*?)<\/script>/ims","",$html);
preg_match("/<head>((.|\n)*?)<\/head>/ims",$html,$matches);
$head=$matches[1];
preg_match("/<title>((.|\n)*?)<\/title>/ims",$head,$matches);
$this->title = $matches[1];
$html=preg_replace("/<head>((.|\n)*?)<\/head>/ims","",$html);
$head=preg_replace("/<title>((.|\n)*?)<\/title>/ims","",$head);
$head=preg_replace("/<\/?head>/ims","",$head);
$html=preg_replace("/<\/?body((.|\n)*?)>/ims","",$html);
$this->htmlHead=$head;
$this->htmlBody=$html;
return;
}
/**
* Write the content int file
*
* #param String $file :: File name to be save
* #param String $content :: Content to be write
* #param [Optional] String $mode :: Write Mode
* #return void
* #access boolean True on success else false
*/
function write_file($file,$content,$mode="w")
{
$fp=#fopen($file,$mode);
if(!is_resource($fp))
return false;
fwrite($fp,$content);
fclose($fp);
return true;
}
}
It will be great if someone can please help me solve this error.. thanks alot..
PS

Undefined offset: 1
means you are trying to read an array key '1' when there is none. That would probably mean the line you are getting it is here:
$head=$matches[1];
or
$this->title = $matches[1];
So your matches do not contain a [1] element, so you do not 'hit' anything there.
Debugging howto:
remove everything after $head=$matches[1];
Is the problem still there: you've found your line. Is it not? It's the second line.
For the preg_match that is the problem, echo the $html (or $head) vars to see their contents. Mind you, the will not show up in a browser if they are html, so check the source or do this on the commandline.
Try to figure out if your var has the content you expect, and if you could actually match with your regular expression. If not: fix the expression or the var. if so:
Make a test-file with the contents of the var hardcoded in your preg_match. Is the problem still there? maybe var_dump your $matches to be sure
If problem still there (you've probably hit the problem by now, but nevertheless): post the test code (that last testfile with the hardcoded preg_match that troublesome) and ask where you are getting it wrong.
bottomline: post a MINIMAL piece of code where it still goes wrong. You're bound to find the problem on the way of making that minimal problem, but if you do not it's a lot easier for us to help you.

Nowhere in your code are you actually checking that you managed to successfully open the document to parse, also can you show us more of the code nor do you even check to see if $matches has any content. First thing I suggest you do is to format your code so it is easier to read then look at some if statements to make sure that things are being set.
Just the second tip alone will save you countless hours in the future.
Also remember, arrays start at [0] so if you know that matches is only going to have one thing stored in it, try changing the $matches[1] to $matches[0]

I'm going to go ahead and say that your issue is that you don't have good error messages, not that you've an undefined index.
Follow the track to get to that point:
$head=$matches[1]; is an undefined index.
$matches is retrieved by looking for the head of some HTML which is being parsed with a regexp (*HUGE* No-no by the way. You should really look into a legit HTML parser)
That happens because there is a problem with whatever calls _parseHtml.
_parseHtml is called by createDoc.
You're passing in "<h1>Testing data </h1>" as HTML.
All of that given, OF COURSE you are getting no index found, you're not passing in valid HTML, so it is unable to convert it. Try "<html><head></head><body><h1>Testing data </h1></body></html>" (note: your class does not accept <head /> as a valid head tag... that's a problem).
And there are other areas where this class can be improved.
You're using PHP4 style OOP. Unless PHP4 is part of the functional spec. this is a big no-no. You want _parseHtml to be private...
At one point I noticed this:
EOH;
return $return;`
The probem is that Heredoc does not allow for indented closings. It's in big, red letters. I think they mean it.
createDocFromURL does not allow for https
$doc.=$this->htmlBody; (in createDoc) is not consistent with the code immediately preceding and following it -- everything works with get<value> and that line is a direct access of a property.
You have a fotter in your class (a typo in getFotter)
If PHP 5 is an option, you should use file_put_contents in write_file.
You have inconsistent naming of methods -- write_file v.s. getHeader
I'm not trying to knock you down, but most of these have a large potential for causing problems in the future. You really should consider them.

Related

Catchable fatal error: Argument 1 passed to CorenlpAdapter::getOutput()

I get the following error:
Catchable fatal error: Argument 1 passed to CorenlpAdapter::getOutput() must be an instance of string, string given, called in /Library/WebServer/Documents/website/php-stanford-corenlp-adapter/index.php on line 22 and defined in /Library/WebServer/Documents/website/php-stanford-corenlp-adapter/src/CoreNLP/CorenlpAdapter.php on line 95
index.php 21 and 22 contain:
$text1 = 'I will meet Mary in New York at 10pm';
$coreNLP->getOutput($text1);
corenlpAdapter.php lines 95 and onwards contain:
public function getOutput(string $text){
if(ONLINE_API){
// run the text through the public API
$this->getServerOutputOnline($text);
} else{
// run the text through Java CoreNLP
$this->getServerOutput($text);
}
// cache result
$this->serverMemory[] = $this->serverOutput;
if(empty($this->serverOutput)){
echo '** ERROR: No output from the CoreNLP Server **<br />
- Check if the CoreNLP server is running. Start the CoreNLP server if necessary<br />
- Check if the port you are using (probably port 9000) is not blocked by another program<br />';
die;
}
/**
* create trees
*/
$sentences = $this->serverOutput['sentences'];
foreach($this->serverOutput['sentences'] as $sentence){
$tree = $this->getTreeWithTokens($sentence); // gets one tree
$this->trees[] = $tree; // collect all trees
}
/**
* add OpenIE data
*/
$this->addOpenIE();
// to get the trees just call $coreNLP->trees in the main program
return;
}
Why exactly am I getting this error when text1 is a string?
I am the original author of this class. As you can see, the function getOutput looks like this:
public function getOutput(string $text){
...
}
Change that to:
public function getOutput($text){
...
}
The function tries to enforce that the input is string. The original code should work. However, it seems that in your case, PHP thinks "string" is not actually a string. Maybe the coding environment (the IDE) you are using uses the wrong character set? Or maybe you copy-pasted the code from HTML into the IDE or something like that. Thus whilst it says "string" on the screen, it's not actually a string to PHP.
If you are sure the input is a string, you can safely change the code like above. The class should then work normally.
public function getOutput($text){
.
.
.
}

Object error when trying to print index 0 on array with PHP

I am new to PHP and I am getting an error:
"Fatal error: Cannot use object of type Confrence as array on line 22"
I am trying to take data that is put into an array into a table where you have the number 1 seed in column 1 row 1 and the number 16 seed in column 2 row 1. I do not know if this is the correct logic to go about this, but that is my goal. For some reason it won't echo the first index of the array. This is my code.
Class Conference:
<?php
class Confrence
{
public $team1;
public $team2;
function loadGame($teamone, $teamtwo)
{
$this->$team1 = $teamone;
$this->$team2 = $teamtwo;
}
}
?>
This is my main code.
<?php print( '<?xml version = "1.0" encoding = "utf-8"?>' ) ?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>User Selection Page</title>
</head>
<?php
require_once("loadGameClass") or die ("Could not load file");
$westTeams = array();
$loadGameClass = new Confrence();
$loadGameClass->loadGame("(1) Gonzaga", "(16) Southern U");
$westTeams = $loadGameClass;
echo $westTeams[0];
?>
<body>
</body>
</html>
The variables for $westTeams and $loadGameClass reference an your Conference object, which is not an array. Therefore, you cannot use notation like $westTeams[0].
If you're planning on populating the class with many teams, you might want to submit an array to the Conference class and have that stored.
Class Conference:
class Conference
{
protected $teams;
function loadTeams($teams)
{
$this->teams = $teams;
}
function getTeams()
{
return $this->teams;
}
}
Regarding putting these in a table, you could use the following code. I'm assuming you have a total of 16 teams.
<table>
<tbody>
<?php
/* Load your teams in the array */
$loadGameClass = new Conference();
$loadGameClass->loadTeams(array(...));
$teams = $loadGameClass->getTeams();
for ($i = 0; $i < 8; $i++) {
$highSeed = $teams[$i];
$lowSeed = $teams[((2*8)-1)-$i];
echo "<tr><td>$highSeed</td><td>$lowSeed</td></tr>";
}
?>
</tbody>
</table>
This will output the first seed in the first column, first row and the 16th seed in the 2nd column, first row. The pattern will repeat down to the 8th column.
In my code, the conference class is somewhat useless, as it's just a container for the teams array, but you can add functionality to that class to make it worthwhile.
The loadGame method isn't returning anything, so using echo on it all won't do anything.
The error you see is due to the [x] syntax being for arrays only, you're using a class.
In the case the class member vars are public so you can use the following in your html:
$westTeams->team1;
But you also need to change the class, you have a syntax error:
$this->$team1 should be $this->team1
istead of
$westTeams[0]
use
$westTeams->team1
Also use
$this->team1
instead of
$this->$team1

Merge FDF and PDF without PDFTK

Is there a way to merge FDF file and a PDF File to create a flat format of all the data and form into 1 pdf without using PDFTK?
Any light shed upon this would be greatly appreciated.
No.. There's no other way easy way to flatten, but it's awesome. Why would you need anything else?
PDFTK is actually mostly Java (literally hundreds of Java files). You could think about wrapping your own project around it. The functionality that you're looking for is here (java/com/lowagie/text/pdf/AcroFields.java:931):
/** Sets the fields by XFDF merging.
* #param xfdf the XFDF form
* #throws IOException on error
* #throws DocumentException on error
*/
public boolean setFields(XfdfReader xfdf) throws IOException, DocumentException {
boolean ret_val_b= false; // ssteward
xfdf.getFields();
for (Iterator i = fields.keySet().iterator(); i.hasNext();) {
String f = (String)i.next();
String v = xfdf.getFieldValue(f);
String rv = xfdf.getFieldRichValue(f); // ssteward
if (rv != null)
ret_val_b= true;
if (v != null)
setField(f, v, v, rv); // ssteward
}
return ret_val_b; // ssteward
}

Get iso8601.time tag from SimpleXMLElement in PHP

I have the function bellow. I want to add support for iso8601 time format but I just can't get it to work. Since I in php can't do (string)$tag->iso8601.time. Is there a way to get the iso8601.time element? The tag is a SimpleXMLElement.
private function _tagToPhpType($tag) {
/*
* <i4> or <int> four-byte signed integer -12
* <boolean> 0 (false) or 1 (true) 1
* <string> string hello world
* <double> double-precision signed floating point number -12.214
* <dateTime.iso8601> date/time 19980717T14:08:55
* <base64> base64-encoded binary eW91IGNhbid0IHJlYWQgdGhpcyE=
*
* Source: http://www.xmlrpc.com/spec
*/
if(!empty($tag->string)) {
return (string)$tag->string;
}
elseif(!empty($tag->int)) {
return (int)$tag->int;
}
elseif(!empty($tag->i4)) {
return (int)$tag->i4;
}
elseif(!empty($tag->boolean)) {
return (bool)$tag->boolean;
}
elseif(!empty($tag->double)) {
return (double)$tag->double;
}
elseif(!empty($tag->base64)) {
// #todo: Decode BASE64
return (int)$tag->base64;
} // #todo: Add iso8601 time type
else {
return (string)$tag;
}
}
As noted in the manual (SimpleXML basic usage) and the associated example (#3):
Accessing elements within an XML document that contain characters not permitted under PHP's naming convention (e.g. the hyphen) can be accomplished by encapsulating the element name within braces and the apostrophe.
So in your case $tag->{'dateTime.iso8601'} will get an <dateTime.iso8601> element.
(Your iso8601.time doesn't match the comment in the code, though if you need to get that tag then it should be easy to work out from the answer above.)

accents at image names

In my php + javascript project i have to show images and some of then have accents,
like ~ ç and ^.
My site are not showing these images.
I know that there is a function to treat this, but i forgot.
Somebody can help me?
thank's
Try running the image URLs through rawurlencode().
/* (C)Scripterlative.com
* Strips grave, acute, circumflex umlaut and tilde from vowels and Ñ.
*
* Include this script block, then within the tag of each text element to be controlled, insert:
*
* onblur='this.value=stripVowelAccent(this.value)'
*
* GratuityWare
* ~~~~~~~~~~~~
* You obtained this script probably out of desperation, so if you wish to express your gratitude for our efforts,
* please visit: www.scripterlative.com
*
*/
function stripVowelAccent(str)
{
var rExps=[
{re:/[\xC0-\xC6]/g, ch:'A'},
{re:/[\xE0-\xE6]/g, ch:'a'},
{re:/[\xC8-\xCB]/g, ch:'E'},
{re:/[\xE8-\xEB]/g, ch:'e'},
{re:/[\xCC-\xCF]/g, ch:'I'},
{re:/[\xEC-\xEF]/g, ch:'i'},
{re:/[\xD2-\xD6]/g, ch:'O'},
{re:/[\xF2-\xF6]/g, ch:'o'},
{re:/[\xD9-\xDC]/g, ch:'U'},
{re:/[\xF9-\xFC]/g, ch:'u'},
{re:/[\xD1]/g, ch:'N'},
{re:/[\xF1]/g, ch:'n'} ];
for(var i=0, len=rExps.length; i<len; i++)
str=str.replace(rExps[i].re, rExps[i].ch);
return str;
}

Categories