XF 2.0 Callback Help.

Mellow1234

Member
Requirement:
Join​
xf_user_field_value and xf_user by user_id​
and only for​
xf_user_field_value.field_id = 'miles' and​
xf_user_field_value.field_value > spaces​
order xf_user_field_value.field_value DESC​
Here's my code in (/src/addons/Mileage/Mileage.php) and this is my ONLY file:
PHP:
<?php
namespace Mileage\Mileage;

class Mileage{
    public function getMileage()
    {
      return $this->_getDb()->fetchAll("
        SELECT *
        FROM `xf_user_field_value`
        INNER JOIN `xf_user` ON `xf_user_field_value`.`user_id` = `xf_user`.`user_id`
        WHERE 'field_id` = 'miles' and 'field_value' > ' '
        ORDER BY `field_value` DESC
        ");
    }
}

Here's my Page Node HTML and I know the foreach has to be wrong:

HTML:
<xf:callback class="Mileage\Mileage" method="getMileage"></xf:callback>

<table id="Mileage" width="100%" border="1">
    <th>Rank</th><th>Name</th><th>Mileage</th><th>Miles Per Day</th><th>Projected Year End</th><th>Country</th>    <th>State/Province</th><th>Bike</th>
  <xf:foreach loop="$getMileage" value="$getMileage">
    <tr>
       <td>-</td> <td>-</td><td align='center'>-</td> <td align='center'>-</td><td align='center'>-</td> <td align='center'>-</td><td align='center'>-</td> <td align='center'>-</td>
    <tr>
  </xf:foreach>
</table>

Getting Callback Mileage\Mileage::getMileage is invalid (error_invalid_class).

1 - What's the benefit of putting the class/method in the html block vs the page parms? Do you just get a faster verification when it has issues?
2 - Is my sql correct
3 - what should the foreach examine given that sql? would it be $fetchAll?

Thanks any help is appreciated... I think I'm kinda close just missing something.
 
Last edited:
Code:
Getting Callback Mileage\Mileage::getMileage is invalid (error_invalid_class).

Your namespace is wrong. Following the namespace Mileage\Mileage, your full class name would be Mileage\Mileage\Mileage, which is probably one too many.


1 - What's the benefit of putting the class/method in the html block vs the page parms? Do you just get a faster verification when it has issues?

If you put the callback into the template directly, you have to return a string. If you put it into the page callback, you'll have the ability to pass as many arbitrary objects as you like to the page params. So the latter is what you want.

2 - Is my sql correct
You should use the entity system instead.

PHP:
\XF::finder('XF:UserFieldValue')
    ->with('User', true)
    ->where('field_id', '=', 'miles')
    ->where('field_value', '>', 0)
    ->fetch();
 
Ok changed to this:
PHP:
<?php
namespace Mileage;

class Mileage{
    public function getMileage()
    {
    $structure->table = 'xf_user';

    $finder = \XF::finder('XF:UserFieldValue')
        ->with('User', true)
        ->where('field_id', '=', 'miles')
        ->where('field_value', '>', 0)
        ->fetch();
    }
}

Getting
Callback Mileage\Mileage::getMileage is invalid (error_method_not_static).


In my html block, what would my foreach examine? What is that variable / array called in the html?

HTML:
<xf:callback class="Mileage\Mileage" method="getMileage"></xf:callback>
<table id="Mileage" width="100%" border="1">
    <th>Rank</th><th>Name</th><th>Mileage</th><th>Miles Per Day</th><th>Projected Year End</th><th>Country</th>    <th>State/Province</th><th>Bike</th>
  <xf:foreach loop="$getMileage" value="$getMileage">
    <tr>
       <td>-</td> <td>-</td><td align='center'>-</td> <td align='center'>-</td><td align='center'>-</td> <td align='center'>-</td><td align='center'>-</td> <td align='center'>-</td>
    <tr>
    <tr>
       <td>-</td> <td>-</td><td align='center'>-</td> <td align='center'>-</td><td align='center'>-</td> <td align='center'>-</td><td align='center'>-</td> <td align='center'>-</td>
    </tr>
  </xf:foreach>
</table>
 
Last edited:
Ok.. duh.. had to use the word static to get past the error lol!
public static function getMileage()

So I get a blank screen now so how to I inspect what the finder is sending to the page? What will that be called?
I doubt this is right:
<xf:foreach loop="$getMileage" value="$getMileage">
 
I got rid of the join and just tried something as simple as possible based on the help docs so:

PHP:
<?php
namespace Mileage;

class Mileage{
    public static function getMileage(){

    $finder = \XF::finder('XF:User');
    $usernames = $finder->limit(10)->pluckFrom('username')->fetch();
    }
}

Just bring back 10 usernames..

HTML:
<xf:callback class="Mileage\Mileage" method="getMileage"></xf:callback>
<table id="Mileage" width="100%" border="1">
    <th>USERNAME</th>
  <xf:foreach loop="$usernames" value="$user">
    <tr>
       <td>*</td>
    <tr>
  </xf:foreach>
</table>

I get a page w/table and table header but should be getting 10 rows with *, but nothing..

Do I need a return or something in the php to pass the data back? That's where I'm clueless... or does the html evaluate the $usernames in the php file? If I can just get something simple going, I'm gold.
 
Last edited:
Ok, thanks but didn't make a difference..

PHP:
<?php
namespace Mileage;

class Mileage{
    public static function getMileage(){

    $finder = \XF::finder('XF:User');
    $usernames = $finder->limit(10)->pluckFrom('username')->fetch();
return;
    }
}
 
Last edited:
Also tried this
return $usernames;
but get a server log erorr.
  • Object of class XF\Mvc\Entity\ArrayCollection could not be converted to string

  • src/XF/Template/Templater.php:1339
 
I don't want to intervene, just I would suggest to use the "Code" bbcode @Mellow1234 , so people who try to help you can read the code better. Choose php so the syntax is highlighted better.
1537029612586.webp
 
PHP:
<?php
namespace Mileage;

class Mileage{
    public static function getMileage(){

    $finder = \XF::finder('XF:User');
    $usernames = $finder->limit(10)->fetch();
    return $usernames;
    }
}
 
Last edited:
Didn't work, please see post above yours.
If you put the callback into the template directly, you have to return a string. If you put it into the page callback, you'll have the ability to pass as many arbitrary objects as you like to the page params. So the latter is what you want.
So either do it as a page callback or create the ready-to-use html in your callback function and return the html string to your callback.
 
So either do it as a page callback or create the ready-to-use html in your callback function and return the html string to your callback.
OK, so using my php above.. and this is my page setup, but I don't get any results or errors that I can find...



1537032773749.webp
 
Your callback doesn't have the correct arguments per the explanation text below the class / method fields. In addition, you're not sending your usernames as a parameter correctly.

PHP:
<?php

namespace Mileage;

class Mileage
{
    public static function getMileage(\XF\Pub\Controller\AbstractController $controller, \XF\Mvc\Reply\AbstractReply &$reply)
    {
        $finder = \XF::finder('XF:User');
        $usernames = $finder->limit(10)->fetch();

        $reply->setParams(['usernames' => $usernames]);
    }
}
 
Your callback doesn't have the correct arguments per the explanation text below the class / method fields. In addition, you're not sending your usernames as a parameter correctly.

PHP:
<?php

namespace Mileage;

class Mileage
{
    public static function getMileage(\XF\Pub\Controller\AbstractController $controller, \XF\Mvc\Reply\AbstractReply &$reply)
    {
        $finder = \XF::finder('XF:User');
        $usernames = $finder->limit(10)->fetch();

        $reply->setParams(['usernames' => $usernames]);
    }
}
That's it! got 10 lines so I'm getting something I can work with...

Thank you very much and also to everyone else that chimed in.. sorry if I was a bit dense at times...
 
Top Bottom