Web Design, Programming, Tutorials
Posts tagged Tutorial
Cricket.Net: Part 3 – Unit Testing
Dec 13th
Summary
Cricket.Net is a new open source project that I’ve started on Codeplex. It will be a web application that will be used for tracking software bugs. Cricket.Net will be written in C# using HTML5, ASP.NET MVC 3, Entity Framework 4.1 Code First, StructureMap, and the Onion Architecture. This project will be an example application to demonstrate how to use these technologies together to build a web application from the ground up.
I’ll also be going through using Mercurial both on my system and pushing changes to the Codeplex site.
Cricket.Net Series:
- Part 1: Setting up the initial project
- Part 2: Design Discussion
- Part 3: Unit Testing
Unit Testing Thoughts
The idea behind unit testing is to write a very simple piece of code to test your business logic for one condition. The test either passes or fails. As you build your application, you may have hundreds or thousands of these tests. By keeping them very simple, and not running any time intensive operations such as I/O, these tests will be able to execute very quickly and give you an indication that your program is working correctly.
Unit Tests become most useful when your application has been completed for a number of months and then a required change is needed. As you modify your code, you can re-run your unit tests to make sure your new modifications have not broken your program in some other area.
The difficult part of unit testing is thinking of all the different angles to test your piece of code.
As you write your tests and develop your application, you will undoubtedly break some of the tests that you had previously written. These will then need to be revised. This is the process you will go through to fully flesh out your application and develop it from a user (of the code) perspective.
I usually begin by writing all my tests against the Controllers since that is the entry point to the things my application will do. I also try to write tests against the requirements of the application only. If you test all of an application’s requirements, then you are making sure the application is doing what your customer wants it to do. There is no need to test 100% of the code you write. As mentioned above, you will break unit tests as you develop your application and continually have to revise them. Revising tests that cover 100% of your code could be very time-consuming.
Unit Test Controller Shell
Since we’ll be testing Requirements, the first thing I do is create a new folder in the Unit Test project called Requirements. There is currently a Controllers folder that we will remove later on.
Next, create a new Class item called ApplicationControllerRequirements.
The new class will need to be modified for unit testing. Below is the basic shell for a unit testing class.
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Cricket.UnitTests.Requirements
{
[TestClass]
public class ApplicationControllerRequirements
{
[TestInitialize]
public void Setup()
{
//This method runs before each test method.
}
#region Test Group
[TestMethod]
public void unit_test_method()
{
//Arrange.
//Act.
//Assert.
}
#endregion
}
}
There are three attributes being used on this class: TestClass, TestInitialize, and TestMethod.
- TestClass – Signals this is a unit testing class.
- TestInitialize – This is an initialization method that is executed before each test method.
- TestMethod – This is a unit test function.
A unit test only tests one condition and there may be many conditions we need to test for, so I like to group my tests together using regions. These can be collapsed out of the way within Visual Studio to make it easier to work on other unit tests without the unwanted ones getting in the way.
Within a test method, there are three things that need to be done:
- Arrange – This consists of any mocking or setup tasks.
- Act – This is the execution of the action you are testing.
- Assert – This is the verification you received the desired result.
Writing The First Unit Test
First we will start with a very simple test against the Index action of the controller. This is the default action that is called if none is specified in the application’s URL.
We’re going to test if the Index controller returns a ViewResult. Notice the compiler now has an error on the “controller” object. This is because we haven’t created it yet. One nice aspect of TDD (Test Driven Development) is you think about how the interface to your code is used, and then develop the code afterwards. Now we know we need to create a “controller” object and it needs to have a method called “Index”.
Since the initialization of the controller will need to be done for nearly all tests in this class, we’ll add that to the Setup() method.
Now the compiler is showing errors on the “ApplicationController” class. We need to create the new controller in the main project.
- Right-click on the Controllers folder in the main project.
- Select Add, then Controller.
- Type in the Controller Name: ApplicationController and click Add. (Leaving the Template set on Empty Controller)
- In your unit test class, add the using statement: using Cricket.Controllers;
- Under the Unit Test method, add a cast to the “Act” line: ViewResult result = (ViewResult)controller.Index();
- Also, don’t forget to change the name of your unit test method to something meaningful. The more description you can put in this method name, the better.
Running Your Test
Ideally, you want to see your test fail first, to make sure you didn’t accidentally write a test that can never fail.
We can quickly test this by adding the following line to our Index method on the ApplicationController:
return RedirectToAction("Index");
A ViewResult is expected in the test, so now it will fail.
After you have verified the test has failed, change the Index method back to the following:
public ActionResult Index()
{
return View();
}
Another Test
Next, we’ll add another very simple test to verify the correct view is being returned from the Index method.
[TestMethod]
public void index_action_should_return_the_index_view()
{
//Arrange.
//Act.
ViewResult result = (ViewResult)controller.Index();
//Assert.
Assert.AreEqual("Index", result.ViewName, "result.ViewName");
}
Running this test will fail because the Index method is not returning a specific view. To change this, modify the Index method to show:
public ActionResult Index()
{
return View("Index");
}
Now the test will pass because we are specifying a view to display.

