<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HirdWeb &#187; PEAR</title>
	<atom:link href="http://www.hirdweb.com/tag/pear/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hirdweb.com</link>
	<description>Another Blog clogging up the already crowded internet</description>
	<lastBuildDate>Wed, 28 Jul 2010 16:05:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>GBP and Euro Symbols in Excel</title>
		<link>http://www.hirdweb.com/2009/10/20/gbp-and-euro-symbols-in-excel/</link>
		<comments>http://www.hirdweb.com/2009/10/20/gbp-and-euro-symbols-in-excel/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 15:47:56 +0000</pubDate>
		<dc:creator>stephen</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.hirdweb.com/?p=201</guid>
		<description><![CDATA[Have you used the Spreadsheet_Excel_Writer PEAR package to output data to a spreadsheet? In this data that is being exported, have you needed to format the data? What about numbers, and then formatting further to a currency format. The currency formats for this data: one for Great British Pounds (£) and one for the Euro [...]]]></description>
			<content:encoded><![CDATA[<p>Have you used the Spreadsheet_Excel_Writer PEAR package to output data to a spreadsheet? In this data that is being exported, have you needed to format the data? What about numbers, and then formatting further to a currency format. The currency formats for this data: one for Great British Pounds (£) and one for the Euro (€). The formatting needs to happen with those symbols. So here is the journey . . .</p>
<p>Since this post is not about the querying of the data, that is not going to be covered, but rather just the issues with formatting the currency symbols for Euro and GBP in the Writer. And since this is not about the Spreadsheet writer ins and outs, if you would like to know more about that, please see <a title="Spreadsheet_Excel_Writer" href="http://pear.php.net/package/Spreadsheet_Excel_Writer/docs" target="_blank">Package Information: Spreadsheet_Excel_Writer</a><br />
<span id="more-201"></span><br />
First off, include the PEAR library:</p>
<pre>require_once('Spreadsheet/Excel/Writer.php');</pre>
<p>Set up the Writer, and set the formats up.</p>
<pre>$workbook = new Spreadsheet_Excel_Writer($this-&gt;fileSrc);
$worksheet =&amp; $workbook-&gt;addWorksheet('Data Info');
// Set the formats for text
$formatText =&amp; $workbook-&gt;addFormat(array('Size' =&gt; 30));
// Set the formats for two numeric values for currency
$formatUKCurr =&amp; $workbook-&gt;addFormat(array('Size' =&gt; 12));
$formatEUROCurr =&amp; $workbook-&gt;addFormat(array('Size' =&gt; 12));
// now we need to format the numbers
$formatUKCurr-&gt;setNumFormat('#,##0.00');
$formatEUROCurr-&gt;setNumFormat('#,##0.00');
/**
All other writer code would go here.
**/</pre>
<p>This sets up the spreadsheet library object, added a couple of formats, and then extended it. With the numeric formats, we extended it so that the number will show up in that decimal format. What this means, is that if a number, for example 50, is retrieved from the database, then it will show up in the spreadsheet as 50.00. However, we need to put in the currency symbol in that format.</p>
<p>So, one would think that it would be easy enough, because all we would need to do is:</p>
<pre>$formatUKCurr-&gt;setNumFormat('£#,##0.00');
$formatEUROCurr-&gt;setNumFormat('€#,##0.00');</pre>
<p>Right?<br />
Wrong. Let&#8217;s say the GBP amount is 50, and the Euro amount is 23.5. When the spreadsheet is opened in Excel, what happens to that formatting is the following:<br />
GBP: Â£ 50.00<br />
Euro: â‚¬ 23.50</p>
<p>Yikes, there is an extra character before the pound symbol, and the Euro symbol has been warped.<br />
1. PHP, at least not until version 6, does not support UTF-8 natively. So this means that the character set that defines these symbols is incapable of being displayed properly in the current encode that PHP understands. Thus the extra characters<br />
2. To get more detailed info on why this character encoding is a problem, see <a title="Fun with UTF-8, PHP and MySQL" href="http://www.byteflex.co.uk/en/fun_with_utf8_php_and_mysql.html" target="_blank">Fun with UTF-8, PHP and MySQL</a>. This explains a good deal about UTF-8, ASCII, and ISO 8859-1.</p>
<p>So the first thing I tried was to force the headers to use UTF-8. That was a no go.</p>
<p>The next thing was to use the <a title="iconv encoding" href="http://us3.php.net/manual/en/book.iconv.php" target="_blank">ICONV</a>.</p>
<pre>$pound = iconv("ISO-8859-1", "UTF-8", "£");
$formatUKCurr-&gt;setNumFormat($pound . '#,##0.00');</pre>
<p>That was a no go as well.</p>
<p>I changed the font family of the destination cell. That also did not work.</p>
<p>So I took a walk to the kitchen to clear my head. I was clearly on the wrong track. I may as well try to put everything into an array, explode it, then implode it, then echo it, then die(). So I got back from the kitchen getting some water.</p>
<p>The thought came to me to try using the chr() function. It could not hurt. So I looked at the <a title=" PHP chr()" href="http://us3.php.net/manual/en/function.chr.php" target="_blank">PHP manual for chr()</a> to get the <a title="ASCII Table" href="http://www.asciitable.com/" target="_blank">ASCII code list</a>. The code for the pound symbol according to that site, is 156, so</p>
<pre>$formatUKCurr-&gt;setNumFormat( chr(156) . '#,##0.00' );</pre>
<p>Well, good news and bad news. First good news, no more additional characters. Bad news, the output for the GBP was :<br />
œ 50.00</p>
<p>OK, close, very close. Now I went hunting for the correct code. It is 163, so</p>
<pre>$formatUKCurr-&gt;setNumFormat( chr(163) . '#,##0.00' );</pre>
<p>After a couple of searches for the Euro symbol, as it is a newer symbol and not in the regular lists, I found it could be 128. So I tested it out</p>
<pre>$formatUKCurr-&gt;setNumFormat( chr(163) . '#,##0.00' );
$formatEUROCurr-&gt;setNumFormat(  chr(128) . '#,##0.00');</pre>
<p>And the output:<br />
£ 50.00<br />
€ 23.50</p>
<p>SUCCESS!</p>
<p>So, if you are struggling with this, using the Spreadsheet_Excel_Writer formatting to get the currency symbols for the GBP  and the Euro, that is the fix that I have found.</p>

<!-- Wordpress Connect Modules v1.05 -->]]></content:encoded>
			<wfw:commentRss>http://www.hirdweb.com/2009/10/20/gbp-and-euro-symbols-in-excel/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PEAR and CakePHP</title>
		<link>http://www.hirdweb.com/2009/05/04/pear-and-cakephp/</link>
		<comments>http://www.hirdweb.com/2009/05/04/pear-and-cakephp/#comments</comments>
		<pubDate>Tue, 05 May 2009 02:23:41 +0000</pubDate>
		<dc:creator>stephen</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[cakePHP]]></category>
		<category><![CDATA[PEAR]]></category>

		<guid isPermaLink="false">http://www.hirdweb.com/?p=185</guid>
		<description><![CDATA[This post is about my experience with loading in PEAR to a CakePHP 1.2.x application. This may be the right way or the wrong way, but I got it to work throughout the application. I had to do some changes, and if there is a better way of doing this, please let me know. First [...]]]></description>
			<content:encoded><![CDATA[<p>This post is about my experience with loading in PEAR to a CakePHP 1.2.x application. This may be the right way or the wrong way, but I got it to work throughout the application. I had to do some changes, and if there is a better way of doing this, please let me know. </p>
<p>First off, here is the issue. I needed to be able to export a group of records from the database to an excel spreadsheet. I have tried to use the <a href="http://bakery.cakephp.org/articles/view/excel-xls-helper" target="_blank">Excel Spreadsheet add in that is listed on the Bakery</a>. It works nice, and I had to do some modification for 1.2, but it worked. But not the way I wanted it. I have used the PEAR library Spreadsheet_Excel_Writer before and I like the type of control that I wanted, over the cells, the formatting, the merging, etc etc etc. It provides the type of control that I wanted. So here is what I did to get this to work with the CakePHP framework. </p>
<p>First, I have to download the PEAR library and the Spreadsheet_Excel_Writer libraries to use. Since I use a local system to help develop, I could download these libraries to the local system and transport these over to the CakePHP application. So I went to PEAR site to get the libraries. To download these I ran the following commands:</p>
<pre>
pear install PEAR-1.8.1
pear install OLE-1.0.0RC1
pear install Spreadsheet_Excel_Writer-0.9.1
</pre>
<p>URL&#8217;s are listed below:</p>
<p>http://pear.php.net/package/PEAR/download</p>
<p>http://pear.php.net/package/Spreadsheet_Excel_Writer/download</p>
<p>http://pear.php.net/package/OLE/download</p>
<p><span id="more-185"></span><br />
These downloaded the to local drives and I copied them over to the CakePHP area. Here is where it gets a little tricky. And I thank &#8220;brian&#8221; who helped me on the <a href="http://groups.google.com/group/cake-php">Cake Google group</a> to get past this when I got into a problem. So here we go, diving in to this. </p>
<p>First off, the PEAR libraries need to be put in the vendors directory. If you look at the directory structure for Cake, it appears like this:<br />
/app<br />
/cake<br />
/vendors</p>
<p>Inside of the /app directory, there is another vendors directory. This is where I put the PEAR libraries. This causes problems, because in the /cake/config/paths.php file, there is a path defined for VENDORS, and for PEAR:</p>
<pre>
if (!defined('VENDORS')) {
	define('VENDORS', CAKE_CORE_INCLUDE_PATH.DS.'vendors'.DS);
}

define('PEAR', VENDORS.'Pear'.DS);
</pre>
<p>Now, I have put the PEAR libraries in the top level vendor directory. If you choose to put it in the app/vendors directory, then you may need to change a core file, which is not advisable, because you would need to change the path above to</p>
<pre>
if (!defined('VENDORS')) {
	define('VENDORS', CAKE_CORE_INCLUDE_PATH.DS.'app/vendors'.DS);
}
</pre>
<p>So back to the PEAR libraries. Here is what I needed to do. I moved the PEAR directories to the /vendors directory. So here is what that directory looks like:</p>
<pre>
/vendors
    /css
    /js
   /Pear   <--- Look at this, case sensitive based on those paths above
        /OLE
        /OS
        /PEAR
        /scripts
        /Spreadsheet
        INSTALL
        LICENSE
        OLE.php
        package.dtd
        PEAR.php
        PEAR5.php
        README
        System.php
        template.spec
    /shells
</pre>
<p>This is part of the PEAR install we need to do. Now we need to update the paths in some of these files so that CakePHP can find them and include them. </p>
<p>**** ORIGINAL ENTRY THAT HAS BEEN EDITED/DEPRECATED ********************<br />
**** EDIT: Based on the original post this is the method I originally used. This way works, but requires a<br />
**** little too much overhead and editing the files in the PEAR libraries which is never really a good idea<br />
**** and should only be used sparingly. To see the way that it should be done, please see below this<br />
**** section.<br />
****<br />
**** In the file /vendors/Pear/Spreadsheet/Excel/Writer.php there is 2 requires<br />
**** require_once 'PEAR.php';<br />
**** require_once 'Spreadsheet/Excel/Writer/Workbook.php';<br />
****<br />
**** In order for the Cake App to see these, at least in my set up, I needed to change these to the<br />
**** following:<br />
**** require_once 'PEAR.php';<br />
**** require_once PEAR . 'Spreadsheet/Excel/Writer/Workbook.php';<br />
****<br />
**** I needed to add "PEAR . " to the require_once call. Now I needed to add this to the following files:<br />
**** /vendors/Pear/Spreadsheet/Excel/Writer.php<br />
**** require_once 'PEAR.php';<br />
**** require_once PEAR . 'Spreadsheet/Excel/Writer/Workbook.php';<br />
****<br />
**** /vendors/Pear/Spreadsheet/Excel/Writer/Workbook.php<br />
**** require_once PEAR . 'Spreadsheet/Excel/Writer/Format.php';<br />
**** require_once PEAR . 'Spreadsheet/Excel/Writer/BIFFwriter.php';<br />
**** require_once PEAR . 'Spreadsheet/Excel/Writer/Worksheet.php';<br />
**** require_once PEAR . 'Spreadsheet/Excel/Writer/Parser.php';<br />
**** require_once PEAR . 'OLE/PPS/Root.php';<br />
**** require_once PEAR . 'OLE/PPS/File.php';<br />
****<br />
**** /vendors/Pear/OLE/PPS.php<br />
**** require_once 'PEAR.php';<br />
**** require_once PEAR . 'OLE.php';<br />
****<br />
**** This had helped the application find my PEAR libraries when trying to do this<br />
**** END ORIGINAL ENTRY ***********************************************</p>
<p><strong><em>Now, a word about the edit. The above method works, but is not a preferred method. The best method for this, so there is no need to edit PEAR library files is the following. And a big thanks to <a href="http://cakebaker.42dh.com/">Daniel Hofstetter</a> for pointing this out. </em></strong></p>
<p>I put this at the top of my controller file. I am sure there is better places for this, probably even the app_controller file so that all controllers get the needed include path set. Here is what I did. </p>
<p>I needed to append the include path so that the new PEAR path would be found. After the php opening, I added this line:</p>
<pre>
ini_set("include_path", PEAR . PATH_SEPARATOR . ini_get("include_path"));
</pre>
<p>I am going to go over this just a little. First off, the ini_set is called to set the include_path. But we do not want to destroy any other include paths that are set up as well. So when we add the PEAR path, we need to also include the other paths as well. So the initial include_path was as follows (given in example form only, where the directory "test" is where I have CakePHP installed)<br />
ini_get("include_path") = </p>
<pre>
/www/htdocs/html/test:/www/htdocs/html/test/app/:.:/usr/local/php5/lib/php
</pre>
<p>Since CakePHP already defines the variable for the PEAR path as "PEAR", we can use that to add to the include path, like shown above. After setting the path using ini_set(), we run ini_get("include_path") it would = </p>
<pre>
/www/htdocs/html/test/vendors/Pear/:/www/htdocs/html/test:/www/htdocs/html/test/app/:.:/usr/local/php5/lib/php
</pre>
<p>By doing it this way, there is no need to edit the PEAR library files, and we can add new PEAR libraries without having to worry about editing those files as well. </p>
<p>Now, I needed to make the controller aware of the vendor library. In my controller file I added this line before the class declaration:</p>
<pre>
App::import('vendor', 'Spreadsheet_Excel_Writer', array('file' => '../vendors/Pear/Spreadsheet/Excel/Writer.php'));
</pre>
<p>In Cake 1.2, this is how the vendor's are imported. The vendor() declaration has been deprecated. This imports a vendor, gives the class a name (I choose the base one that it is usually called), and the location of the of the file. In my set up, I needed to add the "../", you may not have to. </p>
<p>In the function, (I called "export"), I did not want to have a "view" page for it. The first thing I did was grab the information I needed. For this example, I needed all users that signed up for a conference. So I grabbed that information and put it in an array $registrations. </p>
<pre>
function export ($id = null){
       // I only want to get a specific conference, not all of them
	if ( $id == 'all' ){
		$this->Session->setFlash('Please select a specific conference to export the registrations.');
		$this->redirect(array('action' => 'index'));
	}

	// Now get the registrations for the conference
	$registrations = $this->Registration->find('all',
		array(
			'conditions' => array('conference_id' => $id),
			'fields' => array('*'),
			'recursive' => '-1',
			'order' => array('Registration.created'),
		)
	);
</pre>
<p>Now comes the fun part, building the column heading array, and then instantiating the writer</p>
<pre>
	// Set up the header array
	$titles = array(
		'Name' => 15,
		'Address' => 20,
		'City' => 20,
		'State' => 7,
		'Zip Code' => 10,
		'Email' => 20,
		'Phone' => 13,
	);

	$rn = 0; // row number
	// Build the XLS file using PEAR
	$xlsBook = new Spreadsheet_Excel_Writer();
	$xlsBook->send("registrations.xls");
	$xls =&#038; $xlsBook->addWorksheet('Registrations');
</pre>
<p>Everything else is now just as the same as it would be with the Spreadsheet-Excel_writer. Create the formats as you would like, for text, numerics, specialized strings, colors, etc. Write the sheet headings, if you so desire</p>
<pre>
	/* Create styles for the spreadsheet */
	$format_bold =&#038; $xlsBook->addFormat();
	$format_bold->setBold();

	$main =&#038; $xlsBook->addFormat(
		array('Size' => 14,
			'Align' => 'center',
			'Color' => 'black',
			'Bold' => 'true'
		));
	$main->setBold();

	$formatText =&#038; $xlsBook->addFormat(array('Size' => 11));

	$cn = 0;
	$xls->write($rn, 0, "CONFERENCE REGISTRATIONS", $main);
	$xls->mergeCells($rn,0,$rn,11);
	$rn++;
</pre>
<p>As you can see, just use the writer calls to write the data, format it, and do what you need. To get more information on this, please <a href="http://pear.php.net/package/Spreadsheet_Excel_Writer/docs">check the PEAR documentation for this library</a>. </p>
<p>Finish up the column headings by doing a quick little loop</p>
<pre>
	// Set up the headings of the columns
	foreach ( $titles as $t => $val){
		$xls->setColumn($cn, $cn, $val);
		$xls->write($rn, $cn++, $t, $format_bold);
	}
	$rn++;
	// reset the column num
	$cn = 0;
</pre>
<p>Now you can do the actual rows in a loop:</p>
<pre>
	foreach ( $registrations as $r ){
		$xls->write($rn, $cn++, $r['Registration']['name'], $formatText);
	    $xls->write($rn, $cn++, $r['Registration']['address'], $formatText);
	    $xls->write($rn, $cn++, $r['Registration']['city'], $formatText);
	    $xls->write($rn, $cn++, $r['Registration']['state'], $formatText);
	    $xls->write($rn, $cn++, $r['Registration']['zip_code'], $formatText);
	    $xls->write($rn, $cn++, $r['Registration']['email'], $formatText);
	    $xls->write($rn, $cn++, $r['Registration']['contact_phone1'], $formatText);
	    // cycle to the next row
	    $rn++;
	    // Reset the column
	    $cn = 0;
	}

	$xlsBook->close();
	exit();
} // end of function
</pre>
<p>Now, this does the work for me on my code. To call it in the view, I have a page that shows all registrations on the page, the function name is "registrations". I set a variable in this function for the ID number to be passed to the view. In the view for this function, I have put the following:</p>
<pre>
if ( $param != 'all') {
	echo "&lt;p&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; - - &lt;b&gt;";
	echo $html->link(__('EXPORT DATA', true), array('action' => 'export', $param) );
	echo "&lt;/b&gt; - - &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;";
}
</pre>
<p>So I want a specific conference. If there is not one, and they are viewing all registrations for all conferences, then it does not show the link. But if it is a specific id, then it shows the link to export with the corresponding parameter for the ID. </p>
<p>And there it is. Using the Spreadsheet_Excel_Writer PEAR library with CakePHP 1.2. </p>
<p>Again, this works for me, and there may be a better way of doing things, and if so, please feel free to tell me. I am always looking for new things to learn. </p>

<!-- Wordpress Connect Modules v1.05 -->]]></content:encoded>
			<wfw:commentRss>http://www.hirdweb.com/2009/05/04/pear-and-cakephp/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t forget the basics</title>
		<link>http://www.hirdweb.com/2008/07/21/dont-forget-the-basics/</link>
		<comments>http://www.hirdweb.com/2008/07/21/dont-forget-the-basics/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 23:57:27 +0000</pubDate>
		<dc:creator>stephen</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[trouble-shooting]]></category>

		<guid isPermaLink="false">http://www.hirdweb.com/?p=8</guid>
		<description><![CDATA[There was something I was asked to troubleshoot between two different environments. Most reputable places will give at least 2 different environments for application development, the best is to have at least three, development, stage, and production areas. I was asked resolve and fix an issue in the stage area, but it was not happening [...]]]></description>
			<content:encoded><![CDATA[<p>There was something I was asked to troubleshoot between two different environments. Most reputable places will give at least 2 different environments for application development, the best is to have at least three,  development, stage, and production areas.  I was asked resolve and fix an issue in the stage area, but it was not happening in the development area. Normally, I follow a few simple rules to get through this type of troubleshooting. Today, for some reason, I blew those off. Now this is not an end all be all type of list, and I use what is good for me and what I have learned. Other people may find different ways to do this, and find ways that work for them more. Here are some of the major items I check for with web applications in PHP.</p>
<ul>
<li>Check the Apache services, connection, or anything that would lead to just no resulting page whatsoever.</li>
<li>Check the DB server, make sure the server is working, the connection is good, the data flow is there</li>
<li>Check the permission of the database, the tables, the sequences, etc. Whatever is needed from the database, make sure the caller has permissions to do that task</li>
<li>Check the code objects/PEAR packages/framework extensions are installed. If you have a recent version of PHP, then you should be good for PEAR, and if you have the most recent framework version (like Symfony, CakePHP or Zend) that should house them all, but never hurts to check</li>
<li>Check instantiated objects, function calls, object variables, etc. Most of the time it could be a spelling error, or the call is made before the object is created</li>
<li>I check the data being returned and the statements making the calls. What I am calling for may not be listed, or I may need to grab data from another table. This sometimes creates errors for other functions expecting an array and getting a character value.</li>
<li>Dump the session, maybe the session variable was never set, or never started.</li>
<li>Form data and POST variables are always good to give a good ol&#8217; var_dump() or print_r().</li>
</ul>
<p>Obviously this is not all of them, nor is this just a quick checklist. Some of these may take a while to go through, and may have a lot of details to peruse through to find the answer. This will not always give the answer the quickest ways, nor will it ever just shine the answer down to you. But it helps to isolate issues starting form the global level, work down to the application level, and then down to the code level. Plus, it helps eliminate the obvious problems first, so that when someone asks <em>&#8220;is the printer is turned on?&#8221;</em>, I don&#8217;t sit there looking stupid because &#8220;it is turned off&#8221; and I just never looked. But that is what happens at times. </p>
<p>Today, I completely forgot about permissions on a database. Sure, the code works in development, I have my hands all over that environment. But when it does not work in the staging area, I should have checked permissions instead of just lopping off my hand with endless queries to try and see where the code went wrong. Just one simple act of a GRANT permission to the application user calling the query would have fixed it. But I was forgetful and should have checked that first. Sometimes developers go down the wrong path. To stay down the wrong path, well, you can finish that one on your own. </p>

<!-- Wordpress Connect Modules v1.05 -->]]></content:encoded>
			<wfw:commentRss>http://www.hirdweb.com/2008/07/21/dont-forget-the-basics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
