<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Brenelz Web Design Solutions</title> <link>http://brenelz.com</link> <description>a winnipeg website design company.</description> <lastBuildDate>Tue, 27 Jul 2010 16:18:25 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BrenelzsWebDevelopmentTips" /><feedburner:info uri="brenelzswebdevelopmenttips" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://blog.brenelz.com</link><url>http://feeds.feedburner.com/~fc/BrenelzsWebDevelopmentTips?bg=99CCFF&amp;amp;fg=444444&amp;amp;anim=0</url><title>Brenelz's Subscribers</title></image><feedburner:emailServiceId>BrenelzsWebDevelopmentTips</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>WordPress 3.0 Custom Posts</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/xeXnhWdDh10/</link> <comments>http://brenelz.com/blog/wordpress-3-0-custom-posts/#comments</comments> <pubDate>Mon, 19 Jul 2010 13:49:10 +0000</pubDate> <dc:creator>Alex</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2352</guid> <description><![CDATA[Reading time: 9 &#8211; 14 minutes Since the update of WordPress from version 2.9 to WordPress 3.0 one of the main noticeable improvements (to make it into more of a CMS system) is the ability to add a new custom post type into your WordPress system. If you want to have an option to be able to [...]Related posts:<ol><li><a href='http://brenelz.com/blog/using-wordpress-custom-fields/' rel='bookmark' title='Permanent Link: Using WordPress Custom Fields'>Using WordPress Custom Fields</a></li><li><a href='http://brenelz.com/blog/quick-tip-wordpress-random-posts/' rel='bookmark' title='Permanent Link: Quick Tip: WordPress Random Posts'>Quick Tip: WordPress Random Posts</a></li><li><a href='http://brenelz.com/blog/wordpress-27-is-out/' rel='bookmark' title='Permanent Link: WordPress 2.7 is out!'>WordPress 2.7 is out!</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 9 &#8211; 14 minutes</p><p>Since the update of WordPress from version 2.9 to WordPress 3.0 one of the main noticeable improvements (to make it into more of a CMS system) is the ability to add a new custom post type into your WordPress system.</p><p><span id="more-2352"></span><br /> If you want to have an option to be able to make a &#8220;Testimonial&#8221; post type, this will require different inputs to what a &#8220;Quote&#8221; or normal blog entry will require. WordPress has a great <a href="http://codex.wordpress.org/Function_Reference/register_post_type">documentation</a> on everything that a custom post can contain.</p><h1>Getting started</h1><p>To get started with our custom posts we want to use <strong>register_post_type()</strong>. The register post type will allow us to use tons of different options to be able to set up our custom post type. For our Testimonials post type, we want to have:</p><ol><li>Company name</li><li>City</li><li>Province</li><li>Description</li><li>Image</li><li>Title</li></ol><p>To start off with we want to add the following to functions.php in your active theme:</p><pre class="brush: php;">
add_action( 'init', 'testimonials_posts'); // tell WordPress to look for our function
function testimonials_posts() {
    $args = array(
            // Post information will go here
        );
    register_post_type( 'testimonials' , $args );
}
</pre><h2>Labels</h2><p>Labels let us differentiate the type of entry from normal posts. Instead of when you add a new item it saying &#8220;New post&#8221; we can make it say &#8220;New testimonial&#8221; . The labels really let us customize the post type and make it a lot easier for the end user to be able to know what they are doing.</p><p>The <a href="http://codex.wordpress.org/Function_Reference/register_post_type#Arguments">labels</a> are added into an array inside the <strong>register_post_type()</strong> function. After adding labels to make our post more user friendly this is the code we have inside our args variable:</p><pre class="brush: php;">
$args = array(
		'labels' =&gt; array(
			'name' =&gt; __( 'Testimonials' ), // option to show in menu
			'singular_name' =&gt; __( 'Testimonial' ),
			'add_new_item' =&gt; __( 'Add New Testimonial' ),
			'edit_item' =&gt; __( 'Edit Testimonial' ),
			'new_item' =&gt; __( 'New Testimonial' ),
			'view' =&gt; __( 'View Testimonial' ),
			'view_item' =&gt; __( 'View Testimonial' ),
			'search_items' =&gt; __( 'Search Testimonial' ),
			'not_found' =&gt; __( 'No Testimonials found' ),
			'not_found_in_trash' =&gt; __( 'No Testimonials found in Trash' ),
			'parent' =&gt; __( 'Parent Testimonial' ),
		), // end of label array
			'public' =&gt; true,
			'rewrite' =&gt; array('slug'=&gt; 'company'),
			'capability_type' =&gt; 'post',
			'hierarchical' =&gt; true,
			'menu_icon' =&gt; 'http://example.com/images/testimonials_thumb.png',
			'supports' =&gt; array('title', 'editor', 'thumbnail')
);
</pre><h3>Public</h3><p>Public has been added to this post type to make is publicly visible and also allow it to be placed on the WordPress admin menu, show in search engines and be visible to users on the front.</p><div class="wp-caption"> <img src="http://img.skitch.com/20100704-ji63ipc61r6r3h4abdedtyqftd.jpg" alt="Side bar icon" /></div><h3>Rewrite</h3><p>Rewrite allows us to be able to change the url format, having it set up like show above will format these post types as <strong>http://brenelz.com/blog/company/</strong>. To fully set this up you will need to change the <strong>Permalink Structure</strong> to something such as <strong>%postname%</strong>.</p><h3>Capability Type</h3><p>This is for the post type to be use for checking read, edit, and delete capabilities.</p><h3>Hierarchical</h3><p>Setting this to true will allow you to be able to specify a Parent.</p><h3>Menu icon</h3><p>You can also change the menu icon of the post to make it more custom. This is simple to do and will make it even more clear to the user. I found that a picture of about 15px X 15px was best for this area.</p><div class="wp-caption"> <img src="http://img.skitch.com/20100716-fy9ir32ie7bsnqbfedigrx4jpb.jpg" alt="Testimonial menu icon example" /></div><h3><strong>Supports</strong></h3><p>Supports gives up access to allow some of the default areas such as the title, blog area and thumbnail. We want to have all of these in our custom post type so will add support for each of them.</p><h2>Custom Fields</h2><p>To add our custom fields we want to tell WordPress to load them in the admin panel. Then we need to tell wordpress how to save the custom inputs. To do this we need to add the following:</p><pre class="brush: php;">
  	add_action(&quot;admin_init&quot;, &quot;admin_init&quot;);
    function admin_init(){
        add_meta_box(&quot;testimonial_data&quot;, &quot;Company Details&quot;, &quot;meta_options&quot;, &quot;testimonials&quot;, &quot;side&quot;, &quot;low&quot;);
    }

    function meta_options(){
		global $post;
		$custom_fields = get_post_custom($post-&gt;ID);
		$company_name = $custom_fields[&quot;company_name&quot;][0];
		$city = $custom_fields[&quot;city&quot;][0];
		$province = $custom_fields[&quot;province&quot;][0];
?&gt;
	&lt;label for=&quot;company_name&quot;&gt;Company Name:&lt;/label&gt;&lt;input id=&quot;company_name&quot; name=&quot;company_name&quot; value=&quot;&lt;?php echo $company_name; ?&gt;&quot; /&gt;&lt;br /&gt;
	&lt;label for=&quot;city&quot;&gt;City:&lt;/label&gt;&lt;input id=&quot;city&quot; name=&quot;city&quot; value=&quot;&lt;?php echo $city; ?&gt;&quot; /&gt;&lt;br /&gt;
	&lt;label for=&quot;province&quot;&gt;Province:&lt;/label&gt;&lt;input id=&quot;province&quot; name=&quot;province&quot; value=&quot;&lt;?php echo $province; ?&gt;&quot; /&gt;
&lt;?php
	}
</pre><p>After setting this we now have our custom inputs in our &#8220;Company details&#8221; area when we go write a new testimonial.</p><div class="wp-caption"> <img src="http://img.skitch.com/20100716-q557e4dh223ten88swccy4b7rr.jpg" alt="Company Details inputs" width="500" /></div><p>Next we need to set up a way to save what was typed, the custom post fields are very similar to custom fields (which you can read more about <a href="http://brenelz.com/blog/using-wordpress-custom-fields/">here</a>) and we need to set up an option to save them so we can pull them out in the post later. This is done with the following:</p><pre class="brush: php;">
add_action('save_post', 'save_company_info');
function save_company_info(){
	global $post;
	update_post_meta($post-&gt;ID, &quot;company_name&quot;, $_POST[&quot;company_name&quot;]);
	update_post_meta($post-&gt;ID, &quot;city&quot;, $_POST[&quot;city&quot;]);
	update_post_meta($post-&gt;ID, &quot;province&quot;, $_POST[&quot;province&quot;]);
}
</pre><p>Here we get/make the global variable <strong>$post </strong>and update the custom field metadata with each fields input&#8217;s value.</p><p>This should now be all set up for editing/making a new custom post type. Here is all the final code needed.</p><p><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace;line-height: 18px;font-size: 12px"> </span></p><pre class="brush: php;">
add_action('init', 'testimonials_posts');

function testimonials_posts() {
    $args = array(
		'labels' =&gt; array(
			'name' =&gt; __( 'Testimonials' ), // option to show in menu
			'singular_name' =&gt; __( 'Testimonial' ),
			'add_new_item' =&gt; __( 'Add New Testimonial' ),
			'edit_item' =&gt; __( 'Edit Testimonial' ),
			'new_item' =&gt; __( 'New Testimonial' ),
			'view' =&gt; __( 'View Testimonial' ),
			'view_item' =&gt; __( 'View Testimonial' ),
			'search_items' =&gt; __( 'Search Testimonial' ),
			'not_found' =&gt; __( 'No Testimonials found' ),
			'not_found_in_trash' =&gt; __( 'No Testimonials found in Trash' ),
			'parent' =&gt; __( 'Parent Testimonial' ),
		), // end of label array
			'public' =&gt; true,
			'menu_icon' =&gt; 'http://example.com/images/testimonials_thumb.png',
			'rewrite' =&gt; array('slug'=&gt; 'company'),
			'capability_type' =&gt; 'post',
        	'hierarchical' =&gt; true,
        	'supports' =&gt; array('title', 'editor', 'thumbnail')
	);
    register_post_type( 'testimonials' , $args );
}

  	add_action(&quot;admin_init&quot;, &quot;admin_init&quot;);
    function admin_init(){
        add_meta_box(&quot;testimonial_data&quot;, &quot;Company Details&quot;, &quot;meta_options&quot;, &quot;testimonials&quot;, &quot;side&quot;, &quot;low&quot;);
    }

    function meta_options(){
		global $post;
		$custom_fields = get_post_custom($post-&gt;ID);
		$company_name = $custom_fields[&quot;company_name&quot;][0];
		$city = $custom_fields[&quot;city&quot;][0];
		$province = $custom_fields[&quot;province&quot;][0];
?&gt;
	&lt;label for=&quot;company_name&quot;&gt;Company Name:&lt;/label&gt;&lt;input id=&quot;company_name&quot; name=&quot;company_name&quot; value=&quot;&lt;?php echo $company_name; ?&gt;&quot; /&gt;&lt;br /&gt;
	&lt;label for=&quot;city&quot;&gt;City:&lt;/label&gt;&lt;input id=&quot;city&quot; name=&quot;city&quot; value=&quot;&lt;?php echo $city; ?&gt;&quot; /&gt;&lt;br /&gt;
	&lt;label for=&quot;province&quot;&gt;Province:&lt;/label&gt;&lt;input id=&quot;province&quot; name=&quot;province&quot; value=&quot;&lt;?php echo $province; ?&gt;&quot; /&gt;
&lt;?php
	}
  add_action('save_post', 'save_company_info');
function save_company_info(){
	global $post;
	update_post_meta($post-&gt;ID, &quot;company_name&quot;, $_POST[&quot;company_name&quot;]);
	update_post_meta($post-&gt;ID, &quot;city&quot;, $_POST[&quot;city&quot;]);
	update_post_meta($post-&gt;ID, &quot;province&quot;, $_POST[&quot;province&quot;]);
}
</pre><h2>Displaying the custom post</h2><p>To display our custom posts in their theme we need to set up a style for them. To do this, WordPress searches for a file named single-<strong>custom_post_type_name</strong>.php. So we will need to make a file named single-<strong>testimonials.</strong>php. I have copied the code from the Twenty Ten theme and modified it to work with our custom post inputs. This is what I had at the end.</p><pre class="brush: php;">
&lt;?php
/**
 * The Template for displaying all single posts.
 *
 * @package WordPress
 * @subpackage Twenty_Ten
 * @since Twenty Ten 1.0
 */
	$custom_fields = get_post_custom($post-&gt;ID);
	$company_name = $custom_fields[&quot;company_name&quot;][0];
	$city = $custom_fields[&quot;city&quot;][0];
	$province = $custom_fields[&quot;province&quot;][0];
get_header(); ?&gt;
		&lt;div id=&quot;container&quot;&gt;
			&lt;div id=&quot;content&quot; role=&quot;main&quot;&gt;
&lt;?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?&gt;
				&lt;div id=&quot;nav-above&quot; class=&quot;navigation&quot;&gt;
					&lt;div class=&quot;nav-previous&quot;&gt;&lt;?php previous_post_link( '%link', '&lt;span class=&quot;meta-nav&quot;&gt;' . _x( '&amp;larr;', 'Previous testimonial link', 'twentyten' ) . '&lt;/span&gt; %title' ); ?&gt;&lt;/div&gt;
					&lt;div class=&quot;nav-next&quot;&gt;&lt;?php next_post_link( '%link', '%title &lt;span class=&quot;meta-nav&quot;&gt;' . _x( '&amp;rarr;', 'Next testimonial link', 'twentyten' ) . '&lt;/span&gt;' ); ?&gt;&lt;/div&gt;
				&lt;/div&gt;&lt;!-- #nav-above --&gt;

				&lt;div id=&quot;post-&lt;?php the_ID(); ?&gt;&quot; &lt;?php post_class(); ?&gt;&gt;
					&lt;h1 class=&quot;entry-title&quot;&gt;&lt;?php the_title(); ?&gt;&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;
					&lt;b&gt;Company Name:&lt;/b&gt;&lt;?php echo $company_name; ?&gt;  &lt;br /&gt;
					&lt;b&gt;Company City:&lt;/b&gt;&lt;?php echo $city; ?&gt; &lt;br /&gt;
					&lt;b&gt;Company Province:&lt;/b&gt;&lt;?php echo $province; ?&gt;
				    &lt;div class=&quot;entry-content&quot;&gt;
				        &lt;?php the_post_thumbnail(); ?&gt;
				        &lt;br /&gt;&lt;b&gt;Details:&lt;/b&gt;&lt;?php the_content(); ?&gt;
				        &lt;?php edit_post_link( __( 'Edit', 'twentyten' ), '&lt;span class=&quot;edit-link&quot;&gt;', '&lt;/span&gt;' ); ?&gt;
				    &lt;/div&gt;
&lt;?php endwhile; // end of the loop. ?&gt;
			&lt;/div&gt;&lt;!-- #content --&gt;
		&lt;/div&gt;&lt;!-- #container --&gt;

&lt;?php get_sidebar(); ?&gt;
&lt;?php get_footer(); ?&gt;
</pre><p>Which produces a nice template for our theme.</p><div class="wp-caption"> <img src="http://img.skitch.com/20100716-rh9dtdqcaua8gm2mxt5g67djh7.jpg" alt="Final example" /></div><h2>Conclusion</h2><p>I personally like the new custom posts and think that they can become very useful for building sites for people that won&#8217;t be able to know how to use the standard custom post fields, or know that &#8220;Posts&#8221; are what they need to click on. To get more help with the code and what to do WordPress also has a great codex on <a href="http://codex.wordpress.org/Function_Reference/register_post_type">registering</a> the post type and general information/help about the <a href="http://codex.wordpress.org/Custom_Post_Types">Custom Post types</a>.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/using-wordpress-custom-fields/' rel='bookmark' title='Permanent Link: Using WordPress Custom Fields'>Using WordPress Custom Fields</a></li><li><a href='http://brenelz.com/blog/quick-tip-wordpress-random-posts/' rel='bookmark' title='Permanent Link: Quick Tip: WordPress Random Posts'>Quick Tip: WordPress Random Posts</a></li><li><a href='http://brenelz.com/blog/wordpress-27-is-out/' rel='bookmark' title='Permanent Link: WordPress 2.7 is out!'>WordPress 2.7 is out!</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=xeXnhWdDh10:iV0Xk-DMv1I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=xeXnhWdDh10:iV0Xk-DMv1I:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=xeXnhWdDh10:iV0Xk-DMv1I:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/xeXnhWdDh10" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/wordpress-3-0-custom-posts/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://brenelz.com/blog/wordpress-3-0-custom-posts/</feedburner:origLink></item> <item><title>Top 4 HTML5 Features</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/QmGzpSxuFK4/</link> <comments>http://brenelz.com/blog/top-4-html5-features/#comments</comments> <pubDate>Wed, 07 Jul 2010 16:46:34 +0000</pubDate> <dc:creator>Dixon Crews</dc:creator> <category><![CDATA[Web Programming]]></category><guid isPermaLink="false">http://brenelz.com/?p=2368</guid> <description><![CDATA[Reading time: 3 &#8211; 4 minutes You&#8217;ve undoubtedly heard of HTML5 multiple times in the past. It was started in June 2004 and is currently in the &#8216;Working Draft&#8217; state. Ian Hickson (a Google Inc. employee) is the editor of HTML5, and he estimates that HTML5 will become a Candidate Recommendation in 2012, and a [...]Related posts:<ol><li><a href='http://brenelz.com/blog/html5-overview/' rel='bookmark' title='Permanent Link: HTML5 Overview'>HTML5 Overview</a></li><li><a href='http://brenelz.com/blog/google-launched-font-api/' rel='bookmark' title='Permanent Link: Google Launches a New Font API'>Google Launches a New Font API</a></li><li><a href='http://brenelz.com/blog/reading-xml-using-flash/' rel='bookmark' title='Permanent Link: Reading XML Using Flash'>Reading XML Using Flash</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 3 &#8211; 4 minutes</p><p>You&#8217;ve undoubtedly heard of HTML5 multiple times in the past. It was started in June 2004 and is currently in the &#8216;Working Draft&#8217; state. Ian Hickson (a Google Inc. employee) is the editor of HTML5, and he estimates that HTML5 will become a Candidate Recommendation in 2012, and a W3C Recommendation in 2022. Seems like I&#8217;ll be old and gray by the time it&#8217;s the norm!</p><p>The great thing is that despite the fact that HTML5 will not be a W3C Recommendation until 2022, you can use many of the elements of it today! The website <a href="http://caniuse.com">caniuse.com</a> reports that this percentage of features in HTML5 are currently supported:</p><ul><li>Internet Explorer 8.0: 25%</li><li>Firefox 3.6: 76%</li><li>Safari 5.0: 86%</li><li>Google Chrome 5.0: 85%</li><li>Opera 10.6: 77%</li></ul><p>I&#8217;ll be using Safari 5.0 as it currently has the highest percentage and seems to run the best in my current setup. Let&#8217;s dive right in, shall we?</p><h3>1. Geolocation</h3><p>Geolocation is already being used all over the web today. Many websites will ask for your current location to display information like weather or local news. Some or all of your information including your IP address, RFID, MAC addresses, GSM/CDMA information will be used to determine your information. It can only be used if the user gives permission.</p><p>Try it <a href="http://slides.html5rocks.com/#slide14">here</a>.</p><h3>2. Video</h3><p>One of the main reasons why Apple is not supporting Flash on any iOS devices is because they believe so strongly in the HTML5 Video element. It couldn&#8217;t get any simpler than this markup:</p><pre class="brush: xml;">

&lt;video src='movie.mp4' autoplay controls&gt;&lt;/video&gt;
</pre><p>Provided the feature is fully supported, video plays smoothly, fullscreen works great, and it doesn&#8217;t eat up your CPU cycles like some HD flash players can.</p><p>Try it <a href="http://slides.html5rocks.com/#slide22">here</a>.</p><h3>3. Canvas</h3><p>Creating simple graphics for the web in Photoshop then saving and inserting them in the correct place in your web page can be a complete time waster, especially if you get it wrong and have to go through the whole process again. That&#8217;s where the Canvas element comes in.</p><p>Take the simple &#8216;loading&#8217; image. Instead of searching high and low for the perfect looking image, you can create exactly what you want with a canvas element. Here&#8217;s an example: <a href="http://html5demos.com/canvas">link</a>.</p><h3>4. @font-face</h3><p>@font-face is really more of a CSS feature, but it ties in directly with HTML5. Inserting custom fonts into web pages is always a pain. My tool of choice is Cufón, for its sole use of JavaScript. There are others that get more complicated like sIFR using Flash all to get a font on a web page. No more! Custom Web Fonts are now as easy as uploading the .ttf or .otf file to your server, linking it into your CSS file and creating a font-family, and displaying your text! Typography lovers unite!</p><pre class="brush: xml;">
@font-face {
font-family: 'LeagueGothic';
src: url(LeagueGothic.otf);
}

