XF 2.1 Trouble getting tokeninput value into an entity

I'm trying to get the array of names from the <xf:tokeninput> in my template to something that can be stored inside my Server entity The token input I'm using comes from the option_template_registrationWelcome its not giving me any errors or anything like that so I feel that I am missing a step in converting my input data into something can be stored by the Entity. Any help would be appreciated!

PHP:
protected function serverSaveProcess(Server $server)
{
    $entityInput = $this->filter([
        'title' => 'str',
        'addr' => 'str',
        'port' => 'int',
        'query_port' => 'int',
        'game' => 'int',
        'rcon' => 'str',
        'managers' => 'array-str',
        'description' => 'str'
    ]);

    $form = $this->formAction();
    $form->basicEntitySave($server, $entityInput);

    return $form;
}

public function actionSave(ParameterBag $params)
{
    $this->assertPostOnly();
    if ($params['server_id'])
    {
        $server = $this->assertServerExists($params['server_id']);
    }
    else
    {
        $server = $this->em()->create('Retro\ServerTracker:Server');
    }
    $this->serverSaveProcess($server)->run();
    return $this->redirect($this->buildLink('servers/list'));
}

protected function assertServerExists($id, $with = null, $phraseKey = null)
{
    return $this->assertRecordExists('Retro\ServerTracker:Server', $id, $with, $phraseKey);
}

PHP:
class Server extends Entity
{
    public static function getStructure(Structure $structure)
    {
        $structure->table = "xf_retro_servers";
        $structure->shortName = 'ServerTracker:Server';
      $structure->primaryKey = 'server_id';
      $structure->columns = [
            'server_id' => ['type' => self::UINT, 'autoIncrement' => true],
            'title' => ['type' => self::STR],
            'addr' => ['type' => self::STR],
            'port' => ['type' => self::UINT],
            'query_port' => ['type' => self::UINT, 'default' => null],
            'game' => ['type' => self::UINT],
            'rcon' => ['type' => self::STR],
            'online' => ['type' => self::BOOL],
            'max_players' => ['type' => self::UINT],
            'players' => ['type' => self::JSON],
            'managers' => ['type' => self::LIST_COMMA,'default' => [],
                'list' => ['type' => 'posint', 'unique' => true, 'sort' => SORT_NUMERIC]
            ],
            'info' => ['type' => self::JSON],
            'description' => ['type' => self::STR]
        ];
      $structure->getters = [];
      $structure->relations = [
            'Game' => [
                'entity' => 'Retro\ServerTracker:Game',
                'type' => self::TO_ONE,
                'conditions' => [['game_id', '=', '$game']],
                'primary' => true
            ]
        ];

      return $structure;
    }
}

HTML:
<xf:if is="$server.isInsert()">
    <xf:title>{{ phrase('add_server') }}</xf:title>
<xf:else />
    <xf:title>{{ phrase('edit_server:') }} {$server.title}</xf:title>
</xf:if>

<xf:pageaction if="$server.isUpdate()">
    <xf:button href="{{ link('servers/delete', $server) }}" icon="delete" overlay="true" />
</xf:pageaction>
{{dump($server)}}
<xf:form action="{{ link('servers/save', $server) }}" ajax="true" class="block">
    <div class="block-container">
        <div class="block-body">
            <xf:textboxrow name="title" value="{$server.title}" autosize="true"
                label="Server Name"
                explain="" />
            <xf:textboxrow name="addr" value="{$server.addr}" autosize="true"
                label="Server Adress"
                explain="" />
            <xf:numberboxrow name="port" value="{$server.port}" min="1"
                label="Server Adress"/>
            <xf:numberboxrow name="query_port" value="{$server.query_port}"
                label="Server Query Port"/>
            <xf:selectrow name="game" value="{{$server.game}}" label="Game">
                <xf:option value="none" label="(Please select a game)" />
                <xf:foreach loop="$games" key="$key" value="$game" i="$i">
                    <xf:option value="{$game.game_id}" label="{$game.display}" />
                </xf:foreach>
            </xf:selectrow>
            <xf:textboxrow name="rcon" value="{$server.rcon}" autosize="true"
                label="Rcon Password"
                explain="Used to track playtime on SourceQuery servers" />
            
            <xf:if is="$server.managers AND is_array($server.managers)">
                <xf:set var="$users" value="{{ $xf.app.em.getRepository('XF:User').getUsersByIdsOrdered($server.managers) }}" />
                <xf:set var="$value" value="{$users.pluckNamed('username')|join(', ')}" />
            </xf:if>
            <xf:tokeninputrow label="Managers" name="managers" value="{$value}" href="{{ link('users/find') }}">
                <xf:explain>List of users who will be marked as managers of this server.</xf:explain>
            </xf:tokeninputrow>
            
            <xf:textarearow name="description" value="{$server.description}" autosize="true"
                label="Description"
                explain="A description of the server(HTML Allowed)" />
        </div>

        <xf:submitrow sticky="true" icon="save" />

    </div>
</xf:form>
 
Last edited:
Solution
The token input will give you a string of comma separated values. You would want to change 'managers' => 'array-str' to 'managers' => 'str'. From there, you'll need to process the string into the format your entity is expecting, which looks to be an array of user IDs. You can see an example of how you might do this in \XF\Option\RegistrationWelcome::verifyOption().

Jeremy P

XenForo developer
Staff member
The token input will give you a string of comma separated values. You would want to change 'managers' => 'array-str' to 'managers' => 'str'. From there, you'll need to process the string into the format your entity is expecting, which looks to be an array of user IDs. You can see an example of how you might do this in \XF\Option\RegistrationWelcome::verifyOption().
 
Solution
Thanks for the response @Jeremy P I was kind a figuring I had to manually parse the data into the array. I even tried the 'managers' => 'str' before but figured I was doing it wrong since nothing was changing. The only thing I'm confused about is where I would go about converting the managers into an array of user IDs would I do this inside the serverSaveProcess using $entityInput or is this something I would be doing inside the entity itself? Sorry if this question seems a bit newbie the XF api confused me most of the time lol.

Edit: Nvm I figured it out. It was the serverSaveProcess using $entityInput once again thanks for the help Jeremy P
 
Last edited:

Jeremy P

XenForo developer
Staff member
You're probably fine doing this in the controller at this stage. You can look at moving the logic into a repository if you find yourself needing to use it elsewhere in the future.
 
Top