Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Options

Creating query var fore tpl 2.3.1

PixelDotPixelDot New
edited September 2017 in Vanilla 2.0 - 2.8

I am trying to create a var that is global not based on session of the original user id so that i can add it to a link in the tpl file of my theme

I found the code below to work. in PHP parts

$LinkID = Gdn::SQL()->GetWhere('UserAuthentication',array('UserID'=>$this->User->UserID))->FirstRow(); ?>

Then echo it out

<?php echo $LinkID->ForeignUserKey; ?>

I got this to work in the userinfo box just fine , but what I am trying to do is echo just the id at the end of a link. is there any way to turn this in to maybe a global that i can call like this {LinkID} because I need to add this to my tpl theme.

Comments

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    Vanilla uses Smarty just for the layout. Normally you would try to do changes with php. If you give a screenshot on where you would like to see such a link, I would be able to help.

    But what you are talking about right now is a custom smarty function. You need a custom theme with a themehooks file for this to work. In that themehooks file, you have to add a method like that:

        public function gdn_smarty_init_handler($sender) {
            $sender->plugins_dir[] = __DIR__.DS.'SmartyPlugins';
        }
    

    Afterwards you would be able to save custom smarty functions in a file named like that: /themes/YourThemeFolder/SmartyPlugins/function.foreignuserkey_link.php

    The function would have to look similar to this (untested!):

    <?php
    
    function smarty_function_foreignuserkey_link($params, &$smarty) {
        $userID = val('UserID', $params, Gdn::session()->UserID);
        $userName = val('UserName', $params, Gdn::session()->User->Name);
        $foreignUserKey = Gdn::sql()
            ->select('ForeignUserKey')
            ->from('UserAuthentication')
            ->where(['UserID' => $userID])
            // ->where(['ProviderKey' => 'Whatever'])
            ->get()
            ->value('ForeignUserKey');
        if (!$foreignUserKey) {
            return '<span class="NoForeignID">No ID found!</span>';
        }
    
        return '<a href="whatever/'.$foreignUserKey.'" class="ForeignIDLink">'.$userName.'</a>';
    }
    

    Have you noticed the additional where condition? You really should provide enough information that the result could be unique. Maybe now in your current setup this is not needed, but you will face unpredictable errors if something changes in the future.

    From the template it should be able to use it like that {ForeignUserKey_Link UserName="someone" UserID="9"} or simply {ForeignUserKey_Link} for the currently logged in user.

    But really: although it looks like fun, enhancing Vanilla with Smarty is not the best idea. I strongly suggest that you try the PHP way. Ask your question and try to give a visual impression on what you need and from the answers you will get, you will soon be able to learn how to solve such problems all by yourself.

  • Options
    R_JR_J Ex-Fanboy Munich Admin

    One additional comment: if you do one database query very often, you have to think about improving that. You should save that information directly to the user table and afterwards you would be able to access it with e.g. Gdn::session()->User->GroovyID

    Here comes something which I'm not able to test, but I think it should work. I will need a provider name and since I don't know it, I will call it "Groovy". You would have to replace that string in the code...

    public function gdn_auth_authSuccess_handler($sender, $args) {
        $groovyID = Gdn::sql()
            ->select('ForeignUserKey')
            ->from('UserAuthentication')
            ->where(
                [
                    'UserID' => $args['UserData']['UserID'],
                    'ProviderKey' => 'Groovy'
                ]
            )
            ->get()
            ->value('ForeignUserKey');
        Gdn::userModel()->saveAttribute(
            $args['UserData']['UserID'],
            'GroovyID',
            $groovyID
        );
    }
    

    In theory when a user successfully authenticates, the current foreign key is written to the attributes column in the user table. Values of that column are accessible like any other column. Therefore $user->GroovyID would shouw the result without an addtional database query.

    But it is all untested. It might fail, but I think it is probable and if you want to show that info quite often throughout your forum, caching the value is a must!


    You might not be able to simply use that if you have a lot of users already using this authentication provider. The first time this would work is when they have to authenticate on your forum.
    I don't know if there is a simple way to force every user to re-authenticate. A workaround would be to write a small plugin which adds all external ids to the user table. That could be run once as a start. In futuretimes the snippet above should take care of the rest.

Sign In or Register to comment.