Web Design, Programming, Tutorials
ASP.NET MVC Full URL From A Controller
Oct 16th
In working with ASP.NET MVC, I came across the need to send an email with the URL of a document that is to be approved. There are helper functions accessible from the View to build an ActionLink or get the URL of an action, but I had problems finding how to build this URL from within a controller. Here is the simple code that I finally pieced together to do what I wanted:
Dim link As String = HttpContext.Request.Url.Scheme + _
"://" + HttpContext.Request.Url.Authority + _
Url.Action("ActionName", "ControllerName", New With {.id = idOfDocument})
HttpContext.Request.Url.Scheme returns “http” or “https”, which ever one you’re using.
HttpContext.Request.Url.Authority returns the Base Url of your application.
And, the Url.Action method creates the Url to the Controller, Action, and ID of the document that is being sent out for approval.
SOLID Programming Principles
Sep 4th
The SOLID Principles of programming are a good set of rules to follow when you are designing and developing an object oriented application.
S
Single Responsiblity Principle – A class should do one thing and do it well. If you can think of more than one reason to change a class, then it has more than one responsibility.
O
Open / Closed Principle – A class should be open for extension but closed for modification. Classes should be designed so they can be inherited from without having to modify them.
L
Liskov Substitution Principle – Derived classes must be substitutable for their base class. When a class method accepts an object, the method should be able to accept children of that object without knowing anything about the children.
I
Interface Segregation Principle – Interfaces should be fine grained and only provide for your needs. When building your interfaces, you should not add more functionality than what you need at the time.
D
Dependency Inversion Principle – High level modules should not depend on low level modules, but instead both should depend on abstractions. Interfaces should be used as placeholders and factory classes should be used to instantiate objects. This causes loose coupling between classes.
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.
Understanding Polymorphism
Jun 30th
Introduction
This article will explain what polymorphism is and how it can help you design and reuse code in Object-Oriented Programming. You’ll learn what polymorphism is and how to use it. In the following examples, I’ll be using Visual Basic .NET, but any language that supports Object-Oriented Programming should be able to use these same techniques.
If you have not already read the articles on Understanding Objects and Understanding Inheritance, please check them out as some of the terms and other information explained there will be used in this article.
What is Polymorphism?
According to dictionary.com, the definition of Polymorphism is as follows:
3. Biology The occurrence of different forms, stages, or types in individual organisms or in organisms of the same species, independent of sexual variations.
So, how does this relate to programming? We’ll develop Objects that have different forms of the same “species”. The great thing about Polymorphism is that when you are building your program, you assume you are working with the “species” Object, but you actually use an individual “organism” Object. This allows the “organism” Objects to be exchanged in the code for one another.
In other words, say we have a Parent Class called Animal and two Child Classes that Inherit from Animal called Cat and Dog. The Cat and Dog are both Animals, so they will inherit all the properties and methods that an Animal has. If we wanted to store an array of Cats or Dogs, we could just declare the array to be of type Animal and then we’d be able to store either Cats or Dogs within the array. That is Polymorphism.
Parent Classes and Interfaces
Both Parent Classes and Interfaces can be used to setup an Object as the “species” level. Parent Classes have been explained in Understanding Inheritance.
What is an Interface?
An Object’s Interface is how you communicate or interact with that Object. Interfaces in programming terms are similar to a Class Object, but an Interface does not implement the properties or methods it declares, it simply declares them.
Why is this useful? Interfaces force the Class Objects that implement the Interface to have all of the properties and methods of the Interface. So, the following IAnimal Interface could be implemented by Cat and Dog to force them to implement the properties, Height and Weight, along with the methods, Eat and Drink.
Public Interface IAnimal Property Height() As Integer Property Weight() As Integer Function Eat(footType As String) As Boolean Function Drink(drinkType As String) As Boolean End Interface
Interfaces can be used with Parent or Child classes and multiple Interfaces can be used by one Class. Also, in some cases, you may want to use an Interface in place of a Parent Class, forcing all properties and methods to be fully implemented in each class. Another thing to keep in mind is that a Parent Class that implements the IAnimal Interface does not have to fully implement all properties and methods. Instead, the Parent Class could implement those common properties or methods that will not change no matter the Child Class, and leave the others to be implemented by the Child Class. In VB.NET, you can use the MustOverride keyword on the function declaration. This will make the Parent Class an Abstract class.
Public MustInherit Class Animal Implements IAnimal 'Data Members. Private _height As Integer Private _weight As Integer Public Property Height() As Integer Implements IAnimal.Height Get return _height End Get Set(ByVal Value As Integer) _height = value End Set End Property Public Property Weight() As Integer Implements IAnimal.Weight Get Return _weight End Get Set(ByVal Value As Integer) _weight = Value End Set End Property 'Abstract Functions. Public MustOverride Function Eat(foodType As String) As Boolean Implements IAnimal.Eat Public MustOverride Function Drink(drinkType As String) As Boolean Implements IAnimal.Drink End Class
Now, things are looking pretty good. We can force are Classes to implement certain properties and methods, but there is still one downside. Our methods are passing in a String value for foodType and drinkType. What if we wanted to use a different data type, such as our own Object that holds other properties for foodType? We don’t want to have to modify the Interface or Parent Class each time this may change. What we want to do is make the Class or Interface Generic.
How do I make my Interface or Class Generic?
Making a Class or Interface Generic will make your code more reusable. When you make a Class or Interface Generic, you don’t have to know what type of data you will be using with the Object until you declare or create an instance of the Object. So, various programs could use the same Class Object, but passing in different data types to work with when instantiating the Object.
Public Interface IAnimal(Of T) Property Height() As Integer Property Weight() As Integer Function Eat(foodType As T) As Boolean Function Drink(drinkType As T) As Boolean End Interface
T is a place holder for the type of data we will declare later on. Notice in the declaration of the Interface and both methods, Eat and Drink, T is used. Now, when we create a Cat or Dog using the IAnimal Interface, we can determine what type of data will be used for foodType and drinkType.
Public Class Cat Implements IAnimal(Of String)
This would declare a Cat to use a String data type to store the foodType and drinkType.
Public Class Dog Implements IAnimal(Of Integer)
And this one would declare a Dog to use an Integer data type to store the foodType and drinkType.
We could also define our own complex Class Object as the data type.
Advantages of using Polymorphism, Interfaces, and Generic Objects
- Polymorphism allows you to use similar types of data together. It also can be used to improve system maintenance, reuse code, and easily setup testing Objects that mimic communications with databases and other resources.
- Interfaces force the implementation of properties and methods on Objects that implement the Interface.
- Generic Objects allow more reusable code when building Class Objects and Interfaces.
Understanding Inheritance
Jun 26th
Before we get started on the topic of Inheritance, please check out Understanding Objects. Now, onward…
According to dictionary.com, one definition of inheritance is:
2. the genetic characters transmitted from parent to offspring, taken collectively.
This definition also fits with Object Oriented Programming. Remember, that our Objects mimic those found in real-life and just like in real-life, Objects can have Parent Objects or Children Objects. Inheritance is the process of obtaining the properties and methods from another Object. The Child Object inherits these properties and methods from the Parent Object.
Using Inheritance, we can extend the functionality of a Class Object without having to modify that Object. This helps you make your own code more reusable as well as gives you the ability to improve other people’s Class Objects.
Access Modifiers
I had talked breifly about Access Modifiers in Understanding Objects. When building Parent and Child Class Objects, you will most likely be using all three: Private, Public and Protected.
A Child Class that inherits from a Parent does not gain access to all of the Parent’s properties and methods. The Parent uses Encapsulation and Data Hiding to protect it’s Private properties and methods. The Child Class can only access those properties and methods that are Protected or make up the Public Interface for the Parent Class.
The Protected access modifier acts similar to Private, keeping the properties and methods hidden from outside use, but it will allow Child Class Objects access to them.
Below is an example of a Parent Class:
Public Class MyParent
Private _hiddenVariable As String
Private _errors As String
Public Sub New()
_hiddenVariable = “”
_errors = “”
End Sub
Protected Sub AddError(error As String)
_errors += error + VbCrLf
End Sub
Public Function GetErrors()
Return _errors
End Function
End Class
Below is an example of a Child Class:
Public Class MyChild
Inherits MyParent
Public Sub New()
MyBase.New()
End Sub
Public Function MyNewFunction()
Return "It Worked!"
End Function
End Class
In the above examples, the Parent Class has a couple Private string variables. The subroutine, AddError, would normally be a Private function, but since we want the Child Class to have access to this function, we must change it to Protected.
There are two methods on MyParent’s Public Interface: New() and GetErrors().
The MyChild Class uses Inheritance to extend MyParent’s functionality. In VB, the Inherits keyword is used to tell which class is the Parent. Within MyChild, all of the functions on the Public Interface for MyParent as well as the Protected function, AddError, can be accessed.
There are three methods on MyChild’s Public Interface: New(), GetErrors(), and MyNewFunction().
Overriding Methods
When developing a Child Class, you may find that you need to change the way that one of the Parent Class’ methods work. To do this, you must override the method in the Child Class. When an instance of the Child Class is used, the overridden function would be used within the Child Class instead of the Parent Class.
Some languages allow you to override the function by simply declaring the same function in the Child as in the Parent. In VB, you would use the Overrides keyword to declare you are overriding a function.
Protected Overrides Sub AddError(error As String)
_errors += "MyChild:" + error + VbCrLf
End Sub
This subroutine would be placed in the MyChild Class and would override the AddError subroutine found in the MyParent Class. Errors that occur in the Child Class would show “MyChild:” in front of them.
Also, the Child method that overrides the Parent, can also call the Parent’s method. This allows you the power of performing some small change without having to re-implement the entire method in the Child Class. In VB, you would use the MyBase keyword to signal you are looking for the Parent Class version of the method.
MyBase.AddError("my error")
Abstraction
Abstraction is the process of declaring a Class, property or method without giving the details on the implementation of that element. A Parent Class can use Abstraction to declare that a function must be present in any Child Class of that Parent. The Child Class can then either define what the method does or declare the method as Abstract also.
If a Class is Abstract, then an instance of that Class can not be created. You must instead, access the Class through one of it’s children.
In VB, you can force a Class to be Abstract by using the MustInherit keyword.
Public MustInherit Class MyParent
Below is an example of the MyParent Class if we wanted to make the AddError function Abstract.
Public Class MyParent
Private _hiddenVariable As String
Private _errors As String
Public Sub New()
_hiddenVariable = “”
_errors = “”
End Sub
Protected MustOverride Sub AddError(error As String)
Public Function GetErrors()
Return _errors
End Function
End Class
Advantages of Inheritance, Abstraction, and Overriding Methods
- Inheritance helps you extend the functionality of your own classes or other people’s classes.
- Abstraction can be useful if you need multiple Classes that have similar properties and methods. You can create an Abstract Parent Class with the common properties and methods and have the Children Classes hold the unique properties and methods.
- Overriding Methods allows you to change the functionality of a Parent Class without modifying the Parent’s code.
Understanding Objects
Jun 22nd
Objects are all around us; the monitor your looking at, your IPod, your cat or dog, etc. Programming objects mimic those found in real life. When you use an object, like an IPod, there are certain things you can do with it. The object has an Interface, or way for you to interact with the object. The object also has properties that work internally that you do not have direct access to, such as the current song playing, the next song to play, the current play position, etc.
Programming Objects store the state of an Object in internal variables and has methods that are used to access that information.
Access Modifiers
Access modifiers let you set the access level of class properties or functions.
- Private – Only this class’ functions can use the item.
- Public – This class’ functions and any outside source can use the item.
- Protected – This class or any Child Class can use the item.
Encapsulation
In Object-Oriented Programming, your Class files have internal data members, or variables. These variables hold properties of the Object. By setting your Class variables to Private or Protected, you ensure that anyone using your Class cannot access the data directly. If the variable needs to be accessed outside the Class, then Get or Set functions can be setup to allow access. This ensures that your Class’ data cannot be changed without your knowledge. This is called Encapsulation and allows for Data Hiding.
Imagine a radio Object in the example on the right-side where the two Class variables (in green) are Encapsulated in the object and surrounded by the Public Interface (in blue) to those variables.
One of the benefits of using Get and Set functions to access your Class variables is that you can do some validation to make sure the data is valid before storing it.
Public Interface
Each object, or Class file, you create will have a Public Interface that allows your program, or other classes, to communicate with it. By using the Public access modifier, you allow anyone who creates an instance of your Class to access that Class variable or function.
Advantages of Object Oriented Programming
- OOP creates a natural structure to your code mimicking real-world examples we can see.
- Code that deals with an Object is grouped together making it easier to reuse and maintain.
- Encapsulation allows for greater control over what variables can store.
New Theme And Other Changes
Jun 21st
I decided to update the site’s theme again. I was already growing tired of the old one. The site looks cleaner due to the spacing and fonts used.
I’ve also added some new items:
1) a code highlighting plug-in to make code snippets more visible.
2) a tag cloud box.
3) a website links box where I can list some of my commonly used websites.
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.
String Replace Function For Lotus Script
Jan 28th
Here is a handy function that I sometimes use in my Lotus Script programs.
'=============================================================================== ' +----------------------------------------------------------------------------+ ' | Function: strreplace ' +----------------------------------------------------------------------------+ ' | Accepts: src, the value to search for to replace. ' | dest, the value to replace with. ' | arg, the string to search within. ' +----------------------------------------------------------------------------+ ' | Description: ' | Replaces all occurances of src with dest in the string arg. ' +----------------------------------------------------------------------------+ '=============================================================================== Public Function strreplace(Byval src As String, Byval dest As String, Byval arg As String) As String 'Declare variables Dim pos As Integer 'Initialize pos = Instr(arg, src) 'Loop through the string While (pos > 0) arg = Left(arg, pos - 1) + dest + Mid(arg, pos + Len(src)) pos = Instr(pos + Len(dest), arg, src) Wend 'Return the replaced string strreplace = arg End Function
Here is an example of how to use the function:
newString = strreplace("WORLD", "World", "Hello WORLD!")
The newString variable would contain “Hello World!”
New Years Resolutions
Jan 14th
Here are a few things I’m going to try and work on for this year:
- Use this website more
- Finish some old projects
- Work on writing more
- Lose weight
- Read more books