Wednesday, January 18th, 2012 | Author:

So, I use CiviCRM and had a piece of software recently upgrade to V3 (from V2). CiviCRM were nice enough to provide a V2 API for compatibility. However, this V2 API unfortunately isn’t 100% compatible with the original V2. Especially in regards to the Location API. To make things a little easier, I wrote a function that transforms V3′s V2 compatible API results into true V2 compatible results.

Here it is:

	function getLocation($contact_id){

		require_once 'v2/Location.php';
		$params = array(
			'contact_id' => $contact_id
		);

		$result = civicrm_location_get( $params );

		if ( civicrm_error ( $result )) {
			return $result['error_message'];
		} else { 

			//OK. In order to deal with the new API, sometimes we have to wrap this in a "location" wrapper that the view understands
			if( is_array($result) ) {

				$rework_results = false;

				foreach( $result as $r_key=>$r_data ) {
					if( !is_numeric($r_key) && !$rework_results ) {
						$rework_results = true;
					}
				}

				//OK. So, the CiviCRM API has changed, and the format has completely changed.
				//	So, we're going to rework it here
				if( $rework_results ) {

					$n_result = array();

					foreach( $result as $r_key=>$r_data ) {

						if( is_array($r_data) && sizeof($r_data) > 0 ){

							//We have element(s)
							foreach( $r_data as $element ){

								if( array_key_exists("location_type_id", $element)) {

									if( !array_key_exists( $element['location_type_id'], $n_result ) ) {
										$n_result[ $element['location_type_id'] ] = array( "location_type_id" => $element['location_type_id'] );
									}

									//Now, the old API did funny things with addresses - instead of putting them as their own element
									//	each location could only have one address. Everything else (I think), could have multiples
									if( $r_key != "address" ) {

										if( !array_key_exists( $r_key,  $n_result[ $element['location_type_id'] ] ) ) {
											$n_result[ $element['location_type_id'] ][ $r_key ] = array();
										}

										if( array_key_exists( $r_key . "_type_id", $element ) ) {
											$n_result[ $element['location_type_id'] ][ $r_key ][ $element[$r_key . "_type_id"] ] = $element;
										}else{
											$n_result[ $element['location_type_id'] ][ $r_key ][] = $element;
										}

									}else{
										$n_result[ $element['location_type_id'] ]['address'] = $element;
									}
								}
							}
						}
					}

					$result = $n_result;
				}//End if reworking Results

			}

			return $result;
		}//End if no CiviCRM Error
	}//End Function
Category: Uncategorized  | Tags: , ,  | Leave a Comment
Tuesday, January 10th, 2012 | Author:

SourceguardianToday I thought I’d give my small unbiased review of Sourceguardian.

What is it?
Sourceguardian is a product that allows you to encrypt your php applications so that you can deliver your PHP application to a client (for use on their servers) without having to give them your source code. Although I’m definitely NOT specialised in the field of computer security, I’ve read several reviews that say Sourceguardian uses industry standard encryption – so that’s got to be good, right?

What are its alternatives?
There are several alternatives, and several sites comparing them to each other – I’m not going to go into that here, as I honestly haven’t used them. However, I’m going to mention though that I fully intend to try Zend Guard in the near future.

How does it work?
Not going to give you a technical explanation here – think of it as a “plugin” (they call them loaders) that you install on your web server that allows you to run PHP apps that are encrypted with Sourceguardian.

What’s good?
Installation. Installation is an absolute breeze. So much so that you as a developer probably don’t have to worry about compatibility. If you’re a sysadmin installing the Sourceguardian “plugin”, it’s as simple as downloading a version of the Sourceguardian loader that works with your OS/Architecture and adding a couple of lines to Apache’s configuration. Easy. Sourceguardian even gives you this nifty little utility that allows you help detect what loader you need. Very nice.