Final Thoughts
Unit Testing does take some time to get the hang of it. It is well worth it in the long run to know you can modify your program to add new features without breaking the current functionality.
As we develop this application, these tests will become more complex, but by focusing on one result and writing multiple tests for each action, we can work through it.
The empty “Arrange” comment for each of these tests is a place holder for mocking objects we may need to place there in the future. Typically, Unit Testing developers say to place all setup code in the arrange. I like to place common setup tasks that will happen for each test in the “Setup” method where I only have to code them once. If there is a specific setup task needed for a single test, then I will place that under the “Arrange” comment.
Visit the project site at: http://cricket.codeplex.com.
Download the source code from this post at:
http://cricket.codeplex.com/SourceControl/changeset/changes/df77b3e9d546
Cricket.Net: Part 2 – Design Discussion
Oct 13th
Summary
Cricket.Net is a new open source project that I’ve started on Codeplex. It will be a web application that will be used for tracking software bugs. Cricket.Net will be written in C# using HTML5, ASP.NET MVC 3, Entity Framework 4.1 Code First, StructureMap, and the Onion Architecture. This project will be an example application to demonstrate how to use these technologies together to build a web application from the ground up.
I’ll also be going through using Mercurial both on my system and pushing changes to the Codeplex site.
Cricket.Net Series:
- Part 1: Setting up the initial project
- Part 2: Design Discussion
Part 3: Unit Testing
What will the application do?
I’m going to take a step back before continuing with the code and look at what this application is suppose to do. I don’t need to determine everything up front, instead I’m going to use an Agile approach and lay down some basic requirements for what the system is suppose to do and if those change as the development progresses, that is fine.
Ususally the first thing I do is think about what information the application needs to store. Cricket.Net is a bug tracking program, so it will need to store information on a specific bug and what application the bug occurred in. I’m also going to want to track dates for when the bug was created and resolved, the version of the application the bug occurred in and maybe a list of one or more assignees who are working on resolving the bug.
Next, I’m going to open up Visio and separate these ideas into objects on a database model diagram. Since I’ve already created my solution folder, I’m going to add a folder within it called !Design. I’ll place all of my design files here to keep them with the solution when I update the Mercurial repository.
You don’t necessarily need to create a diagram of the database, you could just write-up the code using Entity Framework: Code First, but it is nice for non-programmers to have something to look at. Also, complex databases with many relationships can be difficult to work with if you don’t have a diagram to look at.
Onion Architecture and StructureMap
Now I’d like to talk for a minute about the Onion Architecture. Structuring an application in this way separates the business logic from the web and infrastructure components in a way that limits their dependencies on each other. Take a look at the following diagram:
The blue boxes represent a project within the solution. The arrows point to their dependencies. Notice how all projects depend on Core. This is where the business logic classes and interfaces are found. Also, notice how the Web project (in this case will be MVC 3) does not depend on Infrastructure (where the database repositories reside). There is an indirect dependency through the DependencyInjection project. This is where StructureMap (or another IoC framework) lives. StructureMap will wire-up the dependencies between the Web and Infrastructure frameworks using the interfaces found in the Core project.
Why go through all this work to setup your project this way? Encapsulation of components that could be replacable in the future makes it easy to upgrade an application to those new componenets. With Onion Architecture you could switch the entire application over to a different database server and only have to modify the database classes found in the Infrastructure project. As long as the interfaces do not change for those classes, the reset of the application will work as it did previously. This can save much time over rewriting the entire application because the db code is embedded everywhere.
The UI component could be changed as well (in this case the Web project) for a console application. The Core and Infrastructure will function the same, but the application would appear totally different.
Projects Summary:
- UnitTests – As the name implies, it contains all unit testing code. The Moq mocking framework will be used here.
- Web – This is the user interface project. This contains the controllers, views, view models, and wrapper classes around MVC or web specific operations.
- Core – This contains all interfaces for the application and business logic including: the domain model and service classes.
- DependencyInjection - This contains the classes needed by StructureMap. StructureMap will register all interfaces and concrete classes used in the application.
- Infrastructure – This contains any IO wrappers or classes using 3rd party projects (including our own common projects).
Unit Testing
When starting a project, I try to get in the habbit of coding a Unit Test first, before anything else. This helps me think about how I want to use a method before I worry about how the method works. This tends to lead to an overall better design of the application. I also try to adhere to the SOLID principles, DRY, and YAGNI by only coding what is needed at the time.
Unit Tests should also be very simple. Test for one condition to be met and pass or fail.
Requirements
- Allow users to manage Applications (including adding different versions for each).
- Allow users to manage their issues.
- Allow users to be managed by users.
- (Managing each of these includes listing, adding, creating, editing, and deleting).
Visit the project site at: http://cricket.codeplex.com.
Download the source code from this post at: http://cricket.codeplex.com/SourceControl/changeset/changes/a115ce901573
Cricket.Net: Part 1 – Setting up the initial project
Oct 12th
Summary
Cricket.Net is a new open source project that I’ve started on Codeplex. It will be a web application that will be used for tracking software bugs. Cricket.Net will be written in C# using HTML5, ASP.NET MVC 3, Entity Framework 4.1 Code First, StructureMap, and the Onion Architecture. This project will be an example application to demonstrate how to use these technologies together to build a web application from the ground up.
I’ll also be going through using Mercurial both on my system and pushing changes to the Codeplex site.
Cricket.Net Series:
- Part 1: Setting up the initial project
- Part 2: Design Discussion
- Part 3: Unit Testing
Prerequisites
To get started, I’ll be using Visual Studio 2010 SP1Rel and ASP.NET MVC 3 Tools Update. Later, I’ll be using Entity Framework 4.1 Update 1 so that I can use Code First. You can either download and install Entity Framework, or we’ll attempt to install this from the Nuget package first.
Creating A New Project
Initially, I’m going to start with the basic MVC package created by Visual Studio. After this package is created, I’m going to create the Mercurial repository so that I can send the code to Codeplex.
- Open Visual Studio 2010.
- Click the File menu, then New, Project.
- In the New Project window, under Installed Templates, expand Visual C# and choose Web. Select the template called “ASP.NET MVC 3 Web Application.” The Name field will be the default name and namespace of your initial project, the Location will be the folder on your C:\ drive where to store your solution, and the Solution Name is the name of your solution folder (if you wish it to be different).

