Thursday, January 28, 2010

Subversion subfolder access fun

After such a fantastic morning trying to set up subfolder access on various subversion repositories - its nice to share this little gem with anybody that might be interested.

I wanted a user to have read access to a whole project folder, but to restrict write access to just one folder inside the project. According to the docs I read this should work:

[Project1:/]
newuser = r

[Project1:/trunk/graphics]
newuser = rw

But it didn't. After a whole wasted morning, I found - much to my chagrin - that I had to grant rw rights at the root to the new user, and then deny rights where they weren't applicable, to be able to grant write rights (apache with subversion 1.6.6) to a subfolder (read rights worked ok funnily enough).

[/]
newuser = rw

[Project1:/]
newuser = r

[Project1:/trunk/graphics]
newuser = rw

[Project2:/]
newuser =

I suppose there is some kind of logic there, somewhere...

If you're reading this because you're having the same problem -I really do hope I've helped you.

Monday, January 25, 2010

AIR 2 Beta native process and the PHP CLI

With the release of the Adobe Air 2 beta comes a rake of cool new features. The most promising amongst them for future development is the ability to call and communicate with native processes on the machine on which Air is running. This obviously opens up all sorts of possibilities for extending the capacity of AIR without the need for the required API to be a part of AIR itself.

The application I'm building has so far has been slowly growing as a bunch of Flex applications, working with MYSQL via AMFPHP. But as more things are moved into AIR I wanted to get rid of the need for the webserver, in the case of the application working standalone on a local machine with a local installation of a MYSQL database.

Using the new native process API in AIR, and the CLI version of PHP, I've managed to come up with a way of communicating with AMFPHP directly through STDIN and STDOUT without the need for a webserver. The code is in its infancy, but I thought this would be a good time to share the idea and get some comments and input from those of you out there who are working in the same environment.

Rather than trying to post the code here on the blog - I've opened a Google Code project so that anybody who's interested can download the code and develop the idea if they want to. The project is at http://code.google.com/p/aircmdamfphp/ - you can download from subversion or there's a zip that you can download for convenience.

My main concern so far is security. For this to work on in a live application scenario on a user's machine the first consideration would be to have the PHP code compiled and have some way of securing the PHP installation against possible attacks. Any comments and/or suggestions on this or any other areas of concern regarding security on this particular idea would be appreciated. I suppose the other concern might be somebody hooking something in between the parent and child process...

There is a truly annoying caveat with AIR on Windows at the moment. If you install and run an AIR application using the 2 beta you get a command line pop-up window appearing each time you run php.exe (or it seems any other command line executable). I was hoping Adobe would come up with a fix for this before a production version is released, but looking at the Adobe Forums, Chris Thilgen is telling us that it won't be... (apparently its a "feature request" to not show the command window!) http://forums.adobe.com/thread/558533?tstart=0.

Maybe next time eh?

Thursday, February 19, 2009

The Base Index Thing

Having already converted to MYSQL as a backend database while still using VFP – I have come up against an old xbase peculiarity with the base number for array indexing. In most other languages that I’ve come across (including Actionscript) – array indexing starts at zero – in xbase it starts at 1. Kind of cool for “FOR loops” in xbase, and has workable logic to it, but that’s about it!

A common practice for a finite number of options for a given field value is to tie an integer field to a combobox. Let me give an example: in an application that I’ve been working on there is a pricing option that is stored in a rate table. This defines how a price is calculated – “per person”, “group” or “group + additional”. The application only works with those price calculations, the list is not something that’s customizable by the user, so we don’t need a related table for that list – we just need a 1, 2 or 3 (or in Actionscript 0, 1 or 2) to tell us which pricing option has been assigned.

NB: You could argue that the best practice would be a related table with formulaic data that the application uses to calculate and the user could customise – that’s on the to-do list!