header {
font-family: 'LeagueGothic';
}
</pre><p>Try it <a href="http://slides.html5rocks.com/#slide31">here</a>.</p><p>All of the demo links included in this post are courtesy of Google, Inc. Check out the rest of <a href="http://html5rocks.com">html5rocks.com</a> for some great resources!</p><p>These four features are just a taste of what HTML5 really can do. I look forward to what the world&#8217;s web developers will be making in the years to come!</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/html5-overview/' rel='bookmark' title='Permanent Link: HTML5 Overview'>HTML5 Overview</a></li><li><a href='http://brenelz.com/blog/google-launched-font-api/' rel='bookmark' title='Permanent Link: Google Launches a New Font API'>Google Launches a New Font API</a></li><li><a href='http://brenelz.com/blog/reading-xml-using-flash/' rel='bookmark' title='Permanent Link: Reading XML Using Flash'>Reading XML Using Flash</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=QmGzpSxuFK4:sWoSwxZKYyI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=QmGzpSxuFK4:sWoSwxZKYyI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=QmGzpSxuFK4:sWoSwxZKYyI:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/QmGzpSxuFK4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/top-4-html5-features/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://brenelz.com/blog/top-4-html5-features/</feedburner:origLink></item> <item><title>Yogile – Photo Sharing Service</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/8Tm3iZQ_aBI/</link> <comments>http://brenelz.com/blog/yogile-photo-sharing-service/#comments</comments> <pubDate>Tue, 06 Jul 2010 13:00:11 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2362</guid> <description><![CDATA[Reading time: 1 &#8211; 2 minutes At Yogile they have developed a new photo sharing service that makes it incredibly easy to share images privately and within groups. While established photo sharing sites already exist, Yogile is different because it lets multiple people contribute with ease. Once you create an album, you get a customizable [...]No related posts.]]></description> <content:encoded><![CDATA[<p>Reading time: 1 &#8211; 2 minutes</p><p>At Yogile they have developed a new photo sharing service that makes it incredibly easy to share images privately and within groups.</p><div class="wp-caption"> <a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/07/yogile.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/07/yogile.jpg" alt="" title="yogile" width="500" height="371" class="alignright size-full wp-image-2364" /></a></div><p>While established photo sharing sites already exist, Yogile is different because it lets multiple people contribute with ease. Once you create an album, you get a customizable URL and e-mail address to share with anyone who wants to add photos, either as e-mail attachments or uploads through the site. There&#8217;s no need for these users to register, keeping the process simple and hassle-free.</p><p>Take a wedding, for example. Dozens of attendees take their own photos, all from different cameras and angles. While you might try asking everyone for their shots afterward, Yogile offers a smart alternative. Visit <a href="http://www.yogile.com">http://www.yogile.com</a> to try it out!</p><h3>What Do You Think of Yogile?</h3><p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=8Tm3iZQ_aBI:R4fYps34g-4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=8Tm3iZQ_aBI:R4fYps34g-4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=8Tm3iZQ_aBI:R4fYps34g-4:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/8Tm3iZQ_aBI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/yogile-photo-sharing-service/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/yogile-photo-sharing-service/</feedburner:origLink></item> <item><title>Multiple Borders with Simple CSS</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/nN-L5SbU1rk/</link> <comments>http://brenelz.com/blog/multiple-borders-with-simple-css/#comments</comments> <pubDate>Mon, 21 Jun 2010 16:41:56 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2335</guid> <description><![CDATA[Reading time: 1 &#8211; 2 minutes Jeffrey Way from Nettuts has another quick tip that is definitely worth me posting. Please follow him @nettuts, and myself @brenelz. Here is his quick intro to this tip: Did you know that we can achieve multiple borders with simple CSS, by using the :after amd :before psuedo-classes? This [...]Related posts:<ol><li><a href='http://brenelz.com/blog/css-rounded-corners/' rel='bookmark' title='Permanent Link: CSS Rounded Corners'>CSS Rounded Corners</a></li><li><a href='http://brenelz.com/blog/change-text-selection-color-using-css/' rel='bookmark' title='Permanent Link: Change Text Selection Color using CSS'>Change Text Selection Color using CSS</a></li><li><a href='http://brenelz.com/blog/creating-semantic-css-navigation/' rel='bookmark' title='Permanent Link: Creating Semantic CSS Navigation'>Creating Semantic CSS Navigation</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 1 &#8211; 2 minutes</p><p>Jeffrey Way from <a href="http://nettuts.com">Nettuts</a> has another quick tip that is definitely worth me posting.  Please follow him @nettuts, and myself @brenelz.</p><p>Here is his quick intro to this tip:</p><blockquote><p> Did you know that we can achieve multiple borders with simple CSS, by using the :after amd :before psuedo-classes? This is something I recently learned myself! I’ll show you how to add more depth to your designs, without images, in just a few minutes.<br /><cite>- Nettuts.com</cite></p></blockquote><p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=80864' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=80864' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/css-rounded-corners/' rel='bookmark' title='Permanent Link: CSS Rounded Corners'>CSS Rounded Corners</a></li><li><a href='http://brenelz.com/blog/change-text-selection-color-using-css/' rel='bookmark' title='Permanent Link: Change Text Selection Color using CSS'>Change Text Selection Color using CSS</a></li><li><a href='http://brenelz.com/blog/creating-semantic-css-navigation/' rel='bookmark' title='Permanent Link: Creating Semantic CSS Navigation'>Creating Semantic CSS Navigation</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=nN-L5SbU1rk:IHgHcwaTWt8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=nN-L5SbU1rk:IHgHcwaTWt8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=nN-L5SbU1rk:IHgHcwaTWt8:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/nN-L5SbU1rk" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/multiple-borders-with-simple-css/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/multiple-borders-with-simple-css/</feedburner:origLink></item> <item><title>New Video Edit iPhone App!</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/2bBIalv9zpI/</link> <comments>http://brenelz.com/blog/new-video-edit-app-for-iphone-3gs/#comments</comments> <pubDate>Wed, 02 Jun 2010 13:00:04 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2296</guid> <description><![CDATA[Reading time: 2 &#8211; 3 minutes &#8220;Video Edit&#8221; for iPhone 3GS lets you trim, organize and stitch together camera roll videos to create fun and share-worthy video compilations. Video Edit is lightning fast, easy-to-use, and lets you quickly edit your video compilation to be shared with your entire network. This app is great for bloggers, [...]No related posts.]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 3 minutes</p><p><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image004.png"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image004.png" alt="" title="image004" width="57" height="57" class="alignright size-full wp-image-2321" /></a></p><p>&#8220;Video Edit&#8221; for iPhone 3GS lets you trim, organize and stitch together camera roll videos to create fun and share-worthy video compilations. Video Edit is lightning fast, easy-to-use, and lets you quickly edit your video compilation to be shared with your entire network.</p><p>This app is great for bloggers, parents, vacationers, sports enthusiasts, basically anyone who loves sharing media with their network. Designed specifically for speed and ease of use, the developers have removed extraneous features to emphasize the art of storytelling and enable the fastest possible rendering speed.</p><h3>Details</h3><p><strong>App Name: </strong>Video Edit<br /> <strong>Release Date: </strong>June 1st, 2010<br /> <strong>Company Name:</strong> DHI Inc.<br /> <strong>Category:</strong> Photography<br /> <strong>Cost: </strong>$4.99<br /> <strong>Release Details:</strong> In Review as this time, but hopefully soon!</p><p><strong>Visit the <a href="http://www.videoeditapp.com" target="_blank">Video Edit App</a> website for more details on the iPhone app.</strong></p><h3>Screenshots</h3><div class="wp-caption"> <a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image001.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image001.jpg" alt="" title="image001" width="247" height="371" class="size-full wp-image-2318" /></a></div><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image002.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image002.jpg" alt="" title="image002" width="247" height="371" class="size-full wp-image-2319" /></a></div><div class="wp-caption"> <a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image003.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/06/image003.jpg" alt="" title="image003" width="247" height="371" class="size-full wp-image-2320" /></a></div><h3>Are you giving away free copies?</h3><p>Yes, there are some free copies of the app available but they are limited.  Leave a comment below, and you never know!</p><h3>Win a 64GB iPad!</h3><p>To top it all off the great folks that created the app are running a contest!  Here is what you have to do:</p><ol><li><a href="http://brenelz.com/feed" target="_blank">Subscribe to my RSS Feed</a></li><li>Follow <a href="http://twitter.com/videoeditapp" target="_blank">@videoeditapp</a>, and <a href="http://twitter.com/videoeditapp" target="_blank">@brenelz</a></li><li>Check back regularly for more directions on entering!  Should be within a couple weeks&#8230;</li></ol><h3>Is this an app you would consider buying?</h3><p>Leave your comments below.</p><p>No related posts.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=2bBIalv9zpI:-7lVNCQCvTk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=2bBIalv9zpI:-7lVNCQCvTk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=2bBIalv9zpI:-7lVNCQCvTk:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/2bBIalv9zpI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/new-video-edit-app-for-iphone-3gs/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://brenelz.com/blog/new-video-edit-app-for-iphone-3gs/</feedburner:origLink></item> <item><title>Creating Columns using CSS3</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/MQEoODc2yJ4/</link> <comments>http://brenelz.com/blog/creating-columns-using-css3/#comments</comments> <pubDate>Fri, 28 May 2010 20:58:29 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2291</guid> <description><![CDATA[Reading time: < 1 minute Jeffery Way has released another neat Quick Tip which shows us the just another powerful property of CSS3. We have so much to look forward to! Can you think of any CSS3 properties that don&#8217;t get utilized enough? Share them in the comments. Related posts:Client-Side Javascript AJAX / JSON Guide [...]Related posts:<ol><li><a href='http://brenelz.com/blog/client-side-javascript/' rel='bookmark' title='Permanent Link: Client-Side Javascript'>Client-Side Javascript</a></li><li><a href='http://brenelz.com/blog/ajax-json-guide/' rel='bookmark' title='Permanent Link: AJAX / JSON Guide'>AJAX / JSON Guide</a></li><li><a href='http://brenelz.com/blog/default-and-configuration-objects-with-javascript/' rel='bookmark' title='Permanent Link: Default and configuration objects with JavaScript'>Default and configuration objects with JavaScript</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: < 1 minute</p><p>Jeffery Way has released another neat Quick Tip which shows us the just another powerful property of CSS3.  We have so much to look forward to!</p><p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' ></param><param name='flashvars' value='i=74314' ></param><param name='allowFullScreen' value='true' ></param><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=74314' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer' ></embed></object></p><h3>Can you think of any CSS3 properties that don&#8217;t get utilized enough?  Share them in the comments.</h3><p>Related posts:<ol><li><a href='http://brenelz.com/blog/client-side-javascript/' rel='bookmark' title='Permanent Link: Client-Side Javascript'>Client-Side Javascript</a></li><li><a href='http://brenelz.com/blog/ajax-json-guide/' rel='bookmark' title='Permanent Link: AJAX / JSON Guide'>AJAX / JSON Guide</a></li><li><a href='http://brenelz.com/blog/default-and-configuration-objects-with-javascript/' rel='bookmark' title='Permanent Link: Default and configuration objects with JavaScript'>Default and configuration objects with JavaScript</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=MQEoODc2yJ4:2zMrjZsAzhs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=MQEoODc2yJ4:2zMrjZsAzhs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=MQEoODc2yJ4:2zMrjZsAzhs:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/MQEoODc2yJ4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/creating-columns-using-css3/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://brenelz.com/blog/creating-columns-using-css3/</feedburner:origLink></item> <item><title>Play PacMan on Google’s Homepage!</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/UXzm1e_6NOg/</link> <comments>http://brenelz.com/blog/play-pacman-on-googles-homepage/#comments</comments> <pubDate>Fri, 21 May 2010 15:39:45 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2285</guid> <description><![CDATA[Reading time: < 1 minute Today Google is celebrating the popular PacMan game's birthday is a real cool way. They have embedded their Google Logo in a playable PacMan game. Maybe I shouldn't have posted this, because now your productivity for the day is ruined. Copyright Google. Visit Google&#8217;s Homepage What do you think&#8230; cool [...]Related posts:<ol><li><a href='http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/' rel='bookmark' title='Permanent Link: Google Makes Changes: A Lot Like Bing?'>Google Makes Changes: A Lot Like Bing?</a></li><li><a href='http://brenelz.com/blog/google-launched-font-api/' rel='bookmark' title='Permanent Link: Google Launches a New Font API'>Google Launches a New Font API</a></li><li><a href='http://brenelz.com/blog/can-you-google-map/' rel='bookmark' title='Permanent Link: Can you Google Map?'>Can you Google Map?</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: < 1 minute</p><p>Today Google is celebrating the popular PacMan game's birthday is a real cool way.  They have embedded their Google Logo in a playable PacMan game.</p><p>Maybe I shouldn't have posted this, because now your productivity for the day is ruined.</p><div class="wp-caption"> <a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/05/google-pacman.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/05/google-pacman.jpg" alt="" title="google-pacman" width="500" height="167" class="aligncenter size-full wp-image-2288" /></a>Copyright Google.</div><h3><a href="http://www.google.ca/">Visit Google&#8217;s Homepage</a></h3><p>What do you think&#8230; cool or annoying?</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/' rel='bookmark' title='Permanent Link: Google Makes Changes: A Lot Like Bing?'>Google Makes Changes: A Lot Like Bing?</a></li><li><a href='http://brenelz.com/blog/google-launched-font-api/' rel='bookmark' title='Permanent Link: Google Launches a New Font API'>Google Launches a New Font API</a></li><li><a href='http://brenelz.com/blog/can-you-google-map/' rel='bookmark' title='Permanent Link: Can you Google Map?'>Can you Google Map?</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=UXzm1e_6NOg:tU-WGfafvaE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=UXzm1e_6NOg:tU-WGfafvaE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=UXzm1e_6NOg:tU-WGfafvaE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/UXzm1e_6NOg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/play-pacman-on-googles-homepage/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://brenelz.com/blog/play-pacman-on-googles-homepage/</feedburner:origLink></item> <item><title>Google Launches a New Font API</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/ypCvxKqOCss/</link> <comments>http://brenelz.com/blog/google-launched-font-api/#comments</comments> <pubDate>Wed, 19 May 2010 20:32:15 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2282</guid> <description><![CDATA[Reading time: 1 &#8211; 2 minutes Google has announced a Font API which is sure to change the way we embed fonts on our websites. Remember the pains of using sIFR, or FLIR in your website. Going into Flash and changing your font was a real hassle. Along came CSS3 to make it easier using [...]Related posts:<ol><li><a href='http://brenelz.com/blog/screencast-ideas/' rel='bookmark' title='Permanent Link: Screencast Ideas'>Screencast Ideas</a></li><li><a href='http://brenelz.com/blog/validate-your-forms-with-ease-using-jquery-2/' rel='bookmark' title='Permanent Link: Validate your Forms with Ease using jQuery'>Validate your Forms with Ease using jQuery</a></li><li><a href='http://brenelz.com/blog/google-feedburner-has-rough-start/' rel='bookmark' title='Permanent Link: Google Feedburner has Rough Start&#8230;'>Google Feedburner has Rough Start&#8230;</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 1 &#8211; 2 minutes</p><p>Google has announced a Font API which is sure to change the way we embed fonts on our websites.</p><p>Remember the pains of using sIFR, or FLIR in your website.  Going into Flash and changing your font was a real hassle.  Along came CSS3 to make it easier using the @font-face rule.  Now this is even simpler.</p><p>Take a look at Jeffery Way&#8217;s screencast from <a href="http://www.nettuts.com">Nettuts</a> and see for yourself.</p><p><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' ></param><param name='flashvars' value='i=71738' ></param><param name='allowFullScreen' value='true' ></param><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=71738' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer' ></embed></object></p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/screencast-ideas/' rel='bookmark' title='Permanent Link: Screencast Ideas'>Screencast Ideas</a></li><li><a href='http://brenelz.com/blog/validate-your-forms-with-ease-using-jquery-2/' rel='bookmark' title='Permanent Link: Validate your Forms with Ease using jQuery'>Validate your Forms with Ease using jQuery</a></li><li><a href='http://brenelz.com/blog/google-feedburner-has-rough-start/' rel='bookmark' title='Permanent Link: Google Feedburner has Rough Start&#8230;'>Google Feedburner has Rough Start&#8230;</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=ypCvxKqOCss:-bG5i4fD8KE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=ypCvxKqOCss:-bG5i4fD8KE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=ypCvxKqOCss:-bG5i4fD8KE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/ypCvxKqOCss" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/google-launched-font-api/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/google-launched-font-api/</feedburner:origLink></item> <item><title>Using WordPress Custom Fields</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/mS3AEVxEpD8/</link> <comments>http://brenelz.com/blog/using-wordpress-custom-fields/#comments</comments> <pubDate>Mon, 10 May 2010 16:28:04 +0000</pubDate> <dc:creator>Alex</dc:creator> <category><![CDATA[Web Programming]]></category><guid isPermaLink="false">http://brenelz.com/?p=2267</guid> <description><![CDATA[Reading time: 2 &#8211; 4 minutes I am going to show how to build a simple way to add a &#8220;star&#8221; rating at the bottom of a post using WordPress&#8217; Custom Fields. The custom fields are a great way of adding extra bits of information such as paragraphs, images or content which you want to [...]Related posts:<ol><li><a href='http://brenelz.com/blog/wordpress-3-0-custom-posts/' rel='bookmark' title='Permanent Link: WordPress 3.0 Custom Posts'>WordPress 3.0 Custom Posts</a></li><li><a href='http://brenelz.com/blog/quick-tip-wordpress-random-posts/' rel='bookmark' title='Permanent Link: Quick Tip: WordPress Random Posts'>Quick Tip: WordPress Random Posts</a></li><li><a href='http://brenelz.com/blog/wordpress-more-than-just-a-blogging-platform/' rel='bookmark' title='Permanent Link: WordPress: More than just a blogging platform?'>WordPress: More than just a blogging platform?</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 4 minutes</p><p>I am going to show how to build a simple way to add a &#8220;star&#8221; rating at the bottom of a post using WordPress&#8217; Custom Fields. The custom fields are a great way of adding extra bits of information such as paragraphs, images or content which you want to be displayed differently.</p><h2>Creating a custom field</h2><p>When adding a new post we want to scroll down to the area called &#8220;Custom Fields&#8221; and then add a new one. Its good to give this field a useful name as once you have added the custom field you can select it from the drop down box. Next in the value field add what your rating will be. So a value of  &#8220;3/5&#8243; is what I used.</p><p><img src="http://farm5.static.flickr.com/4001/4589124342_440510fea5_o.png" border="0" alt="Custom Field" /></p><h2>Displaying the Custom Field</h2><p>WordPress has a useful <a href="http://codex.wordpress.org/Custom_Fields">documentation </a>showing how to get started with the custom fields. For this custom field we want to add the following code inside the post loop.</p><pre class="brush: php;">
&lt;?php if( get_post_meta(get_the_ID(), 'rating') ){
		$rating = get_post_meta(get_the_ID(), 'rating');
		$rating = explode(&quot;/&quot;, $rating[0]);
		$good = round($rating[0]);
		$total  = round($rating[1]);

		echo &quot;&lt;h2&gt;This was rated:&lt;/h2&gt;&lt;p class='rating'&gt;&quot;;
		if(!empty($good) &amp;&amp; !empty($total) &amp;&amp; ($good &lt;= $total) &amp;&amp; is_numeric($good) &amp;&amp; is_numeric($total) ){
			$i=0;
			while($i &lt; $good){
				echo &quot;&lt;img src='http://localhost/wordpress/wp-content/themes/default/images/stars/star_on.png'  border='0' /&gt;&quot;;
					$i++;
			}

			$i = 0;
			while($i &lt; ($total - $good)){
				echo &quot;&lt;img src='http://localhost/wordpress/wp-content/themes/default/images/stars/star_off.png'  border='0' /&gt;&quot;;
					$i++;
			}
		}else{
			echo &quot;Invalid input for the rating.&quot;;
		}

		echo &quot;&lt;/p&gt;&quot;;
	};
?&gt;
</pre><p>To get the meta data we need to use <strong>get_post_meta(); </strong>which uses 2 (optional 3rd) values. The first is the post ID, next the key/name of the field and the last optional value is either &#8220;true&#8221; or &#8220;false&#8221; to say if you want the information returned as a string.<br /> That script will use the post ID to check if there is any information &#8220;rating&#8221; that has been set. Next, if it has we assign it to a variable and <a href="http://php.net/manual/en/function.explode.php">explode</a> it at the &#8220;/&#8221;, this means we have the two numbers for the light star and the dark star. After splitting up the rating we run a few checks to make sure that it is valid before we loop through them.</p><p>Next we run the two loops that will produce the stars by using the split data and a while loop. And then its done!<br /> <img src="http://farm5.static.flickr.com/4052/4589190976_2357a482ec_o.png" border="0" alt="Rating example" /></p><p>As you can see, its very  easy to add extra bits of data to your post. This is just one example of how to use the custom fields.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/wordpress-3-0-custom-posts/' rel='bookmark' title='Permanent Link: WordPress 3.0 Custom Posts'>WordPress 3.0 Custom Posts</a></li><li><a href='http://brenelz.com/blog/quick-tip-wordpress-random-posts/' rel='bookmark' title='Permanent Link: Quick Tip: WordPress Random Posts'>Quick Tip: WordPress Random Posts</a></li><li><a href='http://brenelz.com/blog/wordpress-more-than-just-a-blogging-platform/' rel='bookmark' title='Permanent Link: WordPress: More than just a blogging platform?'>WordPress: More than just a blogging platform?</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=mS3AEVxEpD8:19A0mlOVXpQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=mS3AEVxEpD8:19A0mlOVXpQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=mS3AEVxEpD8:19A0mlOVXpQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/mS3AEVxEpD8" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/using-wordpress-custom-fields/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://brenelz.com/blog/using-wordpress-custom-fields/</feedburner:origLink></item> <item><title>Google Makes Changes: A Lot Like Bing?</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/RJ2ds59JD2w/</link> <comments>http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/#comments</comments> <pubDate>Wed, 05 May 2010 21:11:44 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2252</guid> <description><![CDATA[Reading time: 1 &#8211; 2 minutes Today Google launched some cool changes which has some people thinking it looks a lot like Bing. New Logo Google has changed its logo. It has a lot less bevel and shadows which I think makes it much more clear and crisp. Google tunes up search results, touches up [...]Related posts:<ol><li><a href='http://brenelz.com/blog/play-pacman-on-googles-homepage/' rel='bookmark' title='Permanent Link: Play PacMan on Google&#8217;s Homepage!'>Play PacMan on Google&#8217;s Homepage!</a></li><li><a href='http://brenelz.com/blog/googles-new-canonical-option/' rel='bookmark' title='Permanent Link: Google&#039;s New Canonical Option'>Google&#039;s New Canonical Option</a></li><li><a href='http://brenelz.com/blog/google-pagerank-updated-dec-30/' rel='bookmark' title='Permanent Link: Google PageRank Updated Dec. 30'>Google PageRank Updated Dec. 30</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 1 &#8211; 2 minutes</p><p>Today Google launched some cool changes which has some people thinking it looks a lot like Bing.</p><h3>New Logo</h3><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/05/google-newlogo.png"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/05/google-newlogo.png" alt="" title="google-newlogo" width="285" height="108" class="aligncenter size-full wp-image-2264" /></a></div><p>Google has changed its logo.  It has a lot less bevel and shadows which I think makes it much more clear and crisp.</p><p><a href="http://www.google.com/hostednews/ap/article/ALeqM5ibasBFrIzGg1lIH-2qmVvOPBxk3AD9FGPEGG1">Google tunes up search results, touches up logo</a></p><h3>Left Hand Search Bar</h3><p>This is the feature that seems to be ripping off Bing.  The funny part is that Microsoft has said that most people ignore this feature.  Here is a quick look at the sidebar:</p><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/05/new-google1.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/05/new-google1.jpg" alt="" title="new-google" width="151" height="271" class="aligncenter size-full wp-image-2257" /></a></div><h3>Video of the New Google Features</h3><p><object width="500" height="301"><param name="movie" value="http://www.youtube.com/v/C-rnxNFRAQA&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/C-rnxNFRAQA&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="301"></embed></object></p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/play-pacman-on-googles-homepage/' rel='bookmark' title='Permanent Link: Play PacMan on Google&#8217;s Homepage!'>Play PacMan on Google&#8217;s Homepage!</a></li><li><a href='http://brenelz.com/blog/googles-new-canonical-option/' rel='bookmark' title='Permanent Link: Google&#039;s New Canonical Option'>Google&#039;s New Canonical Option</a></li><li><a href='http://brenelz.com/blog/google-pagerank-updated-dec-30/' rel='bookmark' title='Permanent Link: Google PageRank Updated Dec. 30'>Google PageRank Updated Dec. 30</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=RJ2ds59JD2w:-4-i5hT2Oh0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=RJ2ds59JD2w:-4-i5hT2Oh0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=RJ2ds59JD2w:-4-i5hT2Oh0:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/RJ2ds59JD2w" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/</feedburner:origLink></item> <item><title>Using Social Media to Raise Money for Charities</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/7n4StP8zfck/</link> <comments>http://brenelz.com/blog/using-social-media-to-raise-money-for-charities/#comments</comments> <pubDate>Mon, 03 May 2010 13:00:13 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2246</guid> <description><![CDATA[Reading time: < 1 minute Social Media often gets a bad rap for being a place where people push their own agendas above all else. Today I am going to point out one individual who is using Twitter for the right reasons. She is raising money for the St. Jude Children&#8217;s Research Hospital. Want to [...]Related posts:<ol><li><a href='http://brenelz.com/blog/can-social-networking-raise-1k-for-cancer-in-6-hours/' rel='bookmark' title='Permanent Link: Can social networking raise $1k for cancer in 6 hours?'>Can social networking raise $1k for cancer in 6 hours?</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: < 1 minute</p><p>Social Media often gets a bad rap for being a place where people push their own agendas above all else.  Today I am going to point out one individual who is using Twitter for the right reasons.  She is raising money for the <strong>St. Jude Children&#8217;s Research Hospital</strong>.</p><p>Want to know what the most amazing thing is?  Bailey Browning (@LittleChuckFan) is only 9 years old and has raised OVER $3,500 for her cause!!</p><p>I would suggest you all follow her (@LittleChuckFan), and give to her amazing cause.</p><h3><a href="https://waystohelp.stjude.org/sjVPortal/public/displayUserPage.do?programId=551&#038;eventId=67067&#038;sectionStyle=subMenuTwo&#038;userId=473278">Help the children of St. Jude Today!</a></h3><p>One you have donated, please leave a comment below as I am hoping to give something away.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/can-social-networking-raise-1k-for-cancer-in-6-hours/' rel='bookmark' title='Permanent Link: Can social networking raise $1k for cancer in 6 hours?'>Can social networking raise $1k for cancer in 6 hours?</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=7n4StP8zfck:2kydpgk9p3k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=7n4StP8zfck:2kydpgk9p3k:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=7n4StP8zfck:2kydpgk9p3k:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/7n4StP8zfck" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/using-social-media-to-raise-money-for-charities/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/using-social-media-to-raise-money-for-charities/</feedburner:origLink></item> <item><title>Building a Tweetblast</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/UWwginmnO18/</link> <comments>http://brenelz.com/blog/building-a-tweetblast/#comments</comments> <pubDate>Mon, 19 Apr 2010 13:48:43 +0000</pubDate> <dc:creator>Alex</dc:creator> <category><![CDATA[Web Programming]]></category><guid isPermaLink="false">http://brenelz.com/?p=2227</guid> <description><![CDATA[Reading time: 8 &#8211; 13 minutes The amount of users on Twitter has increased dramatically recently! It is now a great way to get your product noticed, talked about (and if your very popular) trending. People like MacHeist often do a Tweetblast to spread the word about  something new and by participating you get something [...]Related posts:<ol><li><a href='http://brenelz.com/blog/building-a-simple-php-mailing-list/' rel='bookmark' title='Permanent Link: Building a Simple PHP Mailing List'>Building a Simple PHP Mailing List</a></li><li><a href='http://brenelz.com/blog/snazzy-css-double-border-effect/' rel='bookmark' title='Permanent Link: Snazzy CSS Double Border Effect'>Snazzy CSS Double Border Effect</a></li><li><a href='http://brenelz.com/blog/build-a-php-twitter-widget/' rel='bookmark' title='Permanent Link: Build a PHP Twitter Widget'>Build a PHP Twitter Widget</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 8 &#8211; 13 minutes</p><p>The amount of users on <a href="http://twitter.com">Twitter</a> has increased dramatically recently! It is now a great way to get your product noticed, talked about (and if your very popular) trending. People like <a href="http://macheist.com/">MacHeist</a> often do a Tweetblast to spread the word about  something new and by participating you get something in return. In the tutorial you will see how to build an AJAX-ed twitter tweetblast that will search twitter for a hash tag, and if it has been found it will then show a thanks slide. There are many things you can adapt this script to do, such as putting the users username in the database to make sure a user can only Tweet once, finding that users pictures and show all the users that have tweeted so far or just sending an email to say thanks.<br /> For this we just need an index page, some nice CSS, JavaScript for the AJAX, and PHP to search through Twitter using Twitters&#8217; <a href="http://apiwiki.twitter.com/Twitter-API-Documentation">search API</a>.</p><p><a id="live_demo" href="http://demo.alexbor.com/tweetblast">Live Demo</a><br /> <a id="download_file" href="http://demo.alexbor.com/downloads/tweetblast.zip">Download</a></p><p><span id="more-2227"></span></p><h2>Index page</h2><p>The index page will have 3 slides, they will be</p><ol><li>Entering the data/errors slide</li><li>Searching slide</li><li>Thanks slide</li></ol><p>and we will animate them in and out depending on the information that we get from out PHP script. Here is the layout:</p><pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;

&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Tweet Blast!&lt;/title&gt;

		&lt;!-- Start of CSS --&gt;
 	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/reset.css&quot; /&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/main.css&quot; /&gt;
		&lt;!-- Start of JS --&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;js/scripts.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;div id=&quot;wrap&quot;&gt;
	&lt;div id=&quot;header&quot;&gt;
		&lt;p&gt;You should follow:
			&lt;a class=&quot;brenelz&quot; href=&quot;http://twitter.com/brenelz&quot;&gt;@brenelz&lt;/a&gt; and
			&lt;a class=&quot;alex&quot; href=&quot;http://twitter.com/alexanderbor&quot;&gt;@AlexanderBor&lt;/a&gt;
		&lt;/p&gt;
	&lt;/div&gt;

		&lt;div id=&quot;blaster&quot;&gt;
			&lt;div id=&quot;slide1&quot; class=&quot;slide&quot;&gt;

										&lt;!-- What we want the user to tweet
											We are going to search for the #tag but
											# needs to be %23 when we direct them to Twitter with
											this status

										 --&gt;
				&lt;a class=&quot;tweetText&quot; href=&quot;http://twitter.com/?status=Testing the Tweetblast %23findthis&quot; target=&quot;_blank&quot;&gt;
					Testing the Tweetblast #findthis!
				&lt;/a&gt;
				&lt;div class=&quot;form&quot;&gt;
					&lt;!-- The username of our twitter-er --&gt;
					&lt;label for=&quot;username&quot; class=&quot;label&quot;&gt;Username: @&lt;/label&gt;
					&lt;input type=&quot;text&quot; size=&quot;20&quot; class=&quot;input&quot; id=&quot;username&quot; name=&quot;username&quot; /&gt;&lt;br /&gt;

					&lt;!-- A span this is defult to be hidden but will be show if this field has an error --&gt;

					&lt;p class=&quot;errorU error&quot;&gt;Please enter a username&lt;/p&gt;&lt;br /&gt;

					&lt;label for=&quot;email&quot; class=&quot;label&quot;&gt;Email Address:&lt;/label&gt;
					&lt;input type=&quot;text&quot; size=&quot;20&quot; class=&quot;input&quot; id=&quot;email&quot; name=&quot;email&quot; /&gt;&lt;br /&gt;&lt;p class=&quot;errorE error&quot;&gt;Please enter a valid email&lt;/p&gt;
					&lt;button type=&quot;submit&quot; class=&quot;next&quot; name=&quot;next&quot; value=&quot;Next&quot;&gt;&lt;/button&gt;

				&lt;!--
					Twitter will not add people who's profiles are
					private so if everything is OK and we didn't find
					the tweet that is probebly why.
				--&gt;
					&lt;p class=&quot;errorP error&quot;&gt;Your account must not be private, if its not try again.&lt;/p&gt;
				&lt;/div&gt;
			&lt;/div&gt;

			&lt;!-- Our processing side --&gt;
			&lt;div id=&quot;slide2&quot; class=&quot;slide&quot;&gt;
				&lt;p class=&quot;tweetText searching&quot;&gt;
					Searching Twitter for your Tweet!
				&lt;/p&gt;
				&lt;img src=&quot;images/loading.gif&quot; class=&quot;loading&quot; alt=&quot;Loading...&quot; width=&quot;32px&quot; height=&quot;32px&quot; /&gt;
			&lt;/div&gt;

			&lt;!-- Our thanks for Tweeting side --&gt;
			&lt;div id=&quot;slide3&quot; class=&quot;slide&quot;&gt;
				&lt;p class=&quot;tweetText done&quot;&gt;
					We found your tweet! Thanks for tweeting!
				&lt;/p&gt;
			&lt;/div&gt;

		&lt;/div&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html