Another good point is speed. In the application I’m working on, speed is relatively important (Although not mission critical). I compared speeds for my unencrypted files vs my encrypted files, and on average each page took about 0.03 seconds longer to load. That may differ depending on your configuration, but it was an acceptable result for me.

What’s bad?
Well… There’s only a couple of things I’ve noticed so far wrong with the actual program. They’re Minor annoyances, and I think it’s pretty poor that the Sourceguardian team don’t have an FAQ to address this. I like to know what to watch out for BEFORE I deploy to a client (and consequently look like an idiot when things don’t work).

The first is the DIRECTORY_SEPARATOR constant. If you’re writing for cross platform compatibility (read windows and Linux) the directory separator constant is essential. If you’re not, then it’s not a big deal. All it does is tell PHP to use the correct slash. eg: “model\filename.php” will not work nicely on Linux. Using “model” . DIRECTORY_SEPARATOR . “filename.php” makes sure that the file path is valid regardless of the OS you’re using.
Bottom line is that Sourceguadian’s implementation of the constant will always be reflective of the platform that you ENCRYPTED the source on. It’s stupid, and it should have been documented (if it can’t be fixed).

The next is a PHP 5.3 feature. If you’re including files, you might be like me and use the __DIR__ constant. I’m not saying that you should use it, but it is a valid part of PHP 5.3. Again, this doesn’t work. If you use this function in your source, Sourceguardian will reflect the directory that it was encrypted in. Imagine my surprise when I echoed __DIR__ on a Linux system and got the text “C:\encrypted\testapp”. Again, this shouldn’t happen, and if it’s known, it should be in an FAQ somewhere. Fortunately this one is easy to solve – just replace all instances of __DIR__ with dirname(__FILENAME__). Again, it’s not a dealbreaker, but it’s unacceptable that this isn’t documented.

Their GUI application that encrypts (on windows anyway) is also buggy. Even basic features like “rescan this application’s directory for changes” frequently results in the program hanging if the directory has lots of files. Considering the GUI app doesn’t do all that much, this is pretty poor.

The last thing I don’t like about Sourceguardian is the support. Let me be clear – I have contacted them 3 times about 3 separate issues (one of which is outlined above) and I have NEVER received a reply. This is not good.

A colleague of mine also mistakenly bought the wrong OS version of Sourceguardian, but tried to activate it on another platform. The (wrong) platform took his key, promptly expired and left him with nothing. He emailed their support team several times and got no reply. $200 down the drain.

Thoughts:
Overall, Sourceguardian looks good on the surface. It’s cheap in comparison to other products that deliver a similar function set, but it comes with a few “gotchas” that aren’t documented. I still intend to use it in future, but will definitely be giving Zend Guard a look. Although, I’d definitely be a lot more partial to Sourceguardian if it had decent support.

Sunday, January 23rd, 2011 | Author:

So, a while ago I decided that I wanted to make a JSON-based calendar that felt like a desktop app. I modelled the look off OSX’s iCal, and I was pretty happy with the result.

I’m calling it olal-cal (OSX Look-a-like Calendar). It is licensed under the LGPL (so you can use it in commercial apps if you decide you want to) and available for download HERE. If you’ve used it or like it, leave a comment or send me an email! If you want to see a basic demo (No adding of events allowed, and restricted to one month), you can view it here.

The first section of the README file is below:

Olal-cal is a simple HTML/JQuery calendar that allows you to easily display events in a calendar that
is similar in appearance to the OS X iCal calendar. It is fairly interactive and gives the
look-and-feel of a desktop application.

Olal-cal relies heavily on JSON files. The structure of these JSON files is outlined in both the
provided .php files and in the documentation below.
Olal-cal was designed to work with PHP, but you can easily change this to whatever server-side
scripting language you wish.

olal-cal is not a complete calendaring solution, but rather it allows you to implement your own
backend. olal-cal was designed with a simple calendar database in mind, where each calendar event
has a unique Identifier, and belongs to a uniquely named Calendar (eg. Home or Work).

