ReadOnly Form Elements
Here’s a quick note for the frustrated:
When setting the readonly parameter on a form element via javascript, make sure you use a capital “O” as follows:
elem = document.getElementById('myInputElement');
elem.readOnly = true;
Why it took me so long to find that out, I have no idea why. Most forums threads by others seem to think the disabled parameter is the best way to go. Actually, the sheer number of people suggesting that makes me think it’s a bad idea – just following the crowd. This is why readOnly might be the right option: You’re still allowed to post the form value, but the user isn’t able to change what’s inside the box. When using disabled *nothing* gets posted from that element. So if all you want to do is prevent a user from editing the value of a form element, use readOnly. If you don’t want that value posted, then go ahead and use disabled.
Enjoy!
Filed under: Design and Usability, Javascript, Tips | Leave a Comment
I was looking for a simple solution to backup my newly constructed server to an off-site location in case something were to happen. I don’t mean I lost a file… more like catastrophic hardware failure, fire, water damage, physical damage, and even theft!. Local backups really are best, and I don’t plan on abandoning them any time soon, but in the case of the one in a million chance where something like this occurs, there’s a high likelihood that everything might be lost.
Enter Cenolan.com: How to: Incremental Daily Backups Using Aamazon S3 Duplicity. It really is pretty easy. Just one thing: besides installing Duplicity (also required a few other dependencies), I had to install Python-boto: yum install python-boto
You may also be interested in doing regular backups of your MySQL database (from HowToForge.com)
Filed under: LAMP, SQL, Tips, Tutorials, sysAdmin | Leave a Comment
I recently performed a major upgrade on my file server this week. It was a lot harder than it should have been, but that’s only because my Linux Foo can only go this far. Two to three re-installs later on the new hardware it was getting old, so I told the Fedora installer to just do the base package and I would worry about the rest later.
Worry is not my middle name, but frustration might be. For reasons unknown to me I thought I could just do an “upgrade” from the installer. Wrong. Then I thought maybe I could boot normally, insert the DVD, and I could then select it as a package source. Wrong. Download all those packages I missed the first time around isn’t an option on slower-than-molasses connection I have at home. So I did what any other self-respecting nerd would do – turn to Google.
The trick lies in the Yum Repos list, located in /etc/yum.repos.d/fedora.repo
Check it out. Normally you have three entries: Fedora, a Debug branch, and a Sources branch. The primary Fedora branch configs look something like this (I’m using Fedora 10 in my example) :
[fedora]
name=Fedora $releasever - $basearch
failovermethod=priority
baseurl=http://download.fedoraproject.org/pub/fedora/linux/releases/$releasever\
/Everything/$basearch/os/
mirrorlist=http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&\
arch=$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$basearch
Our job is to copy and modify it so Yum and the GUI app manager can use the DVD. First you need to copy the block of code pertaining to [fedora] and paste the copy into your file – after [fedora] is fine.
- Change the line
[fedora]to[fedora-dvd] - change the
nameline toname=Fedora 10 x86_64 - DVD - change the
baseurlline tobaseurl=file:///media/Fedora%2010%20x86_64%20DVD(the path to your DVD might be different – check it first) - delete the
mirrorlistline - make sure the
enabledline isenabled=1(you can turn it off later through the “Software Sources” app) - Save and exit
Use Yum or the Application manager to install. Rather than taxking your network and your patience you’ll see the DVD activity light busily blinking as you begin installing packages. One tip you might need to keep in mind is that refresh packages button on the package manager. There were a few packages I tried installing that were no longer available when I turned-off the net-based repo source. This is equivalent to yum clean [option]
Happy installing!
Filed under: Tips, Tutorials, sysAdmin | 1 Comment
Tags: DVD, fedora, yum
Nasty WordPress Worms
I just ran across a nasty worm in one of my WordPress blogs (not the most current install). Not only did it overwrite a ton of files, inserting spam links and malware into the pages, but it was sneaky enough to go into my wp-admin/.svn/prop-base/ directory and re-write those files as well. It’s fairly ingenious from the hacker standpoint. Most people like me will rely on the svn revert file.php to send the file back to its original version. That won’t work if the .svn/prop-base files are altered because svn will see that they are the same – it doesn’t bother actually checking the repo, so you’re stuck with infected files.
I solved my problem by deleting the wp-admin directory and doing an svn-up on its parent. That forces SVN to say “hey – that directory is missing. I should pull it down from the repository.” Problem solved (for now).
And I am now running the most current version of WordPress, so hopefully I’m free of risk and infection from here on out.
Filed under: PHP, Tips, Web Apps, sysAdmin | Leave a Comment
I had the unfortunate event of having to send my MacBook Pro into Apple for some repairs. The machine came back working fine, however there was something odd going on with TimeMachine – it wanted to do a full backup of my disk. Odd, considering I keep it plugged-in all the time when I’m at my office desk. I tried re-selecting the disk, but that didn’t work. Clearly this would require some detective sleuthing on my part.
There are a couple points you need to know.
* First of all, check the Apple Support forums. They have some good information on there, but most of it is pretty basic. Start there then move on if you haven’t quickly solved your problem.
* Time Machine disks know your computer by the MAC address. This was the root of my problem – it seems my mac address had changed (new logic board?).
* I eventually found my solution at MacOSXHints.com, however I had to do a little more work to actually get everything working. See below.
What made this a step more difficult was that the MacOSXHints solution didn’t quite work, however one reader commented on a unique situation that resembled mine. in the /Volumes/TimeMachine/Backups.backupdb directory there were MyComputerName and “MyComputerName 2″ directories. The former had all my backups in there, the latter didn’t have any completed backups and showed a file creation time of today, not the last time I ran a backup. So with the ACL turned off (see the directions) I removed the “MyMachineName 2″ directory (mind you – I had already completed all the steps on MacOSXHints.com before trying this. It might be important). It worked.
YMMV but hopefully this will work for you.
Filed under: Mac, Tips, sysAdmin | Leave a Comment
Tags: Backups, MacOS X, Time Machine
I just noticed that the live feed from this blog to my brochure site at mistercameron.com was broken. The code I wrote to parse the rss data was throwing an error because the link to http://iamcam.wordpress.com/feed no longer resolved. Huh. The folks at WordPress must have changed something in their .htaccess file recently because adding a trailing slash fixed the problem.
Filed under: Uncategorized | Leave a Comment
There are many situations in web apps where site-wide configurations need to be accessible to users through admin interfaces, rather than configuration files residing on the server. It is a practical method of storing configuration values that may need changing from time to time, but without access to the core configuration file.
UPDATE (2008-10-22): This article has been published to the CakePHP Bakery
Code
Settings are stored in the database, so we will first need to start by creating the table:
CREATE TABLE `settings` (
`id` int(10) unsigned NOT NULL auto_increment,
`key` varchar(48) NOT NULL,
`value` text,
PRIMARY KEY (`id`),
UNIQUE KEY `key` (`key`)
)
Next, go ahead and bake your model and controller, but don’t worry about baking-in some of the pre-built methods. Modify your model to look like this:
class Setting extends AppModel {
var $name = ‘Setting’;
var $key = ‘MyApp’;
//retrieve configuration data from the DB
function getcfg(){
$key=$this->key;
$cfgs = $this->find(’first’,array(’fields’=>array(’id’,'key’,'value’)));
if (count($cfgs)) {
$this->checksum=$cfgs['Setting']['value'];
$cfgVal = unserialize($cfgs['Setting']['value']);
}
Configure::write($key,$cfgVal);
}
//write configuration data back to the DB
function writecfg(){
$key = $this->key;
$rev = Configure::read($key);
$value=serialize($rev);
//if the configs haven’t changed, no need to save them
if ($value==$this->checksum) return;
//otherwise the configs have changed, so
$this->data = array(’key’=>$key,’value’=>$value);
if ($setting = $this->findByKey($key)) {
$this->data['id'] = $setting['Setting']['id'];
}
$this->save($this->data);
}
}
You’ll notice that Configure:: values are serialized and stored together using the MyApp Configure::key. At first this may seem somewhat counter intuitive to how we think we should store configurations. However, consider the hassle involved with trying to figure out how/where to store multi-dimensional arrays in an inherently flat storage system (db). It’s probably doable, but not without considerable headaches. Storing everything in a serialized string allows Cake to worry about creating the structure – we just save the output.
Next, open up your app_controller.php file and add the following code to the top of the class:
var $uses = array('Setting');
You will also need to add some code to your AppController beforeFilter() and afterFilter() methods:
class AppController extends Controller {
var $uses = array(’Setting’);
function beforeFilter(){
//reads the site-wide config values from the DB and puts them through the Configure::write method
$this->Setting->getcfg();
}
function afterFilter(){
//retrieves the site-wide configurations from Configure::read($key) and puts it back into the db if new
$this->Setting->writecfg();
}
}
Usage
Any place you would like to store a Configure:: value in the database, you only need to use the $key specified in the model. If you don’t, the values will not get saved. An example would look something like:
<? Configure::write('MyApp.themeName','My Great Theme'); ?>
Since the retrieval code is run in the before filter, we can treat the Configure:: vars like any others in our app when we need to access them. To recall a value we would run something like:
<? $myVar = Configure::read('MyApp.themeName'); //returns 'My Great Theme' ?>
Next Steps
Because this is only a very simple way to store configuration data (one row for the entire app), there will likely be some desire to extend it. You may wish to segregate certain data into their own rows (perhaps individual plugins or components), which would only require some additional code to accept additional keys for read/write access. That, my friends, is a job for another tutorial.
Filed under: PHP, Tutorials, Web Apps | 3 Comments
Tags: CakePHP, configuration
Reading through a few of my most recent posts, you’ll quickly learn that I’m learning CakePHP as my PHP framework of choice. So far, so good. Actually, it’s pretty good, but that is not without some questions I’ve had along the way. I’m probably getting stuck more than I should on best practice coding, but I like to do it the right way, not necessarily the easiest way (read: hacks).
Among some of my initial stumbling blocks has been working through the idea of access control from the framework viewpoint. I “get it” when it comes to writing my own code, like in the revealCMS, and I “get it” in the context of certain “things” (usually users) needing access to specific things (often controllers and actions). The hard part is sorting out where to even start with all the alphabet soup: Auth, Acl, Aro, Aco, etc etc etc. How do you even get to a point where you have a simple working prototype to expand on?
Apparently there are numerous examples and tutorials of how to get started with Cake Acl, however I find many of them to be over-complicated or thorough. In other cases some are simply too terse. There is a fine line between terseness and conciseness. Even the CakePHP docs leave much to be desired for newer users: the official Acl documentation is long and kind-of confusing, and the sample application tutorial (also part of the official docs) seems to do things differently than explained in the primary documentation – a considerable problem, in my opinion. Yes, I do realize that the concept of Acl really depends on your application, but shouldn’t documentation at least be consistent? The one saving grace, however, is that the Bakery has a few examples, which brings me to my next point.
I found a tutorial I actually like so far. By “so far,” I mean I haven’t finished it yet, but to this point I’ve gotten more done than most articles have gotten me in just setting up the Acl… and it’s not all that difficult. It’s Ketan’s How to use Acl with Cake PHP 1.2.x?* No dobut some of you will stumble across this post here, and hopefully find it useful. I think once the dust settles on the first step, you(we) will be able to look at some of the other tutorials and adapt them to our own specific needs.
I’ll try to keep this post updated with additonal solutions as I find them.
* There ARE some typos in the example code, so be aware of that and make modifications as necessary.
Filed under: PHP, Reviews and Discussions | Leave a Comment
Tags: Acl, CakePHP
HABTM Unit Testing in CakePHP
I use this blog quite a bit for documenting little quirks, bugs, work-arounds, neat things, and tutorials so that I know where I can find the solution in the future. At the same time, you benefit by hopefully not having to go through some of the same messes I did just to get to this point.
I love CakePHP so far (but still quite the noob), but my biggest gripe is the documentation. The basics are there, but there’s often too little documentation to get the novice going. From the Bakery docs, it’s not exactly clear how to perform tests on models when HABTM (has and belongs to many) relationships are involved. Have no fear, it’s doable (though not straightforward).
Hopefully you baked your MVC pieces and included test scripts to go along with them. If not, do that first. The key part to getting the tests for models that have HABTM relationships is to set-up a fixture representing the table that stores the relationship. Don’t actually set-up the test – just the fixture.
Filed under: PHP, Tips | 3 Comments
Tags: CakePHP, habtm, unit testing
Framework Mania: CakePHP
It has been an interesting month – at the same time I’m picking up CakePHP, I have a client project that uses the Zend Framework. Right out of the gates I like CakePHP better. ZF doesn’t seem quite as cohesive as Cake, so getting it set-up has been more challenging. Granted, the client’s setup is a little more complex than the standard setup, but it still seems like there’s a lot more work involved just to get things going – lots more configuration. After two days on Zend I already realize how spoiled I am with Cake.
With Cake, I’m finally starting to learn unit testing. It seems real simple in theory, and I’m sure it is once you get the hang of it, but it is tedious. I’m talking about the amount of actual work involved just getting these test cases working. My simple pleasure at the end of the day is watching the screen fill up with a bunch of green “Pass” statements… no red.
Filed under: PHP, Reviews and Discussions | Leave a Comment
Tags: CakePHP, unit testing, Zend Framework
Search
-
Affiliations
Blogroll
Books
Recent Entries
- ReadOnly Form Elements
- Backups to Amazon S3 the Easy Way
- Adding the Fedora Install DVD to Your Yum Repo List
- Nasty WordPress Worms
- Fixing a Broken TimeMachine Backup
- Update your WordPress.com RSS links!
- CakePHP: Storing Configs in your DB
- CakePHP Access Control Alphabet Soup
- HABTM Unit Testing in CakePHP
- Framework Mania: CakePHP
- Zend Framework – Getting Started
Categories
- AJAX (3)
- Announcements (1)
- Business (1)
- CSS (3)
- Data Visualization (3)
- Design and Usability (8)
- DFL (17)
- Flood (2)
- Javascript (3)
- LAMP (13)
- Mac (3)
- PHP (37)
- Reviews and Discussions (37)
- RubyOnRails (1)
- Smarty (2)
- SQL (2)
- sysAdmin (10)
- Tips (13)
- Tutorials (25)
- Uncategorized (9)
- User Experience (1)
- Web 2.0 (5)
- Web Apps (17)
Archives
- April 2009
- March 2009
- January 2009
- November 2008
- October 2008
- September 2008
- July 2008
- April 2008
- February 2008
- January 2008
- December 2007
- November 2007
- July 2007
- June 2007
- May 2007
- March 2007
- February 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005