</pre><p>Anything that is special has been commented in the code.</p><h2>CSS</h2><p>In the CSS we want to make sure that the slides our horizontal, and that they will be hidden if they are not meant to be shown.</p><pre class="brush: css;">
@charset &quot;UTF-8&quot;;
/* CSS Document */
/* UTULITIES */
.clear{clear: both;}
.push{height: 30px;}
/* END */
/* ORDER PAGE CORRECTLY */
*{margin: 0; padding: 0;}
html{overflow-y: scroll;position: relative;}
body{font-family: Helvetica, Verdana, Arial, sans-serif; width: 100%; height: 100%; background: #3EA9DF;}
/* END */

#wrap{width: 720px; margin: 0 auto;} /*  Center everything  */
#header{background: url(../images/blast.jpg) left top no-repeat; height: 131px;position: relative;}
#header p{position: absolute; bottom: 0px; padding-left: 190px;color: #3D3D3D;}
#header p a{color: #626262;padding: 5px;text-decoration: none;}
#header p a:hover{color: #7B7D7D;text-decoration: none;}

#blaster{
	overflow: hidden; /*  So we can hide the slide we don't want  */
	width: 720px; /*  Need to set a width of what area can be shown  */

	padding-bottom: 30px;
	padding-top: 35px;
	position: relative;
	height: 220px;
	background: white;

	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	border-radius: 6px; /*  When a browser FINALY support it  */
}

.slide{width: 715px;
	overflow: hidden;
	display: inline-block; /*  We can set a width and they will be inline  */
	position: absolute;
	}/*  The size of each of our sides  */

.tweetText{
	background:none repeat scroll 0 0 #B9CBD5;
	display:block;
	font-family:helvetica;
	font-size:22px;
	margin:0 auto;
	padding:30px 0;
	text-align:center;
	text-decoration:none;
	width:680px;
	color: #626262;
	-moz-border-radius: 6px;
	-webkit-border-radius: 6px;
	border-radius: 6px;
}
.tweetText:hover{
	background: #BCD5E4;
	color: #727374;
}
.form{
	margin-left:30px;
	margin-top:30px;
	font-size: 17px;
	color: #595D5F;
}