So to return to the problem – values in the database were stored originally in Foxpro but now need to be integrated into Flex. This means we now have an issue with just tying the value to the selectedIndex for a combobox – 1 now = 0, 2 now = 1 etc. The straightforward answer is to “just convert the data for Flex”. I actually adopted that policy previously on a different project and for reasons I won’t bother to explain right now it slowed down development and kept biting me in the nether region. Additionally – I want to use Flex and Foxpro concurrently - replacing sections of the front end in stages - and eventually ending up with an AIR application. In some areas of the application the user is working in Flex, in others it is still the Foxpro GUI.

The answer I came up with was relatively simple – override the getter and setter for selectedIndex, and use a separate private variable for binding the value from the data field. A little bit of plus and minus 1 and it all works. The code is below in the subclass of the combobox.

But then a second issue arose making things just a little more complicated. As soon as I put this extension of the Combobox on a canvas in a TabNavigator that wasn’t the first to be displayed (ie: the second or subsequent tab) strange things happened. Whatever I had the data field set to, I ended up with a blank comboBox when I clicked the tab the very first time. Move to another record and everything starts working and the values start displaying…

I am guessing this is related to some code inside Flex that is doing some delayed jiggery-pokery to enhance performance. Without delving into the code though – that will have to remain just a guess. In the meantime – I tweaked a way round it. The test in the override for selectedIndex checks to see if the combobox is on a tabNavigator – and make sure that if it is - when Flex sets the selectedIndex it doesn’t set it to minus one after it has already been set via the cbSelected variable.

Admittedly this is obscure stuff – but if I’ve helped out just one other person – I’ll be a happier individual for it!

Here’s the extension of the combobox.


package
{
import mx.containers.TabNavigator;
import mx.controls.ComboBox;
import mx.containers.Canvas;


/**
* ...
* @author ...
*/
public class ComboBoxSelectedIndex extends ComboBox
{
private var _cbSelected:int;
private var _selectedIndex:int;

public function ComboBoxSelectedIndex()
{
super();

}
public function get cbSelected():int
{
return _cbSelected;
}
public function set cbSelected(value:int):void
{
_cbSelected = value;

if (value > 0)
{
super.selectedIndex = value -1;
}
}
public override function get selectedIndex():int
{
return _selectedIndex;
}
public override function set selectedIndex(value:int):void
{
var setSelected:Boolean = true;
if (owner is Canvas)
{
if ((owner as Canvas).parent is TabNavigator)
{
if (cbSelected is int)
{
if (selectedIndex < 0 && cbSelected >= 0)
{
setSelected = false;
}
}
}
}
if (setSelected)
{
_cbSelected = value + 1;
super.selectedIndex = value;
_selectedIndex = value;
}
}
}
}

Wednesday, February 18, 2009

Checkbox Renderer Ignores Editable Property in a Grid Column

I've been having problems getting a Flex 3 checkbox to pay attention to a datagrid columns editable status. I finally found a solution using a component I had previously lifted from Alex's Flex Closet. The solution was in the code for the clickHandler - an override with a test of the parent columns editable status seems to have done the trick for me. This took me a while to work out - and even then there may be some issues with it. If anybody has a more efficient working method please let me know. I will come back soon and update this post with a full working example - but for now the code for extending the checkbox class is below.



