Disable taxonomy term delete button if term has nodes.

The below snippet will disable the delete button on the taxonomy term edit page if the term has any nodes assigned to it.
It implements hook_form_FORM_ID_alter()

 function hook_form_taxonomy_form_term_alter(&$form, &$form_state) { 
$query = db_select('taxonomy_index', 't');
$query->condition('tid', $form_state['term']->tid, '=');
$query->join('node', 'n', 't.nid = n.nid');

$count = $query->countQuery()->execute()->fetchField();
if ($count) {
$form['actions']['delete']['#disabled'] = TRUE;
$form['actions']['delete']['#suffix'] = "<span>$count nodes, cant delete</span>";
}
}

No storage space on your phone? Are you using Tango?

Today while I was trying to move some music on to my phone I noticed there was not much free space left (8 Gig Nexus 4). I initially thought that it must be because I had too many photos or videos on the phone, so I went into the 'settings->storage' section of the phone to check things out.

I was surprised to see that I had over 450MB of pictures and video and thought I should probably cull a few, but I was even more surprised to see that apps were taking up nearly 2.5GB. WTF, I haven't got that many apps installed, how can this be.

Clicking on 'Apps (app data & media content)' took me to a list of all my installed apps ordered by the amount of storage space they were using. WTF, Tango is taking up 1.05GB, how can this be. Clicking on tango in the list takes me to an App info page where it reports that the app itself is using 62.46MB and 0.99GB of data.

I think that Tango must be caching everything it can and never actually clearing the cache. As I have a Nexus 4 with only 8 GB of space, this is a real concern.

Along with the fact that you can see friends of friends on Tango , I am considering removing Tango from my phone altogether.

Drupal Module: Watchdog Event Extras

When checking the logs on the Drupal sites I run I often find myself copying the IP and searching it on google. Most of the time it is when I'm looking at a page not found or login attempt failure and I would like to know if these came from some sort of spam or a legitimate user. This process became a little tedious, so I created the Watchdog Event Extras module.

Basically what the module does is overrides the standard drupal log event page, outputting the same and adding a drupal_alter()
call. At the moment the module includes two sub modules, the first of which adds geolocation data derived from the hostname and the freegeoip.net web service with the second adding data from the stopforumspam.com web service.

Any other module can also add data to the report page by implementing MYMODULE_watchdog_event_extras_alter(&amp;$rows, $dblog)

Cheick it out https://www.drupal.org/project/watchdog_event_extras

Also, don't forget to checkout the Link Favicon Formatter module if you ever needed to add a site favicon to a link field: https://www.drupal.org/project/link_favicon_formatter

Drupal Migrate V2 and Addressfield

While trying to migrate data from a legacy CakePHP system to Drupal 7 recently I had a problem getting an Addressfield field to play nicely.
What I had origianly was this (which did not work).

  $this->addFieldMapping('field_customer_address:thoroughfare', 'address'); 
$this->addFieldMapping('field_customer_address:locality', 'suburb');
$this->addFieldMapping('field_customer_address:administrative_area', 'state');
$this->addFieldMapping('field_customer_address:postal_code', 'postcode');

Looking all over the web I found many examples saying to use the arguments function. eg.
  $address_arguments= array( 
'thoroughfare' => array('source_field' => 'address'),
'locality' => array('source_field' => 'suburb'),
'administrative_area' => array('source_field'=>'state'),
'postal_code' => array('source_field' => 'postcode'),
);
$this->addFieldMapping('field_customer_address')
->arguments($address_arguments);

But when trying this I got a message from the module saying that this was not correct. I think the above code was/is for version 1 of the migrate module.
It turns out that all I needed to do was to set a default country. ie.
  $this->addFieldMapping('field_customer_address')->defaultValue('AU'); 
$this->addFieldMapping('field_customer_address:thoroughfare', 'address');
$this->addFieldMapping('field_customer_address:locality', 'suburb');
$this->addFieldMapping('field_customer_address:administrative_area', 'state');
$this->addFieldMapping('field_customer_address:postal_code', 'postcode');

Drupal Domain Access user 1 menu

Today when developing a Drupal site with the Domain Access module I had an interesting problem.
My site is set up with a custom theme and 2 domains.
My custom theme is using Zurb Foundation and so I had to override the main menu theme functions to add the Zurb classes.
This was easily done by implementing theme_links__system_main_menu, theme_menu_tree__main_menu__submenu and theme_menu_link__main_menu as outlined below (my theme name is nexus).

 function nexus_links__system_main_menu($variables) { 
$links = menu_tree_output(menu_tree_all_data(variable_get('menu_main_links_source', 'main-menu')));
$output = drupal_render($links);
return $output;
}

