Getting Notice: Undefined offset: 0 - php

I am getting this error in 3 spots in the function that I pasted below. There is more to this code, but I didn't think it was needed to get this thing figured out.
$count = count($collection);
$i = 1 ;
foreach ($collection as $product)
{
$j = 1 ;
$productId = $product->getDiamondsearchId();
$attributValueOptions = "[" ;
$attributValueOptions .= "'".$productId."', ";
foreach($filterAttributeIds as $filterAttributeId){
$attributValueCollection = Mage::getModel('diamondsearch/diamondsearchattributvalue')->getCollection()->addFieldToFilter('attribut_id',$filterAttributeId)->addFieldToFilter('diamondsearch_id',$productId)->getData();
$attrbutValueId = $attributValueCollection[0]['attrbut_value_id'];
//echo $attrbutValueId."<br>";
$attributValueOptionCollection = Mage::getModel('diamondsearch/diamondsearchattributoptionvalue')->getCollection()->addFieldToFilter('id',$attrbutValueId)->getData();
if($j == 1 && $attributValueOptionCollection[0]['attribut_value'] == ""){
break ;
}
if($j == 15){
$attributValueOptions .= "'".$attributValueOptionCollection[0]['attribut_value']."'";
}else{
$attributValueOptions .= "'".$attributValueOptionCollection[0]['attribut_value']."', ";
}
$j++;
}
if($count == $i ){
$attributValueOptions .= "]";
}else{
$attributValueOptions .= "], ";
}
$i++;
echo $attributValueOptions ;
}

