Fetch users from Azure AD - php

I can't figure out why my loop isn't working at all. I have successfully connected to my clients directory and I am able to fetch some users. I have followed the PHP instructions. But this tutorial doesn't include example for fetching all users only the default page size of 100 users.
I am aware of the skipToken (explained here) but for some reason I am not been able to get it work with my loop.
Basically first I define an array, and two sub arrays.
$myArray = array();
$myArray['skipToken'] = "";
$myArray['users'] = "";
Then I'll perform the first fetch so I can get skipToken and bunch of users that come along.
require_once("GraphServiceAccessHelper.php");
$users = GraphServiceAccessHelper::getFeed('users');
Pushing values into already existing arrays.
$myArray['skipToken'] = $users->{'odata.nextLink'};
$myArray['users'][] = $users->{'value'};
Now they are filled with information. Now its time to loop!
for($i = 0; $i < 2; $i++){
if($myArray['skipToken'] != ""){
$skipToken = $myArray['skipToken'];
require_once("GraphServiceAccessHelper.php");
$users = GraphServiceAccessHelper::getNextFeed('users', $skipToken);
$myArray['skipToken'] = $users->{'odata.nextLink'};
$myArray['users'][] = $users->{'value'};
}
}
Console fires up from error, that points to loop skipToken defining part:
Notice: Undefined property: stdClass::$odata.nextLink
$myArray['skipToken'] = $users->{'odata.nextLink'};

Okay I figured it out.
First I had to remove everything before actual token.
$skipToken = $users->{'odata.nextLink'};
$skipToken = substr($skipToken, strpos($skipToken, "=") + 1);
Then inside the loop use that get new skipToken and do the same like above:
$new = GraphServiceAccessHelper::getNextFeed('users', $skipToken);
if(isset($new->{'odata.nextLink'})){
$skipToken = empty($new->{'odata.nextLink'});
} else{
break;
}
$skipToken = substr($skipToken, strpos($skipToken, "=") + 1);
$myArray['tokens'] = $skipToken;
$myArray['users'][] = $new->{'value'};
By checking if 'odata.nextLink" exists I can easily stop the while loop since lastpage doesn't contain 'odata.nextLink'.
if(isset($new->{'odata.nextLink'})){
$skipToken = empty($new->{'odata.nextLink'});
} else{
break;
}
I am appending each 100 user array to another array that I can call easily use it outside PHP.

Related

How to set GET POST and REQUEST strings dynamically

