XF 2.1 Additional PHP in Page Node callback

Nicky

Active member
Licensed customer
hi all,

i would like to make a listing of books in a page node.

php script which works fine looks like this:

PHP:
<?php
$connection = mysqli_connect ("localhost","xx","xx","xx") or die ("error");

$query = "SELECT * FROM xf_thread WHERE discussion_state = 'visible' AND node_id IN ('293','298') ORDER BY title ASC";
$result = $connection->query($query);

$data = array();
while($row = $result->fetch_array()){
    $firstLetter = mb_strtoupper(mb_substr($row['title'], 0, 1,'UTF8'));
    $data[$firstLetter][] = $row;
}

foreach ($data as $letter => $letterData){
    echo "<h3>Book letter: " . $letter . "</h3>\n";
    foreach ($letterData as $row) {
            echo "" . $row['title'] . "<br />\n";
    }
}
?>

it will break all books into "Books letters" .. 0..1, A-Z and show books below.

now to XF:
callback has been done just with listing of all books without the breaks and works fine in the page.

the code:

PHP:
<?php
namespace Books\ListBooks;
class findbooks
{
    public static function booksfind (
        \XF\Pub\Controller\AbstractController $controller,
        \XF\Mvc\Reply\AbstractReply &$reply
)
    {
    if ($reply instanceof \XF\Mvc\Reply\View) {

        $books1 = \XF::db()->fetchAll("
        SELECT * FROM xf_thread WHERE discussion_state = 'visible' AND node_id IN ('293','298') ORDER BY title ASC");
        $reply->setParam('books1', $books1);

    }
    }
}

and
PHP:
<xf:foreach loop="$books1" value="$book1">
    {$book1.title}<br />
</xf:foreach>

but, how to "break" it like the PHP code?
i'm not expert in xf things, so any help would be great!

thank you in advance and wish you a nice day.
cheers, Nicky
 
Last edited:
Solution
@Lawrence thank you, but with your code, page node will be displayed without content.
The content will be there, you just need to write your foreach like this:

HTML:
<xf:foreach loop="$books1" key="$letter" value="$books">
    {$letter}<br />
    <xf:foreach loop="$books" value="$book">
        {$book.title}<br />
    </xf:foreach>
</xf:foreach>
Do you mean grouped by first letter?

PHP:
    if ($reply instanceof \XF\Mvc\Reply\View)
    {
        $books1 = \XF::db()->fetchAll("
        SELECT * FROM xf_thread WHERE discussion_state = 'visible' AND node_id IN ('293','298') ORDER BY title ASC");

        $grouped = [];
        foreach ($books1 as $book)
        {
            $firstLetter = mb_strtoupper(mb_substr($book['title'], 0, 1,'UTF8'));
            $grouped[$firstLetter][] = $book;
        }
        $reply->setParam('books1', $grouped);
    }

Your select statement is rather simple so you should use a finder here, but as it is for your use only I wouldn't worry too much about it.
 
but, how to "break" it like the PHP code?
Do you mean extract the data from the array and display it?

If so, you've already done that with $book1.title, so you would repeat that for each other item in the array, e.g. $book1.username and so on.
 
thank you guys
@Lawrence thank you, but with your code, page node will be displayed without content.

@Brogan thank you too.
above standalone PHP code produce me list like below.

Book letter: B​

Baby's Very First Fingertrail Play book Garden
Big Book of Colours

Book letter: G​

Garden Sounds
Guess How Much I Love You: Colours

Book letter: L​

Listen and Learn First English Words

Book letter: P​

Peppa Pig: ABC with Peppa
Peppa Pig: George's First Day at Playgroup

this is what i'm searching for to have it in Page Node.
thank you again.
cheers, Nicky
 
@Lawrence thank you, but with your code, page node will be displayed without content.
The content will be there, you just need to write your foreach like this:

HTML:
<xf:foreach loop="$books1" key="$letter" value="$books">
    {$letter}<br />
    <xf:foreach loop="$books" value="$book">
        {$book.title}<br />
    </xf:foreach>
</xf:foreach>
 
Solution
Back
Top Bottom