Thursday, 18 August 2011

Google Chrome on Ubuntu 11.04 Natty - Your profile could not be opened correctly

For me this was due to ghost chrome processes still running. Close chrome, and type:
ps aux | grep chrome
I had output like this:
16660 ?        00:00:15 chrome
16666 ?        00:00:00 chrome
16668 ?        00:00:00 chrome
18159 ?        00:00:11 chrome
18165 ?        00:00:00 chrome
18167 ?        00:00:00 chrome
Then kill em all!!! e.g. to kill the first one (process id 16660), type:
kill 16660
Then when you restart chrome, it should be able to load your profile properly again.

Tuesday, 16 August 2011

Load event for Google Maps Javascript API V3

Use this JavaScript event listener to know when your Google Map finishes initialising.

google.maps.event.addListener(map, 'idle', function() {
   ...
});

REFERENCES
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1516

Saturday, 6 August 2011

Android 2.2 Froyo - Only Enable Auto-Sync when Connected to WiFi

I achieved this using an app called Tasker (currently £4).

1) New profile: on the Tasker homepage, click the plus icon to create a new profile, and don't bother entering a name.

2) Choose the context: go State > Net > WiFi Connected and click the green tick icon to confirm.

3) Select task: you then have to create a task to run when this context is active. There should be a "Task Selection" popup, and you need to click New Task, and again you don't need to bother with a name. Then you should be on the Edit Task page. Click the plus icon to add an action > select Net > AutoSync > Select On and accept. Finally, finish the task by clicking the tick icon.

4) Repeat steps 1-3 for the AutoSync Off task i.e. set the context to be WiFi Connected, but then check Invert on the next page, and set the Task to be AutoSync Off.

That's it - your AutoSync should turn on when you connect to a WiFi network, and off again when you disconnect.


Alternative Apps
-Locale (with a plugin) - expensive at over £6
-AutoSync Account Activator - FREE, and looks good (though I haven't tested it), but too fine-grained controls (i.e. must set individual sync rules for each sync account rather than just overall enable/disable Auto-Sync, ALSO must select specific WiFi networks as triggers, rather than just overall "WiFi connected")
-Toggle Settings - FREE, but not very intuitive interface - I gave up quite quickly.

If anyone can figure out how to achieve this behaviour using a free app, then please let me know in the comments!

Wednesday, 20 July 2011

PHP Doctrine 2: Convert UK date string to datetime

You have a form with a date field, and on submit you want to save the value as a Doctrine Datetime. You may find PHP's strtotime() function, but this will only work for dates in the US format (e.g. mm/dd/yyyy) and not the UK format (e.g. dd/mm/yyyy). The solution is to use DateTime::createFromFormat() which lets you specify the way the date string is formatted.
$result = DateTime::createFromFormat("d/m/Y", $dateString);
This can then be set as your datetime property on your entity, and persisted in the database. You can see which letters to use to represent your date format here.

Wednesday, 13 July 2011

PHP autocomplete / code assist in Eclipse

I've been programming in PHP a lot recently, and the main issue I've been having is that Eclipse finds it difficult to auto-complete e.g. suggest methods that can be run on an instance of a class. This article shows you how to fix this using PHPDoc to give Eclipse more type information. Note: it assumes you have a User class on your include_path.

You can declare types for arguments to functions. Note: ignore the double spacing - it is a bug with the FogBugz wiki
function myFunction(User $user) {
$user-> // this will now autocomplete
}

You can declare return type of functions
/** @return User */
private function getUser() {
return new User();
}

public function run() {
$user = $this->getUser();
$user-> // this will now autocomplete
}

You can declare the type of class properties (AKA fields), accessed with $this->var. Note: you can also do this inline above the property itself, using @var instead of @property, BUT annoyingly the PHPdoc has to be in the 3 line form (doesn't work if you shorten it to 1 line e.g. /** @var User $user */)
/**
* @property User $user
*/
class myClass {
protected $user;
function myFunction() {
$this->user-> // this will now autocomplete
}
}

You can declare the type on variables in the code
/* @var $user User */
$user-> // this will now autocomplete

Zend Log: Log to a file, formatting output, logging request details, and all error info

Wham this in your Bootstrap.php (replacing YOUR_WEBSITE):
protected function _initLogger() {
$writer = new Zend_Log_Writer_Stream('/var/log/YOUR_WEBSITE/output.log');
$format = '%timestamp% %priorityName%: %message%' . PHP_EOL;
$formatter = new Zend_Log_Formatter_Simple($format);
$writer->setFormatter($formatter);
$logger = new Zend_Log($writer);
$logger->setTimestampFormat("d-M-Y H:i:s");
Zend_Registry::set('logger', $logger);
}
Functions starting with _init will automatically be run during the bootstrap. This will setup the logger to log to a file in your logs directory, with a slightly clearer format than the default one (inc. simplified date format). It then saves the logger instance in the Zend_Registry, which means we can access it from our controllers!

Now in your Controller:
class IndexController extends Zend_Controller_Action {
private $logger;
public function init() {$this->logger = Zend_Registry::get('logger');}
public function indexAction() {$this->logger->info("Hello");}
}

Next, lets setup our logger to log the details of all requests, as this is really useful for debugging. We do this with a Controller Plugin, by implementing the preDispatch function (create application/plugins/Logger.php):
class Application_Plugin_Logger extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$uri = $_SERVER['REQUEST_URI'];
if ($uri != "/favicon.ico") {
$logger = Zend_Registry::get('logger');
$logger->info("* REQUESTED URI ".$_SERVER['REQUEST_URI']
    .", CONTROLLER ".$request->getControllerName()
    .", ACTION ".$request->getActionName());
}
}
}
Note: we don't bother logging browsers requests for favicon.ico, as they are not very interesting

Then we need to register the plugin, which we do back in our bootstrap, at the end of _initLogger():
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Application_Plugin_Logger());

Finally, we setup the ErrorController to log all error information by adding this code to errorAction():
$logger = Zend_Registry::get('logger');
$params = $errors->request->getParams();

$paramsString = "array (\n";
foreach($params as $key=>$value) {
$paramsString .= "'".$key."' => '".$value."'\n";
}
$paramsString .= ")";

$logger->crit("ERROR = ".$this->view->message."\n"
    ."MESSAGE = ".$errors->exception->getMessage()."\n"
    ."STACK TRACE = \n".$errors->exception->getTraceAsString()."\n"
    ."REQUEST PARAMS = ".$paramsString);

Monday, 27 June 2011

Gnome-do Suspend not working in Ubuntu Lucid 10.04

I love Gnome-do, but the version in the Lucid repo stopped at 0.8.3.1 (and 0.8.2.1 for gnome-do-plugins), which had a bug that meant Suspend didn't work (from the Session Management plugin). After noticing this had been fixed in a later version, I resorted to grabbing the latest version of the source code and compiling it myself. This was a surprisingly easy task.

1) Get the dependencies (including Bazaar which you need to download the source code)
sudo apt-get install bzr
sudo apt-get build-dep gnome-do
sudo apt-get build-dep gnome-do-plugins
2) Download the source code
bzr branch lp:do gnome-do
bzr branch lp:do-plugins
3) Install (do this for both of the new directories)
cd gnome-do
./autogen.sh
make
sudo make install
4) Restart gnome-do and enable GNOME Session Management plugin

Note: I actually left the old repo versions installed, in the hope that there may be some dependencies fulfilled. Hopefully this wont cause any headaches in the future (it hasn't so far).