- After clicking OK, the New ASP.NET MVC 3 Project window pops up. I’m going to choose Internet Application so that the tooling will allow me to go ahead and create a Unit Test project also. I’m going to change the name of the Unit Test project to Cricket.UnitTests.

- After Visual Studio finishes creating the project, it should look like the image below. The Internet Application template that we had chosen in the previous step has added some files that will may or may not use, but for now we’ll leave these in the solution and move on to creating the Mercurial repository.

Setting up the Mercurial Repository
If you are unfamiliar with Mercurial, it is a source control application that is very fast and pretty easy to use. Before you can continue with this tutorial, you will need to install at least TortoiseHg to manage the Mercurial repository from Windows Explorer. If you’d also like to work with it from within Visual Studio, you will need VisualHg. If you’d like to know more about what Mercurial can do, check out this video from tekpub.com.
- If you still have your new solution open in Visual Studio, go to the File menu and choose Close Solution.
- Next, browse to the folder where your solution folder is located. (In my case, I need to go to the C:\Users\cjackson\Documents\All Projects\ folder)
- Right-click on the Cricket.Net folder and expand the TortoiseHg context menu and choose Create Repository Here.
- TortoiseHg will display an Init window. Click the Create button to create the repository.
- After the repository has been created, a green check mark icon will appear over the Cricket.Net folder icon.
- Open the Cricket.Net folder and then edit the .hgignore file. This file will tell the repository to ignore certain files/folders that are used by Visual Studio and do not need to be version controlled. Paste the text below into the file and save it.
# use glob syntax syntax: glob *.obj *.pdb *.user *.aps *.pch *.vspscc *.vssscc *_i.c *_p.c *.ncb *.suo *.tlb *.tlh *.bak *.cache *.ilk *.log *.lib *.sbr *.scc [Bb]in [Dd]ebug*/ obj/ [Rr]elease*/ _ReSharper*/ [Tt]humbs.db [Tt]est[Rr]esult* [Bb]uild[Ll]og.* *.[Pp]ublish.xml *.resharper
Next, I’ll save the initial project into the Mercurial repository.
- Return to the folder where your solution is stored. (C:\Users\cjackson\Documents\All Projects\ folder)
- Right-click on the Cricket.Net folder and choose Hg Commit…
- The Cricket.Net commit window will pop up. On the left pane, click the check box at the top to select all files then in the top-right pane, type in a comment for the commit. After you enter whatever comments you wish, click the Commit button to save the current state of the solution.

