Wednesday, December 28, 2011

subuser and organizational administration

Once subusers were creating, with content profiles creating and editing alongside, I also needed the ability to delete those users that I'd created. 

Administer subusers wasn't enough, since I didn't want my parent users visiting the user administration page - just cause it's one more thing to train them on.

Instead, I added a views field handler to show a delete link, plus I had to customize the access callback to ensure that users don't delete themselves.

All in all, not so bad.  I think I'll contribute that back into the module if I can...

Posted via email from dsayswhat's posterous

virtual_roles module

Just implemented virtual roles module for the first time.  After some initial headache, it works well.

virtual_roles (henceforth: VR) uses contexts (oh no not again, find a new word please) to decide when to trigger some role-related action.  VR ties contexts to role processing, lets you define custom logic for when that role is to be applied, etc.  All very nice.

The key thing about virtual_roles is that it has cache baked in, and it's non-optional.  Contexts are made up of two possible $ops, cache and process...you can turn off caching in the UI, but you still have to provide a cache case in the context, or things won't work as expected.  Be safe: define a cache id in your virtual roles context.

Posted via email from dsayswhat's posterous

Friday, March 18, 2011

Creating a views handler for Drupal 6 - Part I

A note about the purpose of this post:

I tend to work from the UI backward when I can.  It's helpful to mock up the process little by little, and working front-to-back lets you click and experience the work you're doing early on.  That can have good results with usability, and also can help to clarify thinking when you don't know quite what you're building yet. 

In the case of both views and custom CCK fields, I've had difficulty figuring out how to achieve that basic prototyping, as their methods of implementing the UI layer are very specific and abstracted.  Even after reading several blog posts and the views API documentation, the process of creating a filter for views was still fairly opaque to me.  Sometimes the minimum set of steps to achieve a simple result isn't top-of-mind when people blog about development tasks, so I'm making my own notes.

In Drupal, the all-important Views module can be extended with 'handlers'.  Handlers are used to implement filters, fields, and arguments.  They are php classes, typically contained in a .inc file somewhere in your module directory.  You describe your classes and how they'll be used by implementing one of several hooks.  The most lightweight views filter implementation requires 4 things: 3 hook implementations and a class. 

Hooks you must implement:

  1. hook_views_api - this declares that you're going to do something 'viewish' with your custom module.  This function returns an array specifying the lowest views api version you'll support, and where your module is located.  See http://views.doc.logrus.com/group__views__hooks.html#gc67ffd4a2f61f9814ee37b541c472c47hook_views_data
  2. hook_views_handlers - here you announce to Drupal that you're implementing an handler.  This hook specifies you'll specify the parent class and the filename your class lives in.  See http://views.doc.logrus.com/group__views__hooks.html#gbf506f44bd8d8a86876f27396f5341ed
  3. hook_views_data_alter OR hook_views_data - these hooks tell Views where your handler fits into the data model that views uses to generate queries.  For simple filters that rely on existing tables, use hook_views_data_alter to add your handler to, say, the information already related to the node module.  If you've got a whole module with its own tables, you'll want to describe them to views using hook_views_data.  The array that describes your data to views does so field by field, specifying what kind of field, argument and filter handlers your fields will use.  You'll also be able to specify relationships and joins to other data in hook_views_data.  See http://views.doc.logrus.com/group__views__hooks.html#g227057901681e4a33e33c199c7a8c989
Once you've told Drupal your module wants to work with Views (hook_views_api), that it implements handlers (hook_views_handlers) and how the handlers relate to the database schema that Views knows about, you're all set.

Well not really - with the three hooks implemented, and your cache cleared to pick up the new hook implementations, you'll be able to see your handler in the appropriate spot in the views interface.  In my case that was in the taxonomy group under 'Filters', as I was implementing a slightly customized term id filter.

With the hooks, you'll be able to select the filter and add it to your view - but the filter class doesn't exist yet.  Views will tell you that your handler is broken, but you will be able to see the handler in the Views UI.