Category: Uncategorized  | Tags: , , , ,  | 2 Comments
Wednesday, September 22nd, 2010 | Author:

I’m learning XSLT at the minute, and I found out that there are a lot of ways to get the day of the week from a UTC date, but most of them involve using XSLT 2.0 features, or functions. Unfortunately, Firefox (which I’ve had to use to transform XML docs into XHTML) doesn’t support any of that (yet anyway).

So, I wrote a template that can be included in any XSLT 1.0 document. Later on, a friend showed me that there are a couple of templates already out there that I could have used, but they’re essentially templates that call other templates, and they’re quite long. So… I don’t know if this would be useful to anybody, but I’m going to post it anyway.

<!-- My Template for spitting out day names from utc dates -->
<xsl:template name="get_day_name">
<xsl:param name="utc" />
<xsl:variable name="month" select="number(substring($utc,6,2))" />
<xsl:variable name="year" select="number(substring($utc,1,4))" />
<xsl:variable name="day" select="number(substring($utc,9,2))" />
<xsl:variable name="a" select="floor((14-$month) div 12)" />
<xsl:variable name="y" select="$year - $a" />
<xsl:variable name="m" select="$month + 12*$a - 2" />
<xsl:variable name="result" select="($day + $y + floor($y div 4) - floor($y div 100) + floor($y div 400) + floor((31*$m) div 12) ) mod 7" />

<xsl:if test="$result=0">Sunday</xsl:if>
<xsl:if test="$result=1">Monday</xsl:if>
<xsl:if test="$result=2">Tuesday</xsl:if>
<xsl:if test="$result=3">Wednesday</xsl:if>
<xsl:if test="$result=4">Thursday</xsl:if>
<xsl:if test="$result=5">Friday</xsl:if>
<xsl:if test="$result=6">Saturday</xsl:if>
</xsl:template>
Category: Uncategorized  | Tags: , ,  | Leave a Comment
Tuesday, July 06th, 2010 | Author:

So. Today I spent WAY too long trying to find a Max OS X driver for a cheapo little USB-to-Serial I bought off eBay.

It’s model is HL-340  - it’s a generic little adapter out of China, and after a bit of digging around, I discovered it’s got a PL-2303 chip in it…

Some champions have written a driver for devices with this chip. You can download it at http://osx-pl2303.sourceforge.net/ – Worked OK for me on Snow Leopard 10.6

If you’re looking for Terminal Applications for OSX, there’s some good information here and here on that.

Category: Uncategorized  | 6 Comments
Tuesday, June 15th, 2010 | Author:

Come In Spinner Album ArtSo. My other love in life is Music. A few years ago I very quickly wrote an arrangement of “Don’t know much about love” that was present on a Vince Jones and Grace Knight CD I had lying around – Come in Spinner.

Anyway, I have a band that recently performed at the Merimbula Jazz Festival, and I got a few compliments on the arrangement. It’s not a very common song, and I couldn’t any arrangements suiting my band’s lineup (which is a little unique, I’ll give you that). So… here is a lovely free arrangement I wrote, based more or less of the recording. The piano part is a little lacking (I play piano, and tend to make it up as I go along), and the drum part is a guideline only. Feel free to download it and play it. Leave a comment if you played/liked/hated it.

DKMAL_Score
DKMAL_Vocals
DKMAL_Alto_Sax
DKMAL_Bass
DKMAL_Drums
DKMAL_Piano
DKMAL_Tenor_Sax
DKMAL_Trombone
DKMAL_Trumpet_1
DKMAL_Trumpet_2

Friday, May 28th, 2010 | Author:

We have an automated system set up at work that automatically records programs from TV using TV Scheduler. It’s a fantastic system, but our media-management program (Clickview – which I highly recommend for schools) only accepts videos that have been encoded with DivX/XviD. TV Scheduler records in TS format, so I needed a program that converts TS files automatically to DivX. Traditionally, I’ve used Auto Gordian Knot, which is great for one-off conversions, but not really good for automation as it lacks a command-line interface.

