VanDragt

SilverStripe relation records management - or why do I have so many database records?

You have a bunch of DataObjects that has_many RelatedItems. You might have the following seperate situations:

  1. Get the Dataobject->RelatedItems() and remove() one RelatedItem. What happens to that RelatedItem?
  2. Delete() a DataObject. What happens to the RelatedItems for that DataObject?

Regarding 1: (in SilverStripe 3.0.x) - the DataObjectID for that RelatedItem is set to 0.

Regarding 2: Nothing, their DataObjectID will point to a non-existing record.

Wrong Expectations

In both cases I expected the objects to be deleted, but SilverStripe is going for safety first and keeps the records around just in case.

This means that you might need to write maintenance code if you don’t expect this happening.

Things to keep in mind

If you are writing an sync task and want to make sure RelatedItems are fresh, do not delete / remove RelatedItems before creating new ones. You will be creating thousands of records over time.

Instead, get the list of IDs, and unset the IDs that you find. Then remove any IDs left in the list as they weren’t in the source.

My Hearthstone Strategy Tips

I’ve been playing Hearthstone, Blizzard’s card game battler, for a month or two now and am enjoying it very much.

Although by the very nature of a collectible card game people that pay money will have access to more cards, it’s currently very possible to win most matches without paying. My philosophy on free games is to pay the developer around as much money as I would have for the game if it was paid, but not more.

That said, if you are looking to play better here are some things I have discovered (I’m not involved in the HS community or read any strategy guides so my advice might be old hat):

Deck naming

I always change the name of my custom decks to the following format: X/Y [Approach of the deck]. X stands for the number of matches won, and Y for the numer of losses. After every couple of matches I rename the deck and update the stats. Example: 15/4 DrawHeal is my popular Priest deck.

Naming your deck this way allows you to keep tabs on if the approach works with the cards in the deck, if your deck is any good ‘in the field’, and it helps you remember your playstyle.

Refine one card at a time

You’re only as good as the hand you draw so before decimating your deck make sure you give it enough plays. One way I like to do this is to play a few matches and find any weaknesses in my deck, then swap one card for a better suited one.

This gives you valuable playing experience with the deck whilst incrementally making it better (hopefully). Should you take out 4 or 5 cards at a time then you might imbalance the deck in another way.

Spread of cards

Unless you have a specific approach you want to try out, try to have cards more or less evenly spread out across the mana spectrum (1-7). This ensures you have the best chance of opportunities at every turn. Nothing is more devastating to have a hand full of cards you cannot play.

Also make sure you have creature cards across the mana spectrum. As you don’t know in what order you’ll draw the cards, it is important that you can go on the defense or attack at any point in the game. Thus you need creatures across all mana levels.

Make a note of what is not working

Why did you lose? Did you end up with a lot of high mana cards in your hands that you couldn’t put into play? Or did you have a lot of low mana and high mana creatures but nothing in the middle ranges? Perhaps you were unable to stop the rushing Hunter because you didn’t have enough area of effect spells (spells that affect all (enemy) creatures)? Or did the right cards not come up, maybe you should draw more cards? Sometimes you’re just unlucky.

Slowly adjusting your deck in this way makes it more flexible to deal with any situation that arises.

Understand the classes

Initially I had a lot of trouble playing the Paladin (even though in World of Warcraft this is my favourite class) because I didn’t understand how to play it. Look at the unique cards the classes have. In this case, my impression is that the paladin tries to preserve and grow their creatures, so using it in a deck with sturdy defensive creatures and then growing them can be a viable approach.

You can’t play any approach with any class. Although combining cards to allow a certain approach is a risky but fun experience.

Be courteous

A game is only as fun as its players. So be kind and say hello, and compliment a player on a impressive play.

Personally, I do not like to admit my mistakes during the match because the opponent might not know that I made a mistake.

I’m sure you have your own tips and hints so any feedback is welcome via twitter.

Tweak Firefox UI using ChromEdit

For a long time I have been wanting to switch to Firefox as my main browser. I haven’t done so before today because I didn’t like two things: The font-size of the address bar, and having a seperate search box.

Today I’ll show you how to fix these issues.

Fix Address bar font-size: Install the ChromEdit Plus addon. Then, under Tools > ChromEdit Plus > ChromEdit add the following code to the userChome.css:

#urlbar { font-size: 16px; }

Press the Save and Restart buttons. Afterwards you can disable this addon.

Remove the search box: right click on a toolbar > Customise. Drag the searchbox into the Customise Toolbar dialog to remove it from the UI.

The iPad Effect

After using the iPad mini for a day now, I have noticed it already has affected how I see my iPhone 4 and a hypothetical iTV. I find that this is very much like any other experience in life; the best way to form an opinion about something is to contrast it with something else. This is true from cultures to operating systems, and is also one of the reasons why I encourage people to travel.

The iPad experience

