Posted by rjleigh on March 7, 2007 at 6:02am
18 followers
Jump to:
| Project: | Content Construction Kit (CCK) |
| Version: | 6.x-2.x-dev |
| Component: | General |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Issue Summary
I've tried several methods, and I've searched for quite a while without luck, looking for an example of using PHP code in a CCK field to return a keyed array of allowed values.
Anyone able to give a simple example?
Comments
#1
latest 1.x release shows a little more informative help text.
#2
I'm using the latest 4.7.x-1.4 version. All it says under the PHP code box is:
Advanced Usage Only: PHP code that returns a keyed array of allowed values. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the allowed values list above.I understand that it needs a keyed array, but when I create one it does nothing. I'm guessing the array has to have to have a specific name, or be declared in a particular way, but can't find any info on that.
I was hoping for a sample that works, so I can see what is needed.
#3
yes, "latest 1.x" means "the 4.7-1.x-dev (or 5.0-1.x-dev) non official code", available under the "all releases" link on the project's page (http://drupal.org/project/cck), or via CVS
It will appear in 1.5 release, when it's published (not scheduled yet...)
#4
OK, sorry, I screwed this completely :-)
I'm talking about the 'default value php code', whereas you're asking about the 'allowed values php code' - i read too fast, and mixed threads with http://drupal.org/node/126776
So, just to make things clear : I did not commit anything to make this area more informative
And AAMOF, I'm not too familiar with the 'allowed values stuff', so I don't have a precise answer out of the box...
So setting back to 'active' :-(
#5
Here's an example that should work:
$sql = 'SELECT first_name
FROM civicrm_contact
JOIN civicrm_group_contact ON civicrm_contact.id = civicrm_group_contact.contact_id
JOIN civicrm_individual ON civicrm_contact.id = civicrm_individual.contact_id
WHERE group_id =2
ORDER BY first_name';
$res = db_query($sql);
while ($row = db_fetch_row($res)) {
$rows[] = $row;
}
return $rows;
#6
CORRECTION:
while ($row = db_fetch_row($res)) {
should be
while ($row = db_fetch_array($res)) {
However, it doesn't work very well. On my server, the select box shows both the key and the value. Check boxes don't work at all. And, a small error in the syntax resulted in bringing down my entire site. Not ready for prime time.
#7
Change your code to this:
while($row = db_fetch_array($res)){
$rows[] = $row['first_name'];
}
This will disregard the key and will only display the values.
Logically, you would only need this for your select fields.
#8
Here's the simple answer that the help text and documentation doesn't provide:
Enter this:
0|Label for off
1|Label for on
into the "Allowed values" field. Then your default setting will be respected, and the label will properly show on the form.
#9
#10
I'm using CCK 6.x-2.2 and had to do the same thing. I don't really know MySQL querying and I'm relatively noobish at PHP. But here's an example of one I did that worked for a similar situation:
global $user;
$sql = "SELECT title FROM node WHERE uid = ".$user->uid." AND type = 'hyperfiction'";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[] = $row['title'];
}
return $rows;
This returns a list of all the hyperfictions (content type) a user has created. I applied this for a content type called "hyperfiction node" so that I could associate all the hyperfiction nodes with their parent hyperfiction (kind of a story functionality, I suppose). So when they go to make a hyperfiction node, they now have to select which hyperfiction it goes with, and it provides a dropdown populated with all the hyperfictions they have made.
Awesome!
#11
jgarbe... thanks from one noob to another... it worked perfectly
I combined the output of two fields into one with a dash in between... just another example for up and comers:
$sql = "SELECT `field_acronym_value`, `field_fullname_value` FROM `content_type_course`";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[] = $row['field_acronym_value'] . " - " . $row['field_fullname_value'];
}
return $rows;
Thanks!
#12
One thing missing from these examples is that $rows needs to be a keyed array (the key is what is stored, so something like
global $user;$sql = "SELECT title FROM node WHERE uid = ".$user->uid." AND type = 'hyperfiction'";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[] = $row['title'];
}
return $rows;
should be more like
global $user;$sql = "SELECT nid, title FROM node WHERE uid = ".$user->uid." AND type = 'hyperfiction'";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[$row['nid']] = $row['title'];
}
return $rows;
Side note: This particular case can be handled with the node reference field plus views.
#13
I am trying to do the same thing unfortunately when I try this code.
$sql = "SELECT title FROM node WHERE type in 'book_series' ORDER BY node_title ASC";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[$row['nid']] = $row['title'];
}
return $rows;
I receive an error "Fatal error: Call to undefined function dq_query()" Any suggestions?
#14
Where did you put the code? Does the code really read "db_query" or as the error suggests "dq_query"?
#15
You have an error in your SQL query:
$sql = "SELECT title FROM node WHERE type in 'book_series' ORDER BY node_title ASC";it should be:
$sql = "SELECT title FROM node WHERE type in ('book_series') ORDER BY title ASC";#16
Hi.
I want more integration with value's node. can you give here example of linked to node value
for example, i have content type "customers" with title 1, 2, 3, 4, etc
now allowed values like
global $user;
$sql = "SELECT nid, title FROM node WHERE uid = ".$user->uid." AND type = 'customers'";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[$row['nid']] = $row['title'];
}
return $rows;
give me not sorted list of customers titles
now i create new node with this field, choose one of my customers and wanna see link to this customers node. how to do it ?
#17
new problem
after creating cck field with php code allowed values like
global $user;
$sql = "SELECT nid, title FROM node WHERE uid = ".$user->uid." AND type = 'customers'";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[$row['nid']] = $row['title'];
}
return $rows;
i create vews block with this field
from administrator account i have node titles , but from anonimous i have nid of row , no title value
anyone can help me ?
#18
Hi there, I'm trying to do something similar to what is mentioned here, except I'm using a "if" statement to determine the allowed values depending on user type.
So to start, I do a query to determine current users user type. -1 is default user, which is employees and user type id "1", is for site users. What I want is to restrict the site user to only the allowed values they need to see, while allowing employees to edit that value when on the node edit screen with all choices.
The first part of the if statement works. However, the "else" part doesn't work. Is this field set up to deal with control structures?
global $user;$sql1 = "SELECT user_type_id FROM user_types_user WHERE uid = ".$user->uid." ";
$res1 = db_query($sql1);
if($res1 = '1'){
$sql = "SELECT account FROM users WHERE uid = ".$user->uid." ";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[] = $row['account'];
}
$rows = drupal_map_assoc($rows);
return $rows;
}
else {
$sql2 = "SELECT title FROM node WHERE type = 'accounts' ";
$res2 = db_query($sql2);
while($row2 = db_fetch_array($res2)){
$rows2[] = $row2['title'];
}
$rows2 = drupal_map_assoc($rows2);
return $rows2;
}
The choices are type=accounts in nodes, however, when a user is created one of the choices is selected and stored in the user table, under a column I created named "account"
Tim
#19
Your if should read
if($res1 == '1')(double equals signs)#20
Wow, that was a noob error, sorry about that.
I fixed that, but still the second (else) block won't execute...
#21
The problem was that I was comparing the value of the column to a string (literal), when the value was an integer.
Here is the working code:
global $user;$sql1 = "SELECT user_type_id FROM user_types_user WHERE uid = ".$user->uid." ";
$res1 = db_query($sql1);
while($type = db_fetch_array($res1)){
$types[] = $type['user_type_id'];
}
$resType = $types[0];
if($resType == "1"){
$sql = "SELECT account FROM users WHERE uid = ".$user->uid." ";
$res = db_query($sql);
while($row = db_fetch_array($res)){
$rows[] = $row['account'];
}
$rows = drupal_map_assoc($rows);
return $rows;
}
else {
$sql2 = "SELECT title FROM node WHERE type = 'accounts' ";
$res = db_query($sql2);
while($row2 = db_fetch_array($res)){
$rows2[] = $row2['title'];
}
return $rows2;
}
#22
I'm NOT a php programmer but would really like to get an example of code that I can use on my site http://www.tinemuller.dk/test_drupal/ in the box PHP code from CCK link because I'm going to use it making several diff. links dynamic using taxonomy and such things but need a simple example to get me started, please?
Edit: And maybe just tell me how to use the code which is under the PHP code
return array(0 => array('url' => value for url, 'title' => value for title, 'attributes' => value for attributes),
// You'll usually want to stop here. Provide more values
// if you want your 'default value' to be multi-valued:
1 => array('url' => value for url, 'title' => value for title, 'attributes' => value for attributes),
2 => ...
);
#23
I got help from IRC to make this but what could attributes be?
return array(0 => array('url' => "www.google.co.uk", 'title' => "link to google uk", 'attributes' => ""),
1 => array('url' => "www.google.com", 'title' => "com version", 'attributes' => ""),
2 => array('url' => "www.google.co.au", 'title' => "co.au version", 'attributes' => "")
);
But only the FIRST link are showed and I want to use some more advanced example so hope someone here can help.
#24
This is not a CCK3 issue, per se.
#25
I really have something strange going on! Why it happens I really don't know...
Check this out:
first my code for the array in the allowed values:
$companies="SELECT DISTINCT value FROM profile_values WHERE fid = '39'";$result=db_query($companies);
$amount=mysql_num_rows($result);
$var=array();
for ($counter=0;$counter<$amount;$counter++)
{
$test=mysql_result($result,$counter);
if ($test <> "")
{
array_push($var, $test);
}
}
return $var;
Now $var really holds the "company names". I checked that! Now I checked the database (the tabel: content_field_company_name) and within the last column "field_company_name_value"... The selected values of the $var array wil not be stored, no!..; even stranger there numeric sequence in the $var array is stored... very strange.. So if, for example "philips" would be the 6th element in the $var array, and the node would be marked with "philips", in the column of the tabel database for that paricular field, "6" will be stored and NOT "philips" I really don't see hopw this is possible!
I also tried the samen with db_fetch_array instead of db_result or db_result instead of mysql_result....
All the same..... Only the seqeunce number of the $var array is stored.... So strange!
Any Idea anybody?
Thanks
#26
Wow, this is creeping me out!!!
Thanks to nevets at #12, I solved my issue in #25.
Really crazy:
See what i did
$companies="SELECT DISTINCT value FROM profile_values WHERE fid = '39'";$result=db_query($companies);
while ($row=db_fetch_array($result))
{
$var[$row['value']]=$row['value'];
}
return $var;
You see the line:
$var[$row['value']]=$row['value'];
As Nevets said: "the key is waht's stored" Damn key! How could I fool that so that the key (whatever that might be) is replacde with what I wanted it to be?
So in Nevets example he used "nid" as the key. I really wanted my company name in those fields in the database. No crazy sequence number derived from location in the arry which I selected the company name from. So I swapped in Nevets code his 'nid" with my 'value'... Yes indeed!
But I must tell you, why did the makers of the CCK module made that so damn harsh? I mean when you fill in the allowed value list yourself, the names are stored in the database, if you wanna do it with a php array, suddenly "they wanna have numbers as keys" or they impose it by taking the sequence number of your selected value in your array. Crazy if you asked me. I already looked where i could change this in the code of the module itself. To look for the peace of code that actually process the import of the array (well we know what that means now) in its respective CCK table into the database but it's so huge. I don't know where this happens. Any Ideas some-one? Or any advises on why this is implemented this way? (so as an argument not to temper with it and change it for the good by my perspective ofcourse)
#27
So you decide to write code you take on responsibilities. The bottom line is the array needs to be indexed with keys so that a choice always means the same thing. The CCK code handles this for you when you use the text box, that makes sense since it provides a UI for someone to provide value pairs, it just happens to be "smart" enough to handle only values (which internally it handles as value1|value1 pairs). As soon as you write code, the code is in charge of making the array, it real does make sense.
#28
...but the CCK module is also in charge of further processing your custom array... so that it's data get stored in the database as well.
I just was wondering why at one hand, when you manually list options, CKK will upload those values and at the other hand when you provide it with a keyed array, it uses the key's instead of the values attached to them.
Why as well not take the values attached to the keys in your custom array (as a default)?
Isn't that quite strange? or maybe odd? (certainly not expected)
Moreover, storing the key indexes breaks any relation with the actual values you wanna store unless you create another on-the-fly table where you begin coupling those array key values with the corresponding values. But that would be massivly "over-the-top", wouldn't we agree? :-) lol
Anyway, now I know, and I overcame this issue... but some people must stumble on this too as well, since it's not really documented and most of us would assume that CCK would take the values of your custom array to store in the DB, rather then the key indexes of your array.
#29
I am pretty sure that the Form API is responsible for processing the array.
#30
Ok sorry my mistake --> I didn't realize that Form API handles the array :-)
But nevertheless, it doesn't take a way the core issue at hand.
Why handling the keys of the array instead of the actual value that those keyes respond to? Wouldn't it be more logical or at least usefull to handle the values instead of the keys?
#31
From a database point a view have key/value pairs generally make sense. For one thing keys are unchanging where in a lot of cases the value can change, if keys are numeric they take up less space.
#32
indeed, key/value pairs... I agree ofcourse
but in this particular example... the values part is not stored. That's exactly my point.
Since the API is storing only the key sequence of the array. the values itself are not stored, nor is there any other table made that gives reference to the stored keys and the values in your array. So in this particular instance actually there is no storing of key/value pair but key/key pair... (and without any other tables elaborating this combination, it makes no sence...)
You see?
And that's why I fooled the "keys" of the array so that the API thinks it's storing keys in that table, but actually values are stored,. Just what I needed (and what one might expect)
And now that table is an nice key/value pair.
#33
I am trying to make some sense out of this thread but it isn't quite clicking with me. I need a select list like this:
<select><option value='some value 1'>Some Description 1</option>
<option value='some value 2'>Some Description 2</option>
</select>
I have a database table that contains two fields. One for the value and one for the description. I want to run a query like this:
select value,description from tableTo create the list above using a select (or other) list control.
I have tried this:
$q=mysql_query("select value,description from table");$linkarray=array();
while ($r=mysql_fetch_array($q))
{
$linkarray[]=array('url'=>$r["value"],'title'=>$r["description"],'attributes'=>'');
}
return $linkarray;
with the result being a drop down list with one item: "array".
I have also tried this:
$q=mysql_query("select value,description from table");$linkarray=array();
while ($r=mysql_fetch_array($q))
{
$linkarray[$r["value"]]=$r["description"];
}
return $linkarray;
with the result being:
<select><option value='description 1'>description 1</option>
<option value='description 2'>description 2</option>
</select>
(same thing for value and description).
What am I missing?
#34
Your later code should work, try changing it to
$q=mysql_query("select value,description from table");$linkarray=array();
while ($r=mysql_fetch_array($q))
{
drupal_set_message("<pre>" . print_r($r, TRUE) . '</pre>');
$linkarray[$r["value"]]=$r["description"];
}
return $linkarray;
which will show each record when you add/edit content with this field. The code should work so I am wonder about the value of
$r["value"].