I have a PHP function that returns an array. This is the output of print_r($myArray):
Array (
[id] => 8166
[customer_id] => 73
[nickname] => AnnieB
[name] => Anastasia Beaverhausen
[email] => annieb#annieb.com
[phone] => 555-555-5555
[company] => Annie B's
[address1] => 123 Main Street
[address2] => Apartment 555
[city] => Chicago
[state] => IL
[zip] => 55555
[billing] => 1
[residence] => 0
[token] =>
[verified] => 1 )
I should be able to access any of the members by saying something like $myArray['city'], correct? I know I've done this in the past, but it keeps returning an empty string, even when there is a value in the city field.
Any ideas?
==================MORE CODE POSTED PER REQUESTS=============================
I'm using this in Joomla, so there are a few lines that are specific to Joomla. The end purpose of this code is to populate a dropdown list with addresses from a database; the option values contain an imploded string of all column values (to be accessed via javascript later) and the option text is a single field. Here's the code that creates the dropdown:
foreach (getAddresses($AcctID) as $id => $info) {
print_r($info);
$nickName = $info[2];
error_log("nickname=".$nickName);
$infoStr = implode("|", $info);
$addressOptions .= "<option value=\"{$infoStr}\">$nickName</option>";
}
The getAddresses function is here (this is working correctly):
function getAddresses($AcctID) {
$db =& JFactory::getDBO();
$query = "select * from jos_customers_addresses where customer_id = ".$db->quote($AcctID);
$db->setQuery($query);
if (!$db->query()) error_log($db->stderr());
if (!$db->getNumRows())
return false;
else
return $db->loadAssocList();
}
The print_r($info) line is what is returning the array I originally posted. The next two lines are the ones giving me problems:
$nickName = $info[2];
error_log("nickname=".$nickName);
I've also tried $nickName = $info['nickname'] and gotten the same result - no value, even though there's obviously a value in the print_r, and the value does come through correctly in the code generated by the implode line. If you can find someplace between those two lines where I'm overwriting my variable, or whatever, please point it out to me, because I'm clueless as to why I can't get a handle on this value.
I should be able to access any of the
members by saying something like
$myArray['city'], correct?
Yes, that's correct.
I know I've done this in the past, but
it keeps returning an empty string,
even when there is a value in the city
field.
If nothing is showing up, there's probably not a value there, which as the comments said, is most likely a bug in your code (something overwriting that key). To be sure there's nothing there, instead of echo $myArray['city'] try var_dump($myArray['city']) -- this will tell you if it's an empty string (string(0) "") or not set at all (NULL)
Take your print_r($myArray) and put it immediately before the statement where you use $myArray['city']. is the 'city' key still set? If so, double check to make sure you don't have a typo... capitalization matters! If it's not still set, move the print_r($myArray) up a few lines and repeat until you find what's unsetting $myArray['city']
...Or just post more code ;-)
EDIT: Did $info[2] need to be $info['city']?
Related
I'll note that this is a very special case, hence the question to begin with. Under normal circumstances, such a function would be simple:
I have an array named $post_id, which contains 5 values
(Each numerical)
In order to print each value in the array, I use the following loop:
.
for ($i = 0; $i < $num; $i++)
{
echo $post_id[$i] . ' ';
}
...Which prints the following: 49, 48, 47, 46, 43
3. In my database, I have a table that looks like this:
post_categories
_____________________
post_id | category
__________|__________
43 | puppies
43 | trucks
46 | sports
46 | rio
46 | dolphins
49 | fifa
4. So, using the data in the array $post_id, I'd like to loop a database query to retrieve each value in the category column from the post_categories table, and place them into uniquely named arrays based on the "post id", so that something like...
echo $post_id_49[0] . ' ', $post_id_46[1];
...Would print "fifa rio", assuming you use the above table.
An example of such a query:
//Note - This is "false" markup, you'll find out why below
for ($i = 0; $i < $num; $i++)
{
$query = "SELECT category FROM post_categories WHERE post_id = $post_id[$i]";
fakeMarkup_executeQuery($query);
}
Why is this a "special" case? For the same reason the above query is "false".
To elaborate, I'm working inside of a software package that doesn't allow for "normal" queries so to say, it uses it's own query markup so that the same code can work with multiple database types, leaving it up to the user to specify their database type which leaves the program to interpret the query according to the type of database. It does, however, allow the query to be stored in the same "form" that all queries are, like "$result = *query here*" (With the only difference being that it executes itself).
For that reason, functions such as mysql_fetch_array (Or any MySQL/MySQLi function akin to that) cannot, and will not work. The software does not provide any form of built in alternatives either, effectively leaving the user to invent their own methods to achieve the same results. I know, pretty lame.
So, this is where I'm stuck. As you'd expect, all and any information you find on the Internet assumes you can use these MySQL & MySQLi functions. What I need, is an alternative method to grab one array from the results of a looped query per loop. I simply cannot come to any conclusion that actually works.
tl;dr I need to be able to (1) loop a query, (2) get the output from each loop as it's own array with it's own name, and (3), do so without the use of functions like mysql_fetch_array. The query itself does not actually matter, so don't focus on that. I know what do with the query.
I understand this is horrifically confusing, long, and complicated. I've been trudging through this mess for days - Close to the point of "cheating" and storing the data I'm trying to get here as raw code in the database. Bad practice, but sure as heck a lot easier on my aching mind.
I salute any brave soul who attempts to unravel this mess, good luck. If this is genuinely impossible, let me know so that I can send the software devs an angry letter. All I can guess is that they never considered that a case like mine would come up. Maybe this is much more simple then I make it to be, but regardless, I personally cannot come to an logical conclusion.
Additional note: I had to rewrite this twice due to some un explained error eliminating it. For the sake of my own sanity, I'm going to take a break after posting, so I may not be able to answer any follow up questions right away. Refer to the tl;dr for the simplest explanation of my need.
Sure you can do this , here ( assuming $post_ids is an array of post_id that you stated you had in the OP ), can I then assume that I could get category in a similar array with a similar query?
I don't see why you couldn't simply do this.
$post_id = array(49, 48, 47, 46, 43);
$result = array();
foreach($post_id as $id)
{
//without knowing the data returned i cant write exact code, what is returned?
$query = "SELECT category FROM post_categories WHERE post_id = $id";
$cats = fakeMarkup_executeQuery($query);
if(!empty($cats)) {
if(!isset($result[$id])){
$result[$id] = array();
}
foreach( $cats as $cat ){
$result[$id][] => $cat;
}
}
}
Output should be.
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
Ok, assuming you can run a function (we'll call it find select) that accepts your query / ID and returns an array (list of rows) of associative arrays of column names to values (row), try this...
$post_categories = [];
foreach ($post_id as $id) {
$rows = select("SOME QUERY WHERE post_id = $id");
/*
for example, for $id = 46
$rows = [
['category' => 'sports'],
['category' => 'rio'],
['category' => 'dolphins']
];
*/
if ($rows) { // check for empty / no records found
$post_categories[$id] = array_map(function($row) {
return $row['category'];
}, $rows);
}
}
This will result in something like the following array...
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
I'm new to PHP and I'm trying to modify my Wordpress-based Learning Management theme (called Academy on ThemeForest) to be able to work out which lesson in the current course the user is up to.
In other words, I want to run a check to see which lessons the user has completed, getting only the ID of the first lesson in the course hierarchy that has not been completed.
Here's everything I know:
Within the loop of a single post (in this case a "course"), this is how I get the array of the current course's lessons:
<?php $lessons_array = ThemexCourse::sortLessons(ThemexCourse::$data['course']['lessons']); ?>
This produces this nested array:
Array ( [0] => WP_Post Object ([ID] => 117 [menu_order]=>1) [1] => WP_Post Object ([ID] => 124 [menu_order]=>2) [2] => WP_Post Object ([ID] => 156 [menu_order]=>3))
I've truncated it a bit since the two values, [ID] and [menu_order], are the most important: they tell you the ID of each lesson and their hierarchy in the course.
But this is where I get stuck: I don't want to get all of the lesson IDs, just the one the user has yet to complete.
In order to check if a user has completed a lesson or not, I've been using this:
<?php if(ThemexCourse::isCompletedLesson($lesson_ID)) { echo 'Completed'; } ?>
So using the above information, is it possible to return a single ID of only the next incomplete lesson?
Thanks to anyone in advance for your help!
I think that should do it:
$next_lesson = NULL;
foreach($lessons_array as $index=>$lesson) {
if(!ThemexCourse::isCompletedLesson($lesson->ID)) {
$next_lesson = $lesson;
break;
}
}
echo "Next lesson is: " . $next_lesson->ID;
I have created a light Model Manager for LDAP over PHP's API to ease object managements from Active Directory.
Everything runs fine but I have a problem when updating multi valued attributes even if I change all the values, the transaction fails with «Type or value exists» error and the attribute is not changed in the database.
The test case I am using is to change de multi valued "description" field for a user. If I add new values or change the whole array of values, the transaction always fail.
The part of the code is the following:
if (count($mod_attr) > 0)
{
$ret = #ldap_mod_replace($this->getHandler(), $dn, $mod_attr);
if ($ret === false)
{ $this->log(sprintf("LDAP ERROR '%s' -- Modifying {%s}.", ldap_error($this->getHandler()), print_r($mod_attr, true)), \SlapOM\LoggerInterface::LOGLEVEL_CRITICAL);
throw new LdapException(sprintf("Error while MODIFYING values <pre>%s</pre> in dn='%s'.", print_r($mod_attr, true), $dn), $this->getHandler(), $this->error);
}
$this->log(sprintf("Changing attribute {%s}.", join(', ', array_keys($mod_attr))));
}
The complete code can be found [here on github](https://github.com/chanmix51/SlapOM/blob/master/lib/SlapOM/Connection.php#L115 [github]).
The logs show the following lines:
2013-06-04 10:39:54 | => MODIFY dn='CN=HUBERT Gregoire,OU=...
2013-06-04 10:39:54 | => LDAP ERROR 'Type or value exists' -- Modifying {Array
(
[description] => Array
(
[0] => Description 2
[1] => Description 3
)
)}
Even if the preceding values were ["description" => ['Description 1']]. Is there something I am not getting or doing wrong ?
The answer is short: «Description is not a multi valued field». As usual, the error message was so confusing, it lead me to spend hours on the wrong problem.
In short: the LDAP error 20 «Type or value exists» can be either you are trying to insert twice the same values in a multi valued field or you are trying to insert several values in a single valued field.
Just today I noticed a strange behavior in an object model that was previously working just fine (I have checked everything possible and nothing about its configuration has changed, so I am suspecting a change to PHP version and wondering if anyone else has experience anything similar)
Until recently, I could set the keys of object properties that were arrays manually. The specific implememation of this in one of my models was contained in a gallery class that looked like this:
public function __construct($gid){
parent::__construct($gid);
$this->Photos = $this->getPhotos();
$this->AlbumCover = $this->getCover();
}
public function getPhotos(){
$sql = 'SELECT GalleryPhotoID FROM GalleryPhoto WHERE GalleryID = ?';
$params = array($this->GalleryID);
$allids = DatabaseHandler::GetAll($sql, $params);
$output = array();
foreach($allids as $id){
$gp = new GalleryPhoto($id['GalleryPhotoID']);
$output[$gp->GalleryPhotoID] = $gp;
}
return $output;
}
Irrelevant parts omitted.
Basically, I could set the array keys of the Gallery's Photos object to the individual photo's id in the database. This just made it easier to code for individual iteration and made the whole thing run smoother.
Now, no matter what I set that key to, automatic integers are generated when the foreach runs. I even tried typing a literal string in there, which theoretically should replace every iteration, but I still got incremented, automatic integers for the keys of the property Photos.
[Photos] => Array
(
[0] => GalleryPhoto Object
(
[GalleryID] => 9
[Caption] =>
[Orientation] => 0
[AlbumCover] =>
[DateAdded] => 2011-01-03 16:58:51
[GalleryPhotoID] => 63
[Thumbnail] =>
[Image] =>
[src] => http://..com/galleryImage/getImage/63
)
[1] => GalleryPhoto Object
(
[GalleryID] => 9
[Caption] =>
[Orientation] => 0
[AlbumCover] =>
[DateAdded] => 2011-01-03 16:58:51
[GalleryPhotoID] => 64
[Thumbnail] =>
[Image] =>
[src] => http://..com/galleryImage/getImage/64
)
)
Has the abillity to manually set keys within an object property that is an array been removed in some minor release and I am unaware of it? I have googled all over, looked through the PHP manual site and found no answer. Has anyone experienced anything similar? Is there a better approach I should consider? I only really went with this because it made it so much easier to implement a next/previous system via ajax requests back to the next logical id (keeping in mind that ids can be deleted between!)
Thanks!
I don't see anything wrong with what you have, and I've never experienced the behavior you describe. However, a quick solution could be to replace the assignment line with something like this:
$output[$id['GalleryPhotoID']] = $gp;
You could also echo $gp->GalleryPhotoID; to ensure that the GalleryPhotoID property can actually be accessed that way.
Lastly, you said you replaced the above line with something akin to:
$output['foobar'] = $gp;
and it still created a new entry, with integer keys, for each entry? If that's the case, then I think there may be something in the code you omitted that's causing the problem.
Facepalm all the way. The effluvium of New Year's must still be in my brain, else I would have noticed that the function I added to fetch the album cover thumbnail shuffled the array if there wasn't a photo with the AlbumCover property set!
private function getCover(){
foreach($this->Photos as $ind=>$p){
if($p->AlbumCover){
return $this->Photos[$ind];
}
}
shuffle($this->Photos); //this is the problem
return current($this->Photos);
}
I amended this to just make a local copy of the variable and shuffle that instead if no cover is set.
private function getCover(){
foreach($this->Photos as $ind=>$p){
if($p->AlbumCover){
return $this->Photos[$ind];
}
}
$Photos = $this->Photos;
shuffle($Photos);
return current($Photos);
}
I accepted and upvoted both the answer and the comment posted since your caveats lead me to my error. Thanks guys!
I am working with a hook_form_alter on a CCK type (for you drupal-ers). I have a field that is normally a select list in my node form. However, in this instance, I want to hide the select list, and populate its value in the form with an SQL query.
Everything was going nicely. I could see that my desired value was showing up in the HTML source, so I knew my query was executing properly. However, when I submit the form, it only inserts the first character of the value. A few of my tests were values of 566, 784, 1004 - the column values were 5,7,1, respectively.
At first I thought it had to be the DB column attributes, but when I removed my form_alter that makes the field hidden and select the value manually, the correct value is inserted?!?
<?php
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
if (arg(0) == 'user' && is_numeric(arg(1))) {
$account = arg(1);
$club = 2589;
$form['field_sr_account'] = array( '#type' => 'hidden',
'#value' => $club
);
}
}
?>
Can anyone see why only the first character would be inserted??
Note: I have tried deleting and recreating the column, using #value & #default_value, and it is still submitting only the first character of the integer. Also, I eliminated the submit handler as a possible cause by removing it, which still resulted in only one character being submitted
More Updates - Still Searching!
Okay, some good questions. Allow me to answer them:
The DB column type is integer(4)
The HTML the hook produces is :
input type="hidden" name="field_sr_account" id="edit-field-sr-account" value="2589"
Latest Update: I think the issue has been narrowed to the structure of the array. When I do var_dump on this field after the form alter has been processed, this is what I get..
[43] => Array
(
[#type] => hidden
[#default_value] => 2589
[#post] => Array
(
)
[#programmed] =>
[#tree] =>
[#parents] => Array
(
[0] => field_sr_account
)
[#array_parents] => Array
(
[0] => field_sr_account
)
[#weight] => 0.016
[#processed] => 1
[#description] =>
[#attributes] => Array
(
)
[#required] =>
[#input] => 1
[#process] => Array
(
[0] => form_expand_ahah
)
[#name] => field_sr_account
[#id] => edit-field-sr-account
[#value] => 2589
[#defaults_loaded] => 1
[#sorted] => 1
)
What is the structure of the field that I can set the form value to. It's gotta be something like what abhaga is suggesting..
Since the field you are trying to change was originally using a select widget, CCK will be looking for $form_state['values']['field_sr_account'][0]['value']. By setting the field to a #hidden type and setting #value, you will get its value in $form_state['values']['field_sr_account']. CCK will try to access the first element of that and end up with the first character of the value.
Updated: The easiest way to achieve what you need would be to do something:
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
if (arg(0) == 'user' && is_numeric(arg(1))) {
$account = arg(1);
$club = 2589;
// Use this property to store the value to restore back
$form['#field_sr_account'] = $club;
$form['field_sr_account'] = array( '#type' => 'hidden','#value' => $club);
}
}
/*in your submit handler, restore the value in the proper format*/
$form_state['values']['field_sr_account'] = array('0' => array('value' => $form['#field_sr_account']));
Old Answer
One way of accomplishing what you are
trying to do is to copy the whole
$form['field_sr_account'] into
$form['#field_sr_account'] and then
provide the value through the SQL
query in the right format in the
submit handler itself.
Ok take a look at http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#hidden versus http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#value
It is also recommended you use value instead of hidden. You can find this info on http://api.drupal.org/api/drupal/developer--topics--forms_api.html/6
Also, type hidden is not allowed to have properties your assigning to it so this may be causing a problem. Any usage problems you may be having with the forms API should be answer in those resources as I"m still a little unclear on what you're trying to accomplish... specifically with the submit button.
Old answer:
Ok if I understand this correctly
$club is not being set correctly. If
the first result from your query is
the number your looking for then this
should work.
Try calling
<?php print_r(db_fetch_array($result)) ?>
to get a look at everything returned
from the query.
I'm a little unclear as to what is
being set incorrectly. If it's
#value inside your associated array
then the culprit must be the query.
If #value is being set correctly and
whatever your doing with it later may
be the culprit (not shown here). If
its the values in your $form_state I
don't see that your using $club here
at all.
Also, in your addSR_submit_function
you don't seem to be using the $form
variable, or using $club for anything
except for setting the message which
appears at the top of the page your on
when it's called.
I may need some further clarification
as to what exactly is going wrong.
Also, when you're calling
drupal_set_message function, are you
just doing this for debugging
purposes?
Shouldn't you check
drupal_set_message($form_state['values']['field_sr_account']);
instead of
drupal_set_message($club);
in addSR_submit_function ?
OK, just a quess: not sure what type db_result returns for your query, may be it has something to do with types conversions? So this is to make sure value is int.
'#value' => (int)$club
cinqoTimo, Out of curiosity what kind of CCK field is this? Is it a Integer, Decimal, Float? and do you have any special parameters on that field not normally on by default? What is the column type in the db?
Can you post the html output of the form. That might give a clue as to what might be going on.
Are you using any javascript to edit any values for this field?
Have you tried outputting the value results from addSR_form_service_request_node_submit hook? Any difference there.
Sorry for all the questions. Just thinking out loud as it seems you have covered most of your bases.