- Next, for new untracked files, a window may pop up asking to add untracked files. Click Add.
To save the current repository to Codeplex, follow these instructions:
- Return to the folder where your solution is stored. (C:\Users\cjackson\Documents\All Projects\ folder)
- Right-click on Cricket.Net and expand the TortoiseHG context menu and choose Synchronize.
- Under Remote Repository, change the drop down to HTTPS and enter the name of the repository so the URL looks like this (http://hg01.codeplex.com/cricket)
- Click on the
icon to push changes to Codeplex. - Enter your Codeplex username and password when prompted and the files will be uploaded to Codeplex.
Visit the project site at: http://cricket.codeplex.com.
Download the source code from this post at: http://cricket.codeplex.com/SourceControl/changeset/changes/1569d75e695b#
Configuring IIS 6 and ASP.NET MVC
Jan 28th
By default, IIS 6 does not work with ASP.NET MVC and needs to be configured to use wild-card mapping to get MVC’s routing and clean URLs to work correctly. Unfortunately, IIS 6 does take a performance hit because all requests are processed by ASP.NET. Static files, such as images, CSS, and JavaScript are processed as a dynamic page instead of a static one.
Install ASP.NET MVC
Follow the first two steps of the instructions for installing ASP.NET MVC. The third step can be ignored since Visual Studio will not be installed on the server.
Configuring ASP.NET 2.0
First thing to do is open the IIS Manager ->expand your server ->Web Service Extensions folder. Right-click on the white space under the list of Web Service Extensions and select to Add a new Web service extension…
The New Web Service Extension window will pop open. Enter “ASP.NET v2.0.50727″ as the Extension Name and click the Add button. Browse to the C:\Windows\Microsoft.Net\Framework\v2.0.50727 folder and select the aspnet_isapi.dll file. Make sure to check the “Set extension status is Allowed” button before clicking OK.
This will allow your programs to run ASP.NET 2.0, 3.0, and 3.5 versions of the .NET framework.
Configuring Your Web Application
The next thing to do is open the properties of the Web Site where your web application is. Select the ASP.NET tab and select 2.0.50717 in the ASP.NET version drop down box.
Next, click on the Home Directory tab. Click on the Configuration button. Under the Wild-card application maps area, click the Insert button. Browse to the C:\Windows\Microsoft.Net\Framework\v2.0.50727 folder and select the aspnet_isapi.dll file. Uncheck the “Verify that file exists” before clicking OK. Save your changes and your site should now be able to run ASP.NET MVC and use the routes setup by your application.
Clearing the Client Version from the Lotus Notes Directory
Jan 20th
With the latest version of Lotus Notes (8.5.1), you can now view the version of your clients by looking in the People -> by Client Version view. One problem with this, however, is that your users will show each client they have logged in as. Over the years, you may accumulate many versions for each user.
During an upgrade, you may wish to see what users are using the previous version of client against the ones who have the new version installed. But first, we’ll need to clean up the directory so we don’t see all this old version history.
To clean up these fields, you need to write an agent that will empty them for each selected person. This will allow you to run the clean up agent on only the users you wish to run it on.
Writing the agent
Open up the pubnames.ntf template file in your Notes Designer. You’ll need to go to Code and double-click on Agents to see the current agents for the template.
We’ll create a new agent and give it a name. Below is the code for the agent. Copy and paste it in the Designer.
Option Public
Option Declare
Sub Initialize()
'Declare.
Dim s As New NotesSession
Dim db As NotesDatabase
Dim dc As NotesDocumentCollection
Dim doc As NotesDocument
'Initialize.
Set db = s.Currentdatabase
Set dc = db.Unprocesseddocuments
Set doc = dc.Getfirstdocument()
While(Not(doc Is Nothing))
If (doc.Form(0) = "Person") Then
Call doc.Removeitem("ClntBld")
Call doc.Removeitem("ClntDate")
Call doc.Removeitem("ClntDgst")
Call doc.Removeitem("ClntMachine")
Call doc.Removeitem("ClntPltfrm")
Call doc.Save(False, False, False)
End If
Set doc = dc.Getnextdocument(doc)
Wend
End Sub
Now, after you refresh your names.nsf file, you can go to the Action menu and find your agent. Running the agent will only process those Person documents that you have selected.
How to setup CodeIgniter
Jun 30th
Introduction
This article explains the process I go through to setup the CodeIgniter framework and how to configure it so that I can start developing an application.
What is CodeIgniter?
If you don’t already know, CodeIgniter is an MVC framework built on PHP. There are many features and built in functions that make building a web application fairly easy. You can download the current version, 1.7.1, from CodeIgniter.com. Also, check out the very well documented User Guide.
If you are interested in using the Zend library of tools with CodeIgniter, please check out How to use Zend_Search_Lucene with CodeIgniter.
Step-By-Step
For this tutorial, I’m using a WAMP Server running on my local Windows computer. You could just as easily perform these same actions on a web server running PHP, although the paths may be different depending on if you are using Windows or a Linux based server.
Step 1
Download the latest version of CodeIgniter (1.7.1).
Before extracting the files to your server, let’s talk about where to put the files. For security purposes, it is recommended to place the CodeIgniter files outside the path of your web server so those files cannot be accessed by typing in a URL. So, if I access my web server by typing in http://localhost and the web server loads the website at C:\wamp\www\, then I want to place the System folder of CodeIgniter inside the C:\wamp\ folder. Go ahead and extract the System folder from the download package to the C:\wamp\ folder. You can place the System folder in the C:\wamp\www\ folder if you desire. Just make sure to adjust the path name later on.
Step 2
Next, I have decided that I may want to use CodeIgniter for several applications that I develop. To save on hosting space, I can setup all CodeIgniter applications to use the same core framework. First, we need to move some files around from their default locations.
Open the C:\wamp\system\application\ folder. You should see several folders listed here. The default CodeIgniter application is setup for a single application. We will be changing it to run multiple applications. Create a new folder called baseApplication_1234 or something unique. Make a copy of the index.html file and paste it inside baseApplication_1234. Next, move all of the folders located at C:\wamp\system\application\ into C:\wamp\system\application\baseApplication_1234\.
We will configure this base application with all of our default settings that we want to use for all CodeIgniter applications. Then, when you want to make a new application, you can simply copy the baseApplication_1234 and rename it.
Step 3
Next, we will configure the CodeIgniter application files.
Browse to C:\wamp\system\application\baseApplication_1234\config\ and open the following:
autoload.php
Modify line 42 to show:
$autoload['libraries'] = array('database', 'session');
config.php
Modify line 14 to show (change localhost to your domain name):
$config['base_url'] = "http://localhost/";
Modify line 26 to show:
$config['index_page'] = "index.php?";
This line will be very important for the way our URLs are displayed later on.
Modify line 44 to show:
$config['uri_protocol'] = "QUERY_STRING";
Modify line 57 to show (this is optional if you want a .html to be shown on the end of your URLs):
$config['url_suffix'] = ".html";
Modify line 220 to show (add your own unique value within the quotes):
$config['encryption_key'] = "12345";
Modify lines 234 – 241 to show:
$config['sess_cookie_name'] = 'ci_session'; $config['sess_expiration'] = 7200; $config['sess_encrypt_cookie'] = TRUE; $config['sess_use_database'] = TRUE; $config['sess_table_name'] = 'ci_sessions'; $config['sess_match_ip'] = TRUE; $config['sess_match_useragent'] = TRUE; $config['sess_time_to_update'] = 300;
This will require that we have a database and a table within called ci_sessions. This table will need to have certain fields that CodeIgniter will be attempting to write session data to for each users who visits your site. I’ll explain more later on.
database.php
Modify lines 41 – 45 to show:
$db['default']['username'] = "dbuser"; $db['default']['password'] = "mypassword"; $db['default']['database'] = "mydbname"; $db['default']['dbdriver'] = "mysql"; $db['default']['dbprefix'] = "dev_";
You will need to enter your correct username, password, database name, and prefix if you wish to use one. If you use a prefix, you will need to have a table called dev_ci_session instead of ci_session.
routes.php
For the base application, the routes.php file is probably OK. There are two lines that need to be modified when you build an application.
$route['default_controller'] = "welcome"; $route['scaffolding_trigger'] = "12345";
Again, use some unique value for the scaffolding_trigger. If you use a value that is hackable or nothing at all, your application will have a possible security hole. The default controller name can be changed here as well.
Step 4
There are two helper files that I add to my projects that help translate the URLs the way I like them (http://localhost/controller/action/id.html).
MY_form_helper.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('form_open'))
{
function form_open($action = '', $attributes = '', $hidden = array())
{
$CI =& get_instance();
if ($attributes == '')
{
$attributes = 'method="post"';
}
//Modify ->site_url to ->item('base_url').$action
$action = ( strpos($action, '://') === FALSE) ? $CI->config->item('base_url').$action : $action;
$form = '<form action="'.$action.'"';
$form .= _attributes_to_string($attributes, TRUE);
$form .= '>';
if (is_array($hidden) AND count($hidden) > 0)
{
$form .= form_hidden($hidden);
}
return $form;
}
}
?>
MY_url_helper.php
<?php
function redirect($uri = '', $method = 'location', $http_response_code = 302)
{
$CI =& get_instance();
switch($method)
{
case 'refresh' : header("Refresh:0;url=".site_url($uri));
break;
default : header("Location: ".$CI->config->item('base_url').$uri, TRUE, $http_response_code);
break;
}
exit;
}
?>
Create these files and save them to C:\wamp\system\application\baseApplication_1234\helpers\. These functions will override the original CodeIgniter functions and fix some URL rewriting issues.
Step 5
Enabling URL rewriting may depend if your server supports it. Apache has a rewrite_module that must be enabled before this will work. Most hosting providers should already have enabled URL rewriting.
Create a new text file called .htaccess and paste the following code into it:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L]
This will redirect all requests on your domain back to the index.php file, unless the actual path does happen to exist, then the server will serve up whatever file/directory is at that location.
Notice the ? behind index.php. The web server is rewriting the pretty URL into a QUERY_STRING that CodeIgniter is expecting and passes in the controller and action as variables such as index.php?var1=this&var2=that.
The .htaccess file should be stored in the C:\wamp\www\ folder or the root of your web site.
Step 6
Next, the database will need to be created and the ci_sessions table created to store the user sessions to.
After you create the MySQL database, run the following SQL and it will create the table for you:
CREATE TABLE `dev_ci_sessions` ( `session_id` varchar(32) NOT NULL, `ip_address` varchar(15) NOT NULL, `user_agent` text NOT NULL, `last_activity` datetime NOT NULL, PRIMARY KEY (`session_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Make sure to remove the “dev_” if you did not setup a dbprefix.
Step 7
Next, for testing purposes, we’ll setup the baseApplication_1234 web application and attempt to run it.
Find the index.php file that came with the CodeIgniter 1.7.1 download. It should be located in the same folder as the system folder and user_guide folder. Copy this file into your web site root at C:\wamp\www\.
Modify line 26 as shown:
$system_folder = "c:/wamp/system";
Modify line 43 as shown:
$application_folder = "application/baseApplication_1234";
This is the line that specifies which application to load.
This index.php file is the main entry point for the application. It will use these modifications to find the C:\wamp\system\ folder and run the correct web application. The only other files that need to be in the C:\wamp\www\ folder are files that HTML needs to be able to access via URLs such as images and JavaScript.
Conclusion
That should be everything. You can now try to open your web application by going to the URL, http://localhost. The default controller is Welcome and the default action is Index, so you can also test http://localhost/welcome/index.html to verify URL rewriting works. Remember the “.html” can be used to hide that PHP is running your web site. In reality, index is an action of the welcome controller and doesn’t need the “.html” to be there at all.
If you run into problems, you can add this line to an action or the controller’s constructor for further information:
$this->output->enable_profiler(TRUE);
Be sure to shut this down when not needed, or it could give your users information you may not wish them to have.
How to use Zend_Search_Lucene with the PHP framework CodeIgniter
Feb 17th
If you’ve heard the buzz about Apache’s open source search engine, Lucene, then you probably already know what a great search engine tool it is. The search engine is fast, has ports to various languages, and was written to be able to share the search index between the different Lucene ports.
The PHP version of Lucene is packaged in the Zend frameworkand is called Zend_Search_Lucene. When it comes to PHP frameworks, I tend to prefer using CodeIgniteras opposed to Zend. So, you might ask, how can you use a favored framework such as CodeIgniter with the power of Lucene’s search capabilities?
Install CodeIgniter 1.7.1
I downloaded a copy of the latest version of CodeIgniter 1.7.1 and configured it to run the default welcome action. Next, I made a copy of the welcome controller and view to test my indexer and search actions (which we’ll get to in just a minute).
Install Zend Framework 1.7
Next, I downloaded the latest version of the Zend Framework 1.7.5. After extracting the zip file, copy the Zend folder inside ZendFramework-1.7.5/library and paste it into the CodeIgniter framework under System/application/libraries.
Create A Zend Loader Class
The next thing that needs to be done is create a loader file to load the Zend library classes in CodeIgniter. This tutorial also explains how to create this loader class. This file below is named Zend.php and should be located in the System/application/libraries folder of CodeIgniter.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class CI_Zend
{
function __construct($class = NULL)
{
// include path for Zend Framework
// alter it accordingly if you have put the 'Zend' folder elsewhere
ini_set('include_path', ini_get('include_path') .
PATH_SEPARATOR . APPPATH . 'libraries');
if ($class)
{
require_once (string) $class . EXT;
log_message('debug', "Zend Class $class Loaded");
}
else
{
log_message('debug', "Zend Class Initialized");
}
}
function load($class)
{
require_once (string) $class . EXT;
log_message('debug', "Zend Class $class Loaded");
}
}
//End of File: Zend.php
Creating An Indexer
Now we will create the search index. For demonstration purposes, I’m going to place the indexer and search functions in the same controller. You should have your indexer in a separate controller with security that will keep everyone from being able to run it.
We’ll start with the copy of the welcome controller, which I named home.php. After changing the class name and function calls to home instead of welcome, the contents of the file should look like this. Also, add the sanitize function below.
<?php
class Home extends Controller
{
function Home()
{
parent::Controller();
}
function index()
{
$this->load->view('home_view');
}
function sanitize($input)
{
return htmlentities(strip_tags($input));
}
}
/* End of file home.php */
/* Location: ./system/application/controllers/home.php */
Now, we can just replace the contents of the index() function with the following.
$this->load->library('zend', 'Zend/Feed');
$this->load->library('zend', 'Zend/Search/Lucene');
$this->load->library('zend');
$this->zend->load('Zend/Feed');
$this->zend->load('Zend/Search/Lucene');
//Create index.
$index = new Zend_Search_Lucene('c:\wamp\www\ci\tmp\feeds_index', true);
$feeds = array(
'http://www.cmjackson.net/feed/rss/',
'http://andrewmjackson.com/feed/rss');
//grab each feed.
foreach($feeds as $feed)
{
$channel = Zend_Feed::import($feed);
echo $channel->title().'<br />';
//index each item.
foreach($channel->items as $item)
{
if ($item->link() && $item->title() && $item->description())
{
//create an index doc.
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::Keyword(
'link', $this->sanitize($item->link())));
$doc->addField(Zend_Search_Lucene_Field::Text(
'title', $this->sanitize($item->title())));
$doc->addField(Zend_Search_Lucene_Field::Unstored(
'contents', $this->sanitize($item->description())));
echo "\tAdding: ". $item->title() .'<br />';
$index->addDocument($doc);
}
}
}
$index->commit();
echo $index->count() .' Documents indexed.<br />';
This indexer will read in the RSS feeds from this website as well as my brother’swebsite and index the contents of the feed. When the index is created, you must specify a location to store the index. These are binary files that Lucene creates and it does not require a database for storage.
In this article, the author further explains the fields of the index document and when each should be used.
Feeds are not the only resource that Lucene can index. Web sites, databases, Microsoft Office documents, etc. Find out more information on Zend Search Lucene in the Zend Framework Manual .
A Basic Search
After running the indexer, you are ready to try searching the documents that are indexed. For demonstration purposes, I’ve added another function to the same controller as the index called search(). This function does not get the results of a form, but instead simulates a string query as if it were from a form.
function search()
{
$this->load->library('zend', 'Zend/Search/Lucene');
$this->load->library('zend');
$this->zend->load('Zend/Search/Lucene');
$index = new Zend_Search_Lucene('c:\wamp\www\ci\tmp\feeds_index');
$query = 'new movie';
$hits = $index->find($query);
echo 'Index contains '. $index->count() .
' documents.<br /><br />';
echo 'Search for "'. $query .'" returned '. count($hits) .
' hits<br /><br />';
foreach($hits as $hit)
{
echo $hit->title .'<br />';
echo 'Score: '. sprintf('%.2f', $hit->score) .'<br />';
echo $hit->link .'<br /><br />';
}
}
This function loads the same index that we previously created and searches for the key phrase ‘new movie’. The results that are returned are sorted by their score ranking. To make the search results look more like google, styling could be added as well as formatting the result entries, but this gives you a good idea of the basic functions of the search engine and how it works.
Audiobooks On Your IPod
Jan 30th

If you like to listen to audio books on your IPod, you may be wondering how you can load your own audio books from MP3 files and have them show up under the “Audiobooks” category on your IPod.
If you load your audiobook files onto your IPod as MP3s, they will show up under Music and not Audiobooks. The MP3 files need to be converted to the M4B format.
There are a couple different ways to make M4B files. I’ve listed two methods below. Depending on if you want to combine your files into fewer files will determine which method you should probably use.
Using Itunes to convert your files
The easiest method is to use Itunes to do the converting. To do this, you need to import your files into Itunes as MP3 files. Once they are imported, find them in the list of Music (Hopefully they are tagged correctly to make it easy to find them). Next, select all the files you wish to convert and right-click on your selection and select the option “Convert selection to AAC”. This will convert your audio files to M4P files. Then, once they have all been converted, just remove the MP3 and M4P versions from your music list, rename all the converted M4P files to M4B and reimport them into Itunes. Now, your audiobook files should be under the “Audiobooks” category.
Using a third-party program
I have also found the “MP3 to iPod Audio Book Convert” useful when I want to combine multiple files into one M4B. You can add all the MP3 files you want and it will process them all into one M4B for you. This program allows you to do some limited tagging on the newly created file as well.
One note on using this converter: I’ve found that my Ipod sometimes chokes on audiobooks that are only one large file. If you stop listening to the audiobook and switch over to music and then go back, the marker that holds your place sometimes resets to the beginning. This can be annoying when you are near the end and have to fast-forward for several minutes to get back to your place. I’ve found that combining your files works best if you limit the size to around the length of a CD or if you break your audiobooks up by making each chapter its own file.