Okay So for awhile I have been attempting to set GET POST and REQUEST variables dynamically.
I store the variables I want it to get or post or request inside an sql table. each variable has it's own column. In this same row it records the type I want it to try to use(GET,POST,REQUEST). I am telling you this so you see how I want to go about doing this.
Source
$snmpbq=$os_DB->query("SELECT * FROM `spiders` WHERE site = '".$site_name."'") or die(mysql_error());
$num=$os_DB->num($snmpbq);
if($num == 1)
{
//get row as an associative array
$pb=$os_DB->fetch($snmpbq);
//data request type
$req_type = $pb['net_req_type'];
$a1 = $pb['a'];
$b1 = $pb['b'];
$c1 = $pb['c'];
$d1 = $pb['d'];
$e1 = $pb['e'];
$f1 = $pb['f'];
if($req_type == "get")
{
$a = $_GET[$a1];
$b = $_GET[$b1];
$c = $_GET[$c1];
$d = $_GET[$d1];
$e = $_GET[$e1];
$f = $_GET[$f1];
}
You can accomplish this in a much cleaner way by replacing the blocks with 1 block... rather then checking the request type.
If you remove all your blocks and replace with:
$a = $_REQUEST[$a1];
$b = $_REQUEST[$b1];
$c = $_REQUEST[$c1];
$d = $_REQUEST[$d1];
$e = $_REQUEST[$e1];
$f = $_REQUEST[$f1];
As per the PHP Documents here
The variables in $_REQUEST are provided to the script via the GET, POST, and COOKIE input mechanisms and therefore could be modified by the remote user and cannot be trusted. The presence and order of variables listed in this array is defined according to the PHP variables_order configuration directive.
Sounds like you need to use a variable variable.
$result = 'someDataBaseQueryResult';
$$result = 'cool'; // now $someDataBaseQueryResult === 'cool'
You question is a bit confusing, but you could take this to the nth degree.
Idea for the sample code:
$sReq = $pb['net_req_type'];
foreach($pb as $key => $value) {
if($key == 'net_req_type')
continue;
${$key} = $_GET[$value];
}
It's a little late, and I'm a little drunk, but I think that may be close. Haven't executed it though...

Pulling specific random values from php array

On the page I'm creating there is graphic representation of pigeon-holes with five compartments for new comments. If there is new unread comment it should show up as graphic in one random compartment. But it won't happen if all of the 5 are
already occupied. So if someone writes new comment I like the code to check for if there is already five of them taken, and if not, than to randomly occupied one of the remaining ones. So "new_c" stands for number of
unread (new) comments, and c1-c5 stands for compartments. Value 0 means empty compartment for each "c". I was trying to make code that would first separate new_c from rest of the array after knowing the number is smaller than 5,
so I'm only working with 5 compartments. And than to determine which one is/are empty. And then randomly choose one empty to occupy. It's not really working as it is I probably am not using that array_keys properly as c2 is changed to some other value than 0 but still is being echoed, there is probably also a better/more efficient way to achieve that. I will really appreciate some input.
<?php
$tucQuery = "SELECT new_c,c1,c2,c3,c4,c5 FROM users WHERE id = '{$author_id}' LIMIT 1";
$result_tuc = mysqli_query($connection, $tucQuery);
$tucArray = mysqli_fetch_assoc($result_tuc);
mysqli_free_result($result_tuc);
$new_c = $tucArray[0];
if($new_c < 5){
$new_array = array_keys((array_slice($tucArray,1)), 0);
$rand_zero = array_rand($new_array, 1);
echo $rand_zero + 1;
}
?>
Bellow code works but it doesn't seem to be efficient and there is probably a better way.
if($new_c < 5){
$empties = array();
if($tucArray['c1'] == 0){
$empties[] = 1;
}
if($tucArray['c2'] == 0){
$empties[] = 2;
}
if($tucArray['c3'] == 0){
$empties[] = 3;
}
if($tucArray['c4'] == 0){
$empties[] = 4;
}
if($tucArray['c5'] == 0){
$empties[] = 5;
}
print_r($empties);
$rand_zero = array_rand((array_flip($empties)), 1);
echo $rand_zero;
}

PHP / Zend / Google Spreadsheet not getting all rows

I am trying to get all the rows from a Google spreadsheet via a PHP/Zend script. This is the script I am using:
$service = Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient('xxxxxxxxx', 'xxxxxxx', $service);
$spreadsheetService = new Zend_Gdata_Spreadsheets($client);
// Get spreadsheet key
$spreadsheetsKey = 'xxxxxxxxxxxxx';
$worksheetId = 'xxx';
// Get cell feed
$query = new Zend_Gdata_Spreadsheets_CellQuery();
$query->setSpreadsheetKey($spreadsheetsKey);
$query->setWorksheetId($worksheetId);
$cellFeed = $spreadsheetService->getCellFeed($query);
// Build an array of entries:
$ssRows = array();
$ssRow = array();
$titleRow = array();
$tableRow = 1;
foreach($cellFeed as $cellEntry) {
$row = $cellEntry->cell->getRow();
$col = $cellEntry->cell->getColumn();
$val = $cellEntry->cell->getText();
// Add each row as a new array:
if ($row != $tableRow) {
array_push($ssRows, $ssRow);
$ssRow = array();
// Move to the next row / new array
$tableRow = $row;
}
// Build the array of titles:
if ($row == 1) {
$titleRow[$col] = $val;
}
// Build the array of results with the title as the key:
else {
$key = $titleRow[$col];
$ssRow[$key] = $val;
}
}
// Pass the results array:
return array_reverse($ssRows);
This builds me an array with MOST of the details from the spreadsheet, however it always misses off the last entry - can anyone see what I am doing wrong, or is there a better way to get all the data from the spreadsheet?
The form is a 3 part form, based on different answers. On filling out one part, I want to display a URL back to the form, with some details from the first form pre-filled to make the second part of the form faster to fill out. This is all fine, it is simply the missing last entry that is the major problem!
Thanks!
Your code works like this:
if (next_row) {
data[] = current_row
current_row = array();
}
if (first_row) {
title_row logic
} else {
add cell to current_row
}
So you only add the rows to your collector once you go to the next row. This will miss the last row because you'll miss that last transition.
The easy fix is to add array_push($ssRows, $ssRow); right after the foreach loop. You will need to add a check for 0 rows, this should be skipped then.
Perhaps a more proper fix is to iterate by row, then by cell, rather than just by cell.

Twitter API User Lookup 1000 users

I'm trying to fetch 1000+ Twitter users from my database using this API call. However, Twitter lookup only allows 100 users per call, so how can I do it with 10 calls?
If I have 2232 users in my DB and I want to do a lookup on all users and get their details how to do it? Something which will count all the users being searched, break it into array of 100 elements, make the call for 100, and add the response back to database and then move onto the next 100.
I am using the tmhOAuth library for Twitter.
EDITED:
I was able to accomplish it using this code , but my next question is how can i bind those values back to my account ? because the screen_name is a entry and not the KEY of the array, so how can i do it ?
$accounts = $this->accounts->getAll();
$accounts_chunk = array_chunk($accounts,100);
foreach($accounts_chunk as $accounts){
$screen_names = "";
$last_key = end(array_keys($accounts));
foreach($accounts as $k => $account){
$screen_names .= $account->screen_name;
if($last_key == $k){
$screen_names .= "";
} else {
$screen_names .= ",";
}
}
$code = $this->twitter->request('GET', $this->twitter->url("1/users/lookup"),array('screen_name' => $screen_names));
echo "<pre>";print_r(json_decode($this->twitter->response));echo "</pre>";
}
But how to update values in DB using this .. i did a check but the sequence of the responses always changes so cannot use the current keys ..
You could loop through the max number of users and every hundredth time loop through hundred users and do your Twitter-magic there.
$iNumUsers = 2232; // or a mysql_num_rows-like result;
for($i = 0; $i < $iNumUsers; $i++) {
if($i % 100 == 0) {
for($j = $i; $j < 100; $j++) {
// your twitter-code here
}
}
}
Hi here are some simple steps to do this task
1: Get screen names from your db with limit of 100
2: impload with comma (join them with comma)
3: Send these 100 to users/lookup call and get data
4: (important) IF YOU RECEIVE AN ERROR OF "Rate limit exceeded" THEN USE PROXY
proxy will give you another chance to make next call of 100 users
5: decode json and send data to db
(important) if you use user's id instead of screen name then it will be easy to update db
Still have problem shout a comment here
The Twitter API says
You are strongly encouraged to use a POST for larger requests.
So try posting your 2,000 IDs to them.
With regards to the second part of your question
the sequence of the responses always changes so cannot use the current keys ..
Start with your array of user IDd - $ids
Get the response from Twitter as $tl
// Place the users into an array
$sortedUsers = array();
foreach ($tl as $user) {
$user_id = $user->id;
// $tl is *unsorted* - but $ids is *sorted*. So we place the users from $tl into a new array based on how they're sorted in $ids
$key = array_search($user_id, $ids);
$sortedUsers[$key] = $user;
}
// Sort the array by key so the most recent is at the top
ksort($sortedUsers);

MySQL queries optimization

So I've been working on an IRC game for one year now, written in PHP and using a PHP to IRC framework.
Recently, I've added the ability to archive scores (they're being reseted every couple hundreds of games) which forced me to update various admin functions.
I've just updated a function that allows me to merge two players (some users don't bother looking for their old password etc...) in order to merge archived scores too (in case a reset has occurred before I find the duplicated accounts).
The score-merging part (below) works has intended, but I'm wondering if I can optimize the process because I find it rather heavy (but can't think of something better) :
$from_stats = $this->db->query("SELECT `games`, `wins`, `points`, `date_archive` FROM ".$this->dbprefix."score WHERE `id`=".$id1." AND `channel`='".$gamechan."' GROUP BY `date_archive`"); // get scores for the original account
$to_stats = $this->db->query("SELECT `games`, `wins`, `points`, `date_archive` FROM ".$this->dbprefix."score WHERE `id`=".$id2." AND `channel`='".$gamechan."' GROUP BY `date_archive`"); // get scores for the duplicated account
$from_games = array();
$from_wins = array();
$from_points = array();
$from_date = array();
while (list($fromstats_games,$fromstats_wins,$fromstats_points,$fromstats_date) = $this->db->fetchRow($from_stats)) { // build score arrays for the original account
$from_games[count($from_games)] = $fromstats_games;
$from_wins[count($from_wins)] = $fromstats_wins;
$from_points[count($from_points)] = $fromstats_points;
$from_date[count($from_date)] = $fromstats_date;
}
$to_games = array();
$to_wins = array();
$to_points = array();
$to_date = array();
while (list($tostats_games,$tostats_wins,$tostats_points,$tostats_date) = $this->db->fetchRow($to_stats)) { // build score arrays for the duplicated account
$to_games[count($to_games)] = $tostats_games;
$to_wins[count($to_wins)] = $tostats_wins;
$to_points[count($to_points)] = $tostats_points;
$to_date[count($to_date)] = $tostats_date;
}
foreach ($from_date as $key1 => $id1_date) {
foreach ($to_date as $key2 => $id2_date) {
if ($id1_date == $id2_date) { // merge scores if dates match
$from_games[$key1] += $to_games[$key2];
$from_wins[$key1] += $to_wins[$key2];
$from_points[$key1] += $to_points[$key2];
$this->db->query("UPDATE ".$this->dbprefix."score SET `games`=".$from_games[$key1].", `wins`=".$from_wins[$key1].", `points`=".$from_points[$key1]." WHERE `id`=".$id1." AND `channel`='".$gamechan."' AND `date_archive`='".$id1_date."'");
break;
}
}
}
$this->db->query("DELETE FROM ".$this->dbprefix."score WHERE `id`=".$id2); // delete all entries for the duplicated account
Just one tip: after all use this query (if You have appropriate privilages)
$this->db->query("OPTIMIZE TABLE ".$this->dbprefix."score");
This should cause all indexes in this table to be recalculated. You'll notice the index file size has changed to 1kb (or few bytes)

Categories