XF 2.1 Save to database from account/new-section

abdfahim

Well-known member
I am trying to imitate the existing xxxxSaveProcess functions to save data from a new account/section to a new table in my database, but so far have not succeeded. What step am I skipping? Is it because basicEntitySave() can only insert data, not update? I want it to update if a record exists, otherwise, insert a new row.


Code:
class Account extends XFCP_Account
{
public function actionNewSection()
    {
        if ($this->isPost())
        {
            $visitor = \XF::visitor();

            if ($visitor->canEditProfile())
            {
                $this->newSectionSaveProcess($visitor->user_id)->run();
            }

            return $this->redirect($this->buildLink('account/new-section'));
        }
        else
        {
            $view = $this->view('XF:Account\NewSection', 'abdfahim_new_section');
            return $this->addAccountWrapperParams($view, 'abdfahim_new_section');
        }
    }

    protected function newSectionSaveProcess($userid)
    {
        $form = $this->formAction();

        $input = $this->filter([
            'col1' => 'str',
            'col2' => 'str',
            'user_id' => $userid
        ]);

        //var_dump($input);

        $entity = $this->em()->create('AbdFahim\MyAddon:MyEntity');

        $form->basicEntitySave($entity, $input);

        return $form;
    }
}
Error:
InvalidArgumentException: Unknown filter type 1 in src/XF/InputFilterer.php at line 412
 

Lukas W.

Formerly katsulynx
The error pretty much says it all. filter() filters the given post input of the page, so you can't add other data there, as it'll try to grab the post input with a filter of w/e value is given (1 in your case) and then throw that error. You'll have to add the User ID after fetching the input.
 

abdfahim

Well-known member
The error pretty much says it all. filter() filters the given post input of the page, so you can't add other data there, as it'll try to grab the post input with a filter of w/e value is given (1 in your case) and then throw that error. You'll have to add the User ID after fetching the input.
Oh, thanks a lot! Now that you said, it seems obvious!

I still have some issues though:
1) It can now insert a new record, but cannot update an existing record. So, when there is an entry in the table with the same $userid, it throws an error "User ID must be unique". How do I solve this?

2) A general question, is it the correct way of updating a custom table from a new account page?
 

abdfahim

Well-known member
If anyone can give me a hint, please, I couldn't find a way to update an existing record in a table. The following can only add a new record, but throws an error when there exists a record (with the same user_id)
Code:
class Account extends XFCP_Account
{
public function actionNewSection()
    {
        if ($this->isPost())
        {
            $visitor = \XF::visitor();

            if ($visitor->canEditProfile())
            {
                $this->newSectionSaveProcess($visitor->user_id)->run();
            }

            return $this->redirect($this->buildLink('account/new-section'));
        }
        else
        {
            $view = $this->view('XF:Account\NewSection', 'abdfahim_new_section');
            return $this->addAccountWrapperParams($view, 'abdfahim_new_section');
        }
    }

    protected function newSectionSaveProcess($userid)
    {
        $form = $this->formAction();

        $input = $this->filter([
            'col1' => 'str',
            'col2' => 'str'
        ]);

        $input['user_id'] = $userid;

        $entity = $this->em()->create('AbdFahim\MyAddon:MyEntity');

        $form->basicEntitySave($entity, $input);

        return $form;
    }
}
Here is my entity

PHP:
class MyEntity extends \XF\Mvc\Entity\Entity
{
    public static function getStructure(Structure $structure)
    {
        $structure->table = 'xf_abdfahim_myaddon';
        $structure->shortName = 'AbdFahim\MyAddon:MyEntity';
        $structure->primaryKey = 'user_id';
        $structure->columns = [
            'user_id' => ['type' => self::UINT, 'required' => true],
            'col1' => ['type' => self::STR, 'nullable' => true, 'default' => null],
            'col2' => ['type' => self::STR, 'nullable' => true, 'default' => null]
        ];
        $structure->getters = [];
        $structure->relations = [
            'User' => [
                'entity' => 'XF:User',
                'type' => self::TO_ONE,
                'conditions' => 'user_id',
                'primary' => true
            ],
        ];

        return $structure;
    }
}
 

Snog

Well-known member
Try this (untested)...
Code:
protected function newSectionSaveProcess($userid)
{
    $form = $this->formAction();

    $input = $this->filter([
        'col1' => 'str',
        'col2' => 'str'
    ]);

    $entity = $this->finder('AbdFahim\MyAddon:MyEntity')
        ->where('user_id', $userid)
        ->fetchOne();

    if(!$entity)
    {
        $input['user_id'] = $userid;

        $entity = $this->em()->create('AbdFahim\MyAddon:MyEntity');
    }

    $form->basicEntitySave($entity, $input);

    return $form;
}
 
Top