I stumbled upon a really good program that has an excellent command-line interface called StaxRip. It allows you to make templates using a GUI so you can customise the video settings you want with ease, and then use a batch command to batch convert videos. It’s great, and has worked flawlessly for me.

I’ve written a script using AutoIT that scans a remote directory for TS files, moves them over to a local location (presumably a directory on a server that can convert files really fast), converts the TS files to DivX AVI using the “XviD” template, and moves them back. Really, you could use any language, or even use a VBScript. Anyway, here’s the source. Mine also spits out a log file so you can see if it’s working. Of course you’d put it as a scheduled task if you wanted it to run automatically.

scheduled_videncode_nebev

Friday, May 21st, 2010 | Author:

Today I came across a very interesting problem in regard to Group Policy folder redirection in Windows 7. All folder redirection was failing with reason codes similar to the one below:


Application Source: Microsoft-Windows-Folder Redirection
12:12:58 PM
Event ID: 502
Task Category: None
Level:
Error Keywords:
User: username
Computer: computername
Description: Failed to apply policy and redirect folder "Documents" to "\\server\share$\username\". Redirection options=0x9020. The following error occurred: "Failed to build the list of known sub folders".
Error details: "The system cannot find the file specified. "

This was happening for all redirected folders – Start Menu, Documents, Music, Desktop etc etc. I assumed firstly that this was a permissions issue. I checked and rechecked all permissions. I logged on as a user – saw the redirection fail, and tried to access the “failed” directory as that user. The user could access (and write) to the documents directory without any problems. I sort of already guessed this was the case because XP clients weren’t having any problems. I also knew that I was in a bit of trouble because googling this error returs no results (sigh).

I cast my mind back to a couple of days ago and remembered that I approved a bunch of updates that had been piling up (I know, I shouldn’t let them pile up but I don’t often get time to approve them). Anyway, after a LOT of painful update installs (pretty much one at a time – took me and some colleagues 3 hours), I found the update that broke folder redirection: KB980408

Microsoft’s description of this KB is: Install this update to resolve reliability issues with Windows 7 and Server 2008 R2.

Well, that didn’t work. After some careful googling, I found that other people have had problems with this update too. Not the same problem mind you. There was a fix recommended in this forum. I wasn’t sure that it was going to solve my problem, but it did.

The [temporary] solution I used involved the following: Make a reg File with the following in it:

Windows Registry Editor Version 5.00</code>

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{2112AB0A-C86A-4ffe-A368-0DE96E47012E}]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{2112AB0A-C86A-4ffe-A368-0DE96E47012E}\PropertyBag]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{491E922F-5643-4af4-A7EB-4E7A138D8174}]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{491E922F-5643-4af4-A7EB-4E7A138D8174}\PropertyBag]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{7b0db17d-9cd2-4a93-9733-46cc89022e7c}]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{7b0db17d-9cd2-4a93-9733-46cc89022e7c}\PropertyBag]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{A302545D-DEFF-464b-ABE8-61C8648D939B}]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{A302545D-DEFF-464b-ABE8-61C8648D939B}\PropertyBag]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{A990AE9F-A03B-4e80-94BC-9912D7504104}]

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{A990AE9F-A03B-4e80-94BC-9912D7504104}\PropertyBag]

Run the reg file. It’s important that you reboot after the fix has been applied. I’ve got a friend who is emailing Microsoft about this issue, and hopefully they’ll release a hotfix or something. I’d be interested to know if anyone else has had similar issues (or fixed it using these steps).

EDIT: A side-effect of this fix is that renaming via Windows Explorer sometimes fails. Still… better than having no folder redirection

Tuesday, April 27th, 2010 | Author:

