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.

Pockets Panel Position Index

edited September 2017 in Vanilla 2.0 - 2.8

Hi i used pockets and really works excellent, i have a doubt,

  • With this configuration it works perfectly:

    Page; discussions / Location: Panel /Repeat; After

  • With this configuration it does not work:

    Page; discussions / Location: Panel /Repeat; Index: 4.

I would like the pockets to appear above the online now, attached image.

«1

Comments

  • I have already installed it, but it does not have any documentation how it works, I add the module OnlineNow in Conversations and I put it of last and it does not change anything in the panel,

    Regards,

  • I have read the documentation to order the changes but Pockets is a plugin, and OnlineNow is a module, I still do not understand how to add Pockets in the order.

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    It works by reordering the modules to what you want. Maybe try the plugin Widgets, it creates modules that can be sorted and you can put anything in them.

  • Thks @vrijvlinder excelent your pluging widgets, create twitter feed and disable css to avoid breaking the css of the boostrap theme,

    Modules Orders:

    config.php

    $Configuration['Modules']['Vanilla']['Panel'] = array('MeModule', 'UserBoxModule', 'GuestModule', 'NewDiscussionModule', 'DiscussionFilterModule', 'SignedInModule', 'Ads', 'CategoriesModule', 'ArticlesModule', 'TagModule', 'TwitterModule', 'OnlineNowModule');

    Regards

    Resolved.

  • @vrijvlinder What would be the best practice to add permission to view by role the modules created with the plugin widgets,

    regards,

  • vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited September 2017

    You would need to enact permissions to each module.

    here is an example,check for valid session only moderators can see, if it is not the moderator, it will not be loaded.

    public function AssetTarget() {
         $Session = Gdn::Session();
         if ($Session->CheckPermission('Garden.Moderation.Manage')) {
        return 'Panel'; 
    
    } else { 
    
    return;
     }
    
  • @vrijvlinder it would be great to be able to add, for example, the view permission for each of the roles, edit it in the panel and be able to display the widgets for each role (Admin, Moderator, Member, Guest),

    Regards,

  • vrijvlindervrijvlinder Papillon-Sauvage MVP
    edited September 2017

    I think you could do that, it's just a matter of creating all the modules for each role and giving them permissions to check for each role. It can be a bit complicated but I am sure it can be done.

    I can't help you do it at the moment I am too busy, but I am sure @R_J could , he is a wizard ...

    You could check:

    if admin
    if member
    if moderator
    if x role

    Based on who it is the modules would show or not show.

  • edited September 2017

    @vrijvlinder I have created the function to see for the widgets addon, in a simple way, so that they are seen by roles, of course it would be interesting to do it by module:

    Code:

    Modify default.php --> addon widget

    $PluginInfo['Widgets'] = array(
         'Name' => 'Widgets',
         'Description' => "This plugin adds modules/widgets you create to the panel . ",
         'Version' => '1.1',
         'RegisterPermissions' => array('Plugins.Widgets.View'), ---> Add Permission for Role.
         'Author' => "VrijVlinder",
         'AuthorEmail' => 'contact@vrijvlinder.com',
         'AuthorUrl' => "http://www.vrijvlinder.com"
    );
    

    Modify class.twittermodule ---> Widget Twetter Feed.

    <?php if (!defined('APPLICATION')) exit();
    
        class TwitterModule extends Gdn_Module {
    
        public function AssetTarget() {
            $Session = Gdn::Session();
            if ($Session->CheckPermission('Plugins.Widgets.View')) { ---> Check Permission for Role.
                return 'Panel';
             }
         } 
    
         public function ToString() {
    
             echo '<div class="Box" id="Twitter"><h4>Twitter Feed</h4>
                 <a class="twitter-timeline" data-lang="es" data-dnt="true" data-theme="dark" data-tweet-limit="1" 
                  href="https://twitter.com/UserTwitter">Tweets by UserTwitter</a> 
                 <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
             </div>';
         }
    }
    

    Any suggestions, I have tried and it works well,

    Regards,

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    Yes the simplest way is to obfuscate the plugin entirely based on roles, but I think it would be better to do it by module.

    Since you can create an unlimited amount of modules, it would be better by module.

  • R_JR_J Ex-Fanboy Munich Admin

    That should help: https://open.vanillaforums.com/discussion/comment/225254/#Comment_225254

    Create a plugin called "moduleVisibility" or whatever, add some permissions to the info array like that
    Plugins.ModuleVisibility.Twitter.View

    Then assign this permission to the appropriate roles. In the code do the following checks
    Is that module part of the assets array
    If yes, check if the user has the permission to see it
    If not, unset it

  • edited September 2017

    @vrijvlinder @r_j

    It is extremely simple, with the widgets module, and this we can have all the modules in an orderly way and with the permissions as if it were a plugin

    Config Widget Plugin: default.php:

    $PluginInfo['Widgets'] = array(
         'Name' => 'Widgets',
         'Description' => "This plugin adds modules/widgets you create to the panel . ",
         'Version' => '1.1',
         'RegisterPermissions' => array('Plugins.Widgets.Twitter.View', 'Plugins.Widgets.Facebook.View', 
         'Plugins.Widgets.Youtube.View'), ---> Permissions Modules Widgets.
         'Author' => "VrijVlinder",
         'AuthorEmail' => 'contact@vrijvlinder.com',
         'AuthorUrl' => "http://www.vrijvlinder.com"
    );
    

    // Check Permissions: class.twittermodule.php

    public function AssetTarget() {
        $Session = Gdn::Session();
        if ($Session->CheckPermission('Plugins.Widgets.Twitter.View')) {
            return 'Panel';
        }
    } 
    

    Thank you very much indeed, I hope you can modify your plugin so that more people can see it and learn more about Vanilla Forum, that's what makes free software really powerful when they are well thought out.

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    Awesome work ! Widgets is free to modify as you did to work for you. I made it just to make easier for people to add modules and sort them. You have extended it and that is great !!

    Send me the modified plugin and I will update it to include permission models.

  • R_JR_J Ex-Fanboy Munich Admin
    edited September 2017

    @terabytefrelance said:
    @vrijvlinder @r_j

    It is extremely simple, with the widgets module, and this we can have all the modules in an orderly way and with the permissions as if it were a plugin

    Config Widget Plugin: default.php:

    $PluginInfo['Widgets'] = array(
         'Name' => 'Widgets',
         'Description' => "This plugin adds modules/widgets you create to the panel . ",
         'Version' => '1.1',
         'RegisterPermissions' => array('Plugins.Widgets.Twitter.View', 'Plugins.Widgets.Facebook.View', 
         'Plugins.Widgets.Youtube.View'), ---> Permissions Modules Widgets.
         'Author' => "VrijVlinder",
         'AuthorEmail' => 'contact@vrijvlinder.com',
         'AuthorUrl' => "http://www.vrijvlinder.com"
    );
    

    // Check Permissions: class.twittermodule.php

    public function AssetTarget() {
        $Session = Gdn::Session();
        if ($Session->CheckPermission('Plugins.Widgets.Twitter.View')) {
            return 'Panel';
        }
    } 
    

    Thank you very much indeed, I hope you can modify your plugin so that more people can see it and learn more about Vanilla Forum, that's what makes free software really powerful when they are well thought out.

    Going that route you have to alter every plugin/module that you like to take influence on. That is not very flexible, a lot of extra work, it couldn't be packed into a plugin that you could publish and that are only some of the minor concerns.

    Vanilla is very powerful and when you try to change some behaviour, you will see that in most cases there are general solutions which helps plugin authors a lot.

    Instead of changing the module, add the following to a plugin:

        public function base_render_before ($sender) {
            // Check for Panel asset in order to prevent error messages.
            if (!isset($sender->Assets['Panel'])) {
                return;
            }
            // If we need the session more often in makes sense to get it into
            // a variable, otherwise we could have used it directly.
            $session = Gdn::session();
    
            // Check if the twitter module is in the Panel array.
            if (isset($sender->Assets['Panel']['TwitterModule'])) {
                // If yes, check if user has view permissions.
                if (!$session->checkPermission('Plugins.Widgets.Twitter.View')) {
                    // If not, delete it from array so that it will not be rendered.
                    unset($sender->Assets['Panel']['TwitterModule']);
                }
            }
    
            // Repeat the above if-block for the next modules...
    
        }
    

    Now basically the following will happen: all modules are added normally to the Panel, but before the Panel is rendered, you check for the view permissions and remove it from the array of modules which will be rendered afterwards.

    Far more elegant than repeating the if-block would be to loop through an array. You would have to build an array like that:

    $modules = [
        // 'PermissionIdentifier' => 'ModuleName',
        'Twitter' => 'TwitterModule',
        'Facebook' => 'FacebookModule',
        ...
    ];
    

    With such an array you could replace single if blocks with a loop:

            // Loop through all modules.
            foreach ($modules as $permission => $module) {
                // Check if the module is in the panel.
                if (isset($sender->Assets['Panel'][$module])) {
                    // If yes, check if user has view permissions.
                    if (!$session->checkPermission("Plugins.Widgets.{$permission}.View")) {
                        // If not, delete it from array so that it will not be rendered.
                        unset($sender->Assets['Panel'][$module]);
                    }
                }
            }
    

    Now strip those talkative comments:

        public function base_render_before ($sender) {
            if (!isset($sender->Assets['Panel'])) {
                return;
            }
    
            $session = Gdn::session();
    
            $modules = [
                // 'PermissionIdentifier' => 'ModuleName',
                'Twitter' => 'TwitterModule',
                'Facebook' => 'FacebookModule',
                ...
            ];
    
            foreach ($modules as $permission => $module) {
                if (isset($sender->Assets['Panel'][$module])) {
                    if (!$session->checkPermission("Plugins.Widgets.{$permission}.View")) {
                        unset($sender->Assets['Panel'][$module]);
                    }
                }
            }
        }
    

    That would make your code short, maintainable and flexible. All needed actions are done in your own plugin, so that you do not have to alter other files.

    P.S.: the code is untested and I haven't followed this discussion completely, so there might some things to fix with my code, but basically that's the approach I would take if I would like to create "per module permissions"

  • @vrijvlinder @r_j Thanks a lot is a simple but powerful code since everything is done in the plugin for any module to implement in vanilla forum,

    Regards,

  • vrijvlindervrijvlinder Papillon-Sauvage MVP

    Yes,It makes more sense to create a separate plugin that it's only purpose is to allow or disallow views of modules based on roles and permissions.

  • It is possible that instead of writing the name controllers where I want the module to appear, I can define an array with the name controllers for each module and add the module in public function base_render_before ($sender) ?

    Thanks to the collaboration of @r_j testing two solutions, which I will share to add another feature to the plugin widgets of @vrijvlinder.

    Solution 1: default.php

    <?php
    
    if (!defined('APPLICATION')) exit();
    
    // Define the plugin:
    
    $PluginInfo['Widgets'] = array(
        'Name' => 'Widgets',
        'Description' => "This plugin adds modules/widgets you create to the panel . ",
        'RegisterPermissions' => array('Plugins.Widgets.Twitter.View'),
        'Version' => '1.1',
        'Author' => "VrijVlinder",
        'AuthorEmail' => 'contact@vrijvlinder.com',
        'AuthorUrl' => "http://www.vrijvlinder.com"
    );
    
    class Widgets_Plugin extends Gdn_Plugin{
    
        public function __construct(){
        }
    
        public function base_render_before ($sender) {
            $modules = [
                [
                    'ModuleName' => 'TwitterModule',
                    'PermissionKey' => 'Twitter',
                    'Controllers' => [
                        'activitycontroller',
                        'categoriescontroller',
                        'discussioncontroller',
                        'discussionscontroller',
                        'profilecontroller'
                    ]
                ]
                // Other modules here
            ];
    
            $session = Gdn::session();
    
            foreach ($modules as $item) {
                // Maybe another check would be needed here, but as a start that would be sufficient.
    
                if (!isset($sender->Assets['Panel'])) {
                    return;
                }
    
                if (in_array($sender->ControllerName, $item['Controllers'])) {
                    if ($session->checkPermission("Plugin.Widgets.{$item['PermissionKey']}.View")) {
                        $module = new $item['ModuleName']();
                        $sender->addModule($module);
                    }
                }
            }
        }
    
        public function Setup(){
            // Register permissions
    
            // Set initial admininstrator permissions.
            $PermissionModel->Save(array(
                'Role' => 'Administrator',
                'Plugins.Widgets.Twitter.View' => 1
            ));
        }
    
        public function OnDisable(){
            // Deregister permissions (only in 2.1+)
            if(version_compare(APPLICATION_VERSION, '2.1b1', '>=')) {
                $PermissionModel = Gdn::PermissionModel();
                $PermissionModel->Undefine(
                    array(
                        'Plugins.Widgets.Twitter.View'
                    ));
            }
        }
    

    }

  • edited September 2017

    Solution 2: default.php

    <?php
    
    if (!defined('APPLICATION')) exit();
    
    // Define the plugin:
    
    $PluginInfo['Widgets'] = array(
        'Name' => 'Widgets',
        'Description' => "This plugin adds modules/widgets you create to the panel . ",
        'RegisterPermissions' => array('Plugins.Widgets.Twitter.View'),
        'Version' => '1.1',
        'Author' => "VrijVlinder",
        'AuthorEmail' => 'contact@vrijvlinder.com',
        'AuthorUrl' => "http://www.vrijvlinder.com"
    );
    
    class Widgets_Plugin extends Gdn_Plugin{
    
        public function __construct(){
        }
    
        public function base_render_before ($sender) {
            $controllers = [
                // ControllerName => Modules for Name Controllers.
                'activitycontroller' => ['Twitter'],
                'categoriescontroller' => ['Twitter'],
                'discussioncontroller' => ['Twitter'],
                'discussionscontroller' => ['Twitter'],
                'profilecontroller' => ['Twitter'],
            ];
    
            if (!array_key_exists($sender->ControllerName, $controllers)) {
                return;
            }
    
            $modules = [
                // Widgest => Class Module Name
                'Twitter' => 'TwitterModule'
            ];
    
            $session = Gdn::session();
    
            foreach ($controllers[$sender->ControllerName] as $item) {
                // do the permission check with "Plugins.Whatever.{$moduleName}.View"
                // attach module with $module = new $modules[$moduleName]();
                if ($session->CheckPermission('Plugins.Widgets.{$item}.View')) {
                    $module = new $modules['Twitter']();
                    $sender->addModule($module);
                }
            }
        }
    
        public function Setup(){
            // Register permissions
            // Set initial admininstrator permissions.
            $PermissionModel->Save(array(
                'Role' => 'Administrator',
                'Plugins.Widgets.Twitter.View' => 1
            ));
        }
    
        public function OnDisable(){
            // Deregister permissions (only in 2.1+)
            if(version_compare(APPLICATION_VERSION, '2.1b1', '>=')) {
                $PermissionModel = Gdn::PermissionModel();
                $PermissionModel->Undefine(
                    array(
                        'Plugins.Widgets.Twitter.View'
                    ));
            }
        }
    }
    

    These two solutions work correctly, which would be the best to implement,

    @vrijvlinder @R_J

    Regards,

Sign In or Register to comment.