package
{

import flash.display.DisplayObject;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.text.TextField;
import mx.controls.CheckBox;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.DataGrid;

/**
* The Renderer.
*/
public class CentredCheckBox extends CheckBox
{

private var _listData:DataGridListData;

public function CentredCheckBox()
{
focusEnabled = false;
}

override public function set data(value:Object):void
{
super.data = value;
if (listData is DataGridListData)
{
selected = Boolean(data[DataGridListData(listData).dataField]);
}
}
override public function get listData():BaseListData
{
return _listData;
}
override public function set listData(value:BaseListData):void
{
_listData = DataGridListData(value);
}

/* eat keyboard events, the underlying list will handle them */
override protected function keyDownHandler(event:KeyboardEvent):void
{
}

/* eat keyboard events, the underlying list will handle them */
override protected function keyUpHandler(event:KeyboardEvent):void
{
}

/* eat mouse events, the underlying list will handle them */
/* unless we are in edit mode - in which case process them */
override protected function clickHandler(event:MouseEvent):void
{
var allowEdit:Boolean;
if (listData is DataGridListData)
{
allowEdit = DataGrid(DataGridListData(listData).owner).columns[DataGridListData(listData).columnIndex].editable;
}
if (allowEdit)
{
super.clickHandler(event);
}
}

/* center the checkbox if we're in a datagrid */
override protected function updateDisplayList(w:Number, h:Number):void
{
super.updateDisplayList(w, h);

if (listData is DataGridListData)
{
var n:int = numChildren;
for (var i:int = 0; i < n; i++)
{
var c:DisplayObject = getChildAt(i);
if (!(c is TextField))
{
c.x = (w - c.width) / 2;
c.y = 0;
}
}
}
}
}
}

Friday, October 10, 2008

CLEAR ALL - CANCEL - QUIT

I know some developers out there will be gutted by the demise of Visual Foxpro – I know I was. VFP was a great tool, and I doubt whether that kind of performance will be found again (and I was programming in Clipper before that!). But that said – the more important question for me was “what’s the next step then”.

I’ve settled on AIR and Flex. The possibility of a cross-platform solution that provides both Desktop and web access to an application and an application’s data from the same code base is basically irresistible. The fact that the SDK is open source as well – and that Microsoft are not involved – were also persuasive factors in the decision making process. I also had PHP and Flash experience, and my back-end database was already using MYSQL. But then the final clincher – “oh brilliant, they’ve got grids!”.

Given that, there is still a rather steep gradient going up the learning curve, so I’ll be sharing some of the experiences along the way, and aiming some of that specifically at ex-foxpro developers who might be following the same route. I’ve received a lot of help from fellow coders on blogs and wikis in the past, and I feel it really is about time I made an effort to give something back myself. I would also like to say a big thank you to all of you out there who that go that extra mile to share a few pearls of wisdom.

And so to start in that vein – let me point out some very good general Flex and AS3 resources that are already in place:

Alex’s Flex Closet
Alex is apparently one of the engineers on the Flex project who makes time to share assorted gems from an insider perspective. If you wanted “authoritative” then you wouldn’t find much better.

Peter Ent’s Blog:
Lots of great information – particularly on renderers.

Flex Monkey Patches
Again – a welter of useful information – and pretty much always with a working example.

Colin Moock
Colin Moock is “the man” when it comes to Flash and Actionscript. He has been around pretty much from the beginning - and I’ve consulted his writing in the past while working on flash projects on literally hundreds of occasions. He has also written a very good book – Essental Actionscript 3 (O’Reilly) – which you should make space on your bookshelf for. I even bought a copy myself (well my company paid for it).

Good luck in your efforts anyway – and expect more from me soon.

Tuesday, September 16, 2008

Windows 2000 Server "Foreign" Disk?

Had a lot of trouble this weekend simply changing a disk from one server to another. The first server had an IDE drive as the system disk, the second disk is a sata disk where mysql data was stored (there is a proven performance benefit with many programs to run the executables on one drive, and store the associated data on another).

The mysql sata disk was to go to a new server - a server with the same name going into the same domain. Windows 2000 server recognised the disk once it had been swapped, but after loading drivers and asking for a reboot - still did not show the disk in windows explorer.

I had noticed in the disk management snap-on in control panel-administrative tools-computer management - that the drive was actually being recognised - but was flagged as dynamic and "foreign"... I scratched my head and after some frustrated googling left for home in disgust. The next morning I arrived early, changed my search phrases - and found some answers straight away.

If this ever happens to you - go to the disk management snap-on - right click the offending drive and click "Import Foreign Data" - and you should find your drive is now recognised and your data is still all there.

What the dynamic and foreign nonsense is all about - god knows - I didn't even bother to find out as its ridiculous to me. But try the above which worked for me - and then contact Bill Gates for more information!