Refactoring WordPress

I like WordPress because it’s easy to install and use. But I really dislike the way it’s put up.

I’m not going into an exhaustive critic here because I really bend to the dedication coders devote to WordPress. I’ll just say what refactoring WordPress needs.

  1. the architecture must conform to a clean design, with the details hidden in lower layers, but with the mechanics shown in higher ones.
  2. For example, if you open the wordpress/index.php file this is what you find:

    <?php /* Short and sweet */ define('WP_USE_THEMES', true); require('./wp-blog-header.php'); ?>

    which is certainly short and weird for the main code of any software! We shoud see the famous loop here, shouldn’t we?

  3. the documentation must be organized like any other software documentation: A user guide + a developer guide + an API reference + an instant guide.
  4. For example, at this moment in the docs main page there are 114 content links in 8 categories.

  5. any given external name must get an expert approval, before it’s used for the first time. A name is to be considered external if it’s going to be used (or understood) by someone else, be they persons or software, outside the smallest scope where it appears for the first time.
  6. For example, digging in the code I found this function name: maybe_create_table (at wordpress /wp-admin /upgrade-functions.php :332). By its name I’d say that sometimes the function creates a table, and other times it does not. This is true with respect to the chosen implementation, which has been optimized for not creating a table if it already exists. But it’s false with respect to the context, because before executing the function, a table may exist or not, but after executing it, a table will exist for sure. So, maybe_create_table should be renamed as always_create_table, or just create_table. In case of collision with a previous create_table function, it could be named create_table_if_needed. And it’s generally a good idea to sort the words of a multi word name such that in a sorted list of similar objects, similar/related entries will appear near to each other.

Accessing an Oracle table

A Lotus Connector is a powerful means for accessing an Oracle table. To have it work properly, the machine from which the Lotus code is being executed (wether a Domino server for Web operations or a Notes client) needs a working copy of the Oracle client software. The Lotus Conector will simply use some client libraries for accessing the networked database, so the client needs not be running before executing the Lotus code, nor it needs any custom configurations for accessing the database, like any changes to the tnsnames.ora file.

In fact, all of the conection data that would usually go into the tnsnames.ora configuration file, can be much more conveniently stored inside a LotusScript library, like the following

'Connection_Oracle:  

Option Public 
Option Declare  

Const connection_Host     = "172.18.32.51" 
Const connection_Port     = "1525" 
Const connection_SID      = "extprd" 
Const connection_UserId   = "Notes Log" 
Const connection_Password = "Notes Log"  

Dim connection_Server As String  
Sub Initialize
	connection_Server = {} _
	& {(DESCRIPTION=} _
	& {(ADDRESS_LIST=} _
	& {(ADDRESS=} _
	& {(PROTOCOL=TCP)(Host=} & connection_Host & {)(Port=} & connection_Port & {)} _
	& {)} _
	& {)} _
	& {(CONNECT_DATA=} _
	& {(SID=} & connection_SID & {)} _
	& {)} _
	& {)} 
End Sub

Booking a company ID

This is a very simple use of the Lotus Connector clockwork.
There is a SAP application where companies are added to a database using a SAP data entry screen. For some reason, the time at which all the needed data is available, is too far in the future (;-), and some guy needs the company ID as soon as possible, well before the SAP application will provide one.

Behind the scenes, the SAP application returns as a company ID the record ID of that company into the companies Oracle table. Finally that record ID is a value of an Oracle sequence, which is incremented whenever a new record is added to the companies table. So it is possible to book a company ID, simply by incrementing the sequence. This means that no record is added to the database, but that ID is unique and will never be used for any other record.

'BookCompanyID:  

Option Public 
Option Declare  

Uselsx "*LSXLC"  
Use "Connection Oracle"  

Function BookCompanyID As Long
	On Error Goto HandleError

	Dim session As New LCSession
	session.ClearStatus
	Goto Begin

HandleError:
	Dim errmsg As String
	errmsg = "Error " & Err & Chr$( 10 ) _
	& Getthreadinfo( 1 ) & ":" & Erl & Chr$( 10 )

	If session.Status <> LCSUCCESS Then
		errmsg = errmsg & session.GetStatusText
	Else
		errmsg = errmsg & Error$
	End If
	Error Err, errmsg  

Begin:
	Dim sqlNextval As String
	sqlNextval = { SELECT SQ_COMPANIES.NEXTVAL FROM DUAL }

	Dim connection As New LCConnection( "oracle8" )
	connection.Server = connection_Server
	connection.UserId = connection_UserId
	connection.Password = connection_Password      
	
	'-------------------------------------------------------------------------------------------     connection.Connect
	Dim fields As New LCFieldList
	Call connection.Execute( sqlNextval, fields )
	Dim nextVal As LCField
	Set nextVal = fields.Lookup( "NEXTVAL" )
	Call connection.Fetch( fields )
	BookCompanyID = nextVal.Value( 0 )

Done:
	connection.Disconnect     
	'-------------------------------------------------------------------------------------------  

End Function

CRC32

A CRC is a number which is supposed to change accordingly to the string its computed upon. So it can be used to detect if the user made changes to a chosen subset of the fields of a document.

When saving the document, just join the text values of the fields in an ordered manner, then get the CRC of that string and store it as a new field value. When checking the document for changes to those fields, make the string again and get its CRC. If the saved CRC and the one just computed are equal, then you should be reasonably sure that those field values have not changed, but if the CRC does change, then you can be completely sure that those field have changed as well!

A CRC32 class comes with the java.util.zip package, and LS2J can be used to access and use it.

Here is the code for a Java library, name it CRC32 Java

import java.util.zip.CRC32;

public class StringCRC32 {

    public static String StringCRC32 ( String s )
    {
        byte[] b = s.getBytes();

        CRC32 crc = new CRC32();

        for ( int i=0; i<b.length; i++ )
        {
            crc.update( b[i] );
        }

        return Long.toString( crc.getValue() );
    }

}

And here is a LS2J wrapper, just for making it simpler to use in LotusScript. It’s a LotusScript library and you should name it CRC32

'CRC32:

Option Public
Option Declare

Use "CRC32 Java"
Uselsx "*javacon"

Function StringCRC32( aString As String ) As String
    Dim jSession As JavaSession
    Set jSession = New JavaSession
    Dim jClass As JavaClass
    Set jClass = jSession.GetClass( "StringCRC32" )
    StringCRC32 = jClass.StringCRC32( aString )
End Function