The problem is with this line:
$attributValueCollection = Mage::getModel('diamondsearch/diamondsearchattributvalue')->getCollection()->addFieldToFilter('attribut_id',$filterAttributeId)->addFieldToFilter('diamondsearch_id',$productId)->getData();
$attrbutValueId = $attributValueCollection[0]['attrbut_value_id'];
You're trying to get the first item of array, but this variable is empty. You should verify and then do the stuff you want, like this:
if(!empty(attributValueCollection)){
$attrbutValueId = $attributValueCollection[0]['attrbut_value_id'];
Here's the complete gist:
https://gist.github.com/muriloazevedo/8dc5b11b17d1c4a3a518
But also is important to remember, if you trying to generate a json result, is better to use json_encode for that:
http://php.net/manual/pt_BR/function.json-encode.php

Related

Crawling with PHP and XPATH

I'm crawling a page because I want to show it on our website. I have a problem with getting the link on each team though. I get the team name, but I cant get the href attribute.
My code looks like this:
elements = $xpath->query("//table/tr[contains(#class,'sr')]/td[contains(#class,'c')]");
$count = 0;
foreach ($elements as $elt) {
if($count == 0)
{
$stringInsert = utf8_decode($elt->textContent);
}
else if($count == 1)
{
// tries to echo the href here, but dont get it.
echo $elt->getAttribute('href')
$stringInsert .= ", '".trim(utf8_decode($elt->textContent))."'";
}
else if($count == 3)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
else if($count == 4)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
else if($count == 5)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
else if($count == 6)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
else if($count == 7)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
else if($count == 9)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
else if($count == 10)
{
$stringInsert .= ", ".utf8_decode($elt->textContent);
}
$count++;
if($count == 12)
{
echo $stringInsert;
$count = 0;
}
}
As you can see in the code, i try to echo the $elt->getAttribute('href') in count == 1, but it does not show anything.
I have tried to add a /a to the xpath conditions, but then it only gets the Team name and not all the other stuff like, score, point and etc.
You seem to query for the td Elements, which won't have an attribute href.
May this example is helpful:
//array to store the results
$res = array();
//loop over all <tr> elements of the table.srPoolPosition
foreach ($path->query("//table[contains(#class,'srPoolPosition')]/tr") as $row) {
//new array to store results in each row
$rowRes = array();
//get the <td> elements in current <tr>
$fields = $path->query('td', $row);
//skip if not 12 fields
if ($fields->length < 12) {
continue;
}
//loop over those
foreach ($fields as $field) {
//store the textcontent in the current rows array
$rowRes[] = utf8_decode($field->textContent);
}
//query for the link in the current row
$link = $path->query("a", $row)->item(0)->getAttribute('href');
//add the link to the results array
rowRes[] = $link;
//then add it to the results
$res[] = $rowRes;
}
//example loop over the results
foreach ($res as $tableRow) {
echo sprintf(
'%s: %s - %s<br>',
$tableRow[13], //link href
$tableRow[1], //name
$tableRow[7], //score 1
$tableRow[9] //score 2
);
}

PHP Last in array to CSV

I have been trying to get this code to work for ages now and have looked at other questions but it is not working for me. Any guidance is greatly appreciated.
In context, there is a sql query to bring back all of the results for today's entries. These are converted to a CSV file every day. To import into the software then the end of each row must return "" and a carriage return except the last row which should not add a carriage return.
The code is below:
$xo1 = "\"\"";
$xo2 = "\r\n";
while ($row = mysql_fetch_array($sql)) {
for ($i = 0; $i < $columns_total; $i++) {
$output .='"'.$row["$i"].'",';
if(++$i === $columns_total){
$xo1 = "";
$xo2 = "";}
}
$output .= $xo1;
$output .= $xo2;
}
I guess rtrim() should do the job, if I got the question right.
while ( $row = mysql_fetch_array( $sql ) ) {
foreach( $row as $column ) {
$output .= sprintf( '"%s",""' . "\r\n" , $column );
}
}
rtrim( $output, '""' . "\r\n" );
You can also use the index of the loop for this problem. When index is above zero apply the $xo1 and $xo2. For example:
for ($i = 0; $i < $columns_total; $i++) {
if ( $i > 0 ) {
$output .= $xo1 . $xo2;
}
// now apply other workings
$output .='"'.$row["$i"].'",';
}

Message array to string conversion

That might be a fool question, but I need to know how to solve this:
Notice: Array to string conversion in C:\xampp\htdocs\search_view.php on line 248
Why am I getting this message, what can I do to solve it?
echo'<div id="thumb">
'.$ids = array();
$ids[] = $results['idGames'];
for ($i = 0; $i < count($ids); $i++) {
$id = $ids[$i];
$v = $results['total_votes'];
$tv = $results['total_value'];
if ($v)
$rat = $tv / $v;
else
$rat = 0;
$j = $ids[$i];
$id = $ids[$i];
echo '<div class="topcontentstar">
<div id="' . $id . '" class="">';
for ($k = 1; $k < 6; $k++) {
if ($rat + 1 > $k)
$class = "" . $k . " ratings_stars_index ratings_vote";
else
$class = "" . $k . " ratings_stars_index ratings_blank";
echo '<div class="' . $class . '"></div>';
}
echo '
</div>
</div></div>;
Because in this part of code you tried to convert an array to string via concatenation
echo'<div id="thumb">
(line 248) '.$ids = array();
Separate them: $ids = array()
echo'<div id="thumb">
(line 248) ';
$ids = array();
echo'<div id="thumb">
(line 248) '.$ids = array();
You are concatenating a string and an array, just as the errors says. You are echoing the string, and appending the array $ids to that. Because assigning a value gets a higher precedence than concatenating things, $ids is already an array.
You're doing this:
echo'<div id="thumb">
(line 248) '.$ids = array();
Basically, you can't concatenate array with a string and that's why the error appears.
To fix the error, you can separate the array declaration into a separate line:
echo'<div id="thumb">';
$ids = array();
Hope this helps!
As a side note, I can see a problem in your last few lines:
echo '
</div>
</div></div>;
Should be:
echo '</div></div></div>';

How to write this statement using PHP & CodeIgniter

I'm trying to figure out how to write a statement in my first CI app (and only second PHP app ever) and I'm stuck.
I have a junction table that holds book_id and user_id from their respective tables. I want to find out who has read a book and echo that back out, but I need the formatting to make sense. Here is the query:
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
And here's my logic for one person
// Get my user info
$user = $this->ion_auth->get_user();
// Tell me who has read it.
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
// If only one person has read it
if ($readQuery->num_rows() == 1) {
$readResult = $readQuery->row();
// And if that person was me...
if ($readResult->user_id == $user->id) {
$message = 'You have read this.';
// If it was someone else...
} else {
$reader = $this->ion_auth->get_user($readResult->user_id);
$message = "$reader->first_name $reader->last_name has read this";
}
// If two people have read it
}
So I'm good if only one person has read it. But when two people have read it, I want it to say "Name One and Name Two have read this." if the logged in person hasn't read it. If they're one of the two people, it should say "You and Name Two have read this".
And so on for 3-5. If 3-5 people have read it, the options would be "Name One, Name Two, and Name Three have read this" or "You, Name Two, and Name Three have read this." up to five people
And if it's 6 or more, it should just say the names of two of them, IE "You, Name Two, and 5 other people have read this."
I considered doing a conditional for each instance and then pushing all of the users to an array. Then I could use in_array() to see if the logged-in user has read it and try to report back, but I'm just having some trouble working up the logic.
Is there an easier way?
Thanks much in advance,
Marcus
I'd say use a switch statement with ranges. You'll have to do a bit of acrobatics to handle the issue of including "You" or not. The code below is untested but give you the general idea.
$message = "";
$readers = array();
$me_included = 0; // Counter increment if you're included in the reader list
$this->db->select('user_id');
$readQuery = $this->db->get_where('books_users', array('book_id' => $isbn));
foreach ($readQuery->result() as $row) {
if ($row->user_id == $user->id) {
$message = "You";
$me_included = 1;
} else {
$readers[] = $this->ion_auth->get_user($row->user_id);
}
}
$reader_count = $sizeof($readers) + $me_included;
switch(TRUE)
{
// One reader, not you
case( ($reader_count == 1) && ($me_included == 0) ):
$message .= $readers[0]->first_name . " " . $readers[0]->last_name . " has read this.";
break;
// Only you
case( ($reader_count == 1) && ($me_included == 1) ):
$message .= " have read this.";
break;
// Two readers
case( ($reader_count == 2) ):
for ($i = 0; $i <= sizeof($readers); $i++) {
if ($i == sizeof($readers)) {
$message .= " and ";
}
$message .= $readers[i]->first_name . " " . $readers[i]->last_name;
}
$message .= " have read this.";
break;
case( ($reader_count > 3) && ($reader_count < 6) ):
if ($me_included) {
$message .= ", ";
}
for ($i = 0; $i <= sizeof($readers); $i++) {
if ($i == sizeof($readers)) {
$message .= " and ";
}
$message .= $readers[i]->first_name . " " . $readers[i]->last_name;
if ($i != sizeof($readers)) {
$message .= ", ";
} else {
$message .= " have read this.";
}
}
break;
case( ($reader_count > 6) ):
if ($me_included) {
$message .= ", " . $readers[0]->first_name . " " . $readers[0]->last_name . " and " . ($reader_count - 2) . " others have read this.";
} else {
for ($i = 0; $i <= 1; $i++) {
$message .= $readers[0]->first_name . " " . $readers[0]->last_name . ", " . $readers[1]->first_name . " " . $readers[1]->last_name . " and " . ($reader_count - 2) . " others have read this.";
}
break;
}
$users = array();
while($row)
{
if(currentuser)
{
array_unshift($users,'You')
}
else
{
$users[] = row[name]
}
}
$count = $max = count($users);
if($max >= 6)
{
$max = 2;
}
$str = '';
for($i=0;$i<$max;$i++)
{
$str .= ($str == '' ? '' : ($i == $count-1 && $count < 6 ? ' And ' : ', ') ) . $users[$i];
}
if($count >= 6)
{
$str .= ' and '.$count-2.' others'
}
This should help you along. It's pretty much pseudo-code but the logic is there to achieve what you want (I believe). You'd obviously want to not fetch all the rows if you are just showing a number of users but that can easily be accomplished.
There are actually a couple places we can optimize this.
1) In the initial query do a JOIN with the user table so we don't have to query again multiple times just for each name:
$readers = $this->db->select('id', 'first_name', 'last_name')->from('books_users')->join('users', 'books_users.id =users.id', 'left')->where('book_id' => $isbn);
2) Additionally, we can avoid iterating over the entire (potentially large) result set just to see if you read it, by doing a separate query:
$you_read = $this->db->get_where('books_users', array('book_id' => $isbn, 'user_id' => $user->id));
Just for the sake of completeness, here is the final code I used. Hopefully it will be of use to someone.
// Find out who has read this book
// Get the users
$current_user = $this->ion_auth->get_user();
$users = $this->ion_auth->get_users();
// Get the readers
$this->db->select('user_id');
$query = $this->db->get_where('books_users', array('book_id' => $isbn));
// If there were results
$readers = array();
if ($query->num_rows() > 0) {
foreach ($users as $user) {
if ($current_user->id == $user->id) {
array_unshift($readers, 'You');
} else {
$readers[] = $user->first_name . ' ' . $user->last_name;
}
$count = $max = count($readers);
if ($max >= 6) {
$max = 2;
}
$message = '';
for ($i = 0; $i < $max; $i++) {
$message .= ($message == '' ? '' : ($i == ($count - 1) && ($count < 6) ? ' and ' : ', ')) . $readers[$i];
}
if ($count >= 6) {
$message .= ' and ' . ($count - 2) . ' others';
}
$message .= ($count == 1 && !$current_user->id ? ' has ' : ' have ') . 'read this.';
}
} else {
$message = 'Be the first to read this.';
}

Condition where the result is empty in PHP

$output = "<loginsuccess>";
for( $i = 1; $row = mysql_fetch_array($result); $i++ ) {
$output .="<keyword>".$_POST['keyword']."</keyword><name>".$row['url']."</name><occur>".$row['occurrences']."</occur><queryTime>".(substr($end_time-$start_time,0,5))."</queryTime>";
}
$output .= "</loginsuccess>";
I need now a simple condition where if the result is empty then i need to return no inside the xml [ login success ].
Is this a correct way....
if($row = mysql_fetch_array($result)) {
for( $i = 1; $row = mysql_fetch_array($result); $i++ ) {
$output .="<keyword>".$_POST['keyword']."</keyword><name>".$row['url']."</name><occur>".$row['occurrences']."</occur><queryTime>".(substr($end_time-$start_time,0,5))."</queryTime>";
} } else {
$output.="no";
}
if (mysql_num_rows($result) == 0) {
$output .= '<loginsuccess>no</loginsuccess>';
} else {
// your code
}
Try this instead:
$i = 1;
while($row = mysql_fetch_array($result))
{
$output .="<keyword>".$_POST['keyword']."</keyword><name>".$row['url']."</name><occur>".$row['occurrences']."</occur><queryTime>".(substr($end_time-$start_time,0,5))."</queryTime>";
$i++;
}
if ($i == 1)
$output .= "no";
Just a quick note, I would do what Schnalle does, but in your code I would change the for loop to a while loop as you are not doing anything with the $i
while($row = mysql_fetch_row($result)){
In total I would write you code like this:
$output = '<loginsucces>';
if(mysql_num_rows($result)){
while($row = mysql_fetch_row($result)){
$output .="<keyword>".$_POST['keyword']."</keyword><name>".$row['url']."</name><occur>".$row['occurrences']."</occur><queryTime>".(substr($end_time-$start_time,0,5))."</queryTime>";
}
} else {
$output .= 'no';
}
$output .= '</loginsucces>';
Also It owuld be even better not to mix logic and output, but that would be overkill in this situation.
Wont the for-loop simply be skipped when there are no rows? Otherwise you might want to use mysql_num_rows to count the number of rows in your result set.

Categories