function nexus_menu_tree__main_menu__submenu($variables) {
return '<ul class="menu dropdown">' . $variables['tree'] . '</ul>';
}

function nexus_menu_link__main_menu($variables) {
$element = $variables['element'];
$sub_menu = '';
if ($element['#below']) {
$element['#below']['#theme_wrappers'][] = array('menu_tree__main_menu__submenu');
$sub_menu = drupal_render($element['#below']);
$element['#attributes']['class'][] = 'has-dropdown';
}
if (isset($element['#href']) && ($element['#href'] == $_GET['q'] || ($element['#href'] == '<front>' && drupal_is_front_page())) && (empty($element['#language']) || $element['#language']->language == $language_url->language)) {
$element['#attributes']['class'][] = 'active';
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

The problem was that all node links assigned to the main menu would show up if you were logged in as user 1, even if they were not assigned to the current domain. Though, if you were not logged in the menu would appear correct and only show links assigned to the current domain.
This is obviously the correct behavior as the domain access module uses Drupal's node access system and the access system is bypassed for user 1.
At this point I could have switched...

Drupal Bootstrap 3 theme media queries javascript event (like Omega 3)

Having used the Omega 3 Drupal theme for a few years now I got quite use to writing javascript functions that would react to the 'reponsivelayout' event that was supplied by the theme. This event would fire after the responsive classes were applied to the body tag when the page loaded or when the media queries changed the site layout.
I often used this event to create things like mobile menus and such.
Now on the latest site I am building I am trying out the Bootstrap theme which does not fire such an event, so I thought I would add one that basically uses javascript similar to the Omega 3 theme.
If you would like the same, just add a js file to your Bootstrap sub theme with the js below:

 (function($) { 

var setCurrentLayout = function (oldLayout, newLayout) {
$('body').removeClass('responsive-layout-'+oldLayout).addClass('responsive-layout-'+newLayout);
$.event.trigger('responsivelayout', {from: oldLayout, to: newLayout});
};

var checkCurrentLayout = function () {
var current = 'xs';
var dummy = $('<div id="bootstrap-media-query-dummy" class="container"></div>').prependTo('body');
var width = dummy.outerWidth();

if (width > 750 - 1) {
current = 'sm';
}
if (width > 970 - 1) {
current = 'md';
}
if (width > 1170 - 1) {
current = 'lg';
}
dummy.remove();
if (typeof Drupal.settings.currentLayout == 'undefined') {
Drupal.settings.currentLayout = current;
setCurrentLayout('', current);
} else if (Drupal.settings.currentLayout != current) {
var old = Drupal.settings.currentLayout;
Drupal.settings.currentLayout = current;
setCurrentLayout(old, current);
}
...

My Turbosquid 3d models and textures are now free to download

I have recently made all my assets on Turbosquid free. Some of them have been free all along but as the ones that were not free were not really selling anyway, they might as well be free. The freebies include:

  • a wolfman model
  • a lowpoly demon which is rigged, textured and animated
  • an Australian army tileable texture
  • and a tileable paver texture with normal map

Please credit me if you use these models :)




Seeing friends of friends on Tango

Not long ago I installed the Tango app on my Nexus 4. I mainly did this as friends were using the app and told me I could use it for video chatting, and it seems to work reasonably well for this.

But then I found something that concerned me a little, it seems you can see your friends friends and there is no way to disable this.

To see a particular friends friends, all you have to do it block all the other friends (which may be difficult as Tango lists all contacts, not just Tango friends) then go to "friends" -> "People you may know" and you will see a list of that friends friends.

While I have nothing to hide and don't really care if other people see who I am friends with, the fact that this can not be turned off seems like something that would concern some people.

EDIT - 12 Nov 2014
It seems Tango has been updated and this no longer applies or you can now disable it.

Drupal 7 Changing the taxonomy term link paths

I have seen many questions on the web about how to change the path of the taxonomy term links, so it seems to be a common thing to want to do, I know I have wanted to do this on many projects. Recently on a project I wanted these links to point to a view with an exposed filter on taxonomy. As I had this view to list and filter nodes, there was no real reason for the standard taxonomy term pages.

There are a few ways to change the standard path of the taxonomy term links, but the easiest I have found is the Entity Path module .

It seems it is the successor to the Taxonomy Redirect module which does not have a Drupal 7 version.

If you want to go a step further and disable the taxonomy term pages, you can do this with the Rabbit Hole module .

A note on using with pathauto
The default pathauto alias setting for taxonomy terms is something like [voacbulary:name]/[term:name], you will probably want to remove this altogether. I had some issues with taxonomy path aliases until I removed the taxonomy pathauto setting.