Monday, June 28, 2010

Tracking Customer Companies in OTRS.

I have been playing abound with OTRS for the past few days and ran into a bit of a snag.  I installed it from the Ubuntu repositories but noticed that the Customers can't be linked to the Companies witch would be a useful feature.  I also found out after some digging that there was no option in the SysConfig to fix this.  I found the setting by manually editing the config files but this was of limited use.  In the end I had to make a few manual edits to make the system work as expected.  I outlined the changes below to the base 2.4.7 install.

First open a terminal and cd to your otrs install directory.
cd /usr/share/otrs

Enable CustomerCompanySupport
sudo vim Kernel/Config.pm
Add the following line inside the sub Load method.
# Enable Customer Company linking.
$Self->{CustomerUser}->{CustomerCompanySupport} = 1;

Run the mysql client and add a field to the customer table.
mysql -u root -p
use otrs2;
alter table customer_user add column company_id varchar(100);
exit

Register the extra row with the editor.
sudo vim Kernel/Config/Defaults.pm
Find the CustomerUser variable and then the Map array within it.  Add the following line after the UserCustomerID field.
[ 'UserCompanyID',  'CompanyID',  'company_id',  0, 1, 'var', '', 0 ],

Change the company dropdown list to trigger on the new CompanyID field.
sudo vim Kernel/Modules/AdminCustomerUser.pm
Look for the reference to UserCustomerID and change it to UseCompanyID. It should look like this now.
$Entry->[0] =~ /^UserCompanyID$/i

Change the dispaly logic to match against the new CompanyID.
sudo vim Kernel/System/CustomerUser.pm
Look for the reference to UserCustomerID and change it to UseCompanyID. It should look like this now.
CustomerID => $Customer{UserCompanyID},

You can now restart apache and the changes should show up.
sudo /etc/init.d/apache2 restart

Thursday, May 6, 2010

Adobe Photoshop CS5 Content Aware Fill

I posted an article previously about the Resynthesizer plugin for GIMP.  I took the same pictures as before and did the same edits this time with the CS5 Content Aware Fill and here are the results.  Again I will point out that these pictures are doing a "Single Pass" without doing any manual edits or touchups and are just a test of the Content-Aware logic.



IMG_1065
IMG_1069

Wednesday, April 21, 2010

Extra BoardGameGeek Record a Play links.

This is a simple Greasemonkey script that adds "Record a Play" links to the played games lists. This is useful when browsing your friends Recent Plays list as it allows you to directly add a play from the page without having to first open the game. It also sets the play date to that of the original item so if you both played the same game its a simple two click to copy their play to your own account.

A picture is worth a thousand words:

Installation Instructions:
Install the Greasemonkey plug-in for your web browser. Or use this version for Safari(Click NinjaKit for Safari.)
Restart your web browser as necessary.
Install the Greased MooTools and Extra Log Plays Links scripts into Greasemonkey.

Friday, April 16, 2010

PHP MySQL database abstraction class

I wrote a very elegant database interaction class for PHP some time ago.  The class is a simple layer between a PHP application and its database and provides a very clean and efficient interface to the database.  It does not generate the SQL code for you, but rather it makes a cleaner method of calling your SQL code.  It allows you to generate repeatable queries as objects, provides parameter substitution in queries, and allows reading a record via class accessors.  Some samples of these features are shown below.

I have not posted the source code itself as I feel this is one of my more exquisite projects and I don't want to see it taken without credit.  I may be willing to provide the code on request though.



Examples: A simple reader query. (Select)
$users = new query("SELECT userID, username, lastAccess, enabled FROM users;");

if(!$users->is_valid())
   return false;

while($users->fetch())
{
    echo $users->usersID;
}


A simple non-reader query. (Insert, Update, Delete)
if(!query::run("UPDATE users SET session = '$userSessionID', lastAccess = NOW() WHERE userID = $userID;"))
    throw new Exception("Database update failed.");


The same update only using parameters instead of string substitution. There are two ways to do this and both generate identical SQL code.
return query::run("UPDATE users SET session = @1, lastAccess = NOW() WHERE userID = @2;", $userSessionID, $userID);

return query::run("UPDATE users SET session = @sessionID, lastAccess = NOW() WHERE userID = @usersID;",
   array(sessionID => $userSessionID, usersID => $userID));


All three of the above update calls will generate the following statement. Notice how the second two statements automatically quote string and escape any special characters in strings.

UPDATE users SET session = 'SESSION', lastAccess = NOW() WHERE userID = UID;


You can also use parameters in reader queries exactly the same way as above. Also you can prepare the query and then set parameters/execute the query as a seperate step. Again the folloing are identical.
$users = new query("SELECT userID, username, lastAccess, enabled FROM users WHERE username = @username;", false);
$users->username = $username;
$users->execute();

$users = new query("SELECT userID, username, lastAccess, enabled FROM users WHERE username = @1;", false);
$users->execute(true, $username);

$users = new query("SELECT userID, username, lastAccess, enabled FROM users WHERE username = @username;", false);
$users->execute(true, array(username => $username);


To read the results there are a few other options as well.
$users = new query("SELECT userID, username, lastAccess FROM users WHERE username = @username;", false);

foreach($users as $user) {
    $users->username = $user;

    if(!$users->execute())
        continus;

    echo $users->usersID; // Get a coulmn value.
    print_r($users->get_row()); // Print the entire row.
    echo $users->get_md5(); // Time dependent hash.
    echo $users->get_md5('userID', 'username'); // UserID/Username dependent hash.
    echo $users->get_columns(); // Get a list of loaded columns.
}


Also there are a few other calls that may be useful. You can get the number or records and raw SQL statement like so.
$users = new query("SELECT userID, username, lastAccess, enabled FROM users;");
echo $users->get_length();
echo $users->get_last_sql();

query::run("UPDATE users SET groupName = @1, lastEdit = NOW() WHERE groupName = @2;", $newGroupName, $groupName);
echo query::length();
echo query::last_sql();