So even though I’ve had the pleasure of using an iPhone 4 for several years now, only now do I notice immediately after switching from the iPad mini how heavy it is! It’s actually heavier than the much bigger iPad mini, and feels uncomfortably heavy initially. Up until now, the solidness of the iPhone 4 has always been a positive to me. The iPad mini is almost (but not quite) too light and this changes the expectation of a smaller device.

After using the the mini for a while, I’m also painfully aware when launching Safari how short the phone’s screen is. So I am not surprised that Apple responded to its iPad advances by adjusting the expectations of how an iPhone should look and feel. I just wasn’t prepared for it!

As I currently don’t have a cover, I’m wondering how to take the iPad with me to work. I already much prefer it in terms of speed, easy of use, and screen estate, to the iPhone. Typing feels a lot easier as well making it much more suitable for articles like this one.

On first use

Oh, and how annoying is it to restore from an iPhone backup as your first iPad experience only to find out that half your apps have been miniaturised? Personally, I think iPhone apps shouldn’t restore to iPad at all, and instead if and when iPad versions are available one should see a list of apps to upgrade to.

Also Instacast, why no iPad version? Perhaps it’s makers agree the iPad is not optimal for enjoying podcasts. I wish we had the option to try it.

So far, it seems I have successfully post-predicted the iPhone 5, the podcasts app and Smart Cover! That makes me think Apple has been using the iPad mini internally for one or two years prior to the iPhone 5, and concluded similarly.

On the TV experience

Later that night as I lay awake and watched BBC News two more things hit me:

  • How suitable the iPad mini is for watching TV and using apps like Netflix; not just in terms of screen size and crisp visuals but also in terms of content browsing.
  • How any future Apple TV has to group content apps within a dedicated interface as you don’t want to intersperse these with regular apps on the springboard.

There really should be a way to rest an iPad like how laptops are held up by their bodies, so I can lie back and watch. So I wouldn’t be surprised to see some kind of devices bundle where a small iPad acts as the content guide for an apps enabled Apple TV. Maybe add a content browser app with the content apps inside. The tv itself is then just a bigger output of the content already viewable on your tablet.

Plus in the future I would hope to see some sort of evolution of the Smart Cover that can support a device in a 90 degree angle like the iMac stand.

Creating a WordPress redirection page

This is the simplest way to add a page redirection feature to your WordPress theme.

First, create a new theme file called redirect.php with the following contents:

<?php
 /*
 Template Name: Redirect
 */
 the_post();
 header('Location: ' . get_the_content());
 die();

To create a new redirection page:

New page, change the template to ‘Redirect’. Switch to HTML editing mode and put the url in the content area.

Release 1.1 – wordpress-basetheme

The aim for wordpress-basetheme is a bare bones, well structured, easily customisable WordPress base theme.

You can build on it to speed up your own theme development. It’s so minimal that I wouldn’t recommend it as your final site theme. Instead it makes it trivial to apply your design to a WordPress blog, or to build out from this starting point. This site is build on top of the project for example.

Version 1.1 is now available: Download View on GitHub

Changes:

  • updated styling and version
  • previous next buttons on singles
  • ie style targeting (unused), remove admin bar until supported, top nav
  • archives added and accessibility improvement
  • date permalinks
  • consistent titling
  • edit link in footer, no home
  • moved comments into its own template file
  • padding issue

Your feedback is welcome.

DisplayAnything3

DisplayAnything3 - File and image gallery module for SilverStripe3.0

DisplayAnything3 is a file and image gallery module for SilverStripe 3.0 with a big list of features. I’m looking forward to trying the module on a future project.

When Get-ADUser does not return the complete user

When writing a Powershell script that checks for changes to Active Directory users, you may find that all users change every time you run the script. One explanation for seeing this behaviour is because Get-ADUser does not return all the fields. A field that is not returned can never be equal to a string value.

For example, let’s consider the following code:

$csv_file  = "users.csv"
Import-Csv $csv_file | ForEach-Object {
    $username = $_.USERNAME
    $ad_user = (Get-ADUser -filter {sAMAccountName -eq $username})
    if (!$ad_user) {
        # create account, it does not exist
    }
    else {
        $filter_accountchanged = { $ad_user.DisplayName -cne $displayname }
        if ($ad_user | Where $filter_accountchanged) {
            # update existing accounts with changes
        }
        else {
            # account exists and has not changed
        }
    }
}

You will find that all existing accounts come up as having changed. This is because $user.DisplayName is not returned by Get-ADUser.

The issue is resolved by asking Get-ADUser to return all properties:

$ad_user = (Get-ADUser -filter {sAMAccountName -eq $username} -Properties * )

Now all properties are returned, and the “account change” filter works as expected.

Clear writing

The best way to write a clear blog post is to paste your draft into a text-to-speech engine such as tts-api.com and listen to the output. If you can’t easily understand what is said then that will most likely indicate problems with your sentence structure.

SilverStripe Gists

I’ve released the following data extensions (might pack them up as modules):

HiddenFields DataExtension: Takes form fields specified through $hidden_fields and hides them from edit form.

Description DataExtension: Specify a $db_descriptions array to DataObjects to attach formfield descriptions.

update: They are now modules, see my github page.