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.
Related
I am building a web scraper in PHP and I am not so experimented with all this stuff. What I am trying to achieve is as following:
Split an array of values into strings using foreach
Search any value in a predefined MYSQL table. If value is identical with one of the defined ones, it should be replaced. Otherwise it should remain the same
Put the new values back into an array
Below is my snippet. Basic structure of database is "ID, Marime, Inlocuire". "Marime" is the column to search on, and "Inlocuire" is the column to replace value with.
foreach ($marimi as $marime) {
$sizes[]=trim(strtok($marime->innertext, '-'));
$newArray = array_filter($sizes, 'myFilter');
foreach ($newArray as $marimeFixa) {
$marimeDefinita = $conn->query("SELECT * FROM oc_1_tabelmarimi WHERE Marime = '$marimeFixa'");
if($marimeDefinita->num_rows == 0) {
$marimeFixa = $marimeFixa;
} else {
$marimeFixa = $marimeDefinita['Inlocuire'];
}
$arrayMarimi[] = $marimeFixa;
}
print_r($arrayMarimi);
}
However this doesn't seem to work. Any help is greatly appreciated. Thanks!
try:
$marimeDefinita = $marimeDefinita->fetch_assoc();
before if($marimeDefinita->num_rows == 0) {
or
$marimeFixa = $marimeDefinita->Inlocuire;
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.
I am trying to Plot a Graph with FLOT but I cant get my head around how to get make it Dynamic with multiple series.
I am trying to get Race Data , Eg Laps and Time as the Graph x and y, but also trying to get the Race ID as a new series line for each Rider.
I have tried it at a Loop for each RaceID, and I have tried it as a multidimensional array, But I cant get my head around how to get it formatted to how FLOT wants it.
I can get it to work with 1 Rider:
$GetLapData = mysql_Query("SELECT LapData.*, u.RaceID
FROM `LapData`
left join User as u on LapData.TagID = u.TagID
Where LapData.EventID = '$EventID'
and LapData.RaceNameID = '$RaceNameID'
and LapData.TagID = '$RacingNumber'
ORDER BY `LapData`.`LapNumber` ASC");
while ($row = mysql_fetch_assoc($GetLapData))
{
$dataset1[] = array($row['LapNumber'],$row['LapTimeinSeconds']);
}
and then plot the single Data Set
$(function() {
var d1 = <?php echo json_encode($dataset1) ?>;
$.plot("#placeholder", [ d1 ]);
});
Any Ideas on making it all riders for the Race would be really helpful.
This is a tough question to answer without seeing your database scheme, but I'll give it a shot.
First, let's modify your SQL statement. I'm guessing that this part and LapData.TagID = '$RacingNumber' is what subset's it down to a single rider? Also, what's the purpose of the join, do you want the rider's name from there or some other identifier? I've left it but if you aren't using it, it's a waste...
$GetLapData = mysql_Query("SELECT LapData.TagID, LapData.LapNumber, LapData.LapTimeInSeconds
FROM LapData
LEFT JOIN User AS u ON LapData.TagID = u.TagID
WHERE LapData.EventID = '$EventID'
ANDLapData.RaceNameID = '$RaceNameID'
AND LapData.TagID = '$RacingNumber'
ORDER BY LapData.TagID, LapData.LapNumber ASC");
$allSeries = array(); // our "return value"
$currentSeries = null; // some temp variables
$currentRider = null;
while ($row = mysql_fetch_assoc($GetLapData))
{
$loopRider = $row['TagID']; // get rider for this database row
if ($currentRider === null || $loopRider != $currentRider) // if first loop or new rider
{
if ($currentSeries !== null)
{
$allSeries[] = $currentSeries; // we have a new rider push the last one to our return array
}
$currentSeries = array(); // this is first loop or new rider, re-init current series
$currentSeries["label"] = $loopRider;
$currentSeries["data"] = array();
}
$currentSeries["data"][] = array($row['LapNumber'],$row['LapTimeinSeconds']); //push row data into object
}
$allSeries[] = $currentSeries; // last rider's data push
In the end, allSeries is an array of associative arrays per flots documentation.
Mainly:
$allSeries = [{
"label" = "tag1",
"data" = [[0,12],[1,45],[2,454]]
},{
"label" = "tag2",
"data" = [[0,122],[1,415],[2,464]]
}]
After you Json encode this, the call is:
$.plot("#placeholder", allSeries);
My Standard PHP disclaimer, I'm not a PHP programmer, I've never used it and never ever want to use it. All the above code was peiced together from quickly reading the documentation and is untested.
I am facing problem to retrieve records in descending order with pagination limit from amazon dynamodb as in mysql.
Now I am using the following script, but it gives unordered list of records. I need the last inserted id is on top.
$limit = 10;
$total = 0;
$start_key = null;
$params = array('TableName' => 'event','AttributesToGet' =>array('id','interactiondate','repname','totalamount','fooding','nonfooding','pdfdocument','isMultiple','payment_mode','interaction_type','products','programTitle','venue','workstepId','foodingOther','interaction_type_other'), 'ScanFilter'=> array('manufacturername' => array("ComparisonOperator" => "EQ", "AttributeValueList" => array(array("S" => "$manufacturername")))),'Limit'=>$limit );
$itemsArray = array();
$itemsArray = array();
$finalItemsArray = array();
$finalCRMRecords = array();
do{
if(!empty($start_key)){
$params['ExclusiveStartKey'] = $start_key->getArrayCopy();
}
$response = $this->Amazon->Dynamodb->scan($params);
if ($response->status == 200) {
$counter = (string) $response->body->Count;
$total += $counter;
foreach($response->body->Items as $itemsArray){
$finalItemsArray[] = $itemsArray;
}
if($total>$limit){
$i =1;
foreach($response->body->Items as $items){
$finalItemsArray[] = $items;
if($i == $limit){
$start_key = $items->id->{AmazonDynamoDB::TYPE_NUMBER}->to_array();
$finalCRMRecords['data'] = $finalItemsArray;
$finalCRMRecords['start_key'] = $start_key;
break;
}
$i++;
}
}elseif($total<$limit){
$start_key = $response->body->LastEvaluatedKey->to_array();
}else{
$finalCRMRecords['data'] = $finalItemsArray;
if ($response->body->LastEvaluatedKey) {
$start_key =$response->body->LastEvaluatedKey->to_array();
break;
} else {
$start_key = null;
}
$finalCRMRecords['start_key'] = $start_key;
}
}
}while($start_key);
Regards
Sandeep Kumar Sinha
A Scan operation in DynamoDB can not change the sorting of the returned items. Also is Scan a pretty expensive operation as it always requires to read the whole table.
If you want to take advantage of DynamoDB, here's one advice:
Instead of looking for information, try to just find it.
In the sense of, use lookups instead of scan/query to get the information you need.
As an example, if you have a table that stores Events. Just store all events in that table, with their EventId as HashKey. Then you can have a second table EventLookups to store lookups to EventIds. In the EventLookups table you could put an Item like LookupId: LATEST-EVENT referencing some EventId: .... Every time you insert new events you can update the LATEST-EVENT entry to point to a newer Event. Or use a SET to store the latest 50 EventIds events in one Item.
-mathias
How can I get the record values in the database to be sorted like this in an array. Supose I am adding the day no.
array
[0] => array=>'id'=>'26' 'date'=>'26'
[1] => array=>'id'=>'27' 'date'=>'27',
array=>'id'=>'28' 'date'=>'27',
array=>'id'=>'29' 'date'=>'27'
[2] => array=>'id'=>'30' 'date'=>'29'
[3] => array=>'id'=>'31' 'date'=>'31',
array=>'id'=>'32' 'date'=>'31',
array=>'id'=>'33' 'date'=>'31'
Basically, I want to add an array to the same index if the next id contains a record with the same date (day no) of the month. Otherwise add it normally.
Right now, My function is adding the rows of the record without sorting it in the format I want it to be in.
The reason I want it to be in this format is because, I need to run the foreach, and if 1 day contains 2 records, then it will append another <li> into my unordered list.
public function getArticles()
{
$sql = 'CALL getArticles()';
$articles = Array();
if (Model::getConnection()->multi_query($sql)) {
do {
if ($result = Model::getConnection()->store_result()) {
while ($row = $result->fetch_assoc()) {
array_push($articles,$row);
}
$result->free();
}
} while (Model::getConnection()->next_result());
}
return $articles;
}
I don't recognize what some of your code is doing, but I think this is the important part.
while ($row = $result->fetch_assoc()) {
if (!isset($articles[$row['date']])) {
$articles[$row['date']] = array();
}
$articles[$row['date']][] = $row;
}
The only difference will be that your array will be keyed on the date instead of incrementing from zero. If you really want it reindexed, you can do...
array_values($articles);
As savinger pointed out, there is alot of functionality in your code which I don't really know, so I've included comments to indicate whereabouts the process is:
// Start of your loop
// $value is what you're getting from the DB...
$array_search = array_search($value,$main_array);
if($array_search)
{
// If this value already exists, we need to add
// this value in +1 of its current value
$main_array[$array_search][] = $value + 1;
}
else
{
// Make a new array key and add in the value
$main_array[] = $value;
}
// End of your loop