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

I need to reference external Avatar source, please help?

edited March 2017 in Vanilla 2.0 - 2.8

My main website has profile photos for every forum user already so I want to use those for avatar images. The path of these profile pics are simple too: www.website.com/avatar/vanillaUsername.jpg

I've been looking at applications/vanilla/views/discussion/discussion.php which I assume is the best place to make the modification.

Please can you advise how I can change the Vanilla avatar path to use the new path above?

Comments

  • Options
    vrijvlindervrijvlinder Papillon-Sauvage MVP

    Look at other avatar plugins to see how you could do that . But don't edit core files .

  • Options
    LincLinc Detroit Admin

    You want to make a simple plugin that overwrites the global userPhotoUrl() function. Maybe something like this:

        /**
         * Use my custom photo URLs instead.
         *
         * @param object|array $User
         * @return string
         */
        function userPhotoUrl($User) {
            $FullUser = Gdn::userModel()->getID(val('UserID', $User), DATASET_TYPE_ARRAY);
            return 'https://www.website.com/avatar/'.urlencode(val('Name', $FullUser)).'.jpg';
        }
    
  • Options

    Thanks for helping here. I dumped your code at the end of class.testingground.plugin.php but it didn't change anything.

    Is there a way without a plugin like using bootstrap.before.php?

  • Options
    whu606whu606 I'm not a SuperHero; I just like wearing tights... MVP

    @w1ckedsick

    You can't just add that code to a file. You need to make it part of a plugin

    See here: http://docs.vanillaforums.com/developer/plugins/quickstart/

  • Options
    edited March 2017

    Hello @whu606

    That's what I did - TestingGround was a plugin template I had used previously for another bit of custom code and it worked well. So I went with the same thing here but it didn't result in any change. The particular file that has the code is class.testingground.plugin.php and you can see it at the bottom:

    <?php if (!defined('APPLICATION')) exit();
    /*  Copyright 2014 Zachary Doll
    *   This program is free software: you can redistribute it and/or modify
    *   it under the terms of the GNU General Public License as published by
    *   the Free Software Foundation, either version 3 of the License, or
    *   (at your option) any later version.
    *
    *   This program is distributed in the hope that it will be useful,
    *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    *   GNU General Public License for more details.
    *
    *   You should have received a copy of the GNU General Public License
    *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
    $PluginInfo['TestingGround'] = array( // You put whatever you want to call your plugin folder as the key
        'Name' => 'Custom Avatar', // User friendly name, this is what will show up on the garden plugins page
        'Description' => 'A skeleton plugin that adds its resources to every page, creates a settings page, and creates a stub minicontroller.', // This is also shown on the garden plugins page. Will be used as the first line of the description if uploaded to the official addons repository at vanillaforums.org/addons
        'Version' => '0.1', // Anything can go here, but it is suggested that you use some type of naming convention; will appear on the garden vanilla plugins page
        'RequiredApplications' => array('Vanilla' => '2.0.18.8'), // Can require multiple applications (e.g. Vanilla and Conversations)
        'RequiredTheme' => FALSE, // Any prerequisite themes
        'RequiredPlugins' => FALSE, // Any prerequisite plugins
        'MobileFriendly' => FALSE, // Should this plugin be run on mobile devices?
        'HasLocale' => TRUE, // Does this plugin have its own local file?
        'RegisterPermissions' => FALSE, // E.g. array('Plugins.TestingGround.Manage') will register this permissions automatically on enable
        'SettingsUrl' => '/settings/testingground', // A settings button linked to this URL will show up on the garden plugins page when enabled
        'SettingsPermission' => 'Garden.Settings.Manage', // The permissions required to visit the settings page. Garden.Settings.Manage is suggested.
        'Author' => 'Zachary Doll', // This will appear in the garden plugins page
        'AuthorEmail' => 'hgtonight@daklutz.com',
        'AuthorUrl' => 'http://www.daklutz.com',
        'License' => 'GPLv3' // Specify your license to prevent ambiguity
    );
    
    class TestingGround extends Gdn_Plugin {
    
        // add a Testing Ground page on the settings controller
        public function SettingsController_TestingGround_Create($Sender) {
            // add the admin side menu
            $Sender->AddSideMenu('settings/testingground');
    
            $Sender->Title($this->GetPluginName() . ' ' . T('Settings'));
            $Sender->Render($this->GetView('settings.php'));
        }
    
        public function PluginController_TestingGround_Create($Sender) {
            // Makes it act like a mini controller
            $this->Dispatch($Sender, $Sender->RequestArgs);
        }
    
        public function Controller_Index($Sender) {
            echo T('Plugins.TestingGround.SadTruth');
            echo "\nPlugin Index: " . $this->GetPluginIndex();
            echo "\nPlugin Folder: " . $this->GetPluginFolder();
        }
    
        public function Base_Render_Before($Sender) {
            $this->_AddResources($Sender);
            // decho($Sender)
        }
    
        private function _AddResources($Sender) {
            //$Sender->AddJsFile($this->GetResource('js/testingground.js', FALSE, FALSE));
            //$Sender->AddCssFile($this->GetResource('design/testingground.css', FALSE, FALSE));
        }
    
        public function Setup() {
            // SaveToConfig('Plugins.TestingGround.EnableAdvancedMode', TRUE);
        }
    
        public function OnDisable() {
            // RemoveFromConfig('Plugins.TestingGround.EnableAdvancedMode');
        }
    
      /**
         * Use my custom photo URLs instead.
         *
         * @param object|array $User
         * @return string
         */
       public function userPhotoUrl($User) {
            $FullUser = Gdn::userModel()->getID(val('UserID', $User), DATASET_TYPE_ARRAY);
            return 'https://www.website.com/avatar/'.urlencode(val('Name', $FullUser)).'.jpg';
        }
    }
    
  • Options
    R_JR_J Ex-Fanboy Munich Admin

    You can indeed add it to the bootstrap.before.php file, but I would also recomment to attach it below a plugins class. That way you can easily enable/disable it.

    You would need a custom userPhoto function. This is basically the same code as you will find in the functions.render.php file, I only made changes around line 38 for some external url. You would have to modify that:

    /**
     * Takes a user object, and writes out an anchor of the user's icon to the user's profile.
     *
     * @param object|array $User A user object or array.
     * @param array $Options
     * @return string HTML.
     */
    function userPhoto($User, $Options = array()) {
        if (is_string($Options)) {
            $Options = array('LinkClass' => $Options);
        }
    
        if ($Px = val('Px', $Options)) {
            $User = userBuilder($User, $Px);
        } else {
            $User = (object)$User;
        }
    
        $LinkClass = concatSep(' ', val('LinkClass', $Options, ''), 'PhotoWrap');
        $ImgClass = val('ImageClass', $Options, 'ProfilePhoto');
    
        $Size = val('Size', $Options);
        if ($Size) {
            $LinkClass .= " PhotoWrap{$Size}";
            $ImgClass .= " {$ImgClass}{$Size}";
        } else {
            $ImgClass .= " {$ImgClass}Medium"; // backwards compat
        }
    
        $FullUser = Gdn::userModel()->getID(val('UserID', $User), DATASET_TYPE_ARRAY);
        $UserCssClass = val('_CssClass', $FullUser);
        if ($UserCssClass) {
            $LinkClass .= ' '.$UserCssClass;
        }
    
        $LinkClass = $LinkClass == '' ? '' : ' class="'.$LinkClass.'"';
    
        $username = rawurlencode(strtolower($User->Name));
        $Photo = "www.website.com/avatar/{$username}.jpg";
    
        $Name = val('Name', $FullUser);
        $Title = htmlspecialchars(val('Title', $Options, $Name));
    
        if ($FullUser && $FullUser['Banned']) {
            $Photo = c('Garden.BannedPhoto', 'https://images.v-cdn.net/banned_large.png');
            $Title .= ' ('.t('Banned').')';
        }
    
        if ($Photo) {
            if (!isUrl($Photo)) {
                $PhotoUrl = Gdn_Upload::url(changeBasename($Photo, 'n%s'));
            } else {
                $PhotoUrl = $Photo;
            }
        } else {
            $PhotoUrl = UserModel::getDefaultAvatarUrl($FullUser, 'thumbnail');
        }
    
        $href = (val('NoLink', $Options)) ? '' : ' href="'.url(userUrl($FullUser)).'"';
    
        return '<a title="'.$Title.'"'.$href.$LinkClass.'>'
                .img($PhotoUrl, ['alt' => $Name, 'class' => $ImgClass])
            .'</a>';
    }
    
  • Options

    That's awesome, thanks. I got it almost working but the img src is looking inside Vanilla's avatar location when I need it looking closer to root (website.com/avatars/). I think that's because of line 51. Can you help me fix that bit?

  • Options

    I found a way around that which worked... here's the slightly modified code that is working perfectly now:

    /**
     * Takes a user object, and writes out an anchor of the user's icon to the user's profile.
     *
     * @param object|array $User A user object or array.
     * @param array $Options
     * @return string HTML.
     */
    function userPhoto($User, $Options = array()) {
        if (is_string($Options)) {
            $Options = array('LinkClass' => $Options);
        }
        if ($Px = val('Px', $Options)) {
            $User = userBuilder($User, $Px);
        } else {
            $User = (object)$User;
        }
        $LinkClass = concatSep(' ', val('LinkClass', $Options, ''), 'PhotoWrap');
        $ImgClass = val('ImageClass', $Options, 'ProfilePhoto');
        $Size = val('Size', $Options);
        if ($Size) {
            $LinkClass .= " PhotoWrap{$Size}";
            $ImgClass .= " {$ImgClass}{$Size}";
        } else {
            $ImgClass .= " {$ImgClass}Medium"; // backwards compat
        }
        $FullUser = Gdn::userModel()->getID(val('UserID', $User), DATASET_TYPE_ARRAY);
        $UserCssClass = val('_CssClass', $FullUser);
        if ($UserCssClass) {
            $LinkClass .= ' '.$UserCssClass;
        }
        $LinkClass = $LinkClass == '' ? '' : ' class="'.$LinkClass.'"';
        $username = ($User->Name);
        $Photo = "{$username}.jpg";
        $Name = val('Name', $FullUser);
        $Title = htmlspecialchars(val('Title', $Options, $Name));
        if ($FullUser && $FullUser['Banned']) {
            $Photo = c('Garden.BannedPhoto', 'https://images.v-cdn.net/banned_large.png');
            $Title .= ' ('.t('Banned').')';
        }
        if ($Photo) {
            if (!isUrl($Photo)) {
                $PhotoUrl =  'https://www.website.com/avatar/'.$Photo;
            } else {
                $PhotoUrl = $Photo;
            }
        } else {
            $PhotoUrl = UserModel::getDefaultAvatarUrl($FullUser, 'thumbnail');
        }
        $href = (val('NoLink', $Options)) ? '' : ' href="'.url(userUrl($FullUser)).'"';
        return '<a title="'.$Title.'"'.$href.$LinkClass.'>'
                .img($PhotoUrl, ['alt' => $Name, 'class' => $ImgClass])
            .'</a>';
    }
    

    Thanks everyone :)

Sign In or Register to comment.