<?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>lightyeardesign.com</title>
	<atom:link href="http://lightyeardesign.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://lightyeardesign.com</link>
	<description>Design.  Develop.  Defy.</description>
	<lastBuildDate>Wed, 29 Jun 2011 19:03:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>ExpressionEngine: display a navigation menu if an entry is assigned a specific category.</title>
		<link>http://lightyeardesign.com/2011/06/expressionengine-dynamically-display-navigation-menu-if-an-entry-is-assigned-a-certain-category/</link>
		<comments>http://lightyeardesign.com/2011/06/expressionengine-dynamically-display-navigation-menu-if-an-entry-is-assigned-a-certain-category/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 19:00:48 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[ExpressionEngine]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=124</guid>
		<description><![CDATA[As an avid ExpressionEngine user, I like to dynamically generate as much as I can. This also includes the dynamic generation of navigation menus, naturally. However, there are times when I will use an entry as a static navigation menu by assigned it a specific URL TITLE (for example: whats_new or righthand_menu). Now, in the [...]]]></description>
			<content:encoded><![CDATA[<p>As an avid ExpressionEngine user, I like to dynamically generate as much as I can.  This also includes the dynamic generation of navigation menus, naturally.  However, there are times when I will use an entry as a static navigation menu by assigned it a specific URL TITLE (for example: whats_new or righthand_menu).  Now, in the case of categories, how does one display this right-hand menu <strong>ONLY</strong> on entries of a weblog that are assigned a specific category?  Here is how:<br />
<code><br />
        {!--Display right-hand menu ONLY if the entry has been assigned to the AUTOMOBILES category--}<br />
        {exp:query sql="select count(w.url_title) AS post_count from exp_weblog_titles w, exp_category_posts cp, exp_categories c where w.entry_id = cp.entry_id and cp.cat_id = c.cat_id and c.cat_url_title='automobiles_category' and w.url_title = '{segment_3}' limit 1"}<br />
        <?php $assignedCatVar = "{post_count}";?></p>
<p>        {/exp:query}<br />
        <?php if ($assignedCatVar == "1") { ?><br />
            {!-- Display AUTOMOBILES right-hand menu --}</p>
<div class="contents03">
                        {exp:query sql="SELECT e1.title, e1.entry_date, e1.edit_date, e2.field_id_2 FROM exp_weblog_titles e1, exp_weblog_data e2 WHERE e1.entry_id = e2.entry_id and e2.weblog_id = 51 and e1.url_title = 'righthand_menu' LIMIT 1"}<br />
                            {field_id_2}<br />
                        {/exp:query}
                    </div>
<p>        <?php } ?></code></p>
<p>So, what exactly does this do?<br />
The first query retrieves the post count of any entries (in this case, the URL TITLE of the entry is in the third segment of the URL) that are assigned to a specific category (we are looking for 1 here; in fact, the LIMIT 1 line keeps the query from searching for anything greater, as our relevant choices are either 1 or 0).  The count is then applied to a PHP variable called <em>assignedCatVar</em>.</p>
<p>If the assignedCatVar is = 1, then the next query grabs the contents of the<em> right-hand menu</em> entry and displays it appropriately on the page.  </p>
<p>Simple and effective.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2011/06/expressionengine-dynamically-display-navigation-menu-if-an-entry-is-assigned-a-certain-category/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExpressionEngine search results:  custom template paths for section URLs with categories</title>
		<link>http://lightyeardesign.com/2011/02/expressionengine-search-results-custom-template-paths-for-section-urls-with-categories/</link>
		<comments>http://lightyeardesign.com/2011/02/expressionengine-search-results-custom-template-paths-for-section-urls-with-categories/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 23:12:01 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[ExpressionEngine]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=113</guid>
		<description><![CDATA[We use ExpressionEngine on a number of supported sites, and I tend to use ExpressionEngine&#8217;s (EE) internal search mechanism whenever feasible. The search results are generated from path setting specified at Admin › Weblog Administration › Weblog Management › Edit Weblog Preferences› Path Settings › Search Results URL . For example, setting the Search Results [...]]]></description>
			<content:encoded><![CDATA[<p>We use ExpressionEngine on a number of supported sites, and I tend to use ExpressionEngine&#8217;s (EE) internal search mechanism whenever feasible.  The search results are generated from path setting specified at Admin  ›  Weblog Administration  › Weblog Management  ›  Edit Weblog Preferences›  Path Settings ›  Search Results URL .</p>
<p>For example, setting the <strong>Search Results URL</strong> value to<br />
<code>{homepage}staff-members</code> will create a SEARCH RESULT of <em>http://mysite.com/staff-members/</em>.</p>
<p>Easy enough, right?</p>
<p>Now, what do you do when you have a Weblog that contains category-based information.  The specified <em>Search Results URL</em> does not take this information into account.  So, if you have a weblog with a hard-coded path of <em>http://mysite.com/staff-members/category1/johndoe</em> ,  how do you get the category to show up in the search results?</p>
<p>I have a workaround on the RESULTS template in my SEARCH template group:</p>
<blockquote><p>{exp:search:search_results}</p>
<p>&lt;?php $autoPath = &#8216;{auto_path}&#8217;;</p>
<p>$lastSegment = basename($autoPath);</p>
<p>//Staff-member URL update, based on the category assigned to the entry</p>
<p>if(strpos($autoPath, &#8216;staff-members&#8217;)){</p>
<p>//variable to assign the category to the appropriate URL segment for the Rule</p>
<p>$catVar = 1;</p>
<p>$basename = &#8216;catPath&#8217;;</p>
<p>?&gt;</p>
<p>{categories}</p>
<p>&lt;?php</p>
<p>$tempname = $basename.$catVar;</p>
<p>$$tempname = &#8220;{category_url_title}&#8221;;</p>
<p>$catVar++;</p>
<p>?&gt;</p>
<p>{/categories}</p>
<p>&lt;?php $autoPath = &#8220;{homepage}&#8221;.&#8221;staff-members/$catPath1/$lastSegment&#8221;;</p>
<p>} ?&gt;</p>
<p>&lt;br /&gt;&lt;span&gt;&lt;?php echo $autoPath; ?&gt;&lt;/span&gt;</p>
<p>&lt;/div&gt;</p>
<p>{/exp:search:search_results}</p></blockquote>
<p>So, if the <strong>staff-members</strong> URL segment exists in the specified URL&#8217;s path, the Category/Categories assigned to the Entry are obtained and then added to the URL, defined by the $autoPath variable.</p>
<p>It might not be the most elegant solution, but it works great for us.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2011/02/expressionengine-search-results-custom-template-paths-for-section-urls-with-categories/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Library Not Registered Javascript error with SharePoint and Internet Explorer 8</title>
		<link>http://lightyeardesign.com/2011/01/library-not-registered-javascript-error-with-sharepoint-and-internet-explorer-8/</link>
		<comments>http://lightyeardesign.com/2011/01/library-not-registered-javascript-error-with-sharepoint-and-internet-explorer-8/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 16:33:45 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[Office 2007]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=109</guid>
		<description><![CDATA[We use SharePoint 3.0 for quite a bit of document collaboration. Unfortunately, when using Internet Explorer 8, an error is thrown when we attempted to upload multiple documents within SharePoint. The error details mention Library Not Registered. Luckily, there is an easy fix: Open up any MS Office 2007 product. In my instance, I used [...]]]></description>
			<content:encoded><![CDATA[<p>We use SharePoint 3.0 for quite a bit of document collaboration.  Unfortunately, when using Internet Explorer 8, an error is thrown when we attempted to upload multiple documents within SharePoint.  The error details mention <em>Library Not Registered</em>. </p>
<p>Luckily, there is an easy fix:</p>
<ul>
<li>Open up any MS Office 2007 product.  In my instance, I used Office 2007.</li>
<li>Go to Help>Office Diagnostics.</li>
<li>Run diagnostics.  This took about 5 minutes to complete.</li>
<li>Return to your SharePoint site. the multiple document upload tool should now be working.  Apparently, this fix re-registered any .DLLs that were causing the error.  I love easy fixes!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2011/01/library-not-registered-javascript-error-with-sharepoint-and-internet-explorer-8/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Applying Word Wrap to columns in Excel</title>
		<link>http://lightyeardesign.com/2010/02/applying-word-wrap-to-columns-in-excel/</link>
		<comments>http://lightyeardesign.com/2010/02/applying-word-wrap-to-columns-in-excel/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 22:37:26 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[Office 2007]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=97</guid>
		<description><![CDATA[We have to convert a lot of Microsoft Excel sheets to PDF format.  Unfortunately, multi-column sheets (for example, 5 columns of contact information: names, addresses, email addresses) take up a lot of real estate, so Adobe PDF usually breaks the sheet into 2 or more pages of columns.   One easy way around this is to [...]]]></description>
			<content:encoded><![CDATA[<p>We have to convert a lot of Microsoft Excel sheets to PDF format.  Unfortunately, multi-column sheets (for example, 5 columns of contact information: names, addresses, email addresses) take up a lot of real estate, so Adobe PDF usually breaks the sheet into 2 or more pages of columns.   One easy way around this is to enable WORD WRAP in Excel, then resize the columns; use Print Preview to remove any borders/padding, and you can get most things to fit across one page.</p>
<p>Here is how to enable Word Wrap in Excel (2003 and 2007 version):</p>
<ul>
<li>Hold Control and then click on the top column header (usually has a letter next to it) for each column with content.  You want to get all of your columns (with data in them) highlighted.</li>
<li>Press CONTROL and the 1 key;  this will open up the FORMAT CELLS menu box.</li>
<li>Choose the ALIGNMENT tab, and then put a check next to WRAP TEXT.  Press OK.  Here is what the menu should look like:
<div id="attachment_98" class="wp-caption alignnone" style="width: 473px"><img class="size-full wp-image-98" title="Excel FORMAT CELLS menu" src="http://lightyeardesign.com/wp-content/uploads/2010/02/Excel-format-cells.jpg" alt="Choose Wrap Text from the MS Excel FORMAT CELLS menu." width="463" height="465" /><p class="wp-caption-text">Choose Wrap Text from the MS Excel FORMAT CELLS menu.</p></div>
<p>Don&#8217;t forget to use the PRINT PREVIEW (FILE&gt;PRINT&gt;PRINT PREVIEW) to take a peak at your sheet before printing.  You might have to edit  the margins to get everything to fit as needed.  (Put a check next to SHOW MARGINS at the top menu).</p>
<p>You should now be ready to print to PDF!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2010/02/applying-word-wrap-to-columns-in-excel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Save a semi-colon delimited file in Microsoft Excel</title>
		<link>http://lightyeardesign.com/2010/02/save-a-semi-colon-delimited-file-in-microsoft-excel/</link>
		<comments>http://lightyeardesign.com/2010/02/save-a-semi-colon-delimited-file-in-microsoft-excel/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 14:47:35 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[Office 2007]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=94</guid>
		<description><![CDATA[Microsoft Excel is a great program, especially when you are created delimited files to import into MySQL databases. However, when you have commas within data columns, using commas as the delimiter will ruin your day. A better approach is to use semi-colons as the delimiter&#8230;But Excel does not give you this option. So, the easiest [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft Excel is a great program, especially when you are created delimited files to import into MySQL databases. However, when you have commas within data columns, using commas as the delimiter will ruin your day. A better approach is to use semi-colons as the delimiter&#8230;But Excel does not give you this option. So, the easiest approach is to make this change in the Windows settings.</p>
<p>To do so:</p>
<p>1. Go to START&gt;SETTINGS&gt;REGIONAL AND LANGUAGE OPTIONS<br />
2. Click on the CUSTOMIZE button<br />
3. Next to LIST SEPARATOR, type in a semi-colon (;)</p>
<p>This will set the default delimiter value to a semi-colon.  So, when you save a file in Excel as .csv, you will have semi-colons to separate the row data.</p>
<p>Note: I used Windows XP for the above settings.   A different flavor of Windows might have different options.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2010/02/save-a-semi-colon-delimited-file-in-microsoft-excel/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Harden your At-home Wi-Fi Security</title>
		<link>http://lightyeardesign.com/2009/08/harden-your-at-home-wi-fi-security/</link>
		<comments>http://lightyeardesign.com/2009/08/harden-your-at-home-wi-fi-security/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 13:53:00 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[network]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=89</guid>
		<description><![CDATA[So you have a wi-fi home network. Have you secured it? Or, did you just plug it in and started surfing? If you just plugged it in, chances are that you are giving your neighbors access to your network. I doubt if they will thank you for the freebie, so here are some steps to [...]]]></description>
			<content:encoded><![CDATA[<p>So you have a wi-fi home network.   Have you secured it?  Or, did you just plug it in and started surfing?  If you just plugged it in, chances are that you are giving your neighbors access to your network.   I doubt if they will thank you for the freebie, so here are some steps to keep your wi-fi private and secure.<br />
<span id="more-89"></span></p>
<ul>
<li>If your access point is older than 2 or 3 years, it is time to replace it.  Most older access points do no adhere to the latest security protocols, such as WPA2 security (WEP and WPA security are pretty much out-dated and should be avoided).</li>
<li>Please, please, <strong>PLEASE</strong> change the default SSID (service set identifier) and password that comes with the wireless access point.  The default values are generally simple and are listed on the manufacturer&#8217;s website.  Remember, use strong passwords that are not easy to guess.</li>
<li>Turn off the <strong>auto-connect</strong> option.   Automatically connecting to networks is a good way to open up your computer to security risks.</li>
<li>If your access point has a hardware firewall, enable and use it.</li>
<li>When installing your access point, try to keep it in the center of your home.  That way, less of the signal leaks out of your house&#8230;And into the potential, greedy hands of thy  neighbors.  Nothing wrong with &#8216;security through obscurity.&#8217;</li>
<li>When you are not online, turn off the access point.  It is impossible to hack something that is not powered on.  Go a bit green; hook your access point, computers, monitors, printers to a power strip.  When not in use, turn the power strip off.  You can save some energy and help to protect your systems.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2009/08/harden-your-at-home-wi-fi-security/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing Messages from Outlook to Gmail</title>
		<link>http://lightyeardesign.com/2009/07/importing-messages-from-outlook-to-gmail/</link>
		<comments>http://lightyeardesign.com/2009/07/importing-messages-from-outlook-to-gmail/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 14:49:30 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[Office 2007]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=87</guid>
		<description><![CDATA[I have a ton of messages in my Personal Folder in Outlook 2007. However, I want to quickly add them to my gmail account. After a bit of research, I found an easy, straightforward method to do just that. First, we will need to enable IMAP in Gmail: Sign in to your Gmail account. Click [...]]]></description>
			<content:encoded><![CDATA[<p>I have a ton of messages in my Personal Folder in Outlook 2007.  However, I want to quickly add them to my gmail account.  After a bit of research, I found an easy, straightforward method to do just that.</p>
<p>First, we will need to enable IMAP in Gmail:</p>
<ol>
<li>Sign in to your Gmail account.</li>
<li>Click on <strong>Settings</strong> (the link should be at the top of the page)</li>
<li>Choose <strong>Forwarding</strong> and POP/IMAP.</li>
<li>Choose <strong>Enable IMAP</strong></li>
<li>Choose <strong>Save Changes</strong></li>
</ol>
<p>Now, we need to configure Outlook to connect to the Gmail account:</p>
<ol>
<li>Open Outlook.</li>
<li>Click on <strong>Tools&gt;Account Settings</strong>.</li>
<li>Click <strong>New</strong>.</li>
<li>Enter your display name, email address (including &#8216;@gmail.com&#8217;), and password.</li>
<li>Select the &#8216;<strong>Manually configure server settings or additional server types</strong>&#8216; checkbox.</li>
<div class="wp-caption alignnone" style="width: 634px"><img title="Importing Data from Outlook to Gmail" src="http://www.google.com/help/hc/images/gmail_77689b_en.gif" alt="Step 1 of Configuring Outlook to connect to Gmail." width="624" height="469" /><p class="wp-caption-text">Step 1 of Configuring Outlook to connect to Gmail.</p></div>
<li>Select <strong>Internet E-mail</strong>.</li>
<li>Settings: name, full email address (including &#8216;@gmail.com&#8217; or &#8216;@your_domain.com&#8217;)
<ul>
<li>In the <strong>Account Type</strong> dropdown menu, select <strong>IMAP</strong>; enter the incoming and outgoing server names shown below.</li>
<li>In the &#8216;User Name&#8217; field, give your full Gmail address, including &#8216;@gmail.com&#8217; or &#8216;@your_domain.com.&#8217;</li>
<li>After creating these settings, clicking <strong>Next</strong> takes you to the end of the setup.</li>
</ul>
<div class="wp-caption alignnone" style="width: 634px"><img title="Step 2 of Configuring Outlook to communicate with Gmail." src="http://www.google.com/help/hc/images/gmail_77689c_en.gif" alt="Step 2 of configuring Outlook to communicate with Gmail." width="624" height="469" /><p class="wp-caption-text">Step 2 of configuring Outlook to communicate with Gmail.</p></div></li>
<li>In the <strong>Tools</strong> menu, select <strong>Options</strong> then <strong>Mail Setup</strong>. Under &#8216;Email Accounts,&#8217; click <strong>E-mail Accounts</strong>.</li>
<li> Select an account, and click <strong>Change</strong> above the list of accounts. Click <strong>More Settings</strong>, then the <strong>Advanced</strong> tab.
<ul>
<li>Incoming server must be 993, and must use SSL encryption.</li>
<li>Outgoing server can use 587, TLS encryption.</li>
</ul>
<p><div class="wp-caption alignnone" style="width: 402px"><img title="Configuring Incoming and Outgoing information for communication between Outlook and Gmail." src="http://www.google.com/help/hc/images/gmail_77689d_en.gif" alt="Configuring Incoming and Outgoing information for communication between Outlook and Gmail." width="392" height="430" /><p class="wp-caption-text">Configuring Incoming and Outgoing information for communication between Outlook and Gmail.</p></div></li>
<li>Click the <strong>Outgoing Server</strong> tab. Make sure that &#8216;My outgoing server (SMTP) requires authentication&#8217; is selected. The  button <strong>&#8216;Use same settings as my incoming mail server</strong>&#8216; should also be selected.</li>
<p><div class="wp-caption alignnone" style="width: 402px"><img title="Internet Email Settings for communication between Outlook and Gmail." src="http://www.google.com/help/hc/images/gmail_77689e_en.gif" alt="Internet Email Settings for communication between Outlook and Gmail." width="392" height="430" /><p class="wp-caption-text">Internet Email Settings for communication between Outlook and Gmail.</p></div>
<li>Click <strong>OK</strong> &gt; <strong>Next</strong> &gt; <strong>Finish</strong> &gt; <strong>Close</strong> &gt; <strong>OK</strong>.</li>
</ol>
<p>You can now drop and drag folders/messages from Outlook to your newly created Gmail account from within Outlook.  When you create new folders, this will create new labels/folders in your Gmail account.  One note: sub-folders do not seem to display within Gmail, so you might need to create new folders for each of your sub-folder.   Once you have copied everything over to Gmail, you can simply remove the new account from within Outlook.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2009/07/importing-messages-from-outlook-to-gmail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplified PHP Input Validation for forms</title>
		<link>http://lightyeardesign.com/2009/06/simplified-php-input-validation-for-forms/</link>
		<comments>http://lightyeardesign.com/2009/06/simplified-php-input-validation-for-forms/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 14:21:51 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=75</guid>
		<description><![CDATA[When it comes to online forms, gathering information from the user is of utmost importance. That being said, one must ensure that the user enters the correct information in the form, especially from a security point of view&#8230;Input from users in a web form provides a direct avenue of attack into the application (just google [...]]]></description>
			<content:encoded><![CDATA[<p>When it comes to online forms, gathering information from the user is of utmost importance.  That being said, one must ensure that the user enters the correct information in the form, especially from a security point of view&#8230;Input from users in a web form provides a direct avenue of attack into the application (just google <a href="http://www.google.com/search?client=firefox-a&amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;channel=s&amp;hl=en&amp;q=sql+injection&amp;btnG=Google+Search">SQL Injection</a>).</p>
<div id="attachment_80" class="wp-caption alignnone" style="width: 138px"><img class="size-full wp-image-80" title="Take a simplified, yet effective approach to input validtion with your web forms and PHP." src="http://lightyeardesign.com/wp-content/uploads/2009/06/1245162215_security.png" alt="Take a simplified, yet effective approach to input validtion with your web forms and PHP." width="128" height="128" /><p class="wp-caption-text">Take a simplified, yet effective approach to input validation with your web forms and PHP.</p></div>
<p>As far as input validation goes, most programmers prefer a proactive strategy: you determine what input you want to collect from the user (number format for ages, alpha characters for names, and so forth) and then you collect <strong>only</strong> that format, producing an error message when the user enters something else. However, some users quickly get frustrated when they have to re-enter  the input again, or they can&#8217;t figure out what is causing the problem.  To combat the inherent confusion of the user, why not run all input through a validation function that automatically searches for potentially harmful input, removes the offending characters, then continues to process the form?   This is what we are going to do:</p>
<p>[php]<br />
&lt;?php</p>
<p>//When the form is submitted, our 2 form fields, username and password, will be purged of potentially harmful characters.<br />
//In this case, the characters will be replaced with blank spaces.<br />
if ($_POST) {</p>
<p>//Function to remove specific special characters<br />
function cleanInput($text)<br />
{<br />
$code_entities_match = array(&#8216;-&#8217;,'&gt;&#8217;,'!&#8217;,'#&#8217;,'$&#8217;,'%&#8217;,'^&#8217;,'&amp;&#8217;,'*&#8217;,'(&#8216;,&#8217;)',&#8217;{&#8216;,&#8217;}',&#8217;|',&#8217;:',&#8217;&quot;&#8217;,'&lt;&#8217;,&#8217;[',']&#8216;,&#8217;\\&#8217;,';&#8217;,&quot;&#8217;&quot;,&#8217;,',&#8217;/',&#8217;*',&#8217;~',&#8217;`');<br />
$code_entities_replace = array(&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;);<br />
$text = str_replace($code_entities_match, $code_entities_replace, $text);<br />
return $text;<br />
}<br />
//Set form variables<br />
$Username=stripslashes(cleanInput($_POST['username']));<br />
$Password=stripslashes(cleanInput($_POST['password']));</p>
<p>//process your form variables as needed, as they have been sanitized with our cleanInput function.<br />
//You can write the values to a database, send via an email script, and so forth.</p>
<p>}//End post<br />
?&gt;</p>
<p>&lt;form action=&quot;&lt;?php echo $_SERVER['PHP_SELF']; ?&gt;&quot; method=&quot;POST&quot; id=&quot;login&quot; name=&quot;login&quot;&gt;</p>
<p>&lt;div class=&quot;label01&quot;&gt;Username:&lt;/div&gt;<br />
&lt;input type=text size=30 name=&quot;username&quot; maxlength=30 /&gt;</p>
<p>&lt;div class=&quot;label01&quot;&gt;Password:&lt;/div&gt;<br />
&lt;input type=password size=30 name=&quot;password&quot; maxlength=30 /&gt;<br />
&lt;br /&gt;<br />
&lt;div id=&quot;submitButton&quot;&gt;<br />
&lt;button type=&quot;submit&quot; value=&quot;submit&quot; name=&quot;submit&quot; &gt;Logon&lt;/button&gt;</p>
<p>&lt;/div&gt;</p>
<p>&lt;/form&gt;<br />
[/php]</p>
<p>Please read the script comments to see what is taking place.  This is a rudimentary approach to input validation, but it works, is simple to initialize, and it will help to keep your data safe.</p>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2009/06/simplified-php-input-validation-for-forms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDAP and PHP login script</title>
		<link>http://lightyeardesign.com/2009/06/ldap-and-php-login-script/</link>
		<comments>http://lightyeardesign.com/2009/06/ldap-and-php-login-script/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 20:03:41 +0000</pubDate>
		<dc:creator>Thantos</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=53</guid>
		<description><![CDATA[Authenticating users of your web applications can be tedious, especially when your users are expected to remember multiple passwords (which can become a security vulnerability in it&#8217;s own right). That being said, integrating your login scripts with Active Directory/LDAP can be beneficial for a variety reasons: stronger passwords, fewer login credentials for your user to [...]]]></description>
			<content:encoded><![CDATA[<p>Authenticating users of your web applications can be tedious, especially when your users are expected to remember multiple passwords (which can become a security vulnerability in it&#8217;s own right).  That being said, integrating your login scripts with Active Directory/LDAP can be beneficial for a variety reasons: stronger passwords, fewer login credentials for your user to remember, and fewer headaches for you.   Here is how we integrated LDAP with our online application authentication.</p>
<p>LDAP (short for Lightweight Directory Access Protocol), a directory service that runs over TCP/IP, stores information.  The storage is similar to how a database stores information, but the structure is ideal for attribute-based, hierarchical structured data that does not undergo frequent changes (for example, the employees&#8217;s name, Active Directory group membership, address, and so forth).  The LDAP directory can be thought of as a tree of nodes, where each node represents an entry in the LDAP database.  These entries are comprised of a collection of attribute-value pairs, and they are identified uniquely by a &#8216;distinguished name&#8217; or DN.  The DN is important, because this is what we will be using to determine a user&#8217;s group membership.<br />
Our login script will</p>
<ol>
<li>First bind to our LDAP server with a resource account (we are not using anonymous binding, so we will need to provide a resource account&#8217;s credentials)</li>
<li>Check that the user&#8217;s ID and password are legit and exist in our Active Directory environment</li>
<li>Check if the user is a member of a particular security group
</ol>
<p>If all of these conditions are met, the users will have successfully logged on and will be granted access to our application.</p>
<p>We will store our authentication function in a php file entitled <strong>resourceBind.php</strong>.  The entire contents of resourceBind.php:<br />
[php]<strong>&lt;?php</p>
<p>function UMldap($Username, $SSO_Password){<br />
//*************************************<br />
///////////////////////////////// Using ldap bind<br />
$ldaprdn  = &#8216;bindaccountname&#8217;;    // ldap rdn or dn<br />
$ldappass = &#8216;bindaccountpassword&#8217;;  // associated password<br />
$ldapserver = &#8216;ldaps://your.ldap.server:3269&#8242;;</p>
<p>//This is the Active Directory group that users MUST be a member of in order to login successfully<br />
$groupPath1 = &quot;CN=YOURSECURITYGROUP-GS,OU=Accounting,OU=Lewis-Building,OU=Headquarters,DC=headquarters,DC=acme,DC=com&quot;;</p>
<p>/////////////////////////////Base DN<br />
$ldap_base_dn = &quot;CN=Users,DC=headquarters,DC=acme,DC=com&quot;;</p>
<p>  $ldapconn = ldap_connect($ldapserver)or die(&quot;Could not connect to LDAP server.&quot;);</p>
<p>	if ($ldapconn) {   //connect to ldap server<br />
            // binding to ldap server<br />
        $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);<br />
        // verify binding<br />
        if ($ldapbind) {<br />
           // echo &quot;LDAP bind successful&#8230;&quot;;<br />
			$errorCount = 0;</p>
<p>			$ld_filter = &quot;samaccountname=&quot; . $Username;<br />
			$ldap_base_dn = &quot;DC=com&quot;;<br />
                        //Recursively search for the account name in the directory tree.  Slow, but effective&#8230;<br />
			$result = ldap_search($ldapconn, $ldap_base_dn, $ld_filter);</p>
<p>       //Create result set<br />
       $entries = ldap_get_entries($ldapconn, $result);</p>
<p>      //If the account exists, attempt a bind with it.  This will ensure that the provided password is legit</p>
<p>      $bind = @ldap_bind($ldapconn, $entries[0][dn], $SSO_Password);<br />
if( !$bind || !isset($bind))<br />
{<br />
     //the bind failed, which means that the user could have typed in the wrong ID or password.  We will display another login form<br />
?&gt;</p>
<p>     &lt;form action=&quot;&lt;?php echo $_SERVER['PHP_SELF']; ?&gt;&quot; method=&quot;POST&quot; id=&quot;login&quot; name=&quot;login&quot;&gt;<br />
     Username: &lt;input type=text size=30 name=&quot;ssoname&quot; maxlength=30 /&gt;&lt;br /&gt;<br />
     Password: &lt;input type=password size=30 name=&quot;ssopass&quot; maxlength=30 /&gt;&lt;br /&gt;<br />
     &lt;button type=&quot;submit&quot; value=&quot;submit&quot; name=&quot;submit&quot; &gt;Logon&lt;/button&gt;<br />
     &lt;/form&gt;<br />
&lt;?php<br />
   //no point in running the rest of the function, so exit out.<br />
    exit;</p>
<p>} </p>
<p>	       $ii=0;<br />
	       for ($i=0; $ii &lt; $entries[$i][&quot;count&quot;]; $ii++)<br />
	       {</p>
<p>	          $data = $entries[$i][$ii];</p>
<p>	          if ($data == &quot;memberof&quot;) {</p>
<p>                        $total_memberof = count($entries[$i][$data]);</p>
<p>			  	$jj=0;<br />
			        for ($jj=0; $jj&lt;$total_memberof; $jj++) {</p>
<p>			        //Check the groups that the user is a member of and see if our specific group is in the list<br />
			                if ($entries[$i][$data][$jj] == $groupPath1)<br />
			                {<br />
                                               // The  user is a member of the group, so lets create a session and then return true<br />
						$_SESSION['USERGROUP'] = $entries[$i][$data][$jj];<br />
						return true;<br />
						break;</p>
<p>			                }<br />
                   }//end for<br />
            }//end if<br />
        }//end for<br />
        } else { //could not bind, so display an error message and the login form<br />
                // We could not bind with our default resource account, so let&#8217;s exit and not waste any time with the users credentials<br />
		$displayForm=true;<br />
        }</p>
<p>	}///close connect IF<br />
 //Unbind from our resource account<br />
  ldap_unbind($ldapconn);</p>
<p>//*************************************</p>
<p>}//end function</p>
<p>?&gt;</strong><br />
[/php]</p>
<p>And, our login page, which we will call <strong>login.php</strong>, and which will be located in the same directory as resourceBind.php:<br />
[php]&lt;?php<br />
//Disable error messages<br />
    error_reporting(0);<br />
?&gt;<br />
&lt;?php require_once(&#8216;resourceBind.php&#8217;); ?&gt;<br />
&lt;?php<br />
if ($_POST) {</p>
<p>//Handy function to remove specific special characters from user provided input.  ALWAYS validate user input.  In this case, we are removing characters that are not allowed in usernames and passwords.<br />
     function cleanTxt($text)<br />
     {<br />
     	     $code_entities_match = </p>
<p>array(&#8216;&#8211;&#8217;,'&gt;&#8217;,'&amp;quot;&#8217;,'!&#8217;,'#&#8217;,'$&#8217;,'%&#8217;,'^&#8217;,'&amp;&#8217;,'*&#8217;,'(&#8216;,&#8217;)',&#8217;{&#8216;,&#8217;}',&#8217;|',&#8217;:',&#8217;&quot;&#8217;,'&lt;&#8217;,&#8217;[',']&#8216;,&#8217;\\&#8217;,';&#8217;,&quot;&#8217;&quot;,&#8217;,',&#8217;/',&#8217;*',&#8217;~',&#8217;`');<br />
     	     $code_entities_replace = array(&#8216;-&#8217;,'-&#8217;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;,&#8221;);<br />
     	     $text = str_replace($code_entities_match, $code_entities_replace, $text);<br />
     	     return $text;<br />
     }<br />
  //Set form variables<br />
 $Username=stripslashes(cleanTxt($_POST['ssoname']));<br />
 $SSO_Password=stripslashes($_POST['ssopass']);</p>
<p>//Get Ip Address and User Agent information.   This is useful info to store in sessions, or a database table, especially if you need to track timestamps and access<br />
  $userIP = $_SERVER['REMOTE_ADDR'];<br />
//Get Timestamp<br />
  $myDate = date(&quot;Y-m-d H:i:s&quot;);//Date in easy-to-read format</p>
<p>$displayForm=false;</p>
<p>        if(UMldap($Username,$SSO_Password)){<br />
           //set complex string in case there is no &#8216;whencreated&#8217; field for the username</p>
<p>		//User has valid credentials.  We are creating a new session variable with the user name.  This is also a good place to effectively double up your authentication security by checking to see if the user name exists in another medium, such as a MySQL or Oracle table.<br />
                   $_SESSION['USERCMS'] = $Username;</p>
<p>                   //The login is a smashing success, so redirect the user to the protected page.<br />
				   $MM_redirectWithSuccess = &quot;Successful_login.php&quot;;<br />
				   header(&quot;Location: &quot;. $MM_redirectWithSuccess );</p>
<p>        } else {<br />
        /We can&#8217;t log the user in, so display the login form again<br />
	$displayForm=true;<br />
        }</p>
<p>//unbind<br />
  ldap_unbind($ldapconn);</p>
<p>//*************************************<br />
}//end POST check</p>
<p>?&gt;<br />
&lt;!DOCTYPE html<br />
     PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;<br />
     &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;</p>
<p>&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; &gt;</p>
<p>&lt;head&gt;<br />
&lt;title&gt;LDAP Login Form&lt;/title&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;h1&gt;Login&lt;/h1&gt;<br />
&lt;?php</p>
<p>//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
  //Form variables to display previously filled out fields<br />
 $displayForm=true;<br />
 $ssoname=&#8221;;<br />
 $ssopass=&#8221;;<br />
//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>//Display the login form<br />
if ($displayForm){//Display the request form<br />
?&gt;</p>
<p>&lt;form action=&quot;&lt;?php echo $_SERVER['PHP_SELF']; ?&gt;&quot; method=&quot;POST&quot; id=&quot;login&quot; name=&quot;login&quot;&gt;</p>
<p>UserID:<br />
&lt;input type=text size=30 name=&quot;ssoname&quot; maxlength=30 /&gt;</p>
<p>Password:<br />
&lt;input type=password size=30 name=&quot;ssopass&quot; maxlength=30 /&gt;<br />
&lt;br /&gt;</p>
<p> &lt;button type=&quot;submit&quot; value=&quot;submit&quot; name=&quot;submit&quot; &gt;Logon&lt;/button&gt;</p>
<p>&lt;/form&gt;</p>
<p>&lt;?php<br />
  }<br />
?&gt;</p>
<p>&lt;!&#8211; Javascript to move the cursor to the Username form field.  This is a small convenience to the user. &#8211;&gt;<br />
&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;<br />
document.forms['login'].elements['ssoname'].focus();<br />
&lt;/script&gt;</p>
<p>&lt;/body&gt;<br />
&lt;/html&gt;<br />
[/php]</p>
<p>To figure out how everything works, please read the comments within the code.  If you are interested in learning more, please check out Hugh&#8217;s excellent book:<br />
<iframe src="http://rcm.amazon.com/e/cm?t=gizwhi-20&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596005431&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;m=amazon&#038;lc1=2970A6&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2009/06/ldap-and-php-login-script/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Serving css to iPhones and other mobile devices</title>
		<link>http://lightyeardesign.com/2009/05/serving-css-to-iphones-and-other-mobile-devices/</link>
		<comments>http://lightyeardesign.com/2009/05/serving-css-to-iphones-and-other-mobile-devices/#comments</comments>
		<pubDate>Fri, 15 May 2009 13:42:19 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[CSS]]></category>

		<guid isPermaLink="false">http://lightyeardesign.com/?p=42</guid>
		<description><![CDATA[Do you need to send iPhones and other mobile devices to a separate stylesheet for your phone?  You can use the following code:]]></description>
			<content:encoded><![CDATA[<p>Do you need to send iPhones and other mobile devices to a separate stylesheet for your phone?  You can use the following code:</p>
<blockquote><p><code>
<link media="only screen and (max-device-width: 480px)" href="small-device.css" type="text/css" rel="stylesheet"></code></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://lightyeardesign.com/2009/05/serving-css-to-iphones-and-other-mobile-devices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