.label{display: inline-block; width: 130px;}
.input{color: #8D9499;border: none; background: none; border-bottom: 1px solid #BDD0DA;font-size: 17px;}
.input:hover, .input:focus{border-bottom: 1px solid #6D7980;color: #676C6F;}

.error{
	color:red;
	font-size:15px;
	padding-top:10px;
	display: none;/*  Make sure we have no errors showing  */
}
.errorP{text-align: center;padding-right: 30px;}

.next{
	background:url(&quot;../images/next.jpg&quot;) no-repeat scroll left top transparent;
	border:medium none;
	cursor:pointer;
	height:37px;
	margin-top:-60px;
	position:absolute;
	right:30px;
	width:121px;
}
.next:hover, .next:focus{background:url(&quot;../images/next_over.jpg&quot;) no-repeat scroll left top transparent;}

/*  SLIDE 2  */
.loading{padding-left:339px;
padding-top:50px;}
#slide2{left: 715px;}

/*  SLIDE 3  */

#slide3{left: 715px;}
.done{margin-top: 50px;}
</pre><h2>JavaScript</h2><p>With the JavaScript  lib jQuery we will post the values and move the first slide left while moving the next slides in. We want to check if there are any errors as if there are we want to move the first slide back in else, we move in the thanks slide.</p><pre class="brush: jscript;">
$(function() {
	$(&quot;.next&quot;).click(function(){ /*  When next is clicked  */
		$(&quot;#slide1&quot;).animate({&quot;left&quot;: &quot;-715px&quot;}, 500); /*  Slide away the first slide  */
		$(&quot;#slide2&quot;).animate({&quot;left&quot;: &quot;0&quot;}, 500, function(){ /*  And slide in the new once, once that if finished run this function  */

		$.ajax({
			type: 'post',
			dataType: 'json',
			url: 'grab.php',
			data: 'username=' + $('#username').val() + '&amp;email=' + $('#email').val(),
			success: function(e){ /*  On success  */
				if(e.error == 1){ // if there as an error
					$('.error').css({&quot;display&quot;: &quot;none&quot;});// remove all error messages as we want to display messages for this current go

					if(e.username == 1){
						$('.errorU').css({&quot;display&quot;: &quot;block&quot;});
					}

					if(e.email == 1){
						$('.errorE').css({&quot;display&quot;: &quot;block&quot;});
					}
					if(e.private == 1){
						$('.errorP').css({&quot;display&quot;: &quot;block&quot;});
					}

					/*

						We now slide back in the first slide with the error &quot;p&quot; elements
						Now visible.

					*/

					$(&quot;#slide2&quot;).animate({&quot;left&quot;: &quot;710px&quot;}, 500);
					$(&quot;#slide1&quot;).animate({&quot;left&quot;: &quot;0px&quot;}, 500);
				}else{
					/*

						There was no error so we remove slide 2
						and bring in the thanks!

					*/
	 				$(&quot;#slide2&quot;).animate({&quot;left&quot;: &quot;-710px&quot;}, 500);
					$(&quot;#slide3&quot;).animate({&quot;left&quot;: &quot;0px&quot;}, 500);
				}
			}
		});

		});
	});

});
</pre><h2>Searching Twitter</h2><p>Twitter&#8217;s search API is basically open to use with no limits. They do say not to use it excessively so if your going to use this on a <strong>HUGE</strong> scale you may want to contact them to ask of their permission. Because of this we can use CURL without authentication.</p><pre class="brush: php;">
&lt;?php

	$twitterUsername = $_POST['username'];
	$emailAdd = $_POST['email'];
	$tag = &quot;findthis&quot;; // The #tag that the use will find for

	function reply($type, $username, $email, $private){ // function to reply to the javascript
			/*

				This function shows if there was an error in
				1. overall
				2. username
				3. email
				4. didn't find it

			*/
			$replying = array(&quot;error&quot;=&gt;&quot;{$type}&quot;, &quot;username&quot;=&gt;&quot;$username&quot;, &quot;email&quot;=&gt;&quot;$email&quot;, &quot;private&quot;=&gt;&quot;$private&quot;);
			echo(json_encode($replying)); // json encode the responce
	}

	// Defult everything to OK
	$error = false;
	$username = 0;
	$email = 0;
	$private = 0;

	if( strlen($twitterUsername) &lt; 1 ){
		$username = 1;
		$error = true;
	}

	if( !preg_match('/^[a-z0-9]+([_\.-][a-z0-9]+)*@([a-z0-9]+([.-][a-z0-9]+)*)+\.[a-z]{2,}$/i', $emailAdd) ){
		$email = 1;
		$error = true;
	}

	if( $error == true ){
		reply(1, $username, $email, $private);
		die(); // stop running the script
	}

	/*

		If a user has JUST tweeted then it takes a few seconds for it to appear in
		Twitter's search. Because of this I have made it sleep for a few seconds to
		allow time for that to happen.
		It will also help a bit with mass attacks of people clicking over and over again.

	*/
	sleep(4);

	// search for the tweet				JSON format    The tag	   Who its from
	$search = &quot;http://search.twitter.com/search.json?q=&amp;tag={$tag}&amp;from={$twitterUsername}&quot;;
	$curlhandle = curl_init();
	curl_setopt($curlhandle, CURLOPT_URL, $search);
    curl_setopt($curlhandle, CURLOPT_RETURNTRANSFER, 1);

	// execute the search
    $response = curl_exec($curlhandle);
    curl_close($curlhandle);

	// decode the responce
    $json = json_decode($response);
	// cound the amount of &quot;results&quot; that have been found
    $numb = count($json-&gt;results);

    if($numb != 0){ // if a result has been found reply with no error
    	reply(0, 0, 0, 0);

    	/*

    		If you are going to use this scrip put all your code
    		to happen when a user has successfully tweeted here

    	*/

    	die();

    }else{
    	reply(1, 0, 0, 1); // no result was found so the user is mostlikey private
    	die();
    }
</pre><p>That is all the code that is needed to build a basic tweetblast. It can be easily customised to accomplish what you would want it to do for your site.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/building-a-simple-php-mailing-list/' rel='bookmark' title='Permanent Link: Building a Simple PHP Mailing List'>Building a Simple PHP Mailing List</a></li><li><a href='http://brenelz.com/blog/snazzy-css-double-border-effect/' rel='bookmark' title='Permanent Link: Snazzy CSS Double Border Effect'>Snazzy CSS Double Border Effect</a></li><li><a href='http://brenelz.com/blog/build-a-php-twitter-widget/' rel='bookmark' title='Permanent Link: Build a PHP Twitter Widget'>Build a PHP Twitter Widget</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=UWwginmnO18:tprC9_atOhU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=UWwginmnO18:tprC9_atOhU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=UWwginmnO18:tprC9_atOhU:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/UWwginmnO18" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/building-a-tweetblast/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://brenelz.com/blog/building-a-tweetblast/</feedburner:origLink></item> <item><title>Building a Simple PHP Mailing List</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/4hgnJdpSoE4/</link> <comments>http://brenelz.com/blog/building-a-simple-php-mailing-list/#comments</comments> <pubDate>Mon, 05 Apr 2010 13:00:06 +0000</pubDate> <dc:creator>Alex</dc:creator> <category><![CDATA[Web Programming]]></category><guid isPermaLink="false">http://brenelz.com/?p=2200</guid> <description><![CDATA[Reading time: 15 &#8211; 24 minutes In this tutorial I will be showing you how to build a PHP mailing list web app. In this web app, users will be able to sign up. Once they do they will be added to the database and an unsubscribe hash will be generated. Admins will be able [...]Related posts:<ol><li><a href='http://brenelz.com/blog/building-a-tweetblast/' rel='bookmark' title='Permanent Link: Building a Tweetblast'>Building a Tweetblast</a></li><li><a href='http://brenelz.com/blog/how-to-create-a-simple-api-with-php-and-mysql/' rel='bookmark' title='Permanent Link: How to Create a Simple API with PHP and MySQL'>How to Create a Simple API with PHP and MySQL</a></li><li><a href='http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/' rel='bookmark' title='Permanent Link: Create URL Shortener For Twitter Using PHP'>Create URL Shortener For Twitter Using PHP</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 15 &#8211; 24 minutes</p><p>In this tutorial I will be showing you how to build a PHP mailing list web app. In this web app, users will be able to sign up. Once they do they will be added to the database and an unsubscribe hash will be generated. Admins will be able to send emails and add [unsubscribe] within the email in order to show a way for the subscribers to remove themselves. Javascript will also be added to the sign up process to make it nicer for the users.<br /> <a href="http://demo.alexbor.com/mail_list" id="live_demo">Live Demo</a><br /> Username: alex<br /> Password: password<br /> <a id="download_file" href="http://demo.alexbor.com/downloads/mailing_list_app.zip">Download</a><br /> <span id="more-2200"></span></p><h2>Databases</h2><p>We are going to need two databases for this system. One for the admins and one for the subscribers. Here is the SQL code needed for the tables.</p><pre class="brush: sql;">
CREATE TABLE IF NOT EXISTS `subscribers` (
  `id` int(30) NOT NULL auto_increment,
  `email` varchar(60) NOT NULL,
  `unsubscribeLink` varchar(35) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1  ;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(30) NOT NULL auto_increment,
  `username` varchar(50) NOT NULL,
  `password` varchar(40) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1  ;

INSERT INTO `users` (`id`, `username`, `password`) VALUES
(1, 'alex', '5f4dcc3b5aa765d61d8327deb882cf99');
</pre><p>After running that code you will have two tables one for subscribers that has an ID, email address and a unsubscribe fields (with ID as the primary key and set to auto increment). The other table for the users has an ID, username and password field (again with the ID as the primary key and set to auto increment). After that we insert into the &#8216;users&#8217; table the values &#8220;alex&#8221; for the username and an MD5 hash of the word password. You can change these to what ever you want just make sure that the password is MD5 hashed or you will not be able to login later.</p><h2>Connecting to the database</h2><p>Create a directory &#8220;functions&#8221; and within that two files &#8220;function.php&#8221; and &#8220;config.php&#8221;. We will add information to the config file connecting to the database. This is what you need:</p><pre class="brush: php;">
&lt;?php
	$dbhost = 'localhost'; // database host
	$dbuser = 'USERNAME'; // database username
	$dbpass = 'PASSWORD'; // database password
	$db		= 'DATABASE'; // the database
	$conn 	= mysql_connect($dbhost, $dbuser, $dbpass) or die(&quot;Could not connect to the database&quot;); // creat a connection or die
	mysql_select_db($db) or die(&quot;I couldn't find the database&quot;); // select the database or die
	define(&quot;BASE_URL&quot;, &quot;http://url-to-file/mail_list/&quot;); // the URL to the file
	define(&quot;REPLY_EMAIL&quot;, &quot;noreply@yourdomain.com&quot;); // the email address we want our mailing list to be from
</pre><p>If you load that page and don&#8217;t see anything you have successfully connected to your database. We now need to fill in the &#8216;functions.php&#8217; file. Within &#8216;functions.php&#8217; add</p><pre class="brush: php;">
&lt;?php
session_start();	// start session
require_once(&quot;config.php&quot;); // require our config.php file

function reply($type, $message){ // function to reply to the javascript
		$replying = array(&quot;error&quot;=&gt;&quot;{$type}&quot;, &quot;message&quot;=&gt;&quot;$message&quot;);
		echo(json_encode($replying)); // json encode the responce
}

function add_email_to_database($email){ // adding the email address to the datbase
	// 1. We need to make sure its not already in
	// 2. We need to make a unsubscribe hash
	// 3. We need to add the user

	$email = mysql_real_escape_string($email); // make sure it OK
	$sql = &quot;SELECT * FROM `subscribers` WHERE email = '{$email}' LIMIT 1&quot;; // select all subsribers that has the email and only return (if there is) one
	$qry = mysql_query($sql); // run the query
	if( mysql_num_rows($qry) != 0){ // if that user was found they are not new so return false
		return false;
	}else{ // user was not found
		$unsubLink = &quot;&quot;; // create empty varible
		$unsubLink .= rand(1111, 99999); // generate random number and add it to the empty varible
		$unsubLink .= rand(1111, 99999);
		$unsubLink .= $email; // attach the email address

		$unsubLink = md5($unsubLink); // md5 it
		$unsubLink .= rand(1111, 99999); // then attack a random number

		// insert the values
		$sql = &quot;
				INSERT INTO `subscribers` (
					`id` ,
					`email` ,
					`unsubscribeLink`
				)
				VALUES (
					NULL , '$email', '$unsubLink'
				);
			&quot;;

		mysql_query($sql); // run the query
		return true; // return true as we added the user
	}
}

function loggedIn(){ // check if we are logged in
	if($_SESSION['loggedIn'] != 1){ // if we are not
		return false;
	}else{ // if we are
		return true;
	}
}
[/sourceode]&lt;/pre&gt;
That is all we need for both of these files.
&lt;h2&gt;Sigh up page&lt;/h2&gt;
This page will allow the users to sign up, it will added them to the database after some validation all happening with some AJAX. Create an index.php page and add:
[sourcecode language=&quot;php&quot;]
&lt;?php
 session_start(); // start the session
 $message = $_SESSION['message']; // check if we have a message to display
 $_SESSION['message'] = &quot;&quot;;  // clear the message for next time
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;

&lt;head&gt;
 &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
 &lt;title&gt;Mailing List Web App&lt;/title&gt;

 &lt;!-- Start of CSS --&gt;
 &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/reset.css&quot; /&gt;
 &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/main.css&quot; /&gt;
 &lt;!-- Start of JS --&gt;
 &lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery.js&quot;&gt;&lt;/script&gt;
 &lt;script type=&quot;text/javascript&quot; src=&quot;js/scripts.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;div id=&quot;wrap&quot;&gt;
 &lt;h1&gt;Join my list!&lt;/h1&gt;
 &lt;!-- If we have a message, display it --&gt;
 &lt;?php if(strlen($message) &gt; 0){ ?&gt;&lt;h2 class=&quot;stat&quot;&gt;&lt;?php echo '&lt;br /&gt;'. $message ?&gt;&lt;/h2&gt;&lt;?php } ?&gt;
 &lt;br /&gt;
 &lt;form action=&quot;./add.php&quot; method=&quot;POST&quot; id=&quot;subscribe&quot;&gt;
 &lt;label class=&quot;label&quot; for=&quot;email&quot;&gt;Email&lt;/label&gt;
 &lt;input type=&quot;text&quot; value=&quot;you@you.com&quot; size=&quot;20&quot; id=&quot;email&quot; name=&quot;email&quot; /&gt;
 &lt;input type=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Sign Up!&quot; /&gt;
 &lt;/form&gt;
 &lt;p class=&quot;message&quot;&gt;&lt;/p&gt;
 &lt;br /&gt;&lt;br /&gt;
 &lt;a class=&quot;small&quot; href=&quot;admin&quot;&gt;(admin)&lt;/a&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html
</pre><p>Now create a CSS directory and add a reset CSS file (you can find them online, though this is optional) and a file main.css. Then add this styling:</p><pre class="brush: css;">
@charset &quot;UTF-8&quot;;
/* CSS Document */
/* UTULITIES */
.clear{clear: both;}
.push{height: 30px;}
/* END */
/* ORDER PAGE CORRECTLY */
*{margin: 0; padding: 0;}
html{overflow-y: scroll;position: relative;}
body{background-color: #e1e1e1; font-family: &quot;Lucida Grande&quot;, Verdana, Arial, sans-serif; width: 100%; height: 100%;}
/* END */
h1{
	font-size: 30px;
	font-weight: bold;
	margin-bottom:  20px;
	color: #D0D3D3;
	padding-bottom: 8px;
	border-bottom: 1px solid #B4B6B6;
}
#wrap{
	background-color: #888888;
	width: 500px;
	margin: 0 auto;
	padding: 20px;
}
form{text-align: center;}
.label{color: #C3C5C5;font-size: 20px;}
#email, #password, #username{margin-top: -2px;font-size: 18px;background: none;border: none;border-bottom: 1px dotted black;color: #DBDEDE;}

.message{color:white;padding-top:20px;text-align:center;}
#login{padding-top: 10px;}
#create{text-align: left;}
.input{
font-family: &quot;Lucida Grande&quot;, Verdana, Arial, sans-serif;
background:none repeat scroll 0 0 #E3E5E5;
border:1px solid #9A9C9C;
display: block;
font-size:16px;
padding:5px;
color: #3F4040;
}

.input:hover, .input:focus{background: #EAECEC;border: 1px solid #575858;}
.note{color:white;font-size:13px;}
.log{text-decoration: none; color: white;}
.small{text-decoration: none; color: white;font-size: 15px;}
.small:hover{color: black;}
.stat{text-align: center; color: white;}
</pre><h3>Javascript</h3><p>This javascript file will listen for a submit on the form then post the data to our adder php file using jQuery/AJAX.</p><pre class="brush: jscript;">
$(function() {
function pulse(item){ // an animation to plus an item
	$(item).animate({&quot;opacity&quot;: 0.5}, 200)
	.animate({&quot;opacity&quot;: 1}, 200)
	.animate({&quot;opacity&quot;: 0.5}, 200)
	.animate({&quot;opacity&quot;: 1}, 200)
	.animate({&quot;opacity&quot;: 0.5}, 200)
	.animate({&quot;opacity&quot;: 1}, 200)
	.animate({&quot;opacity&quot;: 0.5}, 200)
	.animate({&quot;opacity&quot;: 1}, 200)
	.animate({&quot;opacity&quot;: 0.5}, 200)
	.animate({&quot;opacity&quot;: 1}, 200)
	.animate({&quot;opacity&quot;: 0.5}, 200)
	.animate({&quot;opacity&quot;: 1}, 500);
}

$('#submit').removeAttr('disabled'); // when we load the page make sure this button is OK
$('.message').css({&quot;display&quot;: &quot;none&quot;});	// hide the message class

var emailsVal = $('#email').val(); // get the current value of #email

$(&quot;#email&quot;).focus(function(){	// when the input is clicked
	if($(this).val() == emailsVal){ // if the value is the defult value
		$(this).val(''); // clear the box
	}
});

$('#subscribe').submit(function(e){	// when clicked
	$('#submit').animate({'opacity': '0.4'}).attr({'disabled': 'disabled'}); // fade out/deactivet submit button
	e.preventDefault(); // prevent defult
	$.ajax({ //ajax
		type: 'post', // post the data
		dataType: 'json', // data type
		url: 'add.php', // url of the file to post to
		data: 'email=' + $('#email').val(), // data to post
		success: function(e){ // on success
			if(e.error == true){ // if we set an error
				pulse('#email'); // pule the email box
				$('.message').html(e.message).slideDown(); // display the message
				$('#submit').animate({'opacity': '1'}, function(){ // fade back in the submit box
					$(this).removeAttr('disabled'); // remove the disabled attr so its clickable
				});
			}else{ // if we set didn't set an error
				$('#subscribe').slideUp(); // slide up the subscribe box
				$('.message').html(e.message).slideDown(); // slide down the message
			}
		}
	});

		$(this).ajaxError(function(){
//			alert(&quot;THERE WAS AN AJAX ERROR, SORRY ABOUT THAT&quot;); // optional, to say if there was a AJAX error
		});
		return false; // return false (stop form from posting)
}); // end of AJAX

});
</pre><h2>Adding the user</h2><p>Create a file &#8220;add.php&#8221; where the javascript will post to. Within we will need to validate and then add the user. Also return a JSON encoded response for the awaiting JS script. This is the needed code:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;functions/functions.php&quot;); // include the functions and the config file
$email = $_POST['email']; // get the email
if (!preg_match('/^[a-z0-9]+([_\.-][a-z0-9]+)*@([a-z0-9]+([.-][a-z0-9]+)*)+\.[a-z]{2,}$/i', $email)) { // make sure it valid
		$error = &quot;Email not valid&quot;;	 // set a message
		reply(1, $error); // set an error
		die(); // die and stop running the script
}

if($email == &quot;you@you.com&quot;){ // if its you@you the user just clicked submit and although its valid it won't be a users email
	$error = &quot;Thats not your email!&quot;;
	reply(1, $error);
	die();
}

if( add_email_to_database($email) ){ // if we added the user
	reply(0, &quot;Thanks! You are now in the know.&quot;); // set no error
}else{
	reply(1, &quot;That email is already in the know.&quot;); // else, the user was found alreay
};
</pre><h2>Admin pages</h2><p>That is all that we need to allow the user to subscribe! Now create a directory &#8220;admin&#8221; and add these files &#8220;index.php&#8221;, &#8220;login.php&#8221;, &#8220;logout.php&#8221; and &#8220;poster.php&#8221;. In the index file we will post to a login form. I am going to build the login/out script first as I know what I will be needing.</p><h3>Login</h3><p>Open the login.php file and add</p><pre class="brush: php;">
&lt;?php
	require_once(&quot;../functions/functions.php&quot;);
		// get/clean values
	$username = mysql_real_escape_string(trim($_POST['username']));
	$password = mysql_real_escape_string(trim($_POST['password']));
		// something was entered
	if(strlen($username) == 0 || strlen($password) == 0){ // if no username of password was entered
		$_SESSION['message'] = &quot;Please enter a username and a password&quot;; // set a message
		header(&quot;Location: &quot;. BASE_URL .&quot;/admin&quot;);   // direct to the admin page
		die(); // die/stop script
	}else{
		$password = md5($password); // hash the password
	}

	$sql = &quot;
		SELECT * FROM users WHERE username = '{$username}' AND password = '{$password}' LIMIT 1;
		&quot;; // search for users with that username/password
	$qr = mysql_query($sql); // run query
	if( mysql_num_rows($qr) == 1 ){  // if the user was found
		$user = mysql_fetch_assoc($qr); // get values
		$_SESSION['loggedIn'] = 1; // set logged in session
		$_SESSION['username'] = $user['username']; //  you may want their username

		$_SESSION['time'] =  $_SERVER['REQUEST_TIME']; // incase you want to time out a user
		$_SESSION['message'] = &quot;You have been logged in&quot;; // set message
		header(&quot;Location: &quot;. BASE_URL .&quot;/admin&quot;);   // redirect the user
		die();
	}else{
		$_SESSION['message'] = &quot;Didn't find a username and password with that information.&quot;;
		header(&quot;Location: &quot;. BASE_URL .&quot;/admin&quot;);
		die();
	}
</pre><h3>Logging Out</h3><p>Now open logout.php and add this small bit of simple code to log the user out:</p><pre class="brush: plain;">
&lt;?php
require_once('../functions/functions.php');
session_destroy(); // destroy all information
session_start(); // start a new session just for the message
$_SESSION['message'] = &quot;You have been logged out&quot;; // say we have been loggged out
header(&quot;Location: &quot; .BASE_URL.&quot;/admin&quot;);  // relocate to the admin page
</pre><p>That is all we need to logout users.</p><h3>Messeger</h3><p>Open the index.php file where we will add code to check if we are logged in, if we are we will show a form to email people, if not, we will show a login form submitting the the login.php file we made above.</p><pre class="brush: php;">
&lt;?php
	require_once('../functions/functions.php');
	$loggedIn = loggedIn(); // run login function
// checking for message/sessions content

	if( isset($_SESSION['message']) ){ // if we have a message
		$message = $_SESSION['message']; // set a local varible
		$_SESSION['message'] = &quot;&quot;; // clear the session
	}

	if( isset($_SESSION['subject']) ){ // if we have a recovered subject
		$subject = $_SESSION['subject'];
	}else{
		$subject = &quot;&quot;;
	}
	if( isset($_SESSION['messageArea']) ){ // if we have a recovered message
		$messageArea = $_SESSION['messageArea'];
	}else{
		$messageArea = &quot;&quot;;
	}
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;

&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Mailing List Web App || ADMIN&lt;/title&gt;

		&lt;!-- Start of CSS --&gt;
 	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../css/reset.css&quot; /&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../css/main.css&quot; /&gt;
&lt;/head&gt;

&lt;div id=&quot;wrap&quot;&gt;
&lt;?php if(!$loggedIn){ //user is not logged in ?&gt;
	&lt;h1&gt;Please, login&lt;/h1&gt;
	&lt;?php if($message) echo &quot;&lt;h3 class='message'&gt;&quot;.$message.&quot;&lt;/h3&gt;&quot;; ?&gt;
	&lt;form action=&quot;login.php&quot; method=&quot;POST&quot; id=&quot;login&quot;&gt;
		&lt;label class=&quot;lable&quot; for=&quot;username&quot;&gt;Username&lt;/label&gt;
		&lt;input type=&quot;text&quot; value=&quot;alex&quot; size=&quot;20&quot; id=&quot;username&quot; name=&quot;username&quot; /&gt;
		&lt;br /&gt;&lt;br /&gt;
		&lt;label class=&quot;lable&quot; for=&quot;password&quot;&gt;Password&lt;/label&gt;
		&lt;input type=&quot;password&quot; value=&quot;&quot; size=&quot;20&quot; id=&quot;password&quot; name=&quot;password&quot; /&gt;
		&lt;br /&gt;&lt;br /&gt;
		&lt;input type=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Log me in!&quot; /&gt;
	&lt;/form&gt;
	&lt;p class=&quot;message&quot;&gt;&lt;/p&gt;
&lt;?php }else{ // user is logged in ?&gt;
	&lt;h1&gt;Send A Message&lt;/h1&gt;
	&lt;?php if($message) echo &quot;&lt;h3 class='message'&gt;&quot;.$message.&quot;&lt;/h3&gt;&quot;; // display any messages ?&gt;

	&lt;form action=&quot;poster.php&quot; method=&quot;POST&quot; id=&quot;create&quot;&gt;
		&lt;label for=&quot;subject&quot; class=&quot;label&quot;&gt;Subject&lt;/label&gt;&lt;br /&gt;&lt;br /&gt;
		&lt;input class=&quot;input&quot; name=&quot;subject&quot; id=&quot;subject&quot; type=&quot;text&quot; value=&quot;&lt;?php echo $subject; // echo the varible ?&gt;&quot; /&gt;
		&lt;br /&gt;
		&lt;label for=&quot;messageArea&quot; class=&quot;label&quot;&gt;Message&lt;/label&gt;&lt;br /&gt;&lt;br /&gt;
		&lt;textarea class=&quot;input&quot; name=&quot;messageArea&quot; id=&quot;messageArea&quot; rows=&quot;15&quot; cols=&quot;46&quot; wrap=&quot;wrap&quot;&gt;&lt;?php echo $messageArea; ?&gt;&lt;/textarea&gt;
		&lt;br /&gt;
		&lt;input type=&quot;submit&quot; value=&quot;Send message&quot; /&gt;&lt;br /&gt;
		&lt;small class=&quot;note&quot;&gt;Note: Add [unsubscribe] in the email to add an unsubscribe link.&lt;/small&gt;
	&lt;/form&gt;
	&lt;br /&gt;&lt;br /&gt;
	&lt;a class=&quot;log&quot; href=&quot;&lt;?php echo BASE_URL ?&gt;/admin/logout.php&quot;&gt;Logout&lt;/a&gt;
&lt;?php } ?&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><h3>Sending emails</h3><p>This will now create a nice way to login, and post emails. We just need the scrip to send all the emails. Open poster.php and we will make it.</p><pre class="brush: php;">
&lt;?php
require_once('../functions/functions.php');
if($_SESSION['loggedIn'] != 1){
		// if the user is not logged in, redirect them and add the message to
		// tell them they must be logged in
		// helps with unwanted people running your script by posting to it.
		$_SESSION['message'] = &quot;You must be logged in.&quot;;
		header(&quot;Location: &quot;. BASE_URL .&quot;/admin&quot;);
		die();
}
$message = $_POST['messageArea'];
$subject = $_POST['subject'];
if(strlen($message) == 0 || strlen($subject) == 0){
	// if no information was added in either fields, save what was intered in a session and redirect them
	$_SESSION['subject'] = $subject;
	$_SESSION['messageArea'] =  $message;
	$_SESSION['message'] = &quot;Please fill in both the subject and the message.&quot;;
	header(&quot;Location: &quot; .BASE_URL.&quot;/admin&quot;);
	die();

}
// grab all the subscribers
$sql = &quot;
	SELECT * FROM subscribers;
&quot;;

$qr = mysql_query($sql);
// if we don't have any
if(mysql_num_rows($qr) == 0){
	$_SESSION['message'] =  &quot;You currently have no subscribers&quot;;
	header(&quot;Location: &quot; .BASE_URL.&quot;/admin&quot;);
	die();
}

// go through all the subscribers
while( $user = mysql_fetch_array($qr)){
	// set a message
	$_SESSION['message'] =  &quot;Your emails are being sent...&quot;;
	// redirect the user (no point in them waiting for all the messages to send...)
	header(&quot;Location: &quot; .BASE_URL.&quot;/admin&quot;);
	$newMessage = &quot;&quot;; // set a clear varible
	// search for the [unsubscribe] tag and replace it with a URL for the user to unsubscribe
	$newMessage = str_replace(
		&quot;[unsubscribe]&quot;,
		BASE_URL.&quot;/unsubscribe/&quot;.$user['unsubscribeLink'].&quot;&amp;email=&quot;.$user['email'],
		$message
	);

	// replace all special characters
	$newMessage = htmlspecialchars($newMessage);
	// replace new lines with break tags
	$newMessage = str_replace( &quot;\r\n&quot;,
								&quot;&lt;br /&gt;&quot;,
								$newMessage
							);
	// content type
	$headers  = 'MIME-Version: 1.0' . &quot;\r\n&quot;;
	$headers .= 'Content-type: text/html; charset=iso-8859-1' . &quot;\r\n&quot;;
	$headers .= &quot;From: &quot;.REPLY_EMAIL.&quot;\r\n&quot;; // who the reply is to
	mail($user['email'], $subject, $newMessage, $headers); // send the email to the user
}
</pre><h2>Unsubscribe</h2><p>Only one small thing left to do&#8230; Build the unsubscribe page which is being sent in the email. For this we need a directory called &#8220;unsubscribe&#8221; and inside that two files. A .htaccess file to make the URL slightly cleaner and the index.php file.<br /> Open the .htaccess and add</p><pre class="brush: plain;">
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?hash=$1 [L]
</pre><p>This will make the first variable the hash on the index page. Open the index page and this final bit of code:</p><pre class="brush: php;">
&lt;?php
require_once('../functions/functions.php');
$hash = mysql_real_escape_string($_GET['hash']); // get the hash, you don't really need to make sure its clean unless you want to add this to a diffrent database table etc.
$email = mysql_real_escape_string($_GET['email']); // get the email
if(strlen($hash) &lt; 1 || strlen($email) &lt; 1 ){ // make sure they are set
	$_SESSION['message'] = &quot;The code is not valid - please contact support&quot;;
	header(&quot;Location:  &quot;.BASE_URL );
	die();
}
// make sure email is avlid
if (!preg_match('/^[a-z0-9]+([_\.-][a-z0-9]+)*@([a-z0-9]+([.-][a-z0-9]+)*)+\.[a-z]{2,}$/i', $email)) {
	$_SESSION['message'] = &quot;The code is not valid - please contact support&quot;;
	header(&quot;Location:  &quot;.BASE_URL );
	die();
}

$sql = &quot;
		SELECT * FROM subscribers WHERE email = '$email' AND unsubscribeLink = '$hash' LIMIT 1;
	&quot;; // search for that user
	$qr = mysql_query($sql); // run
	$rows = mysql_num_rows($qr); // get the number or rows with that information

	if($rows == 1){ // if it was found delete it
		$sql = &quot;DELETE FROM `subscribers` WHERE `email` = '$email' AND `unsubscribeLink` = '$hash' LIMIT 1&quot;;
		mysql_query($sql);
		$_SESSION['message'] = &quot;You have been unsubscribed successfully&quot;;
		header(&quot;Location:  &quot;.BASE_URL );
		die();
	}else{ // if not tell them to contact support for manual removal
		$_SESSION['message'] = &quot;You where not found - please contact support&quot;;
		header(&quot;Location:  &quot;.BASE_URL );
		die();
	}
</pre><p>That is now all complete and you should have a working mailing list app. Hope that you have found this interesting and learnt a few things.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/building-a-tweetblast/' rel='bookmark' title='Permanent Link: Building a Tweetblast'>Building a Tweetblast</a></li><li><a href='http://brenelz.com/blog/how-to-create-a-simple-api-with-php-and-mysql/' rel='bookmark' title='Permanent Link: How to Create a Simple API with PHP and MySQL'>How to Create a Simple API with PHP and MySQL</a></li><li><a href='http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/' rel='bookmark' title='Permanent Link: Create URL Shortener For Twitter Using PHP'>Create URL Shortener For Twitter Using PHP</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=4hgnJdpSoE4:EQ72t6gZ8zc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=4hgnJdpSoE4:EQ72t6gZ8zc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=4hgnJdpSoE4:EQ72t6gZ8zc:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/4hgnJdpSoE4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/building-a-simple-php-mailing-list/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/building-a-simple-php-mailing-list/</feedburner:origLink></item> <item><title>20 Source Code Hosting Sites You Should Know</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/FPXAQ4-u82k/</link> <comments>http://brenelz.com/blog/20-source-code-hosting-sites-you-should-know/#comments</comments> <pubDate>Mon, 29 Mar 2010 14:00:29 +0000</pubDate> <dc:creator>Abhin Sharma</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2166</guid> <description><![CDATA[Reading time: 6 &#8211; 10 minutes Code sharing and hosting has become easier than ever before, now you can easily share your code with your friends and community. We will take a look at some of the popular sites. Google Code Hosting code.google.com Google code is the most popular hosting site which hosts the likes [...]Related posts:<ol><li><a href='http://brenelz.com/blog/choosing-an-open-source-cms-beginners-guide/' rel='bookmark' title='Permanent Link: Choosing an Open Source CMS: Beginner&#039;s Guide'>Choosing an Open Source CMS: Beginner&#039;s Guide</a></li><li><a href='http://brenelz.com/blog/mssql-vs-mysql/' rel='bookmark' title='Permanent Link: MSSQL vs. MySQL'>MSSQL vs. MySQL</a></li><li><a href='http://brenelz.com/blog/university-of-winnipeg-konami-code/' rel='bookmark' title='Permanent Link: University of Winnipeg Konami Code'>University of Winnipeg Konami Code</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 6 &#8211; 10 minutes</p><p>Code sharing and hosting has become easier than ever before, now you can easily share your code with your friends and community. We will take a look at some of the popular sites.</p><h3>Google Code Hosting</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/11.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/11.jpg" alt="" title="1" width="100" height="100" class="aligncenter size-full wp-image-2168" /></a></div></td><td><a href="http://code.google.com/">code.google.com</a></p><p>Google code is the most popular hosting site which hosts the likes of jQuery and other popular libraries.</td></tr></tbody></table><p><span id="more-2166"></span></p><h3>Github</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/21.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/21.jpg" alt="" title="2" width="100" height="100" class="aligncenter size-full wp-image-2169" /></a></div></td><td><a href="http://github.com/">Github</a></p><p>Next in the line is Github, it provides fast and easy hosting which version support and as well as code monitoring.</td></tr></tbody></table><h3>Sourceforge</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/31.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/31.jpg" alt="" title="3" width="100" height="100" class="aligncenter size-full wp-image-2170" /></a></div></td><td><a href="http://sourceforge.net/">Sourceforge</a></p><p>Not much of a code hosting site but you can create project and is the leading open source hosting site which well supports all type of languages.</td></tr></tbody></table><h3>Launchpad</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/4.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/4.jpg" alt="" title="4" width="100" height="100" class="aligncenter size-full wp-image-2171" /></a></div></td><td><a href="https://launchpad.net/">Launchpad</a></p><p>Launchpad is an online collaboration platform that provides services like bug tracking, version control , code reviews and much more.</td></tr></tbody></table><h3>Codeplex</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/5.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/5.jpg" alt="" title="5" width="100" height="100" class="aligncenter size-full wp-image-2172" /></a></div></td><td><a href="http://www.codeplex.com/">Codeplex</a></p><p>A popular hosting site hosted by microsoft so not much features you can expect.</td></tr></tbody></table><h3>Bitbucket</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/6.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/6.jpg" alt="" title="6" width="100" height="100" class="aligncenter size-full wp-image-2173" /></a></div></td><td><a href="http://bitbucket.org/">Bitbucket</a></p><p>Develop code as a team. Keep all your development in one place, be it issue tracking, documentation or sharing code.</td></tr></tbody></table><h3>Assembla</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/7.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/7.jpg" alt="" title="7" width="100" height="100" class="aligncenter size-full wp-image-2174" /></a></div></td><td><a href="http://www.assembla.com/">Assembla</a></p><p>Not a free code hosting and sharing site, though excellent features such at agile development tools makes it well worth it&#8217;s price.</td></tr></tbody></table><h3>JavaForge</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/8.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/8.jpg" alt="" title="8" width="100" height="100" class="aligncenter size-full wp-image-2175" /></a></div></td><td><a href="http://www.javaforge.com/">JavaForge</a></p><p>An excellent site for the java lovers( like me <img src='http://cdnwww.brenelz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> just joking supports all language and runs on Amazon cloud. It has all the features needed that makes a good hosting site.</td></tr></tbody></table><h3>Pastie</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/9.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/9.jpg" alt="" title="9" width="100" height="100" class="aligncenter size-full wp-image-2176" /></a></div></td><td><a href="http://pastie.org/">Pastie</a></p><p>Awesome site, quickly paste your code and share it.</td></tr></tbody></table><h3>Kenai</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/10.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/10.jpg" alt="" title="10" width="100" height="100" class="aligncenter size-full wp-image-2177" /></a></div></td><td><a href="http://kenai.com/projects">Kenai</a></p><p>Owned by Oracle Sun, excellent hosting features and integrated with netbeans.</td></tr></tbody></table><h3>Codefetch</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/111.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/111.jpg" alt="" title="11" width="100" height="100" class="aligncenter size-full wp-image-2178" /></a></div></td><td><a href="http://codefetch.com/">Codefetch</a></p><p>Not much of a code hosting site but you can search code snippets and examples from books, very handy.</td></tr></tbody></table><h3>Tigris</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/12.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/12.jpg" alt="" title="12" width="100" height="100" class="aligncenter size-full wp-image-2179" /></a></div></td><td><a href="http://www.tigris.org/">Tigris</a></p><p>Tigris.org is a mid-sized open source community focused on building better tools for collaborative software development. Prominent projects include SVN (Subversion).</td></tr></tbody></table><h3>Fedorahosted</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/13.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/13.jpg" alt="" title="13" width="100" height="100" class="aligncenter size-full wp-image-2180" /></a></div></td><td><a href="https://fedorahosted.org/web/">Fedorahosted</a></p><p>Hosted by Fedora group, has a fairly large community.</td></tr></tbody></table><h3>Osor</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/14.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/14.jpg" alt="" title="14" width="100" height="100" class="aligncenter size-full wp-image-2181" /></a></div></td><td><a href="http://www.osor.eu/">Github</a></p><p>The Open Source Observatory and Repository for European public administrations (OSOR) is a platform for exchanging information, experiences and FLOSS-based code for use in public administrations.</td></tr></tbody></table><h3>Joomlacode</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/15.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/15.jpg" alt="" title="15" width="100" height="100" class="aligncenter size-full wp-image-2182" /></a></div></td><td><a href="http://joomlacode.org/">Joomlacode</a></p><p>Specifically created for joomla lovers, you can host code related to joomla here.</td></tr></tbody></table><h3>Bountysource</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/16.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/16.jpg" alt="" title="16" width="100" height="100" class="aligncenter size-full wp-image-2183" /></a></div></td><td><a href="https://www.bountysource.com/">Bountysource</a></p><p>Bounty Source was created with the goal of increasing and improving development in Open Source Software communities, providing features such as task tracker, SVN code repository and a CMS.</td></tr></tbody></table><h3>Berlios</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/17.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/17.jpg" alt="" title="17" width="100" height="100" class="aligncenter size-full wp-image-2184" /></a></div></td><td><a href="http://www.berlios.de/">Berlios</a></p><p>Berlios is an open source software supporter and is quite famous.</td></tr></tbody></table><h3>Tuxfamily</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/18.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/18.jpg" alt="" title="18" width="100" height="100" class="aligncenter size-full wp-image-2185" /></a></div></td><td><a href="http://www.tuxfamily.org/">Tuxfamily</a></p><p>Simple hosting service, perfect for simple projects.</td></tr></tbody></table><h3>Drupal</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/19.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/19.jpg" alt="" title="19" width="100" height="100" class="aligncenter size-full wp-image-2186" /></a></div></td><td><a href="http://drupal.org/">Drupal</a></p><p>As the name suggests code hosting for drupal developers and has a very active community.</td></tr></tbody></table><h3>Alioth</h3><table><tbody><tr><td><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/20.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/20.jpg" alt="" title="20" width="100" height="100" class="aligncenter size-full wp-image-2187" /></a></div></td><td><a href="https://alioth.debian.org/">Alioth</a></p><p>Aimed at the Debian development project, nice community for debian lovers.</td></tr></tbody></table><p>Start sharing</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/choosing-an-open-source-cms-beginners-guide/' rel='bookmark' title='Permanent Link: Choosing an Open Source CMS: Beginner&#039;s Guide'>Choosing an Open Source CMS: Beginner&#039;s Guide</a></li><li><a href='http://brenelz.com/blog/mssql-vs-mysql/' rel='bookmark' title='Permanent Link: MSSQL vs. MySQL'>MSSQL vs. MySQL</a></li><li><a href='http://brenelz.com/blog/university-of-winnipeg-konami-code/' rel='bookmark' title='Permanent Link: University of Winnipeg Konami Code'>University of Winnipeg Konami Code</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=FPXAQ4-u82k:6kZdRPtnU7g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=FPXAQ4-u82k:6kZdRPtnU7g:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=FPXAQ4-u82k:6kZdRPtnU7g:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/FPXAQ4-u82k" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/20-source-code-hosting-sites-you-should-know/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://brenelz.com/blog/20-source-code-hosting-sites-you-should-know/</feedburner:origLink></item> <item><title>Build a PHP Twitter Widget</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/4lnB-q6u92I/</link> <comments>http://brenelz.com/blog/build-a-php-twitter-widget/#comments</comments> <pubDate>Mon, 22 Mar 2010 18:41:07 +0000</pubDate> <dc:creator>Alex</dc:creator> <category><![CDATA[Web Programming]]></category><guid isPermaLink="false">http://brenelz.com/?p=2144</guid> <description><![CDATA[Reading time: 8 &#8211; 14 minutes Today I will be showing you how to use cURL to get your Twitter status and cache it into a file on your server. This file will then be read with JavaScript and displayed on the web-page. Before we start you can view a demo and download the final [...]Related posts:<ol><li><a href='http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/' rel='bookmark' title='Permanent Link: Create URL Shortener For Twitter Using PHP'>Create URL Shortener For Twitter Using PHP</a></li><li><a href='http://brenelz.com/blog/build-a-content-slider-with-jquery/' rel='bookmark' title='Permanent Link: Build a Content Slider with jQuery'>Build a Content Slider with jQuery</a></li><li><a href='http://brenelz.com/blog/creating-an-ellipsis-in-php/' rel='bookmark' title='Permanent Link: Creating an Ellipsis in PHP'>Creating an Ellipsis in PHP</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 8 &#8211; 14 minutes</p><p>Today I will be showing you how to use cURL to get your Twitter status and cache it into a file on your server. This file will then be read with JavaScript and displayed on the web-page. Before we start you can view a demo and download the final files below:</p><p><a id="download_file" href="http://demo.alexbor.com/downloads/twitter_widget.zip">Download</a><br /> <a id="live_demo" href="http://demo.alexbor.com/twitter_widget">Live Demo</a></p><p>The widget will have the following file structure</p><p><img src="http://demo.alexbor.com/twitter_widget/files.jpg" border="0" alt="File structure" /></p><p><span id="more-2144"></span></p><h2>API Limit</h2><p>Twitter has an API limit (currently 150 calls per hour) so its best to use your username/password to make sure that you will get a successful response. If you don&#8217;t (as far as I know) Twitter will use the API calls that are for everyone with your IP/Servers IP. This means that if other people on your server are also using data from twitter (that requires an API call), it will start to give an error saying that you have used up your API limit very quickly.</p><h1>Making the widget</h1><h3>Caching and HTML</h3><pre>
<pre class="brush: php;">
&lt;?php
function twitterCapture() {
        // Set your username and password here
        $user = 'twitter_username'; // Twitter Username
        $password = 'xxxxxxxx'; // Twitter Password

        $tw = curl_init(&quot;http://twitter.com/statuses/user_timeline/{$user}.json&quot;); //grabs the JSON format of your timelines
        curl_setopt($tw,CURLOPT_TIMEOUT, 30); // Timeout (for when Twitter is down)
        curl_setopt($tw,CURLOPT_USERPWD,$user . &quot;:&quot; . $password); // Uses your username and password
        curl_setopt($tw,CURLOPT_RETURNTRANSFER,1); // returns
        $json = curl_exec ($tw); // Executes the cURL and puts it into the varible
        return $json; // returns what was grabbed
}
$cachefile = 'cache/twitterCache.json'; // the location to your cache file
$cachetime = 10 * 60; // set the cach time 10 * 60 (1 hour)
	// if the file exists		// if and the time it was created is less then cache time
if ( (file_exists($cachefile)) &amp;&amp; ( time() - $cachetime &lt; filemtime($cachefile) ) ) {
// script will not use the cached version
}else{ // the file didn't exist or is old
	ob_start(); // turn on the output buffering
	$fp = fopen($cachefile, 'w'); // opens for writing only or will creat it's not there
	fwrite($fp, twitterCapture()); // writes to the file what was grabbed from the previouse function
	fclose($fp); // closes
	ob_end_flush(); // finishes and flushes the output buffer
}
?&gt; 

&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;

&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Little Twitter Widget&lt;/title&gt;

		&lt;!-- Start of CSS --&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/reset.css&quot; /&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/main.css&quot; /&gt;
		&lt;!-- Start of JS --&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-1.4.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;js/main.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;twitter_widget_top&quot; class=&quot;center&quot; &gt;&lt;/div&gt;&lt;!-- The top of the widget --&gt;
&lt;div id=&quot;twitter_widget_body&quot; class=&quot;center&quot;&gt; &lt;!-- The body wrap --&gt;

	&lt;div id=&quot;twitter_widget_tweet&quot;&gt; &lt;!-- The tweet area --&gt;
		&lt;div id=&quot;twitter_movement&quot;&gt; &lt;!-- To position the icon reletive to --&gt;
			&lt;a id=&quot;twitter_icon&quot; href=&quot;http://twitter.com/&quot;&gt;&lt;/a&gt; &lt;!-- Twitter icon --&gt;
			&lt;div id=&quot;twitterWrap&quot;&gt; &lt;!-- The blue area --&gt;
				&lt;div id=&quot;twitter&quot;&gt;	&lt;!-- The main twitter data --&gt;
					&lt;noscript&gt;JavaScript must be on to view tweets&lt;/noscript&gt; &lt;!-- Incase no js --&gt;
					&lt;p class=&quot;tweet&quot;&gt;Loading...&lt;/p&gt; &lt;!-- The Tweet --&gt;
					&lt;p class=&quot;created_at&quot;&gt;&lt;/p&gt; &lt;!-- Date created --&gt;
				&lt;/div&gt;
			&lt;/div&gt;
			&lt;p class=&quot;clear&quot;&gt;&lt;/p&gt; &lt;!-- Clear the floats --&gt;
		&lt;/div&gt;
		&lt;a href=&quot;&quot; class=&quot;previous tweetNav&quot;&gt;&lt;/a&gt;&lt;!-- Next button --&gt;
		&lt;p class=&quot;follow_me&quot;&gt;Follow me - &lt;a href=&quot;http://twitter.com/alexanderbor&quot; class=&quot;screen_name&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;!-- Follow me link --&gt;
		&lt;a href=&quot;&quot; class=&quot;next tweetNav&quot;&gt;&lt;/a&gt; &lt;!-- Pre button --&gt;
		&lt;p class=&quot;clear&quot;&gt;&lt;/p&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;twitter_widget_bottom&quot; class=&quot;center&quot;&gt;&lt;/div&gt;&lt;!-- Bottom of widet --&gt;
&lt;p class=&quot;info&quot;&gt;Join my &lt;span class=&quot;followedNumber&quot;&gt;&lt;/span&gt; followers - &lt;span class=&quot;user_name&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre></pre><p>This will check if the cache file exists and then how old it is. If its older than  how long we want to leave before getting a new copy then will run the function to grab the new copy of the your twitter stream in JSON format. This is then written to your server in the cache file.</p><h3>The CSS</h3><pre class="brush: css;">
@charset &quot;UTF-8&quot;;
/* CSS Document */
/* UTULITIES */
.clear{clear: both;}
.push{height: 30px;}
/* END */
/* ORDER PAGE CORRECTLY */
*{margin: 0; padding: 0;}
html{ position: relative;}
body{font-family: Helvetica, Verdana, Arial, sans-serif; width: 100%; height: 100%; background: #1E202A;color:#3494E5;}
.center{margin: 0 auto;}
a{text-decoration:none;color:#4AA1EF; overflow: hidden}
a:hover{color: #3D658E;}
/* END */
#twitter_widget_top{background: url(../images/top.jpg) top left no-repeat; width: 475px; height: 30px;margin-top:81px; } /*  Top of widget  */
#twitter_widget_body{background: url(../images/body.jpg) left repeat-y; width: 475px;} /*  BODY  */
#twitter_widget_bottom{background: url(../images/bottom.jpg) bottom left no-repeat; width: 475px; height: 21px; } /*  foot  */
#twitter_icon{background:url(&quot;../images/twitter_icon.jpg&quot;) no-repeat scroll center bottom transparent;height:50px;margin-left:30px;position:absolute;top:33%;width:50px;}
#twitter_icon:hover{ background-position: top center;} /*  Move icon on hover  */
#twitterWrap{    /*  Don't show overflow and set a width  */
 overflow: hidden;
 width: 350px;
 float: right;
 background: #1E202A;
 margin: 20px 20px 0;
 border: 1px solid #062333;
 -moz-border-radius: 5px;
 -webkit-border-radius: 5px;
}
#twitter_movement{position: relative;} /*  To align icon to  */
.tweet { /*  The Tweet  */
font-family:&quot;Lucida Grande&quot;,Verdana,Arial,sans-serif;
font-size:15px;
line-height:18px;
padding:15px;
position:relative;
text-align:center;
}

.next{background:url(&quot;../images/arrows.jpg&quot;) no-repeat right top transparent;float:right;height:14px;margin-right:20px;margin-top:10px;width:21px;}
.next:hover{background-position: right center;} /* Next button  */
.previous{background:url(&quot;../images/arrows.jpg&quot;) no-repeat left bottom transparent;float:left;height:14px;margin-left: 103px;margin-top:10px;width:21px;}
.previous:hover{background-position: left center;}

.created_at {display:block;font-size:12px;font-style:italic;padding-right:20px;text-align:right;}
.follow_me{display:block;float:left;margin:10px;text-align:center;width:280px;}
.info{padding-top:5px;text-align:center;}
</pre><h2>Javascript</h2><p>To get the twitter status we will use the javascript library <a href="http://jquery.com/">jQuery</a>, as this makes it a lot easier. We will use the $.getJSON to grab our cached file.</p><pre>
<pre class="brush: jscript;">
$(function() {
$.getJSON('cache/twitterCache.json', function(data) { // get the file and put in var &quot;data&quot;

// 		Add information about the user
	$('.followedNumber').html( data[0].user.followers_count); // follow count
	$('.screen_name').html( data[0].user.screen_name); // screen name
	$('.statuses_count').html(data[0].user.statuses_count); // amount of tweets
	$('.user_name').html(data[0].user.name); // username

	// defult variables

	var totalAmount = &quot;&quot;, 	// total amount of items
		moveOut = &quot;&quot;,		// If we are moving in or out the animation
		moveIn = &quot;&quot;,		// If we are moving in or out the animation
		current = 0,		// Set the current to 0
		$i = 0;				// Set i to 0 

$.each(data, function(){ // for each of the &quot;data&quot;
	totalAmount = $i; // set the varible total amount to i
	$i++; // plus one to i
});
	clicked(current);  // run the function to grab the first item

	$(&quot;.next&quot;).click(function(){ 			// when next is clicked
		if ($(this).hasClass('active') ){ 	// if it's active
			current = current + 1;			// set current to + 1
			moveOut = &quot;+&quot;; 					// make the move out animation correct
			moveIn = &quot;-&quot;;	 				// same with move in
			clicked(current); 				// run the function and pass in current
		}; 									// no else, so nothing will happen if we click when not active

	});
	$(&quot;.previous&quot;).click(function(){ 		// almost the same as above
		if ($(this).hasClass('active') ){
			current = current - 1;			// minus one from the tcurrent
			moveOut = &quot;-&quot;;
			moveIn  = &quot;+&quot;;
			clicked(current);
		};
	});

//
//	Time function from the Twitter Blog JS file
//
function relative_time(time_value) {
  var values = time_value.split(&quot; &quot;);
  time_value = values[1] + &quot; &quot; + values[2] + &quot;, &quot; + values[5] + &quot; &quot; + values[3];
  var parsed_date = Date.parse(time_value);
  var relative_to = (arguments.length &gt; 1) ? arguments[1] : new Date();
  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
  delta = delta + (relative_to.getTimezoneOffset() * 60);

  if (delta &lt; 60) {
    return 'less than a minute ago';
  } else if(delta &lt; 120) {
    return 'about a minute ago';
  } else if(delta &lt; (60*60)) {
    return (parseInt(delta / 60)).toString() + ' minutes ago';
  } else if(delta &lt; (120*60)) {
    return 'about an hour ago';
  } else if(delta &lt; (24*60*60)) {
    return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
  } else if(delta &lt; (48*60*60)) {
    return '1 day ago';
  } else {
    return (parseInt(delta / 86400)).toString() + ' days ago';
  }
}

	function clicked(current){ // when clicked function runs
		// get the width to be able to slide the tweet area
		var tweetAreaWidth = $('#twitterWrap').width();
		// fade out the time it was created
		$('.created_at').animate({&quot;opacity&quot;: &quot;0&quot;}, 400); // fade out the date
		$('.tweet').animate({&quot;right&quot;: moveOut +  tweetAreaWidth + &quot;px&quot;}, function(){ // move the .tweet div left/right then
			$('.tweet')	.html( data[ current ].text  ); // add the next tweet
			var time = relative_time( data[ current ].created_at ); // get the next date
			$('.created_at').html(time);	// put data into useable format
			var tweetAreaHeight = $('#twitter').height(); // get the height of the tweet area now its got the tweet inside
			$('#twitterWrap').animate({&quot;height&quot;: tweetAreaHeight + &quot;px&quot;}, function(){ // change the tweet height to the new div
				$('.tweet').css({&quot;right&quot;:  moveIn + tweetAreaWidth + &quot;px&quot;}).animate({&quot;right&quot;: 0}); // move in the tweet
				$('.created_at').animate({&quot;opacity&quot;: &quot;1&quot;}, 500); // fade in the date
			});
		});
// dealing with the click buttons
		$('.tweetNav').removeClass('inactive').addClass('active'); // remove inactive from all buttons and add active
		if(current == totalAmount){ // if current is equal to the total amount make the next button inactive
			$('.next').removeClass('active').addClass('inactive');
		}
		if(current == 0){
			$('.previous').removeClass('active').addClass('inactive');
		}
		$('.inactive').animate({&quot;opacity&quot;: &quot;0.3&quot;}, 1000); // make inactive buttons fade out
		$('.active').animate({&quot;opacity&quot;: &quot;1&quot;}, 500); // made active buttons fade in
		$('.tweetNav').click( function(){ return false; }); // return false

	}; // end of clicked function
});// end of json
});
</pre></pre><p>This should now work, a great way to see how to access the elements that are returned is using <a href="https://addons.mozilla.org/en-US/firefox/addon/1843">FireBug </a>as this lets us see the name of the json elements and what is nested in them.</p><p><img src="http://demo.alexbor.com/twitter_widget/firebug.png" border="0" alt="Firebug example" /></p><p>I hope that you have found this interesting and now have a working animated twitter widget.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/' rel='bookmark' title='Permanent Link: Create URL Shortener For Twitter Using PHP'>Create URL Shortener For Twitter Using PHP</a></li><li><a href='http://brenelz.com/blog/build-a-content-slider-with-jquery/' rel='bookmark' title='Permanent Link: Build a Content Slider with jQuery'>Build a Content Slider with jQuery</a></li><li><a href='http://brenelz.com/blog/creating-an-ellipsis-in-php/' rel='bookmark' title='Permanent Link: Creating an Ellipsis in PHP'>Creating an Ellipsis in PHP</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=4lnB-q6u92I:MpX9xL5YmBU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=4lnB-q6u92I:MpX9xL5YmBU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=4lnB-q6u92I:MpX9xL5YmBU:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/4lnB-q6u92I" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/build-a-php-twitter-widget/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://brenelz.com/blog/build-a-php-twitter-widget/</feedburner:origLink></item> <item><title>Twitter URL Shortener: Part 2</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/1QK4OnnzPoA/</link> <comments>http://brenelz.com/blog/twitter-url-shortener-part-2/#comments</comments> <pubDate>Wed, 17 Mar 2010 14:00:22 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2135</guid> <description><![CDATA[Reading time: 27 &#8211; 45 minutes Welcome to part 2 of this tutorial. In this we will finish off what we started and add the extra functionality. By the end of this tutorial we will have: Stats Page Admin Page to delete items and make them inactive Settings to add new users and change API [...]Related posts:<ol><li><a href='http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/' rel='bookmark' title='Permanent Link: Create URL Shortener For Twitter Using PHP'>Create URL Shortener For Twitter Using PHP</a></li><li><a href='http://brenelz.com/blog/building-a-simple-php-mailing-list/' rel='bookmark' title='Permanent Link: Building a Simple PHP Mailing List'>Building a Simple PHP Mailing List</a></li><li><a href='http://brenelz.com/blog/build-a-php-twitter-widget/' rel='bookmark' title='Permanent Link: Build a PHP Twitter Widget'>Build a PHP Twitter Widget</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 27 &#8211; 45 minutes</p><p>Welcome to part 2 of this tutorial. In this we will finish off what we started and add the extra functionality. By the end of this tutorial we will have:</p><ol><li>Stats Page</li><li>Admin Page to delete items and make them inactive</li><li>Settings to add new users and change API key</li><li>Work with Tweetie 2 for the iPhone/iPod touch</li></ol><p><span id="more-2135"></span></p><p><a id='download_file' href='http://demo.alexbor.com/downloads/url_part_2.zip' title='Download Files'>Download</a><br /> <a href='http://demo.alexbor.com/url2' id='live_demo' target='_blank' title='Live Demo'>live demo</a></p><h4>Login</h4><p>Username: alexbor <br /> Password: password</p><h3>Some changes</h3><p>Let&#8217;s get started with just a few minor changes to the last tutorial. In the functions.php file, change the &#8220;json_to_jquery&#8221; function to this:</p><pre class="brush: php;">
function json_to_jquery($type, $message, $url){
	$replying = array('error'=&gt;'', 'message'=&gt; '');
	$replying['error'] = &quot;$type&quot;;
	$replying['message'] = &quot;$message&quot;;
	$replying['shortUrl'] = &quot;$url&quot;; //changed from shortURL to shortUrl as that is how Tweetie reads it
	echo(json_encode($replying));
}
</pre><p>also, at the very top of this file, we want to add</p><pre class="brush: php;">
$loggedIn = $_SESSION['loggedIn'];
</pre><p>which is a variable  that will be used later to make sure that we are logged in. Finally inside of the add.js file update &#8220;$(&#8216;#theLink&#8217;).val(e.shortURL);&#8221; to &#8220;$(&#8216;#theLink&#8217;).val(e.shortUrl);&#8221;.</p><p> After doing that you will find that (once the API key is done) you will be able to use this with Tweetie.</p><p> Also, we will be adding more CSS classes and IDs so it&#8217;s best to change the current &#8220;main.css&#8221; file (in the CSS folder) to the following, to save from needing to go through the CSS later.</p><pre class="brush: css;">
@charset &quot;UTF-8&quot;;
/* CSS Document */
/* UTULITIES */
.clear{clear: both;}
.push{height: 30px;}
/* END */
/* ORDER PAGE CORRECTLY */
*{margin: 0; padding: 0;}
html{overflow-y: scroll;position: relative;}																/*  COLOUR  */
body{width: 100%; height: 100%; background: url(../images/theBG.png) repeat; background-color: #00ADED;color: white;}
/* END */

/* header  */
#header{width: 1000px;height: 153px;margin: 0 auto;}
/*  END  */
#stipWrap{width: 1000px; margin: 0 auto;}
#strip, #stripAdmin{		/*  CHANGE REPEAT  */
background:url(&quot;../images/strip.png&quot;) repeat scroll 0 0 transparent;
min-width:1000px;
position:inherit;
}
#strip{
height:270px;
}

#linkForm{
height:30px;
margin-bottom:0;
margin-left:auto;
margin-right:auto;
margin-top:0;
padding-top:100px;
width:500px;
}
.label{color:white;font-size:30px;}
.smallInput{font-family: Helvetica, Verdana, Arial, sans-serif;background:none repeat scroll 0 0 #E9F0F8;border:1px solid #00ADED;color:#1E1C56;font-size:20px;padding:5px;}
#theLink{width:400px;}
#theLink:hover{background: #ffffff;}
#theLink:focus{color: #000000;}
.process{
background:#CC1B00;
color:white;
font-size:23px;
font-weight:bold;
height:0;
margin-left:250px;
position:absolute;
text-align:center;
width:500px;
overflow: hidden;
}
.processingC{padding: 5px;}
ul{font-family:helvetica;list-style:none outside none;margin-left:230px;margin-top:10px;display: none;}
ul li{display:inline-block;text-align:center;width:145px;}
ul li a{color:#2473A0;text-decoration:none;}
ul li a:hover{color:#E4E9E9;}
#message{
color:#CBCBCB;
font-family:Helvetica,Verdana,Arial,sans-serif;
font-size:25px;
font-weight:bold;
margin:0 auto;
padding-top:154px;
text-align:center;
width:1000px;
word-spacing:3px;
letter-spacing: 2px;
text-shadow:0 0 8px #00ADED;
}
.problem{
color:#CBCBCB;
font-family:Helvetica,Verdana,Arial,sans-serif;
font-size:25px;
font-weight:bold;
text-align:center;
width:1000px;
padding-top: 5px;
word-spacing:3px;
letter-spacing: 2px;
text-shadow:0 0 8px #00ADED;
}
/*  LOGIN FORM  */
.inform{color:white;padding:25px 0;text-align:center;}
.loginForm{text-align: center;}
.logOut{color:#B1B3B3;font-size:18px;font-style:italic;padding-top:5px;position:ab
solute;text-decoration:none;}
.logOut:hover, .admin:hover{color:white;}
.admin{color:#B1B3B3;font-size:18px;font-style:italic;padding-top:5px;float:right;text-decoration:none;}
.pright{padding-right: 10px;}
.shorturl, .longurl, .link{color: #CBCBCB; text-decoration: none;}

.shorturl:hover, .longurl:hover, .link:hover{color: white;}
</pre><h3>Admin Page</h3><p>If you have not already, create an admin folder on the home directory and inside this make two files &#8220;index.php&#8221; and &#8220;settings.php&#8221; and open the index.php file. This is going to be a large file that will paginate the links and then display them below with buttons to delete them with option to change if they are active or not. The pagination code is a slightly modified version of <a href="http://papermashup.com/easy-php-pagination/">papermashup</a>&#8216;s and he explains what it means on that page. In this file add the following code:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../files/functions/functions.php&quot;); // get our functions file
admin_page(); // this is a function we will create later to check if the user is logged in
	$tableName=&quot;url&quot;;		// the table to search
	$targetpage = &quot;index.php&quot;; 	// the file that this is in ... So ?page will work
	$limit = 10; // how many per page

	$query = &quot;SELECT COUNT(*) as num FROM $tableName&quot;; // get amount of items in database
	$total_pages = mysql_fetch_array(mysql_query($query)); // run/fetch
	$total_pages = $total_pages[num];	

	$stages = 3;
	$page = mysql_escape_string($_GET['page']);
	$pageRet = mysql_escape_string($_GET['page']);
	if($page){
		$start = ($page - 1) * $limit;
	}else{
		$start = 0;
	}
    // Get page data
	$query1 = &quot;SELECT * FROM $tableName ORDER BY `id` DESC  LIMIT $start, $limit&quot;;
	$result = mysql_query($query1);

	// Initial page num setup
	if ($page == 0){$page = 1;}
	$prev = $page - 1;
	$next = $page + 1;
	$lastpage = ceil($total_pages/$limit);
	$LastPagem1 = $lastpage - 1;					

	$paginate = '';
	if($lastpage &gt; 1)
	{
	$paginate .= &quot;&lt;div class='paginate'&gt;&quot;;
		// Previous
		if ($page &gt; 1){
			$paginate.= &quot;&lt;a href='$targetpage?page=$prev'&gt;previous&lt;/a&gt;&quot;;
		}else{
			$paginate.= &quot;&lt;span class='disabled'&gt;previous&lt;/span&gt;&quot;;	}

		// Pages
		if ($lastpage &lt; 7 + ($stages * 2))	// Not enough pages to breaking it up
		{
			for ($counter = 1; $counter &lt;= $lastpage; $counter++)
			{
				if ($counter == $page){
					$paginate.= &quot;&lt;span class='current'&gt;$counter&lt;/span&gt;&quot;;
				}else{
					$paginate.= &quot;&lt;a href='$targetpage?page=$counter'&gt;$counter&lt;/a&gt;&quot;;}
			}
		}
		elseif($lastpage &gt; 5 + ($stages * 2))	// Enough pages to hide a few?
		{
			// Beginning only hide later pages
			if($page &lt; 1 + ($stages * 2))
			{
				for ($counter = 1; $counter &lt; 4 + ($stages * 2); $counter++)
				{
					if ($counter == $page){
						$paginate.= &quot;&lt;span class='current'&gt;$counter&lt;/span&gt;&quot;;
					}else{
						$paginate.= &quot;&lt;a href='$targetpage?page=$counter'&gt;$counter&lt;/a&gt;&quot;;}
				}
				$paginate.= &quot;...&quot;;
				$paginate.= &quot;&lt;a href='$targetpage?page=$LastPagem1'&gt;$LastPagem1&lt;/a&gt;&quot;;
				$paginate.= &quot;&lt;a href='$targetpage?page=$lastpage'&gt;$lastpage&lt;/a&gt;&quot;;
			}
			// Middle hide some front and some back
			elseif($lastpage - ($stages * 2) &gt; $page &amp;&amp; $page &gt; ($stages * 2))
			{
				$paginate.= &quot;&lt;a href='$targetpage?page=1'&gt;1&lt;/a&gt;&quot;;
				$paginate.= &quot;&lt;a href='$targetpage?page=2'&gt;2&lt;/a&gt;&quot;;
				$paginate.= &quot;...&quot;;
				for ($counter = $page - $stages; $counter &lt;= $page + $stages; $counter++)
				{
					if ($counter == $page){
						$paginate.= &quot;&lt;span class='current'&gt;$counter&lt;/span&gt;&quot;;
					}else{
						$paginate.= &quot;&lt;a href='$targetpage?page=$counter'&gt;$counter&lt;/a&gt;&quot;;}
				}
				$paginate.= &quot;...&quot;;
				$paginate.= &quot;&lt;a href='$targetpage?page=$LastPagem1'&gt;$LastPagem1&lt;/a&gt;&quot;;
				$paginate.= &quot;&lt;a href='$targetpage?page=$lastpage'&gt;$lastpage&lt;/a&gt;&quot;;
			}
			// End only hide early pages
			else
			{
				$paginate.= &quot;&lt;a href='$targetpage?page=1'&gt;1&lt;/a&gt;&quot;;
				$paginate.= &quot;&lt;a href='$targetpage?page=2'&gt;2&lt;/a&gt;&quot;;
				$paginate.= &quot;...&quot;;
				for ($counter = $lastpage - (2 + ($stages * 2)); $counter &lt;= $lastpage; $counter++)
				{
					if ($counter == $page){
						$paginate.= &quot;&lt;span class='current'&gt;$counter&lt;/span&gt;&quot;;
					}else{
						$paginate.= &quot;&lt;a href='$targetpage?page=$counter'&gt;$counter&lt;/a&gt;&quot;;}
				}
			}
		}

				// Next
		if ($page &lt; $counter - 1){
			$paginate.= &quot;&lt;a href='$targetpage?page=$next'&gt;next&lt;/a&gt;&quot;;
		}else{
			$paginate.= &quot;&lt;span class='disabled'&gt;next&lt;/span&gt;&quot;;
			}

		$paginate.= &quot;&lt;/div&gt;&quot;;
}
?&gt;
</pre><p>This will create a variable containing the navigation and also allow us loop through the data that will be shown on this page. To do this we will had the following below that bulk of code:</p><pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Make it short || Admin &amp;rArr; &lt;?php echo $username ; ?&gt; &lt;?php echo $title; ?&gt;&lt;/title&gt;
		&lt;!-- Start of CSS --&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/main.css&quot; /&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/admin.css&quot; /&gt;
		&lt;!-- Start of JS --&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php echo BASE_URL; ?&gt;/files/js/jquery.js&quot;&gt;&lt;/script&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php echo BASE_URL; ?&gt;/files/js/add.js&quot;&gt;&lt;/script&gt;

&lt;?php if($_GET['deleted']): //we will use this function to display a row saying &quot;deleted&quot; after we are redirected by out delete page. ?&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function() {
	var deleted = document.location.hash.substr(1); // this gets the # value in the url
	$('p#' + deleted ).prepend(&quot;&lt;h1 class='deleted'&gt;DELETED&lt;/h1&gt;&lt;p class='push'&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p class='push'&gt;&lt;/p&gt;&quot;);
});
&lt;/script&gt;
&lt;?php endif; ?&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;header&quot;&gt;
&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
&lt;?php echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/files/process/logout.php' class='headLink Logout'&gt;Logout &quot; . $username . &quot;?&lt;/a&gt;&quot;; ?&gt;
&lt;a class='headLink Settings right' href=&quot;&lt;?php echo BASE_URL; ?&gt;/admin/settings.php&quot;&gt;Settings&lt;/a&gt;
&lt;a class='headLink Admin right active' href=&quot;&lt;?php echo BASE_URL; ?&gt;/admin/&quot;&gt;Admin&lt;/a&gt;
&lt;/div&gt;
&lt;div id=&quot;stripAdmin&quot;&gt;
	&lt;div id=&quot;stipWrap&quot;&gt;
		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
		&lt;?php echo $paginate; //display the navigation ?&gt;
		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
		&lt;p class=&quot;right&quot;&gt;FYI: &lt;?php echo $total_pages; //display the amount of records ?&gt; URLS have been shortened&lt;/p&gt;

		&lt;?php
		$i = 0;
		while($row = mysql_fetch_array($result)): //for every result loop through this ?&gt;
		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
		&lt;p id=&quot;&lt;?php echo $i;  ?&gt;&quot;&gt;&lt;/p&gt;
		The full URL is:
		&lt;a class=&quot;longurl&quot; href=&quot;&lt;?php echo urldecode($row['long']); ?&gt;&quot;&gt;&lt;?php echo urldecode($row['long']); ?&gt;&lt;/a&gt;&lt;br /&gt;
		The short URL is:
		&lt;a class=&quot;longurl&quot; href=&quot;&lt;?php echo BASE_URL . &quot;/&quot;. $row['short']; ?&gt;&quot;&gt;&lt;?php echo BASE_URL . &quot;/&quot;. $row['short']; ?&gt;&lt;/a&gt;&lt;br /&gt;
		Clicks: &lt;?php echo  $row['clicks']; ?&gt;&lt;br /&gt;
		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
		This URL was added on &lt;?php echo date(&quot;dS F Y g:i a&quot;, strtotime( $row['dateAdded'])); ?&gt; and is currently set to 

				&lt;form action=&quot;&lt;?php echo BASE_URL; ?&gt;/files/process/change_active.php&quot; method=&quot;post&quot;&gt;
					Active:
					&lt;input &lt;?php if($row['active'] == 1){?&gt;checked=&quot;&quot;&lt;?php } // show as active is the url value is still active?&gt;
					class=&quot;toggle&quot; name=&quot;visible&quot; value=&quot;1&quot; type=&quot;radio&quot; /&gt;&lt;br /&gt;

					Inactive:
					&lt;input &lt;?php if($row['active'] == 0){?&gt;checked=&quot;&quot;&lt;?php }?&gt;
					name=&quot;visible&quot; value=&quot;0&quot; type=&quot;radio&quot; class=&quot;toggle&quot; /&gt;

					&lt;input class=&quot;toggle&quot; type=&quot;hidden&quot; name=&quot;urlID&quot; value=&quot;&lt;?php echo $row['id']; ?&gt;&quot; /&gt;&lt;br /&gt; &lt;!-- SO WE KNOW WHAT TO CHANGE --&gt;
					&lt;input class=&quot;toggle&quot; type=&quot;hidden&quot; name=&quot;page&quot; value=&quot;&lt;?php echo $pageRet; ?&gt;&quot; /&gt;&lt;br /&gt;&lt;!-- TO REDIRECT THE USER AT THE END --&gt;
					&lt;input class=&quot;toggle&quot; type=&quot;hidden&quot; name=&quot;ret&quot; value=&quot;&lt;?php echo $i; ?&gt;&quot; /&gt;&lt;br /&gt;&lt;!-- move user to item  on redirect--&gt;
					&lt;input type=&quot;submit&quot; value=&quot;Change&quot; /&gt;
				&lt;/form&gt;

			&lt;!-- Delete button --&gt;
			&lt;a class=&quot;delete &quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/process/deleteItem.php?urlID=&lt;?php echo $row['id']; ?&gt;&amp;page=&lt;?php echo $pageRet; ?&gt;&amp;ret=&lt;?php echo $i; ?&gt;&quot;&gt;Delete Item?&lt;/a&gt;
			&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
			&lt;hr/&gt; &lt;!-- A line to separate --&gt;
			// increment $i and end loop
		&lt;?php $i++; endwhile;
			// display naviagtion
		echo $paginate;

		?&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;end&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p>For that page, we will add the css file &#8220;admin.css&#8221; inside the css folder as this is just CSS for the admin page and there is no point loading it for people who are not logged in or don&#8217;t need it. We want to add:</p><pre class="brush: css;">
body{font-family: &quot;Lucida Grande&quot;, Verdana, Arial, sans-serif; font-size:18px;}
h1.large{
	color: white;
	font-size: 30px;
	font-weight: bold;
	font-family: &quot;Lucida Grande&quot;, Verdana, Arial, sans-serif;
	padding: 10px;

}
.shorturl, .longurl, .link{color: #CBCBCB; text-decoration: none;}
.shorturl:hover, .longurl:hover, .link:hover{color: white;}
.right{float: right;padding-right: 20px;}
.toggle{width: 16px; height: 16px;}
.deleted{text-align: center;}
.headLink{color: white;text-decoration: none;}
.headLink:hover, .active{color: black;}
.delete{
background:none repeat scroll 0 0 transparent;
border:1px solid #CBCBCB;
color:#CBCBCB;
display:block;
float:right;
margin-top:-30px;
padding:5px;
text-align:right;
text-decoration:none;
width:110px;
}
.delete:hover{border: 1px solid red;color: red;}
.paginate{margin-top: 20px;padding-bottom: 20px;text-align: center;}
.paginate a, .disabled, .current{border:1px solid #CBCBCB;color:#CBCBCB;display: inline-block;padding:5px;text-align: center;margin:5px;text-decoration: none;}
.paginate a:hover{border:1px solid white;color:white;}
.disabled{border: none;}
.current{border: none;}
.tweetielink{text-decoration: none; color: white; font-size: 13px;}
.apiKeyBox{width: 700px; text-align: center;}
</pre><h3>Function</h3><p>In the functions.php file, go to the bottom and we will start writing some new functions that will be used in the tutorial.</p><pre class="brush: php;">
function check_api_key($apiKey){ // checks if there is an API key present
	$existsQ = mysql_query(&quot;SELECT * FROM `users` WHERE `apiKey`='{$apiKey}' LIMIT 1&quot;);	// run a search to find it
	$exsitsRows = mysql_num_rows($existsQ);												// check amount of rows
	if($exsitsRows == 0 ){ 																// if there are 0 it was not found
		return false;
	}else{
		return true;
	}

}

function check_all_logins($loggedIn, $apiKey){ // this will check if we can allow the user to make urls shorter.
	if($loggedIn || !LOGIN_REQ){ // already logged in or they have a session saying logged in
		return true;
	}
	if(check_api_key($apiKey)){ // if API key was found...
		return true;
	}else{
		return false;
	}
}

function admin_page(){
	$loggedIn = $_SESSION['loggedIn'];
	if(!$loggedIn){
		header(&quot;Location:  &quot;. BASE_URL . &quot;/?show_loggin_area=1&quot;); // we will add this in the index.php page, to have a way to show the
																	// login form even if the LOGIN_REQ field is set to false
		die();
	}
}

function get_user_info($username){ // get all information that is in the database about a specific use that is logged in
	$qur = mysql_query(&quot;SELECT * FROM `users` WHERE `username` ='{$username}' LIMIT 1;&quot;);
	$info = mysql_fetch_assoc($qur);
	return $info; // return as an array
}

function isNumber($i) { return (is_numeric($i) &amp;&amp; !preg_match('/[[:^digit:]]/', $i) ? true : false); } // shows if a value is a number

function gen_api_key($email){ // will make a new API key for the user
    $toHash = time(); // the current time
    $toHash .= rand(0, 999999); // a random number
    $tohash .= $_SERVER['REMOTE_ADDR']; // the IP address of the user

    $toHash2 = rand(0, 999999);
    $toHash2 .= $email; // your email
    $hash1 = md5($toHash); // md5 the first hash
    $hash2 = md5($toHash2);  // md5 the second hash
  	$compleate =  $hash1 . $hash2;

  	return $compleate;
}

function get_data_for_url($shortURL){ // gets the user data from an API key
	$qur = mysql_query(&quot;SELECT * FROM `url` WHERE `short` = '{$shortURL}' LIMIT 1&quot;);
	if(mysql_num_rows($qur)){
		return mysql_fetch_assoc($qur);
	}else{
		return false;
	}
}
</pre><p>Now that the &#8220;admin_page()&#8221; function is set up we need to change the index.php in the home directory to show the login for when you are not have that variable in but you have been redirected with the variable to show the form. Open that page change the very top to the following:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;files/functions/functions.php&quot;);
$loggedIn = $_SESSION['loggedIn'];
$username = $_SESSION['username'];
$url           = mysql_real_escape_string( strip_tags($_GET['url']));
$show_loggin_area = mysql_real_escape_string( strip_tags($_GET['show_loggin_area'])); // this gets the varible 

//echo $url;
if(strlen($url) &gt;= 1){
	$redirect = true;
}else{
	$redirect = false;
}
if(!$redirect) :
?&gt;
</pre><p>Then scroll down to</p><pre class="brush: php;">
		&lt;?php if( (LOGIN_REQ) &amp;&amp; ($loggedIn != true) ){ ?&gt;
				&lt;h1 class=&quot;inform&quot;&gt;Please login with the form below:&lt;/h1&gt;
				&lt;form class=&quot;loginForm&quot; action=&quot;files/process/login.php&quot; method=&quot;POST&quot;&gt;
					&lt;label for=&quot;username&quot; class=&quot;label&quot;&gt;Username:&lt;/label&gt;&lt;br /&gt;
					&lt;input type=&quot;text&quot; id=&quot;username&quot; class=&quot;smallInput&quot; name=&quot;username&quot;&gt;&lt;br /&gt;

					&lt;label for=&quot;password&quot; class=&quot;label&quot;&gt;Password:&lt;/label&gt;&lt;br /&gt;
					&lt;input type=&quot;password&quot; id=&quot;password&quot; class=&quot;smallInput&quot; name=&quot;password&quot;&gt;&lt;br /&gt;&lt;br /&gt;
					&lt;input type=&quot;submit&quot; value=&quot;Login me in!&quot; /&gt;
				&lt;/form&gt;

			&lt;?php }else{ ?&gt;
				&lt;?php if($loggedIn){echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/files/process/logout.php' class='logOut'&gt;Logout &quot; . $username . &quot;?&lt;/a&gt;&quot;; } ?&gt;
				&lt;form id=&quot;linkForm&quot; class=&quot;&quot; action=&quot;files/process/add.php&quot; method=&quot;post&quot;&gt;
					&lt;input value=&quot;Make me short...&quot; type=&quot;text&quot; class=&quot;smallInput&quot; id=&quot;theLink&quot; name=&quot;theLink&quot;/&gt;
					&lt;input type=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Shorten&quot; /&gt;
				&lt;/form&gt;		

				&lt;ul class=&quot;postTo&quot;&gt;
					&lt;li class=&quot;tweetie&quot;&gt;&lt;a href=&quot;&quot;&gt;Post With Tweetie&lt;/a&gt;&lt;/li&gt;
					&lt;li class=&quot;twitter&quot;&gt;&lt;a href=&quot;&quot;&gt;Post To Twitter&lt;/a&gt;&lt;/li&gt;
					&lt;li class=&quot;facebook&quot;&gt;&lt;a href=&quot;&quot;&gt;Share On Facebook&lt;/a&gt;&lt;/li&gt;
				&lt;/ul&gt;
		&lt;?php }; ?&gt;
</pre><p>and change it to</p><pre class="brush: php;">
		&lt;?php if( (LOGIN_REQ) &amp;&amp; ($loggedIn != true) || ($show_loggin_area == true)  ){ ?&gt;
				&lt;h1 class=&quot;inform&quot;&gt;Please login with the form below:&lt;/h1&gt;
				&lt;form class=&quot;loginForm&quot; action=&quot;files/process/login.php&quot; method=&quot;POST&quot;&gt;
					&lt;label for=&quot;username&quot; class=&quot;label&quot;&gt;Username:&lt;/label&gt;&lt;br /&gt;
					&lt;input type=&quot;text&quot; id=&quot;username&quot; class=&quot;smallInput&quot; name=&quot;username&quot;&gt;&lt;br /&gt;

					&lt;label for=&quot;password&quot; class=&quot;label&quot;&gt;Password:&lt;/label&gt;&lt;br /&gt;
					&lt;input type=&quot;password&quot; id=&quot;password&quot; class=&quot;smallInput&quot; name=&quot;password&quot;&gt;&lt;br /&gt;&lt;br /&gt;
					&lt;input type=&quot;submit&quot; value=&quot;Login me in!&quot; /&gt;
				&lt;/form&gt;

			&lt;?php }else{ ?&gt;				// link to logout
				&lt;?php if($loggedIn){echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/files/process/logout.php' class='logOut'&gt;Logout &quot; . $username . &quot;?&lt;/a&gt;&quot;;
								// link to settings page
					echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/admin/settings.php' class='admin'&gt;Settings&lt;/a&gt;&quot;;
								// link to admin page
					echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/admin/' class='admin pright'&gt;Admin&lt;/a&gt;&quot;;

				} ?&gt;
</pre><p>This now makes sure that if you need to login to see the admin pages, even if LOGIN_REQ is set to false, it will show this form so you may login.</p><h3>Change if active</h3><p>Create a file change_active.php in the process folder and add the following:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);  // get the functions file
admin_page();
$error = false; // set this as default

$urlID = mysql_real_escape_string( strip_tags($_POST['urlID']) ); // The ID of item to change
$visible = mysql_real_escape_string( strip_tags($_POST['visible']) ); // If it will be visible or invisible
$page = mysql_real_escape_string( strip_tags($_POST['page']) ); // The page to redirect the user back to
$ret = mysql_real_escape_string( strip_tags($_POST['ret']) ); // The item to move the user to

// if &quot;visible&quot; does not have a value or not in integer, or urlID is less then/= to 0 or if urlID is not an integer
if( (strlen($visible) != 1) || (!isNumber($visible)) || (strlen($urlID)  &lt;= 0) || (!isNumber($urlID)) ){
	$error = true;
	echo &quot;ERROR!&quot;;
	$visible_or_id_not_valid = true;
}

if(!$error){ // if no error

	// check that the item exists
	$change = &quot;
		SELECT * FROM `url` WHERE `id` = '{$urlID}' LIMIT 1;
	&quot;;
	$ran = mysql_query($change);
	$rows = mysql_num_rows($ran);
	if($rows != 1){
		$error = true;
	}else{ // it did exist so change it to the visible item that has been posted
		$setChange = &quot;
			UPDATE `url` SET `active` =  '{$visible}' WHERE `id` ='{$urlID}' LIMIT 1 ;
		&quot;;
		mysql_query($setChange);
		// redirect to the page, and add a hash tag of the where to move
		// E.I. the &quot;p&quot; element the has a id of i
		header(&quot;Location: &quot; .BASE_URL.&quot;/admin/index.php?page={$page}#{$ret}&quot;);
	}
}
</pre><p>This should now let you add change if it is active.</p><h3>Delete Item</h3><p>Next create a file called deleteItem.php and we will add this:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);  // get the functions file
admin_page();
$error = false; // set this as defalt
$urlID = mysql_real_escape_string( strip_tags($_POST['urlID']) ); // The ID of item to change
$page = mysql_real_escape_string( strip_tags($_POST['page']) ); // The page to redirect the user back to
$ret = mysql_real_escape_string( strip_tags($_POST['ret']) ); // The item to move the user to
	// if id is not set					and its not a number
if( (strlen($urlID)  &lt;= 0) || (!isNumber($urlID)) ){
	$error = true; // error
	echo &quot;ERROR!&quot;;
	$id_not_valid = true;
}

if(!$error){ // if no error

	// check if it is in the database
	$change = &quot;
		SELECT * FROM `url` WHERE `id` = '{$urlID}' LIMIT 1;
	&quot;;
	$ran = mysql_query($change);
	$rows = mysql_num_rows($ran);
	if($rows != 1){
		$error = true;
	}else{	// was found so delete the item
		$setChange = &quot;
			DELETE FROM `url` WHERE `url`.`id` = '{$urlID}' LIMIT 1;
		&quot;;
		mysql_query($setChange);
			// redirect the use back to the correct page and put deleted set
			// to true, this will show the jquery script that puts &quot;deleted&quot;
			// in the right place due to adding a #item
		header(&quot;Location: &quot; .BASE_URL.&quot;/admin/index.php?page={$page}&amp;deleted=1#{$ret}&quot;); 

	}
}else{
	echo &quot;And error was found.&quot;;
}
// print_r( $_POST );
</pre><h3>The Settings page</h3><p>This settings page will have a few useful items</p><ol><li>Display API key</li><li>Generate new API key</li><li>Display a link to copy into <a href="http://atebits.com">Tweetie 2</a> to use as your custom URL shortener</li><li>Add new user</li></ol><p>Open the settings.php page and add the following</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../files/functions/functions.php&quot;);
admin_page();
$username = $_SESSION['username'];
$info = get_user_info($username);
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Make it short || Admin &amp;rArr; &lt;?php echo $username ; ?&gt; &lt;?php echo $title; ?&gt; || Settings&lt;/title&gt;
		&lt;!-- Start of CSS --&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/main.css&quot; /&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/admin.css&quot; /&gt;
		&lt;!-- Start of JS --&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php echo BASE_URL; ?&gt;/files/js/jquery.js&quot;&gt;&lt;/script&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php echo BASE_URL; ?&gt;/files/js/add.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;	

&lt;div id=&quot;header&quot;&gt;
&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
&lt;?php echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/files/process/logout.php' class='headLink Logout'&gt;Logout &quot; . $username . &quot;?&lt;/a&gt;&quot;; ?&gt;
&lt;a class='headLink Settings right active' href=&quot;&lt;?php echo BASE_URL; ?&gt;/admin/settings.php&quot;&gt;Settings&lt;/a&gt;
&lt;a class='headLink Admin right ' href=&quot;&lt;?php echo BASE_URL; ?&gt;/admin/&quot;&gt;Admin&lt;/a&gt;
&lt;/div&gt;

&lt;div id=&quot;stripAdmin&quot;&gt;
	&lt;div id=&quot;stipWrap&quot;&gt;
		&lt;h1 class=&quot;large&quot;&gt;Hello &lt;?php echo $username; ?&gt;,&lt;/h1&gt;
			&lt;!-- Putting the API key into a text box makes it more clear that this is what the user should copy (and makes it easier to copy that parts you want --&gt;
		Your current API key is: &lt;input type=&quot;text&quot; value=&quot;&lt;?php echo $info['apiKey'];?&gt;&quot; class=&quot;smallInput apiKeyBox&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
		Generate a new API key? &lt;a class=&quot;link&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/process/newKey.php&quot;&gt;Yes, please.&lt;/a&gt;&lt;br /&gt;

		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;

		&lt;h1&gt;Add new user&lt;/h1&gt;
			&lt;form action=&quot;&lt;?php echo BASE_URL;?&gt;/files/process/makeUser.php&quot; method=&quot;POST&quot;&gt;
				&lt;input type=&quot;text&quot; class=&quot;smallInput&quot; value=&quot;Username&quot; id=&quot;username&quot; name=&quot;username&quot; /&gt;(Username)&lt;br /&gt;&lt;br /&gt;
				&lt;input type=&quot;text&quot; class=&quot;smallInput&quot; value=&quot;Email&quot; id=&quot;email&quot; name=&quot;email&quot; /&gt;(Email)&lt;br /&gt;&lt;br /&gt;
				&lt;input type=&quot;password&quot; class=&quot;smallInput&quot; id=&quot;password&quot; name=&quot;password&quot; /&gt; (Password)&lt;br /&gt;&lt;br /&gt;
				&lt;input type=&quot;submit&quot; value=&quot;Add User&quot; /&gt;
			&lt;/form&gt;

		&lt;?php
		//	print_r($info);
		?&gt;&lt;br /&gt;&lt;br /&gt;
		To get Tweetie to work, copy this into the &quot;Custom URL&quot; field in the app:&lt;br /&gt;&lt;br /&gt;
		&lt;?php
			// gets the tweetie link that will allow the user to copy and past it
			echo &quot;&lt;a class='tweetielink' href=' &quot; . BASE_URL . &quot;/files/process/add.php?apiKey=&quot; . $info['apiKey'] . &quot;&amp;theLink=%@'&gt;&quot; . BASE_URL . &quot;/files/process/add.php?apiKey=&quot; . $info['apiKey'] . &quot;&amp;theLink=%@&lt;/a&gt;&quot;;
		?&gt;
		&lt;br /&gt;&lt;br /&gt;

	&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;end&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt; &lt;?php
require_once(&quot;../files/functions/functions.php&quot;);
admin_page();
$username = $_SESSION['username'];
$info = get_user_info($username);
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Make it short || Admin &amp;rArr; &lt;?php echo $username ; ?&gt; &lt;?php echo $title; ?&gt; || Settings&lt;/title&gt;
		&lt;!-- Start of CSS --&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/main.css&quot; /&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/admin.css&quot; /&gt;
		&lt;!-- Start of JS --&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php echo BASE_URL; ?&gt;/files/js/jquery.js&quot;&gt;&lt;/script&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;&lt;?php echo BASE_URL; ?&gt;/files/js/add.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;	

&lt;div id=&quot;header&quot;&gt;
&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
&lt;?php echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/files/process/logout.php' class='headLink Logout'&gt;Logout &quot; . $username . &quot;?&lt;/a&gt;&quot;; ?&gt;
&lt;a class='headLink Settings right active' href=&quot;&lt;?php echo BASE_URL; ?&gt;/admin/settings.php&quot;&gt;Settings&lt;/a&gt;
&lt;a class='headLink Admin right ' href=&quot;&lt;?php echo BASE_URL; ?&gt;/admin/&quot;&gt;Admin&lt;/a&gt;
&lt;/div&gt;

&lt;div id=&quot;stripAdmin&quot;&gt;
	&lt;div id=&quot;stipWrap&quot;&gt;
		&lt;h1 class=&quot;large&quot;&gt;Hello &lt;?php echo $username; ?&gt;,&lt;/h1&gt;
			&lt;!-- Putting the API key into a text box makes it more clear that this is what the user should copy (and makes it easier to copy that parts you want) --&gt;
		Your current API key is: &lt;input type=&quot;text&quot; value=&quot;&lt;?php echo $info['apiKey'];?&gt;&quot; class=&quot;smallInput apiKeyBox&quot; /&gt;&lt;br /&gt;&lt;br /&gt;
		Generate a new API key? &lt;a class=&quot;link&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/process/newKey.php&quot;&gt;Yes, please.&lt;/a&gt;&lt;br /&gt;

		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;

		&lt;h1&gt;Add new user&lt;/h1&gt;
			&lt;form action=&quot;&lt;?php echo BASE_URL;?&gt;/files/process/makeUser.php&quot; method=&quot;POST&quot;&gt;
				&lt;input type=&quot;text&quot; class=&quot;smallInput&quot; value=&quot;Username&quot; id=&quot;username&quot; name=&quot;username&quot; /&gt;(Username)&lt;br /&gt;&lt;br /&gt;
				&lt;input type=&quot;text&quot; class=&quot;smallInput&quot; value=&quot;Email&quot; id=&quot;email&quot; name=&quot;email&quot; /&gt;(Email)&lt;br /&gt;&lt;br /&gt;
				&lt;input type=&quot;password&quot; class=&quot;smallInput&quot; id=&quot;password&quot; name=&quot;password&quot; /&gt; (Password)&lt;br /&gt;&lt;br /&gt;
				&lt;input type=&quot;submit&quot; value=&quot;Add User&quot; /&gt;
			&lt;/form&gt;

		&lt;?php
		//	print_r($info);
		?&gt;&lt;br /&gt;&lt;br /&gt;
		To get Tweetie to work, copy this into the &quot;Custom URL&quot; field in the app:&lt;br /&gt;&lt;br /&gt;
		&lt;?php
			// gets the tweetie link that will allow the user to copy and past it
			echo &quot;&lt;a class='tweetielink' href=' &quot; . BASE_URL . &quot;/files/process/add.php?apiKey=&quot; . $info['apiKey'] . &quot;&amp;theLink=%@'&gt;&quot; . BASE_URL . &quot;/files/process/add.php?apiKey=&quot; . $info['apiKey'] . &quot;&amp;theLink=%@&lt;/a&gt;&quot;;
		?&gt;
		&lt;br /&gt;&lt;br /&gt;

	&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;end&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p>That should be it for that page, we just need to make the two files that the forms submit to. They are &#8220;makeUser.php&#8221; and &#8220;newKey.php&#8221;. Start by making &#8220;makeUser.php&#8221; in the process file and add this:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);  // get the functions file
admin_page();
$error = false; // set this as defalt

$username = mysql_real_escape_string( strip_tags($_POST['username']) ); // Get the username that was posted
$email = mysql_real_escape_string( strip_tags($_POST['email']) ); // Get the email address
$password = mysql_real_escape_string( strip_tags($_POST['password'])); // get the password

if(strlen($username) &lt; 5 ){ 	// if the username is above 5 char
	$error = true;			// if its not set an error
	$errorMessages['username'] = &quot;Please write a username&quot;; // what the error is
}
if(strlen($password) &lt; 5){ // same with password
	$error = true;
	$errorMessages['password'] = &quot;Please write a password&quot;;
}

if(preg_match(&quot;/ /&quot;, $username)){ // check that the username has no white space.
	$error = true;
	$errorMessages['spaces'] = &quot;Username cannot contain white space&quot;;
}

if(preg_match(&quot;/ /&quot;, $username)){ // check that the username has no white space.
	$error = true;
	$errorMessages['spaces'] = &quot;Username cannot contain white space&quot;;
}
			// validate email address
if (!preg_match('/^[a-z0-9&amp;\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $email)) {
	$errorMessages['email'] = &quot;Please enter a VALID email address&quot;;
	$error = true;
}

// if no error
if(!$error){ // if no error
	$password = md5($password); // hash the password
		// we will check if the use is in the database already
	$newQuery = mysql_query(&quot;SELECT *
		FROM `users`
		WHERE `username` =  '{$username}'
		OR `email` = '{$email}'
		LIMIT 1&quot;);

	$newRows = mysql_num_rows($newQuery);
	if($newRows == 0){ // if no info was found with either email or username
		$apiKey = gen_api_key($info['email']); // create an API key for that user
		// then insert them into the database
	mysql_query(&quot;INSERT INTO `users` (`username` ,`password` ,`email`, `apiKey`)
				VALUES ('{$username}', '{$password}', '{$email}', '$apiKey') &quot;);
		// and redirect them back to the settings page
	header(&quot;Location: &quot; . BASE_URL  . &quot;/admin/settings.php&quot;);
	}else{ // if they were
		$error = true;//set an error
		$errorMessages['inAlread'] = &quot;The username or email address is in use already!&quot;;
	}

}
if($error){ // if there is an errir
	foreach( $errorMessages as $errorMessage ){ // for every error message
		echo &quot;Problem: &quot; . $errorMessage . &quot;&lt;br /&gt;&quot;; // echo it out
	}
}
</pre><p>And finally for the admin pages, we want create the &#8220;newKey.php&#8221; page to make the new API key. In the newKey.php file we will add a small bit of code, as we have the functions that we need set up:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);  // get the functions file
admin_page();  // will check if user is logged in, if not it will redirect and stop the script running
$error = false; // set this as defalt

$user = get_user_info($_SESSION['username']); // make sure we have  everything we need

$newAPI = gen_api_key($user['email']); // gen the user a new code
// update their row in the database
mysql_query(&quot;UPDATE `users` SET `apiKey` = '{$newAPI}' WHERE `id` ={$user['id']} LIMIT 1&quot;);
// and finally redirect them back to the settings page
header(&quot;Location: &quot; . BASE_URL . &quot;/admin/settings.php&quot;);
</pre><p>And that is all we need to make a new API Key for a user. Next, we just have to make the &#8220;stats&#8221; page which will show users that are not logged in how many clicks a link has gotten. For this, open the stats folder we made in the last tutorial (inside files then a folder called stats) we want to add another .htaccess file here and put inside it the following code:</p><pre class="brush: plain;">
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
</pre><h3>Stats</h3><p>Put an index.php file inside this stats folder, and here we will create the way to display info about the URL.</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);
$url            = mysql_real_escape_string( strip_tags($_GET['url']));
$data 			= get_data_for_url($url); // get the data from the database
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
	&lt;title&gt;Make it short || Stats&lt;/title&gt;
		&lt;!-- Start of CSS --&gt;
	&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;&lt;?php echo BASE_URL; ?&gt;/files/css/main.css&quot; /&gt;
		&lt;!-- Start of JS --&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;files/js/jquery.js&quot;&gt;&lt;/script&gt;
 	&lt;script type=&quot;text/javascript&quot; src=&quot;files/js/add.js&quot;&gt;&lt;/script&gt;
 	&lt;style&gt;
 		#stipWrap{
 			font-size: 20px;
 			text-align: center;
 		}
 	&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id=&quot;header&quot;&gt;
	&lt;div class=&quot;process&quot;&gt;&lt;div class=&quot;processingC&quot;&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;strip&quot;&gt;
	&lt;div id=&quot;stipWrap&quot;&gt;
		&lt;?php //print_r($data); ?&gt;
		&lt;p class=&quot;push&quot;&gt;&lt;/p&gt;
		&lt;h1&gt;Stats&lt;/h1&gt;&lt;br /&gt;
		URL = &lt;a class=&quot;longurl&quot; href=&quot;&lt;?php echo urldecode( $data['long'] ); ?&gt;&quot;&gt;&lt;?php echo urldecode( $data['long'] ); ?&gt;&lt;/a&gt;&lt;br /&gt;
		Short URL = &lt;a class=&quot;shorturl&quot; href=&quot;&lt;?php echo BASE_URL . $data['short']; ?&gt;&quot;&gt;&lt;?php echo BASE_URL . $data['short']; ?&gt;&lt;/a&gt;&lt;br /&gt;
		Date Added	= &lt;?php echo date(&quot;dS F Y g:i a&quot;, strtotime( $data['dateAdded'])); ?&gt;&lt;br /&gt;
		Clicks	= &lt;?php echo $data['clicks']; ?&gt;&lt;br /&gt;
		Last Clicked	= &lt;?php echo date(&quot;dS F Y g:i a&quot;, strtotime( $data['lastClicked'])); ?&gt;&lt;br /&gt;

	&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;end&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p>And that should be done! We now have a full featured URL shortener set up, I hope that you found this interesting and you can download all the completed files <a href="http://demo.alexbor.com/downloads/url_part_2.zip">here</a></p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/' rel='bookmark' title='Permanent Link: Create URL Shortener For Twitter Using PHP'>Create URL Shortener For Twitter Using PHP</a></li><li><a href='http://brenelz.com/blog/building-a-simple-php-mailing-list/' rel='bookmark' title='Permanent Link: Building a Simple PHP Mailing List'>Building a Simple PHP Mailing List</a></li><li><a href='http://brenelz.com/blog/build-a-php-twitter-widget/' rel='bookmark' title='Permanent Link: Build a PHP Twitter Widget'>Build a PHP Twitter Widget</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=1QK4OnnzPoA:KXh7jh2lCYQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=1QK4OnnzPoA:KXh7jh2lCYQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=1QK4OnnzPoA:KXh7jh2lCYQ:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/1QK4OnnzPoA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/twitter-url-shortener-part-2/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/twitter-url-shortener-part-2/</feedburner:origLink></item> <item><title>Creating a Simple Tooltip jQuery Plugin</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/ADkV52s9RAE/</link> <comments>http://brenelz.com/blog/creating-a-simple-tooltip-using-jquery/#comments</comments> <pubDate>Mon, 15 Mar 2010 14:00:41 +0000</pubDate> <dc:creator>Abhin Sharma</dc:creator> <category><![CDATA[Web Programming]]></category><guid isPermaLink="false">http://brenelz.com/?p=2110</guid> <description><![CDATA[Reading time: 6 &#8211; 10 minutes In this tutorial we will create a simple but awesome popup tooltip using jQuery. So let&#8217;s get started !! Download Creating a tooltip in photoshop. First of all open up photoshop and create a document with dimensions 300 * 150 px, though the dimension may vary on how MUCH [...]Related posts:<ol><li><a href='http://brenelz.com/blog/3-screencasts-for-building-your-own-jquery-plugin/' rel='bookmark' title='Permanent Link: 3 Screencasts For Building Your Own jQuery Plugin'>3 Screencasts For Building Your Own jQuery Plugin</a></li><li><a href='http://brenelz.com/blog/working-with-the-jcrop-plugin/' rel='bookmark' title='Permanent Link: Working with the jCrop Plugin'>Working with the jCrop Plugin</a></li><li><a href='http://brenelz.com/blog/build-a-content-slider-with-jquery/' rel='bookmark' title='Permanent Link: Build a Content Slider with jQuery'>Build a Content Slider with jQuery</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 6 &#8211; 10 minutes</p><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/preview.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/preview.jpg" alt="" title="preview" width="300" height="300" class="aligncenter size-full wp-image-2124" /></a></div><p>In this tutorial we will create a simple but awesome popup tooltip using jQuery. So let&#8217;s get started !!</p><p><a id='download_file' href='http://cdnwww.brenelz.com/wp-content/uploads/2010/03/demo.zip' title='Download Files'>Download</a></p><p><span id="more-2110"></span></p><h2>Creating a tooltip in photoshop.</h2><p>First of all open up photoshop and create a document with dimensions 300 * 150 px, though the dimension may vary on how MUCH data you want show. Tooltips generally show basic and less data. Follow the steps below -</p><ul><li>Select the rounded rectangle tool with radius 5 px and draw a rectangle with about 15px distance from the canvas margins.<div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/1.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/1-300x246.jpg" alt="" title="1" width="300" height="246" class="aligncenter size-medium wp-image-2127" /></a></div></li><li>This will be our background, now go to fx and add a gradient overlay from #1f1f1f to #ffffff.<div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/2.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/2-300x246.jpg" alt="" title="2" width="300" height="246" class="aligncenter size-medium wp-image-2128" /></a></div></li><li>Now select the drop shadow with options,<ul><li>Blend Mode &#8211; normal</li><li>Opacity &#8211; 80%</li><li>Distance &#8211; 0px</li><li>Size &#8211; 21px</li></ul><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/3.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/3-300x246.jpg" alt="" title="3" width="300" height="246" class="aligncenter size-medium wp-image-2129" /></a></div></li><li>Now hide the background and export it as png image using Save for Web and Devices option.</li></ul><p>That&#8217;s it for the photoshop part, Now for the coding part.</p><h3>Step 1</h3><p>We will mould our tooltip into a jquery plugin. So first of all we will start will a basic html file to work with and how to show a tooltip for a particular element.</p><pre class="brush: xml;">
      &lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
           &lt;head&gt;
            &lt;title&gt;jTool&lt;/title&gt;
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;jtool.css&quot;  /&gt;
            &lt;script type=&quot;text/javascript&quot; src=&quot;jquery-1.4.2.min.js&quot; &gt;&lt;/script&gt;
            &lt;script type=&quot;text/javascript&quot; src=&quot;jquery.jtool.js&quot;&gt;&lt;/script&gt;
           &lt;script type=&quot;text/javascript&quot;&gt;
                $(function(){

                $(&quot;a&quot;).jTool(); //our plugin

                 });

             &lt;/script&gt;
            &lt;/head&gt;

        &lt;body&gt;

            &lt;div id=&quot;tool&quot;&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut bibendum orci. Nam scelerisque, risus aliquam pellentesque viverra, libero urna sagittis quam, auctor dictum nunc lectus ut mi.&lt;/div&gt;

        &lt;a href=&quot;#tool&quot;&gt; Simple Tooltip using jQuery &lt;/a&gt;
        &lt;/body&gt;
        &lt;/html&gt;
</pre><p>First of all we have imported jquery, our plugin and css file which we will create later. Then we have called our plugin on the element we want to show tooltip.</p><h4>Setting up which tooltip to show on a particular element</h4><p>To show a particular data on a tooltip we will target the element using href attribute. The href will contain the id of the element which you want to show on hover. That&#8217;s what we have done above, div id &#8216;tool&#8217; is displayed when mouse hovers on anchor with href =&#8217;#tool&#8217;</p><h3>Step 2 Working up with the CSS.</h3><p>Create a css file and name it jtool.css . In this css file we will styling our tooltip elements. The css code could have been set up through jquery but it&#8217;s always a good practice to separate logic from presentation. Add the following code in the css.</p><pre class="brush: css;">
 #jTool
{
color:#CCCCCC;
padding:5px;
display:none;
max-width:300px;
min-width:130px;
font-family:&quot;Lucida Grande&quot;, Tahoma, sans-serif; text-align:justify;
position: absolute;
}</pre><p>Our tooltip is wrapped by jTool div, we will do that in the js part. It is a basic styling and we will keep minimum width of our tooltip 130px and constraint it to 300px.</p><pre class="brush: css;">
#jTool &gt; div
{

padding:10px;
position:relative;
z-index:10;
display:block;

}

#jTool img
{
width:100%;
height:100%;
position:absolute;
padding:0px;
margin:0px;
z-index:1;
}</pre><p>we have used #jTool img here for styling but there is no image present, actually the image is our background tooltip. It is not possible to scale a background image in CSS, for that we will append image in the jTool div and set its dimension to 100% so that it scales automatically. We will also set its z-index less than div so that text is visible.</p><p>Finally our css file looks like.</p><pre class="brush: css;">#jTool
{
color:#CCCCCC;
padding:5px;
display:none;
max-width:300px;
min-width:130px;
font-family:&quot;Lucida Grande&quot;, Tahoma, sans-serif; text-align:justify;
position: absolute;
}

#jTool &amp;gt; div
{

padding:10px;
position:relative;
z-index:10;
display:block;

}

#jTool img
{
width:100%;
height:100%;
position:absolute;
padding:0px;
margin:0px;
z-index:1;
}</pre><h3>Step 3 Creating the Plugin</h3><p>Now create a javascript file and according to jquery plugin naming convection it should be named jquery.plugin.js , so our file name is jquery.jtool.js, First of all we will create a basic structure.</p><pre class="brush: jscript;"> $.fn.jTool = function(){

    });</pre><h3>Step 4</h3><p>Now will declare variables and initialize basic settings.</p><pre class="brush: jscript;">	var element = $(this);
	var tooltip = element.attr(&quot;href&quot;);
	$(tooltip).wrap(&quot;&lt;div id='jTool' /&gt;&quot;);
    $(&quot;#jTool&quot;).prepend(&lt;img src='base.png' /&gt;&quot;);

	 var top = element.offset().top;
	 var right = $(window).width() - element.offset().left;
	 var x,y;
</pre><p>Here first we get the object triggering the tooltip in the element, since we have used href to target elements, we will get the actual tooltip by getting element&#8217;s attribute. Then we will wrap it jTool div and prepend our background image.</p><p>After that we will get the element&#8217;s top position with respect to window and also calculate the length between widow&#8217;s width and element&#8217;s left position.</p><blockquote><p>Note: Reason for calculating top position and left length is that later we will make our plugin little smart <img src='http://cdnwww.brenelz.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p></blockquote><h3>Step 5</h3><p>Now we will fade In the tooltip on element&#8217;s hover state.</p><pre class="brush: jscript;">element.hover(function(event){

						  x = event.pageX;
						  y = event.pageY;

						  $(&quot;#jTool&quot;).css({left:x,top:y});

                          setTimeout(function(){  $(&quot;#jTool&quot;).stop(true,true).fadeIn(&quot;slow&quot;); },200);
							   },
					  function(){
						 $(&quot;#jTool&quot;).fadeOut(&quot;slow&quot;);

				});</pre><p>Now on hover event, we get the mouse&#8217;s position and set the jTool position. After a 200ms delay we then show the tooltip.</p><h3>Step 6</h3><p>There is a problem, if the element showing the tooltip is either at top left or right corner, then tooltips will be out the viewport so we will make it little smarter.</p><pre class="brush: jscript;">   if($(&quot;#jTool&quot;).height()&lt;top)
   y = y-$(&quot;#jTool&quot;).height()-20;

   if($(&quot;#jTool&quot;).width()&gt;right)
   x = x-$(&quot;#jTool&quot;).width();</pre><p>If distance from the top of the element and window is less than tooltip&#8217;s height, it will show towards the bottom and similarly if the difference between window&#8217;s width and element&#8217;s left position is less than tooltip&#8217;s width it will show towards the right.</p><h3>Step 7</h3><p>Though the plugin works fine, but as usual it doesn&#8217;t look properly in IE, The tooltip&#8217;s image isn&#8217;t displayed to cover the whole text of the tooltip. Since IE6 is almost extinct, we will make in compatible for IE7. To get around this, we will force the jTool&#8217;s image to cover the height of the tooltip.</p><pre class="brush: jscript;">   if($.browser.msie&amp;amp;&amp;amp;parseInt(jQuery.browser.version)
    $(&quot;#jTool img&quot;).height($(&quot;#jTool&quot;).height());</pre><h3>Step 8</h3><p>Finally our js code looks like.</p><pre class="brush: jscript;">$.fn.jTool = function(){

		var element = $(this);
		var tooltip = element.attr(&quot;href&quot;);
		$(tooltip).wrap(&quot;&lt;div id='jTool' /&gt;&quot;);

		 $(&quot;#jTool&quot;).prepend(&quot;&lt;img src='base.png' /&gt;&quot;);

		 var top = element.offset().top;
		 var right = $(window).width() - element.offset().left;
		 var x,y;

		element.hover(function(event){

						  x = event.pageX;
						  y = event.pageY;

							if($(&quot;#jTool&quot;).height()&lt;top)
							y = y-$(&quot;#jTool&quot;).height()-20;

							if($(&quot;#jTool&quot;).width()&gt;right)
							x = x-$(&quot;#jTool&quot;).width();

                                $(&quot;#jTool&quot;).css({left:x,top:y});

                        if($.browser.msie&amp;&amp;parseInt(jQuery.browser.version)&lt;8)
                           $(&quot;#jTool img&quot;).height($(&quot;#jTool&quot;).height());

				        setTimeout(function(){

                            $(&quot;#jTool&quot;).stop(true,true).fadeIn(&quot;slow&quot;); },200);
							   },
					  function(){
						 $(&quot;#jTool&quot;).fadeOut(&quot;slow&quot;);

				});

	}</pre><p>We have finally created our tooltip which is lightweight 2kb js size and 1 kb tooltip image and with a good looking UI .</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/3-screencasts-for-building-your-own-jquery-plugin/' rel='bookmark' title='Permanent Link: 3 Screencasts For Building Your Own jQuery Plugin'>3 Screencasts For Building Your Own jQuery Plugin</a></li><li><a href='http://brenelz.com/blog/working-with-the-jcrop-plugin/' rel='bookmark' title='Permanent Link: Working with the jCrop Plugin'>Working with the jCrop Plugin</a></li><li><a href='http://brenelz.com/blog/build-a-content-slider-with-jquery/' rel='bookmark' title='Permanent Link: Build a Content Slider with jQuery'>Build a Content Slider with jQuery</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=ADkV52s9RAE:1LOxfN0w1Yw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=ADkV52s9RAE:1LOxfN0w1Yw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=ADkV52s9RAE:1LOxfN0w1Yw:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/ADkV52s9RAE" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/creating-a-simple-tooltip-using-jquery/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://brenelz.com/blog/creating-a-simple-tooltip-using-jquery/</feedburner:origLink></item> <item><title>Create URL Shortener For Twitter Using PHP</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/uCHHdF8cmUk/</link> <comments>http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/#comments</comments> <pubDate>Wed, 10 Mar 2010 14:00:17 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2084</guid> <description><![CDATA[Reading time: 22 &#8211; 36 minutes Hello, today I am going to go through how to build a custom URL shortener. Why have your own? Because then you are advertising yourself not another service like tinyurl. A URL shortener is a nice way to send incredibly long links. It also helps when writing Tweets on [...]Related posts:<ol><li><a href='http://brenelz.com/blog/twitter-url-shortener-part-2/' rel='bookmark' title='Permanent Link: Twitter URL Shortener: Part 2'>Twitter URL Shortener: Part 2</a></li><li><a href='http://brenelz.com/blog/building-a-simple-php-mailing-list/' rel='bookmark' title='Permanent Link: Building a Simple PHP Mailing List'>Building a Simple PHP Mailing List</a></li><li><a href='http://brenelz.com/blog/creating-an-ellipsis-in-php/' rel='bookmark' title='Permanent Link: Creating an Ellipsis in PHP'>Creating an Ellipsis in PHP</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 22 &#8211; 36 minutes</p><p>Hello, today I am going to go through how to build a custom URL shortener. Why have your own? Because then you are advertising yourself not another service like tinyurl.</p><p> A URL shortener is a nice way to send incredibly long links. It also helps when writing Tweets on Twitter (something I do a lot).</p><p> I decided that this system will have the following:</p><ol><li>Option to need a login or not</li><li>API Key login</li><li>Generate a new API key</li><li>Click count</li><li>Add/remove links when logged in</li><li>Most recent IP tracking (always useful)</li><li>Not to include bots on your clicks</li><li>A nice admin backend</li><li>Maybe: A JS button to login, and past the current URL into the textbox</li><li>Maybe: Not looked how it fully works yet but be able to get a short URL with the Tweetie app for iPhone from <a href="http://atebits.com/">Atebits</a>. (I have nothing to do with them, just like their products.</li></ol><p><span id="more-2084"></span></p><p> Before we start you may want to have a go with the system we will be building here:</p><p><a id='download_file' href='http://demo.alexbor.com/downloads/url_system_part_1.zip' title='Download Files'>Download</a><br /> <a href='http://demo.alexbor.com/url/' id='live_demo' target='_blank' title='Live Demo'>live demo</a></p><p> <b>Username:</b> alexbor <br /> <b>Password:</b> password</p><h3>How it will work</h3><p>I am going to do this in a two-part tutorial. By the end of the first tutorial we would have accomplished:</p><ol><li>Adding URLs</li><li>Tracking (but not a nice view) of URLs</li><li>Redirections (of both adding a Ò+Ó to the end of a URL and normal redirecting)</li><li>AJAX system for adding a new URL</li><li>Adding IP address</li><li>Not to include bots</li><li>Log in/out</li><li>Redirecting visitors</li></ol><p>Just so you can see, the final system that we will build today will have the following files:</p><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/img1.png"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/img1.png" alt="" title="img1" width="192" height="456" class="aligncenter size-full wp-image-2090" /></a></div><h3>The databases</h3><p>Lets get started and create the databases that we will need. Run the following SQL code:</p><pre class="brush: sql;">
CREATE TABLE `url` (
  `id` int(30) NOT NULL AUTO_INCREMENT,
  `short` varchar(30) NOT NULL,
  `long` varchar(300) NOT NULL,
  `dateAdded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `clicks` int(255) NOT NULL DEFAULT '0',
  `lastIP` varchar(30) NOT NULL,
  `lastClicked` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `active` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `short` (`short`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

CREATE TABLE `users` (
  `id` int(30) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(32) NOT NULL,
  `email` varchar(100) NOT NULL,
  `lastIP` varchar(20) NOT NULL,
  `apiKey` varchar(200) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`,`email`,`apiKey`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
</pre><p>If that worked successfully then you will have two tables, one will be for links and the other for users.</p><p>Now lets build the basic HTML of the website. On the home directory create a file index.php and put this in it:</p><pre class="brush: xml;">
	&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
	&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
	&lt;head&gt;
		&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
		&lt;title&gt;Make it short&lt;/title&gt;
			&lt;!-- Start of CSS --&gt;
		&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;files/css/main.css&quot; /&gt;
			&lt;!-- Start of JS --&gt;
	 	&lt;script type=&quot;text/javascript&quot; src=&quot;files/js/jquery.js&quot;&gt;&lt;/script&gt;
	 	&lt;script type=&quot;text/javascript&quot; src=&quot;files/js/add.js&quot;&gt;&lt;/script&gt;

	&lt;/head&gt;
	&lt;body&gt;
	&lt;div id=&quot;header&quot;&gt;
		&lt;div class=&quot;process&quot;&gt;&lt;div class=&quot;processingC&quot;&gt;&lt;/div&gt;&lt;/div&gt;
	&lt;/div&gt;
	&lt;div id=&quot;strip&quot;&gt;
		&lt;div id=&quot;stipWrap&quot;&gt;
					&lt;!-- This is the basic form for sending the url --&gt;
					&lt;form id=&quot;linkForm&quot; class=&quot;&quot; action=&quot;files/process/add.php&quot; method=&quot;post&quot;&gt;
						&lt;input value=&quot;Make me short...&quot; type=&quot;text&quot; class=&quot;smallInput&quot; id=&quot;theLink&quot; name=&quot;theLink&quot;/&gt;
						&lt;input type=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Shorten&quot; /&gt;
					&lt;/form&gt;		

					&lt;!-- This will show up once the URL has been shortened and allow you to post it to Facebook/Twitter/ or with Tweetie quickly --&gt;
					&lt;ul class=&quot;postTo&quot;&gt;
						&lt;li class=&quot;tweetie&quot;&gt;&lt;a href=&quot;&quot;&gt;Post With Tweetie&lt;/a&gt;&lt;/li&gt;
						&lt;li class=&quot;twitter&quot;&gt;&lt;a href=&quot;&quot;&gt;Post To Twitter&lt;/a&gt;&lt;/li&gt;
						&lt;li class=&quot;facebook&quot;&gt;&lt;a href=&quot;&quot;&gt;Share On Facebook&lt;/a&gt;&lt;/li&gt;
					&lt;/ul&gt;
			&lt;/div&gt;
	&lt;/div&gt;
	&lt;div id=&quot;end&quot;&gt;&lt;/div&gt;
	&lt;/body&gt;
	&lt;/html&gt;
</pre><p> Nothing to special there, just a layout with a form for adding/submitting URLs, also a few links that will have URLs once it has worked.</p><p> This file looks for some javascript and css files. We will create them now. Make a new folder called &#8220;files&#8221; the inside that create the following folders: css, functions, images, js, process, stats.</p><p> The main thing to notice from that is the folder &#8220;functions&#8221;, this will contain all functions and the config file. Also the process folder, this will contain process such as login, logout, where forms post to, etc.</p><h3>The CSS file</h3><p> Inside the CSS folder, add a new css file called &#8220;main.css&#8221;. The we will add the following CSS:</p><pre class="brush: css;">
@charset &quot;UTF-8&quot;;
/* CSS Document */
/* UTULITIES */
.clear{clear: both;}
.push{height: 30px;}
/* END */
/* ORDER PAGE CORRECTLY, REMOVING SOME BROWSER DEFULTS */
*{margin: 0; padding: 0;}
html{overflow-y: scroll;position: relative;}
body{width: 100%; height: 100%; background: url(../images/theBG.png) repeat; background-color: #00ADED;}
/* END */

/* header  */
#header{width: 1000px;height: 153px;margin: 0 auto;}
/*  END  */
#stipWrap{width: 1000px; margin: 0 auto;}
#strip{background:url(&quot;../images/strip.png&quot;) repeat-x scroll 0 0 transparent;height:270px;min-width:1000px;position:inherit;}
#linkForm{height:30px;margin: 0 auto;padding-top:100px;width:500px;}

/*  SOME MORE DEFULTS  */
.label{color:white;font-size:30px;} /*  Will be used when we have done the login bit  */
.smallInput{font-family: Helvetica, Verdana, Arial, sans-serif;background:none repeat scroll 0 0 #E9F0F8;border:1px solid #00ADED;color:#1E1C56;font-size:20px;padding:5px;}
#theLink{width:400px;}
#theLink:hover{background: #ffffff;}
#theLink:focus{color: #000000;}

/* These show the progress, and information from jQuery's AJAX   */
.process{background:#CC1B00;color:white;font-size:23px;font-weight:bold;height:0;margin-left:250px;position:absolute;text-align:center;width:500px;overflow: hidden;}
.processingC{padding: 5px;}

/*  The post to links  */
ul{font-family:helvetica;list-style:none outside none;margin-left:230px;margin-top:10px;display: none;}
ul li{display:inline-block;text-align:center;width:145px;}
ul li a{color:#2473A0;text-decoration:none;}
ul li a:hover{color:#E4E9E9;}
#message{color:#CBCBCB;font-family:Helvetica,Verdana,Arial,sans-serif;font-size:25px;font-weight:bold;margin:0 auto;padding-top:154px;text-align:center;width:1000px;word-spacing:3px;letter-spacing: 2px;text-shadow:0 0 8px #00ADED;}

.problem{color:#CBCBCB;font-family:Helvetica,Verdana,Arial,sans-serif;font-size:25px;font-weight:bold;text-align:center;width:1000px;padding-top: 5px;word-spacing:3px;letter-spacing: 2px;text-shadow:0 0 8px #00ADED;}

/*  LOGIN FORM  */
.inform{color:white;padding:25px 0;text-align:center;}
.loginForm{text-align: center;}
.logOut{color:#B1B3B3;font-size:18px;font-style:italic;padding-top:5px;position:absolute;text-decoration:none;}
.logOut:hover{color:white;}
</pre><p>There is nothing really to explain in the CSS or HTML file, this is mainly a tutorial explaining how to build the URL system.<br /> Next add the images into the images folder that are included in the download and load the page. You should have this:</p><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/img2.png"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/img2-e1268159173567.png" alt="" title="img2" width="498" height="267" class="aligncenter size-full wp-image-2093" /></a></div><h3>Javascript</h3><p> Create the following JS files in the appropriate directory. First create file &#8220;add.js&#8221; and the second file &#8220;jquery.js&#8221; is optional, you can also load it from google with<br /> &lt;script type=&#8221;text/javascript&#8221; src=&#8221;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&#8221;&gt;&lt;/script&gt;.</p><p>Just make sure that you are loading version 4.x + as we will be using <code>.submit()</code> and, as far as I know, that was added in the new version.</p><p> In the add.js file, we will add the following.</p><pre class="brush: jscript;">
// when ready
$(function() {
	// we will be using this later (maybe more the once) so create this function that will
	// reset the &quot;process&quot; box to its defaults
	function resetThings(){
		$(&quot;.process&quot;).css({&quot;background&quot;: &quot;red&quot;});
	}

	// now make some variables, these will be used later

	var urlBox = $('#theLink').val(),	// the textarea default value
		submitB = $('#submit'); 		// and the submit button
	$('#theLink').focus(function(){
		if( $(this).val() == urlBox ){
			$(this).val(&quot;http://&quot;);	 	// what to put in the text box by default
		}
	});

// when we click submit on this form
$('#linkForm').submit(function(){
	// reset the process box
	resetThings();
	// remove the submit button
	submitB.fadeOut();
	// tell the user we are doing something
	$('.processingC').html('Shrinking your URL...');
	$('.process').animate({&quot;height&quot;: &quot;50px&quot;}, 500);

	$.ajax({
		type: 'post', // the method will be post
		dataType: 'json', // the data type to post
		url: 'files/process/add.php', // the URL of where to post the information
		data: 'theLink=' + $('#theLink').val(), //the data to post, we just want what is in the box at this time
		// on success the response will added to the &quot;e&quot; so we can call it by writing e.message. You don't need to use &quot;e&quot;
		// you can use what you want, but make sure that if you change it you change all of the other e's to the new thing
		// The response that will will send to this will be
		// 1. If it was successful
		// 2. A message
		// 3. If we have it, the short url. We will create this response in a minuet 

		success: function(e){
			if(e.error == true){ // if no error
				$('.processingC').html(e.message); // display the message in the box at the top saying what has happened
				submitB.fadeIn(); // as there was an error, bring back the submit button
				$('.process').animate({&quot;height&quot;: &quot;50px&quot;}, 3500).animate({&quot;height&quot;: &quot;0px&quot;}, 1000); 	// remove the process box
																									// after giving time to see the message
			}else{ // if there was not an error, it worked!
				$('.processingC').html(e.message); // display message
				$('.process').css({&quot;background&quot;: &quot;green&quot;}).animate({&quot;height&quot;: &quot;50px&quot;}, 3500).animate({&quot;height&quot;: &quot;0px&quot;}, 1000); // make it a nice green
				$('#theLink').val(e.shortURL); // put the URL in the box
				$('.postTo').fadeIn(); // bring up the links
				// change the size of the textbox, not needed but a nice touch
				$(&quot;#theLink&quot;).animate({&quot;width&quot;: &quot;450px&quot;})

				// set the buttons
				$('.postTo .tweetie a').attr({&quot;href&quot;: &quot;javascript:window.location='tweetie:'+'&quot; + e.shortURL + &quot;' &quot;});
				$('.postTo .twitter a').attr({&quot;href&quot;: &quot;http://twitter.com/?status=&quot; + e.shortURL + &quot; &quot;});
				$('.postTo .facebook a').attr({&quot;href&quot;: &quot;http://facebook.com/sharer.php?u=&quot; + e.shortURL + &quot; &quot;});
			}
		}
	}); // end of ajax
		// if we had a time out, alert saying this.
		$(this).ajaxError(function(){
			alert(&quot;THERE WAS AN AJAX ERROR, SORRY ABOUT THAT&quot;);
		});
		// IMPORTANT! So it won't go to the page, return false!
		return false;
}); // end of submit
});
</pre><h3>Lets start on the PHP</h3><p> Create a file called &#8220;config.php&#8221; inside the functions folder. This will contain the database username, password, etc. Along with a way of setting if the login is needed and the base url. The base url will be the location of where you have placed the first index.php file. On my demo page it is http://demo.alexbor.com/url REMEMBER not to include the end &#8220;/&#8221;, nothing that bad will happen, it&#8217;s just best that you don&#8217;t. Put in all the information like this:</p><pre class="brush: php;">
&lt;?php
	$dbhost = 'localhost'; 	// the host (will probably be localhost)
	$dbuser = 'USERNAME'; 	// the username
	$dbpass = 'PASSWORD'; 	// the password
	$db		= 'DATABASE'; 	// the database
							// connect to the database, if fails - die.
	$conn 	= mysql_connect($dbhost, $dbuser, $dbpass) or die(&quot;Could not connect to the database&quot;);
							// select the database
	mysql_select_db($db) or die(&quot;I couldn't find the database&quot;);
							// define the base url... E.g. http://alexbor.com
	define(&quot;BASE_URL&quot;, &quot;http://alexbor.com&quot; );
							// In the end we will check if a login is required to shorten a url
	define(&quot;LOGIN_REQ&quot;, false );
?&gt;
</pre><p> Load this page, and if you get nothing its all good! Now the functions page, create a file &#8220;functions.php&#8221; in this functions folder. I have said what everything (that we will need at this point) does so will not go into an explanation at the bottom.</p><pre class="brush: php;">
&lt;?php
// get the config file that has all the database info
require_once(&quot;config.php&quot;);
session_start(); // we will use sessions so its best to start it here as we will be including it on all pages
// A quick way to respond to the JSON request that we will set up later.
// This will allow us to easily post if it worked, a message, and (if we have it) a short URL
function json_to_jquery($type, $message, $url){
	$replying['error'] = &quot;$type&quot;; // if it worked or not
	$replying['message'] = &quot;$message&quot;; // the message
	$replying['shortURL'] = &quot;$url&quot;; // the URL
	echo(json_encode($replying)); // json encode so that the JS file will know what everything means
}

function gen_short_url(){
		// find the heighest ID
	$query 	= 'SELECT MAX( id ) FROM `url` LIMIT 1 ';
			// run the query/get info
	$res	= mysql_query($query);
	$accoc 	= mysql_fetch_assoc($res);
			// grab the heighest ID and add one
	$id		= $accoc['MAX( id )'];
	$id++;
			// convert to short url code
			// the base conver will convert (when set up like we have) will convert from 1-9 then a-z
			// it is a great way to produce what we want
	$shortURL = base_convert($id, 10, 36);
	return $shortURL;

};

// this will add the values, we will give it the short/and long URL
function add_url_to_database($shortURL, $longURL){
	// create the query, and insert it into the &quot;url&quot; table
	$insert_query = &quot;INSERT INTO `url` (`id` ,`short` ,`long` )
						VALUES (
						NULL ,
						'{$shortURL}',
						'{$longURL}'
						)&quot;;
	// if it did something
	if(mysql_query($insert_query)){
		// set the error to false
		$urlInfo['error'] = false;
		// set the short url
		$urlInfo['shortURL'] = $shortURL;
		// set the long url
		$urlInfo['longURL'] = $longURL;
		return $urlInfo;
	}
}

?&gt;
</pre><p> Leave this and we will come back to it later. Next, create the add page that the jQuery posts to. In the process directory (as we will be processing the information) create a file &#8220;add.php&#8221;. We will add the following:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);  // get the functions file
$error = false; // set this as defalt
$longURL = mysql_real_escape_string( strip_tags($_POST['theLink']) ); // remove bad things and put it into a variable

// check if valid URL
if(!preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $longURL)){
	$message = &quot;Not a valid URL!&quot;; // This will be what will be displayed to the user if there was a problem
	$error = true; // set an error
} else{ // it was valid
		$longURL = urlencode($longURL); // encode the url
}

// if there was no error, add it to the database
if(!$error){
	// next we will create a short url &quot;temp&quot; and pass that into the next function (we will create this in a second)
	$shortURL = gen_short_url();
	$urlInfo = add_url_to_database($shortURL, $longURL); // add the short/long url
}else{ 

// as there was an error, so we will say so. The short URL string is added but left blank as a value as the function requiers it
	json_to_jquery($error, $message, &quot;&quot;);
	die();
}
// if errors
if($urlInfo['error'] || $error){
	json_to_jquery($error, &quot;There was a problem&quot;, &quot;&quot;);
	die();
}else{ 	// this worked so build the short url
		// the base that was set in the config file, then a foward slash, and the shortURL that was returned
	$url = BASE_URL . &quot;/&quot; . $urlInfo['shortURL'];
	json_to_jquery(&quot;0&quot;, &quot;Success!&quot;, $url);  // Send this to the user via our function
}
?&gt;
</pre><p> And that is it for the adding of links!<br /> If you try it out now it should allow you to insert links into the database.</p><p> We will next deal with redirecting the users. For this we will create a &#8220;.htaccess&#8221; file on the home directory. Add the following:</p><pre class="brush: plain;">
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
</pre><p>This will re-write the URL so if you go you it will save you from needing http://alexbor.com/index.php?url=4 and instead just http://alexbor.com/4. This is all good, but we need to get the index.php file read to deal with this. Open up that file again and we will add the following to the very top of the file, above anything already in the file.</p><pre class="brush: php;">

&lt;?php

require_once(&quot;files/functions/functions.php&quot;); // as normal, get the functions
$url           = mysql_real_escape_string( strip_tags($_GET['url'])); // get the varible &quot;url&quot; from the url. This will be the short url.
//echo $url; // uncomment this if you would like to see it get the value.
// if it has a string length
if(strlen($url) &gt;= 1){
	// set a variable saying we are doing a redirect to true.
	$redirect = true;
}else{
	// if not we will load the page as normal, so set it to false.
	$redirect = false;
}
if(!$redirect) : // if we are not re-directing the page do this
// as the rest of the file here. Then at the very bottom add
?&gt;
&lt;html&gt;
 ....
&lt;/html&gt;

&lt;?php endif; if($redirect) :  // check we are redirecting
	// get the full URL (we will set this up in a minute
	// it will take the short url that we got
	$redirect =	get_url_from_small($url);

//	print_r($redirect); // uncomment to see what we are returning

	if($redirect['error']){ // if there is a problem, say so
		echo &quot;That URL is either no longer valid or has been deactivated&quot;;
	}else{ // if not
		$url = urldecode($redirect['long']); // decode the long url
		header( &quot;Location:  &quot; . $url . &quot; &quot; ); // redirect the user
	}
endif; //end of the redirect if.
?&gt;
</pre><p> In that area above, we have used a plethora of function that are yet to exist, so we will now create them.</p><pre class="brush: php;">
function gen_short_url(){
		// find the heighest ID
	$query 	= 'SELECT MAX( id ) FROM `url` LIMIT 1 ';
			// run the query/get info
	$res	= mysql_query($query);
	$accoc 	= mysql_fetch_assoc($res);
			// grab the heighest ID and add one
	$id		= $accoc['MAX( id )'] + 1;
	$id++;
			// convert to short url code
	$shortURL = base_convert($id, 10, 36);
		// if that failed, set an error
	return $shortURL;

};
// get full url
function get_url_from_small($smallURL){ // set up the function

	if(small_url_exists($smallURL)){ // this will return true or false

		$longQ = mysql_query(&quot;SELECT * FROM `url` WHERE `short`='{$smallURL}' LIMIT 1&quot;); // find the url
		// don't need to check amount of rows, we know it exists!
		$accoc 	= mysql_fetch_assoc($longQ); // grab the row values
		if($accoc['active'] == 0){ // if it is no longer active
			$accoc['error'] = true; // set error
			return $accoc; // return this
			die(); // die
		}
		$accoc['error'] = false; // if not, set error to false

		if(get_stats_page($smallURL)){ // check if it has a + at the end of it
			$short = $accoc['short']; // if it does we get the short url from that array
			$accoc['long'] = BASE_URL . &quot;/files/stats/&quot; . $short; // and overwrite the long url to this
			return $accoc; // now return this array
		}else{
				user_clicked_link($accoc['id'], $accoc['clicks']); // add one to the clicked number, we are passing the amount of clicks to save from doing a another SQL query, and we are passing the ID so we know what we are doing.
				return $accoc; // return
		}

	}else{ // it does not exist
		$accoc['error'] = true; // set an error
		return $accoc;
	}

}

function add_url_to_database($shortURL, $longURL){
	$insert_query = &quot;INSERT INTO `url` (`id` ,`short` ,`long` ,`addedByID`)
						VALUES (NULL ,
						'{$shortURL}',
						'{$longURL}',
						'0' )&quot;;
	if(mysql_query($insert_query)){
		$urlInfo['error'] = false;
		$urlInfo['shortURL'] = $shortURL;
		$urlInfo['longURL'] = $longURL;
		return $urlInfo;
	}
}

// check that a value exists
function small_url_exists($smallURL){													// this will take the small url
	$existsQ = mysql_query(&quot;SELECT * FROM `url` WHERE `short`='{$smallURL}' LIMIT 1&quot;);	// run a search to find it
	$exsitsRows = mysql_num_rows($existsQ);												// check amount of rows
	if($exsitsRows == 0 ){ 																// if there are 0 it was not found
		return false;
	}else{
		return true;
	}
}

function get_stats_page($shortURL){ // here we check to see if a short url had a + at the end
$shortURL = urlencode($shortURL); // encode as URL's with +'s get changed into spaces previously.
	if(preg_match('/([+])$/i', $shortURL)){ // check that it contains a + once at the end
		return true;	// it does
	}else{
		return false;	//it does not
	}
}

function user_clicked_link($id, $clicks){ // this will add a click number
	// if user is not a bot
	if( !botCheck() ){
		$clicks = $clicks +1; // add one to the amount of clicks
		$ipAdd 	= $_SERVER['REMOTE_ADDR']; // get the IP address
		$tUnixTime = time(); // get the time
		$timeStamp = gmdate(&quot;Y-m-d H:i:s&quot;, $tUnixTime); // put it into a valid (gmt) time stamp
		$updateQ = &quot;UPDATE `url` SET
					`clicks` = '{$clicks}',
					`lastIP` = '{$ipAdd}',
					`lastClicked` = '{$timeStamp}'
					WHERE `id` ='$id' LIMIT 1&quot;;
		mysql_query($updateQ);// update to the new values
	}
}

// check for bots
function botCheck(){
	// an array containing all the names of the most popular bots
	$botlist = array(&quot;Teoma&quot;, &quot;alexa&quot;, &quot;froogle&quot;, &quot;Gigabot&quot;, &quot;inktomi&quot;,
	&quot;looksmart&quot;, &quot;URL_Spider_SQL&quot;, &quot;Firefly&quot;, &quot;NationalDirectory&quot;,
	&quot;Ask Jeeves&quot;, &quot;TECNOSEEK&quot;, &quot;InfoSeek&quot;, &quot;WebFindBot&quot;, &quot;girafabot&quot;,
	&quot;crawler&quot;, &quot;www.galaxy.com&quot;, &quot;Googlebot&quot;, &quot;Scooter&quot;, &quot;Slurp&quot;,
	&quot;msnbot&quot;, &quot;appie&quot;, &quot;FAST&quot;, &quot;WebBug&quot;, &quot;Spade&quot;, &quot;ZyBorg&quot;, &quot;rabaz&quot;,
	&quot;Baiduspider&quot;, &quot;Feedfetcher-Google&quot;, &quot;TechnoratiSnoop&quot;, &quot;Rankivabot&quot;,
	&quot;Mediapartners-Google&quot;, &quot;Sogou web spider&quot;, &quot;WebAlta Crawler&quot;,&quot;TweetmemeBot&quot;,
	&quot;Butterfly&quot;,&quot;Twitturls&quot;,&quot;Me.dium&quot;,&quot;Twiceler&quot;);
	// foreach of the names, see if the user is one of them
	foreach($botlist as $bot){
						/// get them
		if(strpos($_SERVER['HTTP_USER_AGENT'],$bot)!==false)
		return true;	// Is a bot
	}
		return false;	// Not a bot
}
</pre><p> I have commented throughout explaining in detail what each function does, so have a read through that. This is now good to go! Try it out and see what happens. You can now shorten URL&#8217;s and also go to them.</p><h3>Logging in/out</h3><p> Next, we will do the login bit. For this we will need, a username, md5 hashed password, an API key and email. We will deal with adding users at a later time but for now, add them in manually. To see what an md5 password and API key looks like, create a new php file and use what follows:</p><pre class="brush: php;">
&lt;?php
	echo &quot;Your password is&quot;;
	echo md5(&quot;password&quot;) . &quot;&lt;br /&gt;&quot;;
	// create a API key that will be individual and hard to crack.

	$toHash = time(); // the current time
	$toHash .= rand(0, 999999); // a random number
	$tohash .= $_SERVER['REMOTE_ADDR']; // the IP address of the user

	$toHash2 = rand(0, 999999);
	$toHash2 .= &quot;alex@alexbor.com&quot;; // your email
	$hash1 = md5($toHash); // md5 the first hash
	$hash2 = md5($toHash2);  // md5 the second hash
	echo &quot;Your API key is: &quot; . $hash1 . $hash2 . &quot;&lt;br/&gt;&quot;
?&gt;
</pre><p> Select both of those values and inset them into the database along with you desired username/email with the following SQL query. Note: Make sure the username and password are over 6 characters or over and the username has no white space.</p><pre class="brush: sql;">
INSERT INTO `urls`.`users` (`id` ,`username` ,`password` ,`email` ,`apiKey`)
VALUES (NULL , 'USERNAME', 'PASSWORD', 'EMAIL', 'API KEY');
</pre><div class="wp-caption"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/img31.png"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/img31.png" alt="" title="img3" width="442" height="47" class="aligncenter size-full wp-image-2102" /></a></div><p> That should be the only time we add a user manually, we will build a way to add them ourselves from a nice view.</p><p> We now have a users, so we will create a way to login with the username and password above.</p><p> In the index page we will add the following in the very top under where we are requiring our functions file.</p><pre class="brush: php;">
$loggedIn = $_SESSION['loggedIn'];
$username = $_SESSION['username'];
</pre><p> Next find the div with an ID of &#8220;strip&#8221;, and replace it with this:</p><p/><pre class="brush: php;">
&lt;div id=&quot;strip&quot;&gt;
	&lt;div id=&quot;stipWrap&quot;&gt;
		&lt;!-- If we require a login AND the user is not logged in we will load the login form --&gt;
		&lt;?php if( (LOGIN_REQ) &amp;&amp; ($loggedIn != true) ){ ?&gt;
				&lt;h1 class=&quot;inform&quot;&gt;Please login with the form below:&lt;/h1&gt;
				&lt;form class=&quot;loginForm&quot; action=&quot;files/process/login.php&quot; method=&quot;POST&quot;&gt;
					&lt;label for=&quot;username&quot; class=&quot;label&quot;&gt;Username:&lt;/label&gt;&lt;br /&gt;
					&lt;input type=&quot;text&quot; id=&quot;username&quot; class=&quot;smallInput&quot; name=&quot;username&quot;&gt;&lt;br /&gt;

					&lt;label for=&quot;password&quot; class=&quot;label&quot;&gt;Password:&lt;/label&gt;&lt;br /&gt;
					&lt;input type=&quot;password&quot; id=&quot;password&quot; class=&quot;smallInput&quot; name=&quot;password&quot;&gt;&lt;br /&gt;&lt;br /&gt;
					&lt;input type=&quot;submit&quot; value=&quot;Login me in!&quot; /&gt;
				&lt;/form&gt;
		&lt;!-- else, if we don't require a login, load the submit form --&gt;
		&lt;?php }else{ ?&gt;
				&lt;?php
					// if you are logged in, display a logout URL.
				if($loggedIn){echo &quot;&lt;a href='&quot; . BASE_URL . &quot;/files/process/logout.php' class='logOut'&gt;Logout &quot; . $username . &quot;?&lt;/a&gt;&quot;; }
				?&gt;
				&lt;form id=&quot;linkForm&quot; class=&quot;&quot; action=&quot;files/process/add.php&quot; method=&quot;post&quot;&gt;
					&lt;input value=&quot;Make me short...&quot; type=&quot;text&quot; class=&quot;smallInput&quot; id=&quot;theLink&quot; name=&quot;theLink&quot;/&gt;
					&lt;input type=&quot;submit&quot; id=&quot;submit&quot; value=&quot;Shorten&quot; /&gt;
				&lt;/form&gt;		

				&lt;ul class=&quot;postTo&quot;&gt;
					&lt;li class=&quot;tweetie&quot;&gt;&lt;a href=&quot;&quot;&gt;Post With Tweetie&lt;/a&gt;&lt;/li&gt;
					&lt;li class=&quot;twitter&quot;&gt;&lt;a href=&quot;&quot;&gt;Post To Twitter&lt;/a&gt;&lt;/li&gt;
					&lt;li class=&quot;facebook&quot;&gt;&lt;a href=&quot;&quot;&gt;Share On Facebook&lt;/a&gt;&lt;/li&gt;
				&lt;/ul&gt;
		&lt;?php }; ?&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre><p> That will check if the defined value of &#8220;LOGIN_REQ&#8221; is true or false, it&#8217;s false and the user is not logged in, load the login form. If not then we have aloud public access to this url shortener. If you try it out when changing the value of LOGIN_REQ in the config page you will see it change. We will build the login system.</p><h3>Logging in</h3><p> In the process folder, add two new files &#8220;login.php&#8221; and &#8220;logout.php&#8221;. Then open the login file.</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);
$username = mysql_real_escape_string( strip_tags($_POST['username']) ); // get the posted username
$password = mysql_real_escape_string( strip_tags($_POST['password']) );	// get the posted password
if(strlen($username) &lt; 5 ){ 	// if the username is above 5 char
	$error = true;			// if its not set an error
	$errorMessages['username'] = &quot;Please write a username&quot;; // what the error is
}
if(strlen($password) &lt; 5){ // same with password
	$error = true;
	$errorMessages['password'] = &quot;Please write a password&quot;;
}

if(preg_match(&quot;/ /&quot;, $username)){ // check that the username has no white space.
	$error = true;
	$errorMessages['spaces'] = &quot;Username cannot contain white space&quot;;
}

if($error){ // if there is an errir
	foreach( $errorMessages as $errorMessage ){ // for every error message
		echo &quot;Problem: &quot; . $errorMessage . &quot;&lt;br /&gt;&quot;; // echo it out
	}
}

if(!$error){ // if no error
	$password = md5($password); // hash the pass, we do this know as it generates a 32 char varible. Even if it was left
								// empty
	if(check_username_and_password($username, $password)){ // if we find the user (will create this function)
		// found user
		// set sessions
		$_SESSION['loggedIn'] = true;
		$_SESSION['username'] = $username; // set a session
		header(&quot;Location:  &quot; . BASE_URL . &quot;/&quot;);  // redirect back the the index page
	}else{
		//didn't find user
		echo &quot;Sorry, no user with that username/password combo was found!&quot;;
	}
}?&gt;
</pre><p>And now the logout page. Inside the logout file we create earlier write:</p><pre class="brush: php;">
&lt;?php
require_once(&quot;../functions/functions.php&quot;);
setcookie( session_name(), '', time() - 100); // if there is a session cookie make it expire it from the user's pc
session_destroy();	// destroy the session on our server
header(&quot;Location:  &quot; . BASE_URL . &quot;/&quot;); // redirect back to index page
?&gt;
</pre><p> Almost done, we now just need to add the final function to check if the user was found. Open the functions file at the bottom add:</p><p><pre class="brush: php;">
// DOING THE LOGINS
function check_username_and_password($username, $password){
	$ucheck = mysql_query(&quot;SELECT * FROM `users` WHERE `username`='{$username}' AND `password` ='{$password}' LIMIT 1&quot;);
	$ucheckRows = mysql_num_rows($ucheck);
	if($ucheckRows == 0 ){
		return false;
	}else{
		return true;
	}
}
</pre><h3>Finished</h3><p> That should now be the end of it for. From the plan I set above:</p><ol><li>Adding URLs <b>done</b></li><li>Tracking (but not a nice view) of URLs <b>done</b></li><li>Redirections (of both adding a Ò+Ó to the end of a URL and normal redirecting) <b>done</b></li><li>AJAX system for adding a new URL <b>done</b></li><li>Adding IP address <b>done</b></li><li>Not to include bots <b>done</b></li><li>Log in/out <b>done</b></li><li>Redirecting visitors <b>done</b></li></ol><p> You can download completed files from <a href="http://demo.alexbor.com/downloads/url_system_part_1.zip">here</a> and have a read through them. You may not be able to see the .htaccess file though, so you will have to remake it on the server to get this to work.</p><p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/twitter-url-shortener-part-2/' rel='bookmark' title='Permanent Link: Twitter URL Shortener: Part 2'>Twitter URL Shortener: Part 2</a></li><li><a href='http://brenelz.com/blog/building-a-simple-php-mailing-list/' rel='bookmark' title='Permanent Link: Building a Simple PHP Mailing List'>Building a Simple PHP Mailing List</a></li><li><a href='http://brenelz.com/blog/creating-an-ellipsis-in-php/' rel='bookmark' title='Permanent Link: Creating an Ellipsis in PHP'>Creating an Ellipsis in PHP</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=uCHHdF8cmUk:cobwycswlOc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=uCHHdF8cmUk:cobwycswlOc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=uCHHdF8cmUk:cobwycswlOc:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/uCHHdF8cmUk" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/feed/</wfw:commentRss> <slash:comments>16</slash:comments> <feedburner:origLink>http://brenelz.com/blog/create-url-shortener-for-twitter-using-php/</feedburner:origLink></item> <item><title>Really Simple Model/View Seperation With PHP</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/YtZKvrScTQs/</link> <comments>http://brenelz.com/blog/really-simple-modelview-seperation-with-php/#comments</comments> <pubDate>Mon, 08 Mar 2010 14:00:11 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[Uncategorized]]></category><guid isPermaLink="false">http://brenelz.com/?p=2058</guid> <description><![CDATA[Reading time: 3 &#8211; 5 minutes I think I speak for a number of developers when I say that I strive to have my code readable and easy to maintain. This is way easier said than done as many of you know. The most familiar way of doing this is using the Model View Controller [...]Related posts:<ol><li><a href='http://brenelz.com/blog/howto-mysql-table-joins/' rel='bookmark' title='Permanent Link: How-To MySQL Table Joins'>How-To MySQL Table Joins</a></li><li><a href='http://brenelz.com/blog/how-to-create-a-simple-api-with-php-and-mysql/' rel='bookmark' title='Permanent Link: How to Create a Simple API with PHP and MySQL'>How to Create a Simple API with PHP and MySQL</a></li><li><a href='http://brenelz.com/blog/php-codeigniter-validation/' rel='bookmark' title='Permanent Link: PHP CodeIgniter Validation'>PHP CodeIgniter Validation</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 3 &#8211; 5 minutes</p><p>I think I speak for a number of developers when I say that I strive to have my code readable and easy to maintain.  This is way easier said than done as many of you know.  The most familiar way of doing this is using the Model View Controller (MVC) concept.</p><p>While I see the point in the above, I do sometimes struggle with its practicality.  For example, do I really need to use CakePHP, Symfony, CodeIgniter for a simple PHP based site?  I agree that frameworks can be handy for larger sites, but the majority of my sites are on the smaller side.</p><p>This is the reason that I will teach you a simple way to separate your models/views with very little OO logic, and not using a framework.<br /> <span id="more-2058"></span></p><h3>Folder Structure</h3><p>Start by creating a folder structure using the following:</p><div class="wp-caption"> <a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/folder-structure.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/03/folder-structure.jpg" alt="" title="folder-structure" width="227" height="91" class="aligncenter size-full wp-image-2081" /></a></div><h3>MySQL Database Class (db.class.php)</h3><pre class="brush: php;">
&lt;?php

// best practice is naming the class the same as the first part of the filename
class DB {
	var $db; // property of our class that will store our DB connection

        /*
            This function loads as soon as the class is instantiated.  Eg. $db = new DB();
            PHP5 uses __construct and PHP4 uses a function the same name as the class.  Eg. function DB()
        */
	function __construct()
	{
               // change the following credentials to match your server
		$this-&gt;db = mysqli_connect('localhost','username','password','database') or die('Unable to connect to the MySQL server.');
	}
}
</pre><p><strong>NOTE: Make sure you have created a database on your MySQL server and have changed it in the above class.</strong></p><h3>Create the Products Table</h3><p>Now run the following SQL query on your database using any method you wish (phpMyAdmin, SSH, etc&#8230;)</p><pre class="brush: sql;">
CREATE TABLE IF NOT EXISTS `products` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `description` text NOT NULL,
  PRIMARY KEY (`product_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
</pre><p>This creates the following fields: product_id (PRIMARY KEY), title, description, image</p><h3>Insert Product Data</h3><p>Do the same with the following:</p><pre class="brush: sql;">
INSERT INTO `trailers_products` (`product_id`, `title`, `description`) VALUES
(1, 'Hosting', 'Hosting Description'),
(2, 'Web Design', 'Web Design Description'),
(3, 'Programming', 'Programming Description'),
(4, 'SEO', 'SEO Description'),
(5, 'iPhone Development', 'iPhone Development Description');
</pre><p>This has inserted a couple sample products so we can see our result later on.</p><h3>Product Class (products.class.php)</h3><pre class="brush: php;">
&lt;?php

// include our dababase class we just created
include 'db.class.php';

/*
	NOTE: This class will extend the class we created previously

	This means that our $db variable will be accessible for our queries ($this-&gt;db)
*/
class Products extends DB {

	/*
		Simple function that will get all our products from the db and return an array of objects
	*/
	function getProducts()
	{
		$query = &quot;SELECT product_id, title, description
				  FROM products
				  ORDER BY title&quot;;
		$result = mysqli_query($this-&gt;db, $query);

		$data = array();
		while( $row = mysqli_fetch_object($result) )
		{
			array_push($data, $row);
		}
		return $data;
	}
}
</pre><h3>Pulling It All Together (index.php)</h3><pre class="brush: php;">
&lt;?php
	// include our products class
	include_once 'classes/products.class.php';

    // instantiate our class
	$ProdModel = new Products();

    // call our user defined function which returns an array of products
    $products = $ProdModel-&gt;getProducts();
?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
&lt;title&gt;Brenelz Web Solutions - Products&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Products&lt;/h1&gt;

&lt;?php foreach( $products as $p ) :  ?&gt;
    &lt;h2&gt;&lt;?php echo $p-&gt;title?&gt;&lt;/h2&gt;
    &lt;p&gt;&lt;?php echo $p-&gt;description?&gt;&lt;/p&gt;
    &lt;hr /&gt;
&lt;?php endforeach; ?&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre><p>Now open up index.php in your browser and see all the products that have been entered into the database!</p><h3>Thoughts?</h3><p>Related posts:<ol><li><a href='http://brenelz.com/blog/howto-mysql-table-joins/' rel='bookmark' title='Permanent Link: How-To MySQL Table Joins'>How-To MySQL Table Joins</a></li><li><a href='http://brenelz.com/blog/how-to-create-a-simple-api-with-php-and-mysql/' rel='bookmark' title='Permanent Link: How to Create a Simple API with PHP and MySQL'>How to Create a Simple API with PHP and MySQL</a></li><li><a href='http://brenelz.com/blog/php-codeigniter-validation/' rel='bookmark' title='Permanent Link: PHP CodeIgniter Validation'>PHP CodeIgniter Validation</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=YtZKvrScTQs:D5--saSUlCk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=YtZKvrScTQs:D5--saSUlCk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=YtZKvrScTQs:D5--saSUlCk:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/YtZKvrScTQs" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/really-simple-modelview-seperation-with-php/feed/</wfw:commentRss> <slash:comments>11</slash:comments> <feedburner:origLink>http://brenelz.com/blog/really-simple-modelview-seperation-with-php/</feedburner:origLink></item> <item><title>CDNs: Do They Affect Google Rankings?</title><link>http://feedproxy.google.com/~r/BrenelzsWebDevelopmentTips/~3/0H8ioUYjLBU/</link> <comments>http://brenelz.com/blog/cdns-do-they-affect-google-rankings/#comments</comments> <pubDate>Wed, 10 Feb 2010 19:51:49 +0000</pubDate> <dc:creator>brenelz</dc:creator> <category><![CDATA[SEO]]></category><guid isPermaLink="false">http://brenelz.com/?p=2037</guid> <description><![CDATA[Reading time: 2 &#8211; 3 minutes CDNs just a little while ago seemed like such a complicated topic that only large fortune 500 companies could use. Today they are better understood and more affordable for small businesses. I was lucky enough to be contacted by MaxCDN who was willing to sponsor my website. I was [...]Related posts:<ol><li><a href='http://brenelz.com/blog/googles-new-canonical-option/' rel='bookmark' title='Permanent Link: Google&#039;s New Canonical Option'>Google&#039;s New Canonical Option</a></li><li><a href='http://brenelz.com/blog/google-pagerank-updated-dec-30/' rel='bookmark' title='Permanent Link: Google PageRank Updated Dec. 30'>Google PageRank Updated Dec. 30</a></li><li><a href='http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/' rel='bookmark' title='Permanent Link: Google Makes Changes: A Lot Like Bing?'>Google Makes Changes: A Lot Like Bing?</a></li></ol>]]></description> <content:encoded><![CDATA[<p>Reading time: 2 &#8211; 3 minutes</p><p>CDNs just a little while ago seemed like such a complicated topic that only large fortune 500 companies could use.  Today they are better understood and more affordable for small businesses.</p><p>I was lucky enough to be contacted by <a href="http://www.maxcdn.com/" target="_blank">MaxCDN</a> who was willing to sponsor my website.  I was thrilled as they mentioned they sponsor many well known blogs such as Web Designer Depot, and Mashable.  Anytime I get mentioned with those blogs it is a nice compliment.</p><p>I suggest heading over there and seeing what they can do for you!</p><p><span id="more-2037"></span></p><h3>What is a CDN?</h3><p>CDN stands for &#8220;Content Delivery Network&#8221; and is described by <a href="http://en.wikipedia.org/wiki/Content_delivery_network" target="_blank">Wikipedia.org</a> as:</p><blockquote><p>A CDN is a system of computers  containing copies of data, placed at various points in a network so as to maximize bandwidth for access to the data from clients throughout the network. A client accesses a copy of the data near to the client, as opposed to all clients accessing the same central server, so as to avoid bottleneck near that server.</p></blockquote><div id="attachment_2041" class="wp-caption aligncenter" style="width: 505px"><a href="http://cdnwww.brenelz.com/wp-content/uploads/2010/02/8603_6636_diagram.jpg"><img src="http://cdnwww.brenelz.com/wp-content/uploads/2010/02/8603_6636_diagram.jpg" alt="" title="8603_6636_diagram" width="495" height="430" class="size-full wp-image-2041" /></a><p class="wp-caption-text">Via NetBenefit.com</p></div><h3>Why Use a CDN?</h3><p>The main reason someone would use a CDN is to boost site loading times, and allow for quicker file downloads by your users.  Yahoo states that moving static content to a CDN can improve response times by up to 20%!</p><p>As well with a company like MaxCDN setup is minimal and is a lot more cost effective than it used to.</p><h3>Wait, does it help Google Rankings?</h3><p>This is actually my main point that should peak your interest.  Google now depends on loading speed a whole lot more than they used to.</p><p>Putting your site on a CDN can only help you get to page 1 of the SERPs.</p><p>For example, my <a href="http://www.brenelz.com">winnipeg website design</a> company is climbing up the ranks for the keyword <a href="http://www.google.ca/search?q=winnipeg+web+design">&#8220;Winnipeg Web Design&#8221;</a> and I attribute most of it to now being on a CDN.</p><p>Related posts:<ol><li><a href='http://brenelz.com/blog/googles-new-canonical-option/' rel='bookmark' title='Permanent Link: Google&#039;s New Canonical Option'>Google&#039;s New Canonical Option</a></li><li><a href='http://brenelz.com/blog/google-pagerank-updated-dec-30/' rel='bookmark' title='Permanent Link: Google PageRank Updated Dec. 30'>Google PageRank Updated Dec. 30</a></li><li><a href='http://brenelz.com/blog/google-makes-changes-a-lot-like-bing/' rel='bookmark' title='Permanent Link: Google Makes Changes: A Lot Like Bing?'>Google Makes Changes: A Lot Like Bing?</a></li></ol></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=0H8ioUYjLBU:Snd8x3XlFWE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?a=0H8ioUYjLBU:Snd8x3XlFWE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/BrenelzsWebDevelopmentTips?i=0H8ioUYjLBU:Snd8x3XlFWE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BrenelzsWebDevelopmentTips/~4/0H8ioUYjLBU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://brenelz.com/blog/cdns-do-they-affect-google-rankings/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://brenelz.com/blog/cdns-do-they-affect-google-rankings/</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced) (request URI contains query)
Database Caching 155/515 queries in 1.589 seconds using disk
Content Delivery Network via cdnwww.brenelz.com

Served from: brenelz.com @ 2010-07-28 19:49:34 -->