Ok. So last post I described how to use Altiris and RapiDeploy to roll-out Windows 7. Since then, I’ve found out a couple of things:

  1. Don’t bother leaving UAC enabled in any shape or form. Altiris doesn’t like it. Altiris’s remote desktop doesn’t like it. Altiris won’t join domains when it’s enabled
  2. Rapideploy has a nice GUI, but it’s completely useless and outdated when compared to imageX
  3. Sysprep actually works for me now because I DIDN’T INSTALL Symantec Antivirus (stupid, I know)
  4. Altiris’s Sysprep function actually works much better than I expected it to.
  5. DAgent works better than AClient with Windows 7

The way to deploy Windows 7 out to computers is definitely using ImageX. Altiris comes with built-in support for ImageX, and you don’t have to go through all the messy steps like running bcdedit in Windows PE just to get the machine to boot.

Also, Altiris has the option to Sysprep the machine when it takes the image. I tried enabling this option, and it actually worked – I know I sound surprised here, but to be honest, these things have a tendency to fail miserably. When deploying the image to other computers, I told altiris that this image had been sysprepped for Windows 7 (you must be using at least DS 6.9 to get this option).

What really surprised me was that after the machine had finished running it’s “first-time setup” stuff, the machine was already named properly and already joined to the domain. That’s right folks – The altiris client didn’t have to reboot the machine 700 times. I can only assume that Altiris generates a  Sysprep INI file to reflect the desired name/domain/settings and copies that to the hard disk of the computer being imaged while in WinPE. Clever.

So in summary:

  • Altiris + Rapideploy
    • Admin interaction required: small
    • Time to image 60 Computers to finished state: 4 hours
    • Image Details: Machine Specific
  • Altiris + ImageX + Sysprep
    • Admin interaction required: virtually none (but there’s always 1 that doesn’t want to network boot)
    • Time to image 100 computers to finished state: 1.5 hours
    • Image Details: Works on at least 6 different models of machines (that I’ve tested). Probably works on more given Win7′s driver repository.
Category: Uncategorized  | 5 Comments
Friday, December 04th, 2009 | Author:

So this week I was working on getting Windows 7 deployed onto a lab of 30 computers at my school. Long story short, it was a nightmare, but I learned quite a bit, so I suppose it was all worth it. This blog post outlines some of the problems I ran into

Image Preparation

Okay. I thought this was going to be very much like a Windows XP deployment session, so I started to install all the programs I usually use on the lab computers on a fresh Windows 7 machine. It all went well, and I decided to sysprep it (like I do with the Windows XP machines). The only thing I had to do different was to ensure that the Windows Media Home Sharing service was disabled (look in msconfig).

The actual image creation went as planned until I ran into Problem #1: Sysprep leaves the machine in an unusable state.
Seriously. It’s completely unusable – sysprep tells me to reboot to try again. I tried the process again a couple of times and could not get it to work – but since I’m imaging this image to machines of exactly the same type I decided not to use sysprep this time (not really what I desired, but I was short on time).

Altiris DS and Rapideploy

Okay. So I started off by trying to take an image using Altiris and Rapideploy. It was going fine (after I managed to create a Windows PE environment with the appropriate network drivers) until RapiDeploy got about 46% through the image – which leads to Problem #2insufficient disk space

This was a weird error. I’ve done this maybe 15-20 times before and I’ve never had this issue (and of course, I checked the obvious – I did have enough disk space).
So what I decided to do was do the image the old fashioned way! No PXE Booting – all I did was create a Bart PE bootable CD (with network drivers), and ran rapideploy.exe without any parameters and saved the image to the network. It worked!

Post-Imaging

So I deployed the image to a couple of computers, and wouldn’t you know it, I ran into Problem#3. The bloody thing wouldn’t boot. I got the following screen:

