Правильно, только в json_decode второй параметр true надо добавить, чтобы получить в результате не объект, а массив, с ним проще работать. И вы совсем перепутали все переменные, не красиво.
$extended_json = $row['extended']; $extended = json_decode($extended_json, true); print $extended['age']; // 31
Еще скажу, что объект modUserProfile при попытке получить поле extended ведет себя несколько иначе и возвращает не json-строку, а сразу массив. За это отвечает описание поля в его мап-файле. Если вы выполните
$extended = $modx->getObject('modUser', $id)->Profile->get('extended');
, то получите сразу массив.