Next you have to implement the class - I'll make more notes about that later...

Posted via email from dsayswhat's posterous

Monday, January 24, 2011

subuser access

I've been implementing the subusers module to allow delegation of user creation and editing for non-admin users. 

That works ok, but I had to do a couple of things:

I've got organizations that have staff members, and a general manager who should be able to add/edit those users.

Modules that we're using to enable the org->member relationship.

CCK - defines the content types for org and contact

Content profile - associates the contact cck type with users. Had to be patched with this: http://drupal.org/node/425144#comment-3410500 to add a permission to allow content profiles to be administered by roles other than admin.

subuser - allow users to create users under their account, and edit/delete them.

Subuser required two patches to work with content profile. They're both found on this issue: http://drupal.org/node/571660#comment-3984138

Permissions required to get all this working:

  • content profile module::administer content profiles
  • subuser::administer subusers
  • subuser::create subuser

views_attach - used to put a list of content profiles on the organization node based on the 'belongs to' nodereference field on contacts.


For users who don't have the 'administer users' permission, you'd think you can visit the profile of any of their subusers, but that's not always the case. 

The core user module throws an access denied error when you try to visit the profile of a non-logged in user and you don't have administer users permissions. 

There are some cases where a non-admin user like the ones on my site might want to edit their users regardless of whether they've logged in or not.  For instance, if I type in an email address wrong, I'll want to fix that, but I won't be able to visit their user profile.  I can visit their edit screen, but not the user profile.  The subuser module overrides the user/%/edit access_callback, but not the one for the view page.  May have to adjust that in the subuser module and file a patch. 

Posted via email from dsayswhat's posterous

git setup for new drupal site.

I've been developing a drupal site, and am ready to add it to a git repository for initial deployment.

One of the things I've noticed is that some things you shouldn't version...sites/default/settings.php shouldn't be in git, also sites/default/files and backup/ aren't good to have in there.

So I did the following:

- created the repo out on github.
- cd'd to my site root.
- rashly ran 'git add .'
- ran 'git rm -r --cached sites/default/files/*', 'git rm -r --cached backup/*', and 'git rm --cached sites/default/settings.php'
- created a .gitignore file in the root of my drupal site.  It contains the following lines:

backup/*
sites/default/settings.php
sites/default/files/*

 That will ignore those directories in the future when I got to commit or update.

- ran 'git commit'
- ran 'git remote add origin git@github.com:{repo_path_here}' and 'git push origin master'

Posted via email from dsayswhat's posterous

noderelationships and nodereferrer

Noderelationships sets up the ability to do nice js-enabled usability enhancements for cck nodereference fields.

However, I had more specific constraints...I needed to customize the view that you use when selecting nodes.  Normal arguments and filters don't work when set on noderelationships-based views, provided for your use by the module.

I tried using some instructions found on drupal.org ( issue refs here ) to filter by url arguments, etc but it didn't work...however, plain 'ol ( fancy 'ol ) hook_views_pre_view worked like a charm, using $view->default_handler->override_option('filter', $filter = array( {assoc array defining a views filter} ) );

Also, I needed to filter so that previously referenced nodes wouldn't show in the view - single noderef only please.  I had to install nodereferrer...

Now, node_relationships special treatment of views prevents filters and arguments, but it allows relationships.  So you have to set a nodereferrer relationship on the view, then add a filter such that referencing nodes is empty.  But the filter doesn't take since node_relationships is doing it's fancy thing.  So I ran a views export, copied the resulting filter array, and added another filter in my hook_views_pre_view. 

I feel like I triumphed...huzzah.

Posted via email from dsayswhat's posterous

What to do when Cron gets stuck...

If you're trying to run cron via drush, and it gets stuck due to insufficient memory or something, use drush to delete the 'cron_semaphore' variable.

drush vdel cron_semaphore

Ta-daaa.

Posted via email from dsayswhat's posterous