(Well actually I got error 0xC000000E, but you get the idea)

 Now. The reason this happens is because of the way Windows 7 boots. It (by default) partitions an extra 100MB partition. From my limited understanding this 100MB partition is the boot partition and references files on your other partition (the main one that contains all the data). So the say to fix it is to run the following commands in the Windows PE (or Bart-PE) environment:

BCDEDIT /set {bootmgr} device partition=c:
BCDEDIT /set {default} device partition=d:
BCDEDIT /set {default} osdevice partition=d:

In order to do that in Altiris, you need to make a job that runs in the PE environment (it’s the screen you get after you tell Altiris what you want it to run), and have access to the BCDEDIT.EXE file (my PE environment maps the altiris eXpress share to F: – I put it in there).

Renaming

So at this stage I was sort of jumping with glee. Seems I successfully deployed Windows 7. Guess again. Altiris DS needs to be at least 6.9 SP3 in order to even remotely support Windows 7. After upgrading I found that DS could rename the computers without any issues, but not join them to the domain (Problem #4). I got both of these errors:

Unable to update Client Configuration
Unable to configure Windows Domain Information

As of yet, I have not found a way to join Windows 7 to a domain remotely using Altiris (I’ve read that the usual NETDOM command-line utility doesn’t work anymore, and Altiris’ built-in domain joining thing doesn’t work either). So I joined them manually (ergh, I know, but I was short on time).

Profiles

 So I thought to myself…. “I’ll log on as a student to see how things work”. Nope! Complete and utter failure (Problem #5). The reason is because our students use mandatory profiles. What I discovered is that Windows 7 uses a different profile to Windows XP. All you need to do though is create a new folder for the profile with the same name append a .V2 at the end of it. Like so:

Profiles

The profile path is still the same (eg \\server\profiles$\student ), and Windows XP uses the profile in the student folder, and Windows 7 uses the profile in the student.v2 folder.

I created a mandatory profile the way I usually do, and tested it using my test account (which I created the profile with), and it appeared to work OK. Then I got a student to log on and I got this lovely error (Problem #6).

Group Policy Client Service Failed the logon – Access Denied

 Great. As it turns out, Vista and Windows 7 have this concept of Profile Permissions (that aren’t the same as the permissions set at the file level). So, what I had to do is try and log on with a local account, set everything the way I liked it, log out, log in as an Administrator, and do to Advanced System Settings and click User profiles -> Settings. The idea here is that you have to use the COPY TO button to set permissions of the profile. However, I ran into Problem #7 – the copy to button was greyed out.

useraccounts

I trawled the net. Found nothing of use (rebooting didn’t help). So what I ended up was doing the following. I copied the local default profile (that worked) and set the permissions accordingly.

copyto

Then what I did is copy that profile that has the correct permissions to my student.v2 folder. Then, I

  • Made the student.v2 folder writable for my test account
  • Logged in using my test account
  • Set up the profile the way I liked
  • Logged off
  • Renamed the student.v2\ntuser.dat  to ntuser.man (making it a mandatory profile)
  • Changed the permissions to read-only for student.v2

After this, all students were able to log on successfully.

Group Policy

JUST when I thought things were finally ready, I ran into Problem #8. The start menu for students wasn’t working. We had been using folder redirection to point all students to the same start menu, but the All Programs folder was (empty). Of course, this worked fine in Windows XP, and the strange thing was that the shared desktop (which was nearly an identical setting) seemed to work fine. The culprit was Group Policy. I had the following setting enabled:

Remove User’s Folders from the Start Menu

Now I have no idea how that setting even got there – it seems to have no effect on Windows XP machines, but apparently makes the Shared Start Menu disappear on Windows Vista and 7 machines. So, I left this setting as “Not configured” and the Start Menu CAME BACK!

Conclusion

Well… it’s been an experience, but I now have a fully functioning lab of 30 computers. I’ll work on the altiris domain-joining a little more, but I think I might start upgrading some existing XP boxes if Windows 7 is a hit with the kids next week.