XF 2.2 Equivalent XF syntax for INSERT SQL

FoxSecrets

Active member
What's the equivalent XF syntax for INSERT INTO query?

Code:
<xf:foreach loop="$xf.app.db.fetchAll('SELECT * FROM xf_xxxxxxxxxxxxx')" value="$item">
         ..........................
    </xf:foreach>
 
Templates may only perform read operations.

From PHP, you can do something like:
PHP:
\XF::db()->insert('some_table', ['some_column' => 'some_value']);
 
You'd call it from whatever PHP is rendering the template. How do you view this template? Do you have a controller? Is it a page node?
Yes I can view and it's a page node, but do not have controller. Just did it now, please see below. Does it make sense? How do I call this function from html template?

PS: I changed to update query

Code:
<?php
namespace MyAddon\Pub\Controller;

use XF\Pub\Controller\AbstractController;

class MyClass extends AbstractController
{
    public function actionOnLoad($size)
    {
        $data = $this->finder('MyAddon:MyClass')->fetchOne();

        if($data)
        {
            $db = $this->app->db();

            $itemId = ('SELECT id FROM xf_my_table ORDER BY id LIMIT 1');

            $db->query("
              UPDATE xf_my_table SET itemSize=$size WHERE id=$itemId
            ")->execute();
        }
    }
}
 
Last edited:
I'm trying to use a callback function but am getting "error invalid method". Can someone tell me how to fix that?

Code:
<xf:callback class="MyAddon\Pub\Controller\MyClass" method="actionOnLoad" params="[1500]"></xf:callback>
 
I don't think you need a Controller class for this.

I suggest you simply create a file Callback.php in your add-on's folder which contains something like this:

PHP:
<?php
namespace MyName\MyAddon;

class Callback
{
    public static function someAction($size)
    {
        $data = \XF::app()->finder('MyName\MyAddon:MyClass')->fetchOne();

        if($data)
        {
            $db = \XF::app()->db();

            $itemId = ('SELECT id FROM xf_my_table ORDER BY id LIMIT 1');

            $db->query("
              UPDATE xf_my_table SET itemSize=$size WHERE id=$itemId
            ")->execute();
        }
    }
}

Your template code may look like:

HTML:
<xf:callback class="MyName\MyAddon\Callback" method="someAction" params="[1500]" />

In this case your add-on should be inside the folder src/addons/MyName/MyAddon (folders and namespace must match).

I never worked with callback inside templates, but I think/hope this code should at least work it's way till it reaches the someAction() method inside the Callback class. :)
 
Now I am getting the error "The callback method someAction does not appear to indicate a read only function so cannot be called."

Do you know the reason?
 
Last edited:
Now I am getting the error "The callback method someAction does not appear to indicate a read only function so cannot be called."

Do you know the reason?

For a method to be considered a callback method, it must be named appropriately or it will throw an error 'callback_method_x_does_not_appear_to_indicate_read_only'. For it to be considered read-only, the method name must begin with one of the following prefixes:

  • are
  • can
  • count
  • data
  • display
  • does
  • exists
  • fetch
  • filter
  • find
  • get
  • has
  • is
  • pluck
  • print
  • render
  • return
  • show
  • total
  • validate
  • verify
  • view

 
Ok, I used prefix and that error is gone, but now I'm getting another :oops:

Code:
public:my_template - Container key 'app' was not found in /var/www/html/src/XF/Container.php:46

This is the place where I put the callback syntax. Shouldn't this 'app' be related to XF itself? What is the reason for this one?
 
Might be worth noting that pages themselves have a PHP Callback option, which gets passed the pertinent controller and reply objects. This allows for greater flexibility (and passing data to the page template, for example):

PHP:
<?php

namespace Some\Addon;

use XF\Mvc\Reply\AbstractReply;
use XF\Mvc\Reply\View;
use XF\Pub\Controller\AbstractController;

class MyPage
{
    public static function renderPage(
        AbstractController $controller,
        AbstractReply &$reply
    ): void
    {
        if ($reply instanceof View)
        {
            // you can then use {$hello} in the template
            $reply->setParam('hello', 'world');
        }
    }
}

Then you just set the callback option in the page configuration:
1689648818466.webp
 
I don't think you need a Controller class for this.

I suggest you simply create a file Callback.php in your add-on's folder which contains something like this:

PHP:
<?php
namespace MyName\MyAddon;

class Callback
{
    public static function someAction($size)
    {
        $data = \XF::app()->finder('MyName\MyAddon:MyClass')->fetchOne();

        if($data)
        {
            $db = \XF::app()->db();

            $itemId = ('SELECT id FROM xf_my_table ORDER BY id LIMIT 1');

            $db->query("
              UPDATE xf_my_table SET itemSize=$size WHERE id=$itemId
            ")->execute();
        }
    }
}

Your template code may look like:

HTML:
<xf:callback class="MyName\MyAddon\Callback" method="someAction" params="[1500]" />

In this case your add-on should be inside the folder src/addons/MyName/MyAddon (folders and namespace must match).

I never worked with callback inside templates, but I think/hope this code should at least work it's way till it reaches the someAction() method inside the Callback class. :)
@nocte I can't access the $size parameter inside the function, do you know how to do it?
 
Got it working now!! Thank you all!

Changes: $size as second parameter
Code:
public static function someAction($content, $size)
......

And in the query:
Code:
......
 $db->query("
              UPDATE xf_my_table SET itemSize='{$size[0]}' WHERE id=$itemId
")->execute();
 
Back
Top Bottom