storing API data array somehow - php

I have figured out how to insert my data array into the mysql table. (Thank you Hunsman).
Im wondering if there is neater tighter code that would accomplish what im doing.
I notice that the way Im doing it only lets me insert top level of array results. The array displays correctly but unable to get sub level nodes with same name.Any Recommendations? Also wanted to post for anyone having similar problem. Took me some time to just find you guys.
<?php
function upsTrack($trackingNumber) {
$data ="<?xml version=\"1.0\"?>
<AccessRequest xml:lang='en-US'>
<AccessLicenseNumber>AccessNumber</AccessLicenseNumber>
<UserId>username</UserId>
<Password>Password</Password>
</AccessRequest>
<?xml version=\"1.0\"?>
<TrackRequest>
<Request>
<TransactionReference>
<CustomerContext>
<InternalKey>blah</InternalKey>
</CustomerContext>
<XpciVersion>1.0</XpciVersion>
</TransactionReference>
<RequestAction>Track</RequestAction>
</Request>
<TrackingNumber>$trackingNumber</TrackingNumber>
</TrackRequest>";
$ch = curl_init("https://www.ups.com/ups.app/xml/Track");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$result=curl_exec ($ch);
// echo '<!-- '. $result. ' -->';
$data = strstr($result, '<?');
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
$level[$xml_elem['level']] = $xml_elem['tag'];
}
}
if ($xml_elem['type'] == 'complete') {
$start_level = 5;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
eval($php_stmt);
}
}
curl_close($ch);
return $params;
}
if ($_POST['af0'] == 'xx1') {
if (preg_match('/^[a-z\d_]{4,80}$/i', $_POST['trackingNumber'])) {
$cleanTrackingNumber = $_POST['trackingNumber'];
$someArray = upsTrack("$cleanTrackingNumber");
echo $someArray['RESPONSESTATUSDESCRIPTION'], $someArray['SHIPPERNUMBER'], $someArray['ADDRESSLINE1'],$someArray['CITY'], $someArray['STATEPROVINCECODE'], $someArray['POSTALCODE'], $someArray['COUNTRYCODE'],$someArray['CODE'], $someArray['DESCRIPTION'], $someArray['VALUE'], $someArray['SHIPMENTIDENTIFICATIONNUMBER'], $someArray['PICKUPDATE'], $someArray['TRACKINGNUMBER'], $someArray['ACTIVITYLOCATION']['ADDRESS'] ['STATEPROVINCECODE'], $someArray['DATE'], $someArray['TIME'], $someArray['WEIGHT'];
} else {
echo 'Invalid tracking number... sigh...';
}
}
?>
<?php
/*** mysql hostname ***/
$hostname = 'localhost';
/*** mysql username ***/
$username = 'testdb';
/*** mysql password ***/
$password = 'test123';
/*** database name ***/
$dbname = 'test';
try {
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
/*** echo a message saying we have connected ***/
echo 'Connected to database<br />';
/*** set the PDO error mode to exception ***/
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
/*** begin the transaction ***/
$dbh->beginTransaction();
/*** INSERT statements ***/
$dbh->exec("INSERT INTO upstrackdb ( RESPONSESTATUSDESCRIPTION, SHIPPERNUMBER, ADDRESSLINE1, CITY, STATEPROVINCECODE, POSTALCODE, COUNTRYCODE, CODE, DESCRIPTION, VALUE, SHIPMENTIDENTIFICATIONNUMBER, PICKUPDATE, TRACKINGNUMBER, ACTIVITYLOCATION, DELIVERYDATE, DELIVERYTIME, WEIGHT) VALUES ( '$someArray[RESPONSESTATUSDESCRIPTION]', '$someArray[SHIPPERNUMBER]', '$someArray[ADDRESSLINE1]', '$someArray[CITY]', '$someArray[STATEPROVINCECODE]', '$someArray[POSTALCODE]', '$someArray[COUNTRYCODE]', '$someArray[CODE]', '$someArray[DESCRIPTION]', '$someArray[VALUE]', '$someArray[SHIPMENTIDENTIFICATIONNUMBER]', '$someArray[PICKUPDATE]', '$someArray[TRACKINGNUMBER]', '$someArray[STATEPROVINCECODE]', '$someArray[DATE]', '$someArray[TIME]', '$someArray[WEIGHT]')");
/*** commit the transaction ***/
$dbh->commit();
/*** echo a message to say the database was created ***/
echo 'Data entered successfully<br />';
}
catch(PDOException $e)
{
/*** roll back the transaction if we fail ***/
$dbh->rollback();
/*** echo the sql statement and error message ***/
echo $sql . '<br />' . $e->getMessage();
}
?>
Below are the results i get.
<!-- HTTP/1.1 200 OK
Date: Tue, 02 Apr 2013 19:16:15 GMT
Server: Apache
Pragma: no-cache
Content-Length: 1808
Vary: User-Agent
Content-Type: application/xml
<?xml version="1.0"?>
<TrackResponse><Response><TransactionReference<XpciVersion>1.0</XpciVersion> </TransactionReference> <ResponseStatusCode>1</ResponseStatusCode> <ResponseStatusDescription>Success</ResponseStatusDescription></Response><Shipment> <Shipper><ShipperNumber>975522</ShipperNumber><Address><AddressLine1>1700 SUNFLOWER AVE</AddressLine1><City>COSTA MESA</City><StateProvinceCode>CA</StateProvinceCode><PostalCode>92626 1505</PostalCode><CountryCode>US</CountryCode></Address></Shipper><ShipTo><Address><City>MOUNTAINSIDE</City><StateProvinceCode>NJ</StateProvinceCode><PostalCode>07092</PostalCode><CountryCode>US</CountryCode></Address></ShipTo><Service><Code>002</Code><Description>2ND DAY AIR</Description></Service><ReferenceNumber><Code>01</Code><Value>365357</Value></ReferenceNumber><ReferenceNumber><Code>01</Code><Value>4500137238</Value></ReferenceNumber><ShipmentIdentificationNumber>1Z9755220249869083</ShipmentIdentificationNumber><PickupDate>20130213</PickupDate><Package><TrackingNumber>1Z9755220249869083</TrackingNumber><Activity><ActivityLocation><Address><City>MOUNTAINSIDE</City><StateProvinceCode>NJ</StateProvinceCode><PostalCode>07092</PostalCode><CountryCode>US</CountryCode></Address><Code>M5</Code><Description>MAIL ROOM</Description><SignedForByName>SALEMI</SignedForByName></ActivityLocation><Status><StatusType><Code>D</Code><Description>DELIVERED</Description></StatusType><StatusCode><Code>KB</Code></StatusCode></Status><Date>20130215</Date><Time>093400</Time></Activity><PackageWeight><UnitOfMeasurement><Code>LBS</Code></UnitOfMeasurement><Weight>27.00</Weight></PackageWeight><ReferenceNumber><Code>01</Code><Value>365357</Value></ReferenceNumber><ReferenceNumber><Code>01</Code><Value>4500137238</Value></ReferenceNumber></Package></Shipment></TrackResponse> --><pre>Array
(
[XPCIVERSION] => 1.0
[RESPONSESTATUSCODE] => 1
[RESPONSESTATUSDESCRIPTION] => Success
[SHIPPERNUMBER] => 975522
[ADDRESSLINE1] => 1700 SUNFLOWER AVE
[CITY] => MOUNTAINSIDE
[STATEPROVINCECODE] => NJ
[POSTALCODE] => 07092
[COUNTRYCODE] => US
[CODE] => 01
[DESCRIPTION] => 2ND DAY AIR
[VALUE] => 4500137238
[SHIPMENTIDENTIFICATIONNUMBER] => 1Z9755220249869083
[PICKUPDATE] => 20130213
[TRACKINGNUMBER] => 1Z9755220249869083
[ACTIVITYLOCATION] => Array
(
[ADDRESS] => Array
(
[CITY] => MOUNTAINSIDE
[STATEPROVINCECODE] => NJ
[POSTALCODE] => 07092
[COUNTRYCODE] => US
)
[CODE] => M5
[DESCRIPTION] => MAIL ROOM
[SIGNEDFORBYNAME] => SALEMI
)
[STATUS] => Array
(
[STATUSTYPE] => Array
(
[CODE] => D
[DESCRIPTION] => DELIVERED
)
[STATUSCODE] => Array
(
[CODE] => KB
)
)
[DATE] => 20130215
[TIME] => 093400
[UNITOFMEASUREMENT] => Array
(
[CODE] => LBS
)
[WEIGHT] => 27.00
)

It sounds like you have everything you need. Parse the results, read in the list of email addresses and then INSERT them into the database (double check for duplicates first).
That array looks easily accessible. Its just a simple "INSERT INTO ... VALUES( $array['DATE'], $array['TIME'] ...)"
Heres a good intro to PDO in PHP: http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html#7.1

Related

Parsing an HTML page using curl and xpath in PHP

I need to parse this web page https://www.galliera.it/118 getting the numbers under the coloured bars.
This is my code (that doesn't work!!) ...
<?php
ini_set('display_errors', 1);
$url = 'https://www.galliera.it/118';
print "The url ... ".$url;
echo '<br>';
echo '<br>';
//#Set CURL parameters ...
$ch = curl_init();
curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_PROXY, '');
$data = curl_exec($ch);
curl_close($ch);
//print "Data ... ".$data;
//echo '<br>';
//echo '<br>';
$dom = new DOMDocument();
#$dom->loadHTML($data);
$xpath = new DOMXPath($dom);
// This is the xpath for a number under a bar ....
// /html/body/div[2]/div[1]/div/div/ul/li[6]/span
// How may I get it?
// The following code doesn't work, it's only to show my goals ..
$greenWaitingNumber = $xpath->query('/html/body/div[2]/div[1]/div/div/ul/li[6]/span');
$theText = (string).$greenWaitingNumber;
print "Data ... ".$theText;
echo '<br>';
echo '<br>';
?>
Any suggestions / examples / alternatives?
Here is your php script that is mining request by you data in nicely sorted array, you can see the results of script and change the structure as you need it. Cheers!
$html = file_get_contents("https://www.galliera.it/118");
$dom = new DOMDocument();
$dom->loadHTML($html);
$finder = new DOMXPath($dom);
// find all divs class row
$rows = $finder->query("//*[contains(concat(' ', normalize-space(#class), ' '), ' row ')]");
$data = array();
foreach ($rows as $row) {
$groupName = $row->getElementsByTagName('h2')->item(0)->textContent;
$data[$groupName] = array();
// find all div class box
$boxes = $finder->query("./*[contains(concat(' ', normalize-space(#class), ' '), ' box ')]", $row);
foreach ($boxes as $box) {
$subgroupName = $box->getElementsByTagName('h3')->item(0)->textContent;
$data[$groupName][$subgroupName] = array();
$listItems = $box->getElementsByTagName('li');
foreach ($listItems as $k => $li) {
$class = $li->getAttribute('class');
$text = $li->textContent;
if (!strlen(trim($text))) {
// this should be the graph bar so kip it
continue;
}
// I see only integer numbers so I cast to int, otherwise you can change the type or event not cast it
$data[$groupName][$subgroupName][] = array('type' => $class, 'value' => (int) $text);
}
}
}
echo '<pre>' . print_r($data, true) . '</pre>';
and output is something like:
Array
(
[SAN MARTINO - 15:30] => Array
(
[ATTESA: 22] => Array
(
[0] => Array
(
[type] => rosso
[value] => 1
)
[1] => Array
(
[type] => giallo
[value] => 12
)
[2] => Array
(
[type] => verde
[value] => 7
)
[3] => Array
(
[type] => bianco
[value] => 2
)
)
[VISITA: 45] => Array
(
[0] => Array
(
[type] => rosso
[value] => 5
)
...
This might help simplify your xpath statement for this specific instance.
This will find all li elements with a class attribute matching "verde" that has a span element under it.
the // notation means "match at any level in the document" so you don't have to build your query from root
/* #var $node DOMElement */
$greenWaitingNumber = $xpath->query('//li[#class="verde"]/span');
foreach( $greenWaitingNumber as $node )
{
echo $node->nodeValue;
}
*note this will not deal with class="verde foo bar"
If you're only interested in one particular value...
$greenWaitingNumber = $xpath->query('/html/body/div[2]/div[1]/div/div/ul/li[6]/spa‌​n');
$theText = $greenWaitingNumber[0]->nodeValue;
This will print "2"

Get specific values from CURL JSON response php array

Trying to echo a couple of values from the CURL JSON response so i can put them in to a foreach loop but i can only get single indexed values to work.
$request = curl_init($api); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
//curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment if you get no gateway response and are using HTTPS
curl_setopt($request, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($request, CURLOPT_HTTPHEADER, array(
"Content-Type: application/x-www-form-urlencoded"
));
$response = (string)curl_exec($request); // execute curl fetch and store results in $response
curl_close($request); // close curl object
$result = json_decode($response, true); // true turns it into an array
echo 'First Name: ' . $result['first_name'] . '<br />'; // why doesnt this work
echo 'Last Name: ' . $result[0]['last_name'] . '<br />'; // yet i can return the first value
Example Array output
Array
(
[0] => Array
(
[id] => 34761
[first_name] => A
[last_name] => Bailes
[clinic] =>
[phone] => 7409923279
[fax] => 7409926740
[address1] => 507 Mulberry Heights Rd
[address2] =>
[city] => Pomeroy
[subdivision] => OH
[country_code] =>
[postal_code] => 45769-9573
[timezone] => Array
(
[timezone_type] => 3
[timezone] => America/New_York
)
[state] => OH
)
)
I have json decode set to true for array output
$result = json_decode($response, true); // true turns it into an array
but when i try to echo the 'first_name' values it just returns empty.
echo 'First Name: ' . $result['first_name'] . '<br />'; // why doesnt this work
Yet i can return an indexed value
echo 'First Name: ' . $result[0]['first_name'] . '<br />';
What am i doing wrong here?
Your result array is nested 2 deep. $result is an array of arrays. So:
$result[0]['first_name']
or
foreach ($result as $r) {
echo $r['first_name'];
}
Response depend on server answer your request, the following work perfect to extract access token for example, you can try the following steps to test what you have and extract what you need too
After
$response = curl_exec($ch);
curl_close($ch);
I start to show what I get by
Test:
print_r ($response);
Then go to extract (where server response ) header and body to use what available in each of them
list($header, $body) = explode("\r\n\r\n", $response, 2);
Test:
echo $header;
echo $body;
then I’m extract item in $body to use in my code using stdClass
$bodyObject = json_decode($body);
Test:
print_r($bodyObject);
Test:
echo $bodyObject->access_token;

How to echo a specific value in an array?

i am having a problem with a function that i have got online from somewhere, the issue is the function is supposed to return a specific value in an array but whenever i echo the function, it gives me a big array in the print_r style! here is the code:-
function USPSParcelRate() {
$userName = 'XXXXXXXXXXX';
$orig_zip = '10459';
//Shipping Request
$dest_zip = getshipinfo('zip_code');
foreach($_SESSION as $name=> $value){
if($value>0){
if(substr($name, 0, 5)=='cart_'){
if(substr($name, 0, 5)=='cart_'){
$id=substr($name, 5, (strlen($name)-5));
$query = mysql_query("SELECT `category`,`subcategory` FROM `items` WHERE `id`='".mysql_real_escape_string((int)$id)."' ");
while($query_row = mysql_fetch_assoc($query)){
$category = $query_row['category'];
$subcategory = $query_row['subcategory'];
}
$sql = mysql_query("SELECT `pounds`,`ounces` FROM `categories` WHERE `category`='".$category."' AND `subcategory`='".$subcategory."' ");
while($sql_row = mysql_fetch_assoc($sql)){
$pounds = $sql_row['pounds'];
$ounces = $sql_row['ounces'];
}
}
}
}
}
$url = "http://production.shippingapis.com/shippingapi.dll";
$ch = curl_init();
// set the target url
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
// parameters to post
curl_setopt($ch, CURLOPT_POST, 1);
$data = "API=RateV4&XML=http://production.shippingapis.com/shippingapi.dll=<RateV4Request USERID='151ALHAD4911' >
<Revision/>
<Package ID='1ST'>
<Service>PRIORITY</Service>
<ZipOrigination>$orig_zip</ZipOrigination>
<ZipDestination>$dest_zip</ZipDestination>
<Pounds>$pounds</Pounds>
<Ounces>$ounces</Ounces>
<Container>NONRECTANGULAR</Container>
<Size>LARGE</Size>
<Width>12</Width>
<Length>15.5</Length>
<Height>6</Height>
<Girth>31</Girth>
</Package>
</RateV4Request>";
// send the POST values to USPS
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
$result=curl_exec ($ch);
$data = strstr($result, '<?');
// echo '<!-- '. $data. ' -->'; // Uncomment to show XML in comments
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
$level[$xml_elem['level']] = $xml_elem['tag'];
}
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
eval($php_stmt);
}
}
curl_close($ch);
//echo '<pre>'; print_r($params); echo'</pre>'; // Uncomment to see xml tags
return $params['RateV4Response']['1ST']['1']['RATE'];
}
echo USPSParcelRate();
this code doesn't give me any results unless i uncomment the print_r lines and it shows it like this:-
Array
(
[RATEV4RESPONSE] => Array
(
[1ST] => Array
(
[ZIPORIGINATION] => XXXXX
[ZIPDESTINATION] => XXXXX
[POUNDS] => 3
[OUNCES] => 5
[CONTAINER] => NONRECTANGULAR
[SIZE] => LARGE
[WIDTH] => 12
[LENGTH] => 16
[HEIGHT] => 6
[GIRTH] => 31
[ZONE] => 5
[1] => Array
(
[MAILSERVICE] => Priority Mail 3-Day<sup>™</sup>
[RATE] => 14.05
)
)
)
)
how can i echo the value of this line only :-
[RATE] => 14.05
Array keys are case sensitive, so...
return $params['RATEV4RESPONSE']['1ST'][1]['RATE'];
Should do it

WHMCS getclients searching results

Myself and a few friends are trying to use WHMCS to offer services in a virtual world. Issue is WHMCS does not provide a simple way to search for a specific client record without already having the client id, which wouldn't be stored anywhere besides the WHMCS database. the api function getclients returns results in an XML format, issue is when you search for a client using this method you can only search for firstname, lastname, or email address. Now we have tried passing the variables for firstname and lastname(they have to be passed separately) This unfortunatly returns the client records for all clients that X firstname OR Y Lastname, instead of narrowing down the one client with both X and Y.
What I want to know is how to search PHP array generated from an XML result to try and grab the client records for only the client we are looking for.
The results are posted as such:
Array ( [WHMCSAPI] => Array ( [ACTION] => getclients [RESULT] => success [TOTALRESULTS] => 2 [STARTNUMBER] => 0 [NUMRETURNED] => 2 [CLIENTS] => Array ( [CLIENT] => Array ( [ID] => 9 [FIRSTNAME] => Test1 [LASTNAME] => Test2 [COMPANYNAME] => [EMAIL] => test1#test.com [DATECREATED] => 2013-04-24 [GROUPID] => 1 [STATUS] => Active ) [CLIENT1] => Array ( [ID] => 20 [FIRSTNAME] => Test3 [LASTNAME] => Test2 [COMPANYNAME] => [EMAIL] => test#test.com [DATECREATED] => 2014-01-20 [GROUPID] => 0 [STATUS] => Active ) ) ) )
The code we try using to search is:
$postfields["action"] = "getclients";
$postfields["search"] = $firstname;
$postfields["search"] = $lastname;
$postfields["responsetype"] = "xml";
$query_string = "";
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$xml = curl_exec($ch);
if (curl_error($ch) || !$xml) $xml = '<whmcsapi><result>error</result>'.
'<message>Connection Error</message><curlerror>'.
curl_errno($ch).' - '.curl_error($ch).'</curlerror></whmcsapi>';
curl_close($ch);
$arr = whmcsapi_xml_parser($xml); # Parse XML
$client = searchClient($firstname, $lastname, $arr);
print_r($client); # Output XML Response as Array
/*
Debug Output - Uncomment if needed to troubleshoot problems
echo "<textarea rows=50 cols=100>Request: ".print_r($postfields,true);
echo "\nResponse: ".htmlentities($xml)."\n\nArray: ".print_r($arr,true);
echo "</textarea>";
*/
function whmcsapi_xml_parser($rawxml) {
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $rawxml, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
$alreadyused = array();
$x=0;
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (in_array($xml_elem['tag'],$alreadyused)) {
$x++;
$xml_elem['tag'] = $xml_elem['tag'].$x;
}
$level[$xml_elem['level']] = $xml_elem['tag'];
$alreadyused[] = $xml_elem['tag'];
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
#eval($php_stmt);
}
}
return($params);
}
function searchClient($first, $last, $array)
{
foreach ($array as $key => $val)
{
if($val['FIRSTNAME'] == $first && $val['LASTNAME'] == $last)
{
return $key;
}
}
return null;
}
?>
This returns a blank result. I will admit I am not entirely sure how to do this so any pointers will help.
You are able to "search for a specific client record" via email address utilizing their api and they now support json format for responsetype
"Please note either the clientid or email is required."
http://docs.whmcs.com/API:Get_Clients_Details

PHP LDAP Get User Attributes, Including Associated Groups

What is the best way to run a search on the current user to retrieve all attributes, including associated groups in Active Directory using LDAP / PHP?
For attributes, mainly just first name, last name, and display name.
For associated groups, just the groups the user is a member of, such as the memberOf function.
I've tried a few options, but can't seem to get the right filter / search combination and most examples cover retrieving lists of users where there's a known group.
I've tried running this after a successful bind:
$attributes = array("displayname");
$filter = "(&(sAMAccountName=$username))";
$result = ldap_search($ds, $ldapconfig['basedn'], $filter, $attributes);
$entries = ldap_get_entries($ds, $result);
if($entries["count"] > 0){
echo "displayName: ".$entries[0]['displayname'][0]."<br/>";
} else {
echo("msg:'".ldap_error($ds)."'</br>");
}
Which returns the following error: "No such object".
UPDATE:
This is the latest block I've tried and am able to get results when I print_r the $info variable, however the for clause is still erring out somewhere. I changed the basedn to just the dc attributes:
$filter="($SearchField=$SearchFor)";
$sr=ldap_search($ds, $basedn, $filter, $LDAPFieldsToFind);
$info = ldap_get_entries($ds, $sr);
if($info["count"] > 0) {
for ($x=0; $x<$info["count"]; $x++) {
$sam=$info[$x]['samaccountname'][0];
$giv=$info[$x]['givenname'][0];
$tel=$info[$x]['telephonenumber'][0];
$email=$info[$x]['mail'][0];
$nam=$info[$x]['cn'][0];
$dir=$info[$x]['homedirectory'][0];
$dir=strtolower($dir);
$pos=strpos($dir,"home");
$pos=$pos+5;
if (stristr($sam, $SearchFor) && (strlen($dir) > 8)) {
print "\nActive Directory says that:\n";
print "CN is: ".$nam." \n";
print "SAMAccountName is: ".$sam." \n";
print "Given Name is: ".$giv." \n";
print "Telephone is: ".$tel." \n";
print "Home Directory is: ".$dir." \n";
}
}
}
The print_r of the results are:
( [count] => 1 [0] => Array ( [cn] => Array ( [count] => 1 [0] => George ) [0] => cn [givenname] => Array ( [count] => 1 [0] => George ) [1] => givenname [memberof] => Array ( [count] => 4 [0] => CN=EQCStaff,CN=Users,DC=EQC,DC=local [1] => CN=RDS Users,OU=Security Groups,OU=Service,DC=EQC,DC=local [2] => CN=SFTP Client Folders,OU=Security Groups,OU=Service,DC=EQC,DC=local [3] => CN=EQC Staff,OU=Security Groups,OU=Service,DC=EQC,DC=local ) [2] => memberof [samaccountname] => Array ( [count] => 1 [0] => gortiz ) [3] => samaccountname [mail] => Array ( [count] => 1 [0] => user#domain.com ) [4] => mail [count] => 5 [dn] => CN=George,OU=Users,OU=Accounts,DC=EQC,DC=local ) )
Here's a script we have for dumping AD information, maybe it will help you:
<?php
$ldap_columns = NULL;
$ldap_connection = NULL;
$ldap_password = 'top_secret_password';
$ldap_username = 'top_secret_username#'.LDAP_DOMAIN;
//------------------------------------------------------------------------------
// Connect to the LDAP server.
//------------------------------------------------------------------------------
$ldap_connection = ldap_connect(LDAP_HOSTNAME);
if (FALSE === $ldap_connection){
die("<p>Failed to connect to the LDAP server: ". LDAP_HOSTNAME ."</p>");
}
ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); // We need this for doing an LDAP search.
if (TRUE !== ldap_bind($ldap_connection, $ldap_username, $ldap_password)){
die('<p>Failed to bind to LDAP server.</p>');
}
//------------------------------------------------------------------------------
// Get a list of all Active Directory users.
//------------------------------------------------------------------------------
$ldap_base_dn = 'DC=xyz,DC=local';
$search_filter = "(&(objectCategory=person))";
$result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);
if (FALSE !== $result){
$entries = ldap_get_entries($ldap_connection, $result);
if ($entries['count'] > 0){
$odd = 0;
foreach ($entries[0] AS $key => $value){
if (0 === $odd%2){
$ldap_columns[] = $key;
}
$odd++;
}
echo '<table class="data">';
echo '<tr>';
$header_count = 0;
foreach ($ldap_columns AS $col_name){
if (0 === $header_count++){
echo '<th class="ul">';
}else if (count($ldap_columns) === $header_count){
echo '<th class="ur">';
}else{
echo '<th class="u">';
}
echo $col_name .'</th>';
}
echo '</tr>';
for ($i = 0; $i < $entries['count']; $i++){
echo '<tr>';
$td_count = 0;
foreach ($ldap_columns AS $col_name){
if (0 === $td_count++){
echo '<td class="l">';
}else{
echo '<td>';
}
if (isset($entries[$i][$col_name])){
$output = NULL;
if ('lastlogon' === $col_name || 'lastlogontimestamp' === $col_name){
$output = date('D M d, Y # H:i:s', ($entries[$i][$col_name][0] / 10000000) - 11676009600); // See note below
}else{
$output = $entries[$i][$col_name][0];
}
echo $output .'</td>';
}
}
echo '</tr>';
}
echo '</table>';
}
}
ldap_unbind($ldap_connection); // Clean up after ourselves.
?>
User inventor96 has suggested using 11644473600 instead of 11676009600. I can confirm 11644473600 is correct in a Linux environment - my guess is that inventor96 is in a Windows environment.

Categories