I have created an API which returns me an array of data in json
Array ( [0] => stdClass Object ( [MSN] => 002999001207 [PingDateTime] => 2018-05-04T16:33:27 [PingValue] => 22 ) [1] => stdClass Object ( [MSN] => 002999001195 [PingDateTime] => 2018-05-04T16:34:11 [PingValue] => 21 ) [2] => stdClass Object ( [MSN] => 002999001180 [PingDateTime] => 2018-05-04T14:42:40 [PingValue] => 20 ) [3] => stdClass Object ( [MSN] => 002999001157 [PingDateTime] => 2018-05-04T14:42:52 [PingValue] => 30 ) [4] => stdClass Object ( [MSN] => 002999001142 [PingDateTime] => 2018-05-04T16:37:19 [PingValue] => 13 ) [5] => stdClass Object ( [MSN] => 002999001138 [PingDateTime] => 2018-05-04T16:32:22 [PingValue] => 20 ) [6] => stdClass Object ( [MSN] => 002999001114 [PingDateTime] => 2018-05-04T16:32:52 [PingValue] => 22 )
Now, I am trying to save it in my DB
$curl = curl_init($api_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 1000);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Key'));
$m->start_date_time = date('Y-m-d h:i:s');
$curl_response = curl_exec($curl);
$json = json_decode($curl_response);
$record = $json->data;
foreach ($record as $item){
if($this->isSaved($item->MSN))
{
return false;
}
else if($this->ogpCreated($item->MSN))
{
$m->end_date_time = date('Y-m-d h:i:s');
$m->meter_msn = $item->MSN;
$m->meter_id = Meters::msnmapToid($m->meter_msn);
$m->sub_div_code = Ogpdetail::msnTosubdiv($item->MSN);
$m->sub_div_name = Ogpdetail::subDivToName($m->sub_div_code);
$m->meter_ping_date_time = str_replace('T', ' ', $item->PingDateTime);
$m->save();
}
}
return $this->redirect(['index']);
In above code, there are two if conditions
isSaved($item->MSN)
$meter = MeterPing::find()->where(['meter_msn' => $msn])->one();
if($meter)
return true;
return false;
From the above function, I am trying to check whether the incoming MSN is already saved or not. If it's already present in the table it will not save that particular MSN but yes save all the other MSN that are not saved previously.
ogpCreated($item->MSN)
$meter = Ogpdetail::find()->where(['meter_serial' => $msn])->one();
if($meter)
return true;
return false;
From the above function, I am trying to check that the incoming MSN is OGP created or not. Again it should not save any MSN which is not OGP created.
Now, when I try to run this Create function it only saves one record at a time.
I think there is some issue in if..... elseif that only allows saving one entry. But I am not sure of that.
Update 1
I have tried to remove the checks and then save the incoming data but still, it only saves one record
How can I save the entire received JSON data into my DB with all checks working?
You need to add your model initialization $m=new YourModel(); inside the foreach loop an within the elseif($this->ogpCreated($item->MSN)), that is why it is saving only one record
foreach ($record as $item){
if($this->isSaved($item->MSN)){
return false;
}
else if($this->ogpCreated($item->MSN)){
$m= new YourModel();
You are using the $m in the curl command too it would be better to post all code incase you run into some logical errors you need to adjust the code accordingly, or change the name of the variable from $m inside the foreach
Apart from this you can use this extension Yii2-Curl for curl commands it will allow you more flexibility to your code in a more readable way
Related
I tried to do my first API calls which worked finally with help from this great users here in this community. Thanks again. I want to choose data[1] or the currency with symbol. So i could use a $variable from my CMS. Maybe someone can show me a way how i can change this call to symbol. Here is my API call.
$url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest";
$headers = [
'Accepts: application/json',
'X-CMC_PRO_API_KEY: ___YOUR_API_KEY_HERE___'
];
$request = "{$url}"; // create the request URL
$curl = curl_init(); // Get cURL resource
// Set cURL options
curl_setopt_array($curl, array(
CURLOPT_URL => $request, // set the request URL
CURLOPT_HTTPHEADER => $headers, // set the headers
CURLOPT_RETURNTRANSFER => 1 // ask for raw response instead of bool
));
$response = curl_exec($curl); // Send the request, save the response
$json = json_decode($response);
curl_close($curl); // Close request
$price = $json->data[1]->quote->USD->price; echo $price;
You get the data block IDs with array_column(), then you get the symbol's data block ID with array_search():
$data_ids = array_column($json->data, 'symbol');
$symbol_data_id = array_search('ETH', $data_ids);
$price = $json->data[$symbol_data_id]->quote->USD->price;
Or as an oneliner:
$price = $json->data[array_search('ETH', array_column($json->data, 'symbol'))]->quote->USD->price;
LATER UPDATE: OK, let me elaborate on this. Step by step:
You need a proper URL to acces the API. For this you need the API documentation. Your original question mentioned
$url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest";
while for your comment question you need something like
$url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/info?symbol=ETH";
A proper URL will give you a JSON response structured according to its purpose. You have this part ironed out, so I'll not insist on this. From your question text:
$headers = [
'Accepts: application/json',
'X-CMC_PRO_API_KEY: 1b58ff56-58b2-4fd0-b184-f9c3dd4ff106',
];
$request = "{$url}"; // create the request URL
$curl = curl_init(); // Get cURL resource
// Set cURL options
curl_setopt_array($curl, [
CURLOPT_URL => $request, // set the request URL
CURLOPT_HTTPHEADER => $headers, // set the headers
CURLOPT_RETURNTRANSFER => 1, // ask for raw response instead of bool
]);
$response = curl_exec($curl); // Send the request, save the response
$json = json_decode($response);
curl_close($curl); // Close request
Then you have to decide how to use the response. For me, the fastest way is to look at its structure (var_dump($json) or print_r($json)). Which will give something like this (the original question):
stdClass Object
(
[status] => stdClass Object
(
[timestamp] => 2021-11-06T18:37:59.447Z
[error_code] => 0
[error_message] =>
[elapsed] => 22
[credit_count] => 1
[notice] =>
[total_count] => 7060
)
[data] => Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Bitcoin
[...]
)
[1] => stdClass Object
(
[id] => 1027
[name] => Ethereum
[symbol] => ETH
[slug] => ethereum
[...]
[quote] => stdClass Object
(
[USD] => stdClass Object
(
[price] => 4445.0743486785
[volume_24h] => 14137477206.072
[volume_change_24h] => -9.6622
[percent_change_1h] => 0.2898806
[percent_change_24h] => -1.29677209
[percent_change_7d] => 3.13286959
[percent_change_30d] => 23.49191199
[percent_change_60d] => 28.79913805
[percent_change_90d] => 48.37310902
[market_cap] => 525560956659.07
[market_cap_dominance] => 19.5198
[fully_diluted_market_cap] => 525560956659.07
[last_updated] => 2021-11-06T18:37:03.000Z
)
)
)
[2] => stdClass Object [...]
or this (the question in the comment):
stdClass Object
(
[status] => stdClass Object
(
[timestamp] => 2021-11-06T18:03:05.201Z
[error_code] => 0
[error_message] =>
[elapsed] => 12
[credit_count] => 1
[notice] =>
)
[data] => stdClass Object
(
[ETH] => stdClass Object
(
[id] => 1027
[name] => Ethereum
[symbol] => ETH
[category] => coin
[description] => Ethereum (ETH) is a cryptocurrency . Users are able to generate ETH through the process of mining. Ethereum has a current supply of 118,233,336.749. The last known price of Ethereum is 4,424.33123326 USD and is down -1.39 over the last 24 hours. It is currently trading on 4537 active market(s) with $14,138,162,060.93 traded over the last 24 hours. More information can be found at https://www.ethereum.org/.
[...]
[platform] =>
[date_added] => 2015-08-07T00:00:00.000Z
[twitter_username] => ethereum
[is_hidden] => 0
)
)
)
So data is a property of the $json object.
In the first case, data is an array and its structure suggests using array functions to retrieve specific data.
In the second case, data and ETH are objects, while description is a property of ETH. Which allows me to get the description using object syntax
$description = $json->data->ETH->description;
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have the really complex array:
stdClass Object
(
[matters] => Array
(
[0] => stdClass Object
(
[id] => 1050370768
[client] => stdClass Object
(
[id] => 939940280
[url] => /api/v2/contacts/939940280
[name] => Balter and Son
)
[display_number] => 00001-Balter and Son
[description] => Sueing for pain of having to program
[status] => Open
[open_date] => 2017-07-26
[close_date] =>
[pending_date] =>
[location] =>
[client_reference] => 34241
[responsible_attorney] => stdClass Object
(
[id] => 345011996
[url] => /api/v2/users/345011996
[name] => jon balter
[email] => jbalter#seamlesssolutions.com
)
[originating_attorney] =>
[practice_area] =>
[billable] => 1
[maildrop_address] => ecd6d7b60+matter1050370768#maildrop.clio.com
[created_at] => 2017-07-26T20:46:14+00:00
[updated_at] => 2017-07-26T20:46:14+00:00
[custom_field_values] => Array
(
)
[billing_method] => hourly
[group_id] => 1654280
[permission] => stdClass Object
(
[id] => 1654280
[url] => /api/v2/groups/1654280
[name] => Firm
)
[activity_rates] => Array
(
)
)
[1] => stdClass Object
(
[id] => 1050770508
[client] => stdClass Object
(
[id] => 940983330
[url] => /api/v2/contacts/940983330
[name] => Seamless Solutions
)
[display_number] => 00002-Seamless Solutions
[description] => This is a matter of life and death
[status] => Open
[open_date] => 2017-08-09
[close_date] =>
[pending_date] =>
[location] =>
[client_reference] =>
[responsible_attorney] =>
[originating_attorney] =>
[practice_area] =>
[billable] => 1
[maildrop_address] => ecd6d7b60+matter1050770508#maildrop.clio.com
[created_at] => 2017-08-09T21:37:28+00:00
[updated_at] => 2017-08-09T21:37:28+00:00
[custom_field_values] => Array
(
)
[billing_method] => hourly
[group_id] => 1654280
[permission] => stdClass Object
(
[id] => 1654280
[url] => /api/v2/groups/1654280
[name] => Firm
)
[activity_rates] => Array
(
)
)
)
[records] => 2
[limit] => 200
[next_offset] => 1050770508
[order_dir] => asc
[total_records] => 2
[published_at] => 2017-08-09T21:37:38+00:00
)
I just want to get a return of
Array (
[display_number] => 00001-Balter and Son
[display_number] => 00002-Seamless Solutions
)
Then take this and save this as a CSV
00001,Balter and Son,
00002,Seamless Solutions
Any help would be awesome.
I know there has to be an easy way to do this.
Someone asked for the PHP. Little hard to put here but I will try. It is part of an API for CLIO legal software.
//Get Matters
$matterarry = matter_numbers ($token);
//get array to just matter numbers
$matternumbers = array(); // initialize the array to be used for the export
foreach($matterarry->matters as $key => $matter) { // loop through all the top level element
// isolate the display number '00001' from '00001-Balter and Son'
$displayNumber = explode('-', $matter->display_number);
$displayNumber = $displayNumber[0];
// push the element the export array using the display_number as the key
$matternumbers[$key] = array(
$displayNumber, // '00001'
$matter->client->name // 'Balter and Son'
);
}
Print_r ($matternumbers);
//export to CSV
$f = fopen('/tmp/matternumbers.csv', 'a'); // open the destination file handler
fputcsv($f, array('display_number', 'name')); // start by adding the column headers
// this can also be done by using named keys in your array,
// or having the first element be the value of the headers
// I'm appending manually here for the sake of simplicity
foreach($matternumbers as $key => $element) {
fputcsv($f, $element); // append each element to the file
}
fclose($f); // don't forget to close the file ;)
function matter_numbers ( $token ) {
//$header = array('Authorization: bearer '.$token);
//print_r ($header);
$header = 'Authorization: bearer '.$token;
echo $header."\r\n";
$ch = curl_init();
//curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_URL, 'https://app.goclio.com/api/v2/matters');
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$resp = curl_exec($ch);
if( !$resp ) {
die('Error: "' . curl_error( $ch ) . '" - Code: ' . curl_errno( $ch ) );
}
else if ( 200 != curl_getinfo( $ch, CURLINFO_HTTP_CODE ) ) {
echo "Bad Response Code!";
echo "\n";
echo "Response HTTP Status Code : " . curl_getinfo( $ch, CURLINFO_HTTP_CODE );
echo "\n";
echo "Response HTTP Body : " . $resp;
}
//print "curl response is:" . $resp;
$resp = json_decode($resp);
//print_r ($resp);
curl_close($ch);
return $resp;
}
I'll try addressing the two parts of your question (1) simplifying the array to isolate specific elements and (2) exporting that to a .csv file
Simplifying the array
For this you'll need to iterate over all the matters element of your original object and push whatever value(s) you wish to export in a new array with the appropriate format
$exportArray = array(); // initialize the array to be used for the export
foreach($initialObject->matters as $key => $matter) { // loop through all the top level element
// isolate the display number '00001' from '00001-Balter and Son'
$displayNumber = explode('-', $matter->display_number);
$displayNumber = $displayNumber[0];
// push the element the export array using the display_number as the key
$exportArray[$key] = array(
$displayNumber, // '00001'
$matter->client->name // 'Balter and Son'
);
}
You then end up with an array that should look a little something like that:
Array [
0 => Array [
0 => '00001'
1 => 'Balter and Son'
]
1 => Array [
0 => '00002'
1 => 'Seamless solutions'
]
]
Alternatively, instead of looping over the array you could use array_map() and obtain a similar result. If you're not familiar with array_map() you can find the official doc here
$exportArray = array_map(function($matter) {
// isolate the display number '00001' from '00001-Balter and Son'
$displayNumber = explode('-', $matter->display_number);
$displayNumber = $displayNumber[0];
return array(
$displayNumber,
$matter->client->name
);
}, $initialObject->matters)
Exporting to CSV
This part is actually quite easy as PHP has a function specifically for this (Official Doc)
$f = fopen('/tmp/myFile.csv', 'a') // open the destination file handler
fputcsv($f, array('display_number', 'name')) // start by adding the column headers
// this can also be done by using named keys in your array,
// or having the first element be the value of the headers
// I'm appending manually here for the sake of simplicity
foreach($exportArray as $key => $element) {
fputcsv($f, $element); // append each element to the file
}
fclose($f) // don't forget to close the file ;)
Mixing the two together
Looping over the elements you want to export twice is tedious and will affect readability and maintainability. This is why you should probably mix those examples together in a single loop.
$file = fopen('/tmp/myFile.csv', 'a'); // open the destination file handler
fputcsv($file, array('display_number', 'name')); // add the column headers
foreach($initialObject->matters as $key => $matter) { // loop through all the top level element
// isolate the display number '00001' from '00001-Balter and Son'
$displayNumber = explode('-', $matter->display_number);
$displayNumber = $displayNumber[0];
// Add the information you need directly in the file
fputcsv($file, array($displayNumber, $matter->client->name));
}
fclose($file);
For the sake of simplicity, I have assumed that your destination file is empty. If you don't know how to make sure a file is empty before starting working with, I suggest you look at this question that sums it up very well.
Is it possible to search inside json array which I pull with curl and if match to show only that data?
The array looks like
Array
(
[status] => success
[data] => Array
(
[out] => Array
(
[0] => Array
(
[address] => test address
[amount] => 11
[type] => 1
)
[1] => Array
(
[address] => test address 1
[is_nonstandard] =>
[amount] => 12
[type] => 1
)
)
)
[code] => 200
[message] =>
)
And this is how I pull the array
function get_curl_content_tx($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
$url=get_curl_content_tx("http://example.com");
$total =json_decode($url,true);
So since there can be more that 1 arrays in [out] => Array as current situation they are two I want to search and match by [address] and when match to give data.
Here is a way to do it :
foreach($arr['data']['out'] as $d){
if(strpos($d['address'], 'testaddress') !== false){
//do something
var_dump($d);
}
}
You need to replace var_dump by whatever you want to do.
I used strpos for the sake of this example, but you might want to use a custom method that would suits your needs better
Hope this helps.
<?php
$outArray = $total['data']['out'];
foreach($outArray as $item) {
// echo $item['address'];
}
?>
Try this:
if(isset($total['data']['out'])){
foreach($total['data']['out'] as $out){
if(isset($out['address'])){
if($out['address'] == "your adress"){
//Your Stuff;
}
}
}
}
I'm using the tumblr API and the following code:
$var = xhttp::toQueryArray($response['body']);
print_r($var);
This print on the screen the following:
Array ( [{"meta":{"status":200,"msg":"OK"},"response":{"user":{"name":"lukebream","likes":0,"following":8,"default_post_format":"html","blogs":[{"name":"lukebream","url":"http:\/\/lukebream.tumblr.com\/","followers":5,"primary":true,"title":"Untitled","admin":true,"queue":0,"ask":false,"tweet":"N"}]}}}] => )
How can I access the individual elements and assign them to variables?
Here is what I have finished with:
$tumblr->set_token($_SESSION['oauth_token'], $_SESSION['oauth_token_secret']);
$data = array();
$data['post'] = array();
$response = $tumblr->fetch('http://api.tumblr.com/v2/user/info', $data);
if($response['successful']) {
echo $response['json']['response']['url'];
} else {
echo "api call failed. {$response[body]}<br><br>";
}
It's called JSON, you can parse it using json_decode()
Usage Example :
//I used file_get_contents() to keep things simple
$jsonData = file_get_contents("http://api.tumblr.com/v2/blog/lukebream.tumblr.com/info?api_key=<api_key_here>");
The $jsonData contains :
{
"meta":{
"status":200,
"msg":"OK"
},
"response":{
"blog":{
"title":"Untitled",
"posts":61,
"name":"lukebream",
"url":"http:\/\/lukebream.tumblr.com\/",
"updated":1321830278,
"description":"",
"ask":false,
"likes":0
}
}
}
after it goes through json_decode(), we get a PHP object, so :
$obj = json_decode($jsonData);
will return :
stdClass Object
(
[meta] => stdClass Object
(
[status] => 200
[msg] => OK
)
[response] => stdClass Object
(
[blog] => stdClass Object
(
[title] => Untitled
[posts] => 61
[name] => lukebream
[url] => http://lukebream.tumblr.com/
[updated] => 1321830278
[description] =>
[ask] =>
[likes] => 0
)
)
)
Then you can access the data like with any other object.
You can also use json_decode($str, TRUE): this will return an ARRAY instead of an object, much easier to play with!
I have a function that builds a collection of user objects from the database:
public static function GetUsersByGroup($instanceID, $groupID)
{
$col = null;
if($groupID != null)
{
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_USERGROUP_MEMBERS,array ($instanceID, $groupID));
}
else
{
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID);
}
echo "this is the collection I am going to return: <pre>";
print_r($col);
echo "</pre>";
return $col;
}
The method has some debug output at the bottom, but the point is if I call that method with a null groupid param i.e it runs the second condition, it prints out a nice indication of the collection that I expected to receive, which is great.
However ..
Here is my calling method:
echo "<br> Collection passed through is: </br>";
$collection = UserGroup::GetUsersByGroup($this->GetInstance()->id,$grouplist->GetCurrentCommandParam());
print_r($collection);
$userlist->UpdateCollection($collection);
$userlist->DeSelect();
The intresting thing is the output:
this is the collection I am going to return:
Collection Object
(
[_valueType:protected] => User
[_isBasicType:protected] =>
[_validateFunc:protected] =>
[_collection:protected] => Array
(
[0] => User Object
(
[valid] =>
[validationMessage] =>
[id] => 29
[table:private] => user
[fields:private] => Array
(
[title] => mrs
[fname] => Kirsty
[lname] => Howden
[email] => kirsty2#softyolk.com
[password] => xxxxxxxx
[lastlogin] => 2009-07-05 15:20:13
[instanceID] => 2
[deliveryAddress] =>
[invoiceAddress] =>
[tel] => 01752848484
[isAdmin] => 0
[disabled] => 0
[mustAuthorise] =>
[usergroupID] =>
)
[validationRules:private] => Array
(
)
[_profileStartTime:protected] =>
[_profileTag:protected] =>
)
[1] => User Object
(
[valid] =>
[validationMessage] =>
[id] => 31
[table:private] => user
[fields:private] => Array
(
[title] => master
[fname] => Seb
[lname] => Howden
[email] => seb#antithug.co.uk
[password] => xxxxxxxxx
[lastlogin] => 2009-07-09 02:02:24
[instanceID] => 2
[deliveryAddress] => saltash
[invoiceAddress] => saltash
[tel] => 8908908
[isAdmin] => 0
[disabled] => 0
[mustAuthorise] =>
[usergroupID] =>
)
[validationRules:private] => Array
(
)
[_profileStartTime:protected] =>
[_profileTag:protected] =>
)
)
)
Collection passed through is:
this is the collection I am going to return:
Collection Object
(
[_valueType:protected] => User
[_isBasicType:protected] =>
[_validateFunc:protected] =>
[_collection:protected] => Array
(
)
)
Collection Object ( [_valueType:protected] => User [_isBasicType:protected] => [_validateFunc:protected] => [_collection:protected] => Array ( ) )
The object returned has been modified??
If the GetUsersByGroup method is called with a userGroupID i.e the first case, then output is all as expected.
If i remove the conditional from the method and simply return $col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID); then all output is as expected.
It seems that the else condition executes correctly, and then is corrupted on return, but this only happens if the else condition is present, remove the else condition, and simply return the result of the method call in the else condition, and all is as expected.
Any idea please?
Thanks
ADDED THE UserGroup::GetCollection Method (this is a deep rabbit hole though, could go on)
protected static function GetCollection($class, $sqlID, $params = null)
{
$dal = DAL::GetInstance(); //not to be confused with the Instance object, this is an instance of DAL
$collection = new Collection($class);
$items = $dal->QueryForAssoc($sqlID,$params);
foreach($items as $item)
{
$itemObject = new $class();
$itemObject->LoadFromList($item);
$collection->add($itemObject);
}
return $collection;
}
To further clarify the follwing works fine ::
public static function GetUsersByGroup($instanceID, $groupID)
{
$col = null;
//if($groupID != null)
//{
//$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_USREGROUP_MEMBERS,array ($instanceID, $groupID));
//}
//else
//{
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID);
// }
return $col;
}
I only see the issue if the line is in the else block.
The likely problem here lies in your UserGroup::GetCollection function. PHP 5 passes all objects by reference, so if you are doing any sort of modification in this routine based on the way you are retrieving these objects, then this modification will persist after UserGroup::GetCollection has finished.
I would examine carefully the differences between these two function calls and make sure there are no object changes happening in UserGroup::GetCollection.
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_USERGROUP_MEMBERS,array ($instanceID, $groupID));
vs.
$col = UserGroup::GetCollection("User" ,_DB_GET_ALL_INSTANCE_NOGROUP_MEMBERS,$instanceID);
Turns out the method is being called twice, the second call is using the other condition, and returning a blank collection (the problem result).
By setting an echo in each condition I could see as they are called, and first the null case is called and then the non null.
The actual error is that I had a stateful list calling the method twice in the same postback. Hard to catch.
Thanks for looking