I created a simple Selection Rule that allows you to compare CCK Fields to a configured value.

This allows you to have different Variants based on a Field value, or for Visibility Rules for individual panes.

The project I built it for uses it to let Authors decide (Using a CCK Field) what to show on that Node's Teaser (using panels_teasers.module). Could be used to let Author's choose different layouts, show additional panes based on field selections, etc.

Due to the flexible nature of the actual SQL fields CCK used (*.nid, *.value, *.fid/*.list for files), I decided to add every "column" to the field selector list. This way, you can even compare the *.format of fields.

I had to change the hook_ctools_plugin function to include more than just the "content_types" folder. It now detects if the "panels/$plugin" folder exists, if it does, return the dir.

CVS didn't include the new plugin file in the patch, so I zipped up the patch to content.module and the plugin, which must go in the ./includes/panels/access folder.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

davidwhthomas’s picture

If you'd rather not use a module for this, you can use a PHP code in the Selection Rule for the Variant.

This for a node_view panel with multiple variants, to select based on that node's cck field value.

e.g:

<?php
// Check if CCK field "Section display" has value "Grid"
// CCK field info is in the $contexts variable
$return = FALSE;
if( isset($contexts['argument_nid_1']->data->field_section_display[0]['value']) ){
  if( $contexts['argument_nid_1']->data->field_section_display[0]['value'] == 'Grid' ){
    $return = TRUE;
  }
}
return $return;
?>

Note: don't include the php tags in the snippet.

hth,

DT

P.S It would be nice if Panels supported this natively, but I don't like the idea of patching other modules ( e.g CCK ) to get it to work.

stevector’s picture

Assigned: Jon Pugh » Unassigned
FileSize
3.14 KB

I also started to tackle this functionality about a week ago and went about it in a slightly different way. I didn't realize someone was already working on it. I've posted the code I have so far. This should also be dropped into CCK's /includes/panels/access after applying careernerd's change to the hook_ctools_plugin function.

As I conceptualized such a plugin, I wanted a two-step configuration process. At the first step a user would select which field is being used. At the second step the user would get the CCK widget appropriate to the field as a way of setting the value.

This approach was modeled after the way ctools does the Views content_type. On the first screen, the admin sets which Views display to use. On the second screen, the display is configured.

However, I was not able to replicate this two-step process. I think I'd need assistance from a CTools expert. In the attached file, you'll see some commented out code that attempts to do this.

Instead, this plugin is currently hard-coded to work with a field called field_public. It's a CCK text field that has the radio button options of

0|Private
1|Public

This plugin right now is tested with single-value text fields. Getting support for node refs and any other CCK type would be a small code improvement. Also commented out in this file is code starts to support multivalue fields.

davidwhthomas, I agree that I'd like ctools to support this natively. However, the precedent has been set with CCK supplying it's own content_type plugin. I think it's then appropriate for CCK to supply an access plugin.

careernerd, anyway we can combine our efforts? What if we expanded upon your plugin so that users selected which field to use on one form and then on the next, had the option of using the CCK widget for exact values or an open field for regex?

Jon Pugh’s picture

@davidwhthomas: I'm aware of the PHP selection rule, it's just that this is the whole point of CTools, so you can make simple plugins to make the logic common to many projects easy to configure. I'm not adding this patch for users, I'm hoping to get this into CCK itself.

Also, CTools in fact, should not contain this functionality natively because it is only used with CCK. I discussed this with merlinofchaos at DrupalConSF, since CCK already has the ctools_plugins hook, it is very easy to drop this into the next version of the module.

@stevector: The two step process sounds ideal. I built this plugin to have one step for simplicity, I haven't yet tried to make it two step. Also, I've tried to pull out individual CCK widgets as form items into other modules before and it was a real pain, so I'm not sure its worth the extra work. There are also additional challenges due to the flexible nature of the data column names.

My plugin already scans all values for multiple value fields, if one of them returns true, the selection rule passes.

I agree it's worth a shot, especially thinking about D7, I just won't have the time to work on this until another project pops up that needs this functionality.

Lets take my patch and build from there. I wrote it to be ready for committing, following coding standards and keeping it generic. I don't yet know how to make multipage forms with CTools, but I want to find out.

stevector’s picture

I think you're right careernerd. Your patch should go in because it works and is ready to go as is.

If in the future we want this to be a two-step plugin, I tried to dissect ctools/views_content/plugins/content_types/views.inc to replicate its process but was unsuccessful.

lord_of_freaks’s picture

subscribing

that0n3guy’s picture

sub...

markus_petrux’s picture

Status: Needs review » Needs work

Looking at the code, it seems that there are several snippets commented. These need to be removed. Also, the code does not follow coding standards, and we would need a patch. It's hard to review the code further.

Jon Pugh’s picture

FileSize
5.28 KB
808 bytes

No problem re: coding standards... I hadn't cleaned it up yet, I wanted to get it up so people can test it out.

Here's a patch for the hook_ctools_plugins_directory and a separate one for adding the new plugin file. I'm not fully versed in CVS, so it was a little challenging to add a new directory and file, but I think the patch is proper. instructions for this aren't perfectly clear... http://drupal.org/node/550576

Summit’s picture

Subscribing, greetings, Martijn

Remon’s picture

+1

stevector’s picture

@careernerd, In http://drupal.org/node/798180#comment-2987442 you mention scanning multiple fields but this code is only considering delta 0.

Did you just mean that in configuration of this plugin, multivalue fields could be selected?


$node_field = $node->$field_name;
$field_value = strval($node_field[0][$field_key]);

if (empty($conf['case'])) {
$value = drupal_strtolower($value);
$field_value = drupal_strtolower($field_value);
}

switch ($conf['operator']) {
case '=':
return $value === $field_value;
case '!=':
return $value !== $field_value;
case 'regex':
return preg_match($value, $field_value);
case '!regex':
return !preg_match($value, $field_value);
}

merlinofchaos’s picture

I never do this because I hate to, but this one is important enough, so this is me subscribing to the issue.

merlinofchaos’s picture

If there are ways I can enhance CTools to make this easier I'm very interested in doing so.

One thing I can think of that this might benefit from are wizard forms for access plugins (i.e, select a field in step 1 and in step 2, configure the test against that field).

However I'm not sure that's necessary, just useful. Still, implementing wizard forms for access plugins should be doable.

Lloyd’s picture

I applied the patches to display a variant if a CCK select list was of a specific value.

So, Content: Field Comparison, Node Being Viewed, and I selected the correct CCK field to equal "Info Both" (without quotes).

I get the following error:

warning: array_filter() [function.array-filter]: The first argument should be an array in /var/www/vhosts/provada.com/httpdocs/sites/all/modules/cck/includes/panels/access/content_field_compare.inc on line 132.

KarenS’s picture

I'm trying to understand this patch and its purpose. I'm not really clear on what this will accomplish, but when it comes to panels integration I'm happy to defer to merlinofchaos about what would be useful.

One thing that may not work as intended is if you have shared fields on different content types where you won't discover all the fields for all the types.

You use '$fields = content_fields()' to grab the available fields, but that function will not give you all the instances of shared fields. Instead you should do something like:

$types = content_types();
foreach ($content_types as $type_name => $info) {
  $fields = $info['fields'];
  etc...
}

That would give you all fields on all types. If you know what type you want to limit it to, you can do:

$type = content_types('page');
foreach ($type['fields'] as $field) {
  etc..
}
stevector’s picture

@merlinofchaos, adding wizard support to CTools to get the functionality you describe in #13 would be very helpful. Should a separate feature request be opened in CTools for that?

@KarenS, I'm using this patch to switch show/hide panes based on the value of a CCK field.

merlinofchaos’s picture

Yes, an issue for CTools for that is a good idea. Panels would probably need an update to its implementation of the access plugins as well.

merlinofchaos’s picture

I'm trying to understand this patch and its purpose. I'm not really clear on what this will accomplish, but when it comes to panels integration I'm happy to defer to merlinofchaos about what would be useful.

This patch, when complete and ready to go, would allow users to control the visibility of panel panes, variants and pages based upon the values of CCK fields.

One incredible use case that I really want to be able to put as a standard recipe: Let's say I have a node type 'article'. Articles can be laid out in various ways, and I do not want my content managers worrying about creating layouts or tweaking them. Instead, I want to provide a dozen or so layouts.

In the Panels node view, I can provide all of those layouts and set up the nodes so that when the data is filled in, each one of them will work. To select which layout a node is, I would put a CCK field, 'Layout' as a textfield with a select box. It would be prepopulated with the layouts I want. Then the selection criteria on the variant for that layout would ask "Is the layout field equal to the name of this layout?" If yes, use it.

stevector’s picture

I have created a feature request in CTools for wizards on access plugins. http://drupal.org/node/876722

The use case described in #18 is exactly the kind of functionality I want to provide. Thanks.

Jon Pugh’s picture

@karens: In this case I don't believe detecting the field instance is necessary. Panels handles the node context, and this plugin just checks to see if the field exists and matches the value entered. If the field doesn't exist in that type, the compare will just return false.

However...

@merlinofchaos: Wizards in access control makes sense to me. As far as I can see, "Selection rules" are the future of display logic. There's way to much room for error when you use custom PHP code to determine if something should show or not.

In the case of this plugin, the wizard might not be necessary if we can detect what node types are allowed, kindof like how in the panel content editor, the Field panes only show up for the nodetypes that may be available based on the selection rules... not sure how that would be accomplished, When I get a chance I'll dig through the code.

merlinofchaos’s picture

Yes you can detect what node types are allowed, but there will be instances when you have no idea what type it will be so you have to account for that situation.

That said I believe you want to look at $context->restrictions -- and these restrictions can be applied by previous access rules. Sadly this is not documented anywhere, so the only thing you can do is search for the word 'restrictions' and see how it gets applied.

Lloyd’s picture

Any clue how the warning message below can be fixed?

warning: array_filter() [function.array-filter]: The first argument should be an array in /var/www/vhosts/provada.com/httpdocs/sites/all/modules/cck/includes/panels/access/content_field_compare.inc on line 132.

xtfer’s picture

subscribing

Lloyd’s picture

Has anybody been able to confirm if the patch in #8 works? I still haven't been able to get it running successfully.

abulte’s picture

I'm very interested in this feature too, and I think it's a pretty common use case.

I also strongly agree with that, this is where we should be headed :

As far as I can see, "Selection rules" are the future of display logic. There's way to much room for error when you use custom PHP code to determine if something should show or not.

Lloyd’s picture

Any update with this. The current patch is still unusable for me as it results in errors. Would love to see this happen.

datawench’s picture

snippet at #1 is extremely helpful. subscribing to keep track of the plugin.

drupalok’s picture

subscribing

rickvug’s picture

This is a very common use case. Subscribing.

loganfsmyth’s picture

Status: Needs work » Needs review
FileSize
6.13 KB

Hello people,
This is definitely a feature that'll be useful, so we should try to get it done with. Having it be multi-step would be awesome, but for now we need to get a solution in there, and add more once access plugins can have a wizard options too.

I have reworked the patches from #8 a bit and fixed the array_filter error message that people mentioned. I also removed the negation of each operation because there is already an automatic negation options added by ctools. Finally, I also added a 'delta' option so that you can compare against a particular delta in a CCK field if you want to.

Thoughts?

Lloyd’s picture

Should the patch in #30 be in addition to the plugin patch in #8? Or is the #30 patch alone sufficient?

loganfsmyth’s picture

Just #30 is needed. I took the code from #8 and reworked it a bit and fixed a few issues.

pedrosp’s picture

I can't figure out how to deal with this patch, I've tried patching 6.x-2.9 and today's dev with no fun so far.
As far I understand the code I expect to see some additional options on the Panels Visibility Rules, and/or Selection Rules named : Content: Field Comparison
But nothing new :(

Any tips please ?

loganfsmyth’s picture

I haven't tested it since I posted it, but maybe make sure you've cleared your caches? Ctools will been to process all of it's plugin hooks again, since it caches all of that.

Vote_Sizing_Steve’s picture

FileSize
181.11 KB

I'm having the same problem as #34 - after running update, and clearing caches.

See attachment for screenshot.

Lloyd’s picture

Any progress on perhaps getting this committed? And the patch is no longer working for me.

stevector’s picture

I have an issue started for this is Drupal 7: #1299838: Field Comparison Access Plugin

stevector’s picture

I have an issue started for this is Drupal 7: #1299838: Field Comparison Access Plugin

stevector’s picture

The Drupal 7 version of this functionality has been committed. #1300476: Add Access Plugin for Entity Field Value