Active
Project:
Content Construction Kit (CCK)
Version:
6.x-2.x-dev
Component:
General
Priority:
Normal
Category:
Support request
Assigned:
Unassigned
Reporter:
Created:
7 Mar 2007 at 06:02 UTC
Updated:
28 Feb 2011 at 17:47 UTC
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
Comment #1
yched commentedlatest 1.x release shows a little more informative help text.
Comment #2
rjleigh commentedI'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.
Comment #3
yched commentedyes, "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...)
Comment #4
yched commentedOK, 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' :-(
Comment #5
alan426 commentedHere'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;
Comment #6
alan426 commentedCORRECTION:
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.
Comment #7
webpoga commentedChange 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.
Comment #8
Ken Ficara commentedHere'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.
Comment #9
dopry commentedComment #10
jgarbe commentedI'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!
Comment #11
packetbrain commentedjgarbe... 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!
Comment #12
nevets commentedOne thing missing from these examples is that $rows needs to be a keyed array (the key is what is stored, so something like
should be more like
Side note: This particular case can be handled with the node reference field plus views.
Comment #13
jgoodwill01 commentedI 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?
Comment #14
nevets commentedWhere did you put the code? Does the code really read "db_query" or as the error suggests "dq_query"?
Comment #15
bfdi533 commentedYou have an error in your SQL query:
it should be:
Comment #16
ionmedia commentedHi.
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 ?
Comment #17
ionmedia commentednew 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 ?
Comment #18
bigplanet commentedHi 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?
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
Comment #19
nevets commentedYour if should read
if($res1 == '1')(double equals signs)Comment #20
bigplanet commentedWow, that was a noob error, sorry about that.
I fixed that, but still the second (else) block won't execute...
Comment #21
bigplanet commentedThe 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:
Comment #22
tinem commentedI'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
Comment #23
tinem commentedI got help from IRC to make this but what could attributes be?
But only the FIRST link are showed and I want to use some more advanced example so hope someone here can help.
Comment #24
markus_petrux commentedThis is not a CCK3 issue, per se.
Comment #25
massyboy commentedI 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:
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
Comment #26
massyboy commentedWow, this is creeping me out!!!
Thanks to nevets at #12, I solved my issue in #25.
Really crazy:
See what i did
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)
Comment #27
nevets commentedSo 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.
Comment #28
massyboy commented...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.
Comment #29
nevets commentedI am pretty sure that the Form API is responsible for processing the array.
Comment #30
massyboy commentedOk 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?
Comment #31
nevets commentedFrom 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.
Comment #32
massyboy commentedindeed, 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.
Comment #33
tfrech commentedI 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:
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:
with the result being a drop down list with one item: "array".
I have also tried this:
with the result being:
(same thing for value and description).
What am I missing?
Comment #34
nevets commentedYour later code should work, try changing it to
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"].