XF 2.1 Additional PHP in Page Node callback

Nicky

Active member
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>

Lawrence

Well-known member
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.
 

Nicky

Active member
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

Well-known member
@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
Top