Theme CCK fieldset - drupal

I am attempting to use the CCK theme_fieldgroup_fieldset($elements) hook to convert the fieldset to a two column layout.
I thought that this shouldn't be to hard because the individual fields are in the $elements variable so all I have to do is iterate over them and print them individually. the problem is that I have no way to tell if they have been excluded from display on the "Display Fields" tab of the content type.
Does anyone have any ideas for me? Am I trying to do this the hard way or what am I missing?

Following is the solution that I came up with. The biggest problem is that it requires a database query for every field. These isn't the greatest, but it works so what can you say?
function _brioratheme_include_cck($field) {
$query = "SELECT display_settings AS ds FROM {content_node_field_instance} WHERE field_name = '%s' LIMIT 1";
$result = db_query($query, $field);
if ($result) {
$row = db_fetch_object($result);
$display_settings = unserialize($row->ds);
return !$display_settings['full']['exclude'];
}
}

Related

Limiting fields to certain users

Using SilverStripe 2.4.7.
I've done some searching but I can't seem to be able to find an answer to this. I want to include a checkbox on a popup window in dataobjectmanager but not for every user.
I have two separate pages, one for one user and another for the other, and I only want the checkbox on one. I thought an if statement would suffice, quick and simple right?
public function getCMSFields()
{
$categories = array("Morning","Afternoon", "Evening", "Night");
return new FieldSet(
new TextField('Title'),
new DatePickerField('Date', 'Date'),
new ImageField('Photo', 'Photo'),
new MoneyField('AdultPrice', 'Adult Price'),
new MoneyField('ChildPrice', 'Child Price'),
new DropdownField('Category', 'Choose a Category', $categories)
);
This is my attempt at the if statement approach
if($this->ClassName == 'Movie'){
$films= DataObject::get('Films');
if (!empty($films)) {
// create an array('ID'=>'Name')
$map = $films->toDropdownMap('ID', 'Name');
$fieldset->push(new CheckboxSetField(
$name = "Films",
$title = "Select Films",
$source = $map
));
}
}
Basically this works if I use it within getCMSFields_forPopup, but not in just getCMSFields, but changes my checkboxsetfield to a dropdown.
Edit
I have found that my approach would not work due to the fact that the DOM Popup cannot have the classname of the page which contains the DOM (DataObjectManager). This is a simple inheritance issue and I can't believe I didn't see it before. See the answer below for details of how I solved my original query.
In the end the answer was quite simple. I did the following and I hope someone finds this useful.
Create the checkboxset on the page as normal
if(Permission::check("ADMIN")){
if (! empty($values))
{
$checkBox = new CheckboxSetField(
$name = "Values",
$title = "Select Value",
$source = $values
);
$fieldset->push($checkBox);
}
}
The if statement with Permission::check("ADMIN") checks if the admin is logged in and only shows the checkboxset if they are.
You will also need to include the $fieldset->push within this method to add it to the cms. The ADMIN can be changed to any of your user groups which you created in the security panel so this is an adaptable approach.
I found this the best way for me but if someone can improve on it/offer a better solution I'd love to hear about it.

How to list a form's field-names

I have a form, and want to generate a list of the form's field-names. Here is how I currently do it:
$fieldnames = array();
foreach ($form as $key=>$val){
if (substr($key, 0, 6) === 'field_'){
$fieldnames[] = $key;
}
}
Is there a better way to do this?
UPDATE:
Just to clarify ... I am wondering whether there is a less "kludgey" way of doing this. For example, does the content module provide an api function that loops through fields. (I couldn't find one.)
the field that you added by cck...or from UI field system are begin with "field_"
and this fields are usually in the nodes...so if you are talkin about nodes form
and fields that added by cck....you are in the correct way... but if this fields are added programmatically....so you are in the wrong way
sorry im not 100% sure but i don't think you can get all the fields that added programatically..but if you added this fields from cck or from '/admin/content/node-type/stores/fields' where {stores} is your content type that you are working with then you can get this fields name from {content_node_field_instance} table as the following
$result_handle = db_query("select field_name from {content_node_field_instance} where
`type_name` = '%s'","yourContentTypeName") ;
while($result_object = db_fetch_object($result_handle)){
$fields[] = result_object->field_name ;
}
now you have the array $fields which hav all the fields of your content type...i hope that will help you

Drupal: hook_search only for a content type

I would like to build a custom search module in Drupal 6 for searching through CCK. I need the user to search between his nodes (node.uid=x) and of a certain type (type='xyz'). I think I have to implement hook_search but I don't know where to put my filters. Can anyone help me?
You already accepted an answer (which is probably the best option for you), but there are a few other ways to accomplish this.
IIRC, the Custom Search module will work for what you want.
You can copy the stock hook_search function to a custom module and modify the query. You can do something like this:
// ...
case 'search':
// Build matching conditions
list($join1, $where1) = _db_rewrite_sql();
$arguments1 = array();
$conditions1 = 'n.status = 1';
// NEW BIT START
$allowed = array(
'content_type_1',
'content_type_2',
'content_type_3',
);
$types = array();
foreach ($allowed as $t) {
$types[] = "n.type = '%s'";
$arguments1[] = $t;
}
$conditions1 .= ' AND ('. implode(' OR ', $types) .')';
$keys = search_query_insert($keys, 'type');
// NEW BIT END
This replaces the bit that extracts the type from the actual query string.
You would have to add in the bit to restruct to a particular n.uid. I have been using this method lately, rather that Custom Search, because it simpler from the user's perspective.
HTH
You might try creating a Views with an exposed filter, it's the absolute easiest way to implementing your idea.
Also you can try use CCK Facets. But Views - of course simple.

Displaying similar nodes

I've somewhat ran in to a problem with Drupal today.
I would like to display a node (Product) on a page, and below that node, I'd like to display 3 similar nodes (Products). Similar being: having the same taxonomy id or having a "promoted" tag attached to it.
I've tried crafting the related nodes into a view which is being displayed as a block, only when we're on a product's page. I didn't get far with this.
My second thought was making a panel page with 2 views on it, one for the product, and one for the related products. I also didn't get far with this.
Does anybody know the easiest way to accomplish this?
Update:
I have tried both answers, I am not receiving any related products though. The SQL query that's executed (term id = 1) is:
SELECT node.type AS node_type, node.title AS node_title, node.nid AS nid, node.created AS node_created FROM {node} node INNER JOIN {taxonomy_index} taxonomy_index_value_0 ON node.nid = taxonomy_index_value_0.nid AND taxonomy_index_value_0.tid = :views_join_condition_0 WHERE (( (node.type IN ('product')) AND (taxonomy_index_value_0.tid AND '') AND( (taxonomy_index_value_0.tid IN ('1')) ))) ORDER BY node_created DESC LIMIT 10 OFFSET 0
When I manually execute the query and remove AND (taxonomy_index_value_0.tid AND '') from the query I do receive the related products.
Does anybody know what causes the code to be added to the query and how to fix it?
Update 2:
I've removed the "Allow Multiple Terms per Argument" and am now getting the related products. I don't know what this means for my site though.
Update 3:
I am using Drupal 7 by the way.
Override your node view with panels. And create a view block with 'taxonomy id argument', you need to choose default argument options as PHP Code and place this code.
$node = node_load(arg(1));
if($node) {
foreach($node->taxonomy as $term) {
$term = $term->tid;
return $term;
}
}
I just launched a site using panels + views magic. http://sgigulf.org/culture/synopsis-of-performers-showcased-by-sgi-gulf
Take a look at the RelatedContent module. Links to the module and a couple of tutorials below:
http://drupal.org/project/relatedcontent
http://drupaleasy.com/blogs/ryanprice/2008/06/using-views-2-drupal-6-create-a-related-pages-block
http://www.hankpalan.com/blog/drupal/related-content-views-2-drupal
You say you're having trouble with the display. In that casea, make the view from the above instructions a block, and have it display in a region that's below the node content, though that assumes there's a region in your theme directly below your content.
You can have multiple terms when you change to
$node = node_load(arg(1));
if ($node) {
$ret = array();
foreach ($node->taxonomy as $term) {
$ret[] = $term->tid;
}
return implode('+', $ret);
}
return '';
The '+' in implode is OR. If you want AND, than use ',' instead

Custom logic for exposed filters in a Drupal view

I'm working on a Drupal site and would love some advice on this. Currently, a user enters his level for a number of different skills. This is stored in a CCK integer field and exposed to the user as a drop-down widget containing the key/value pairs 1|Beginner, 2|Intermediate, 3|Advanced.
In a view, I expose the allowed values for each skill, which are presented to the user as checkboxes (using the Better Exposed Filters module) and then listed in a sortable table. In practice, users generally search for people who have "at least knowledge level X in skill Y". Is there a module or straightforward way to display the allowed values as a drop-down and use a "greater than" operator in the query instead of a "one of"?
Any sample code or advice on how to dynamically change the filter logic or the WHERE clause of the query would be very appreciated.
You want to use hook_views_query_alter(), while I haven't specifically altered the WHERE clause, I have altered the SORTBY clause and the idea behind both should be relatively similar.
Here's a quick piece of code:
function my_module_views_query_alter(&$view, &$query) {
switch ($view->name) {
case 'view1':
$args = _my_module_get_querystring();
switch ($args['condition']) {
case 'condition1':
$query->where[0]['args'][0] = 1;
break;
case 'condition2':
$query->where[0]['args'][0] = 2;
break;
}
break;
}
}
/**
* Returns querystring as an array.
*/
function _my_module_get_querystring() {
$string = drupal_query_string_encode($_REQUEST, array_merge(array('q'), array_keys($_COOKIE)));
$args = explode('&', $string);
foreach ($args as $id => $string) {
unset($args[$id]);
$string = explode('=', $string);
$args[$string[0]] = str_replace(' ', '-', $string[1]);
}
return $args;
}
This particular piece would allow you to alter the WHERE clause using a querystring (?condition=condition1), but you could alter it to get the arguments however you wish.
Hope this helps.
Using Decipher's sample and spending a few hours reading up and playing around, I've gotten a basic module that works perfectly for my needs. Thanks again!
Here's my code if anyone else comes across a similar need:
<?php
// $Id$
/**
* #file
* Module for modifying the views query to change an EQUALS
* to a GREATER THAN for specific filters.
*/
function views_greater_than_views_query_alter(&$view, &$query) {
//only implement for views that have Search in their name
if(strstr($view->name, "search")) {
$whereclauses = $query->where[0]['clauses'];
foreach ($whereclauses as $i=>$currentrow) {
$currentrow = str_replace('= %d', '>= %d', $currentrow);
$query->where[0]['clauses'][$i] = $currentrow;
}
unset($whereclauses);
}
}

Resources