Kindly asking for help with a plugin
I've created a plugin that is already working, but quite ugly and not finished. The plugin should do following:
1. if user1 opens profile of user2 a db entry is created
2. if user2 looks at his own profile he has a new menu entry
3. that menu entry shows links to a view that lists every user who clicked his profile
Look at the screenshots and you will see and understand. The plugin is for Vanilla 2.1b2 and can be downloaded here: https://github.com/R-J/ProfileVisitors/archive/master.zip
I already have it working but there are some things that are not working by now and here are my questions:
1. my view doesn't look like any other profilecontroller view. Could anybody tell me what I have to add or have to change?
2. my list should look like the activity list in profile but it does not. When there are no profile pictures, there is no space left free
3. in activity view there is some extra text that makes images fit into rows height. My rows are too small. I want rows with pictures be big enough and rows without picture to be smaller
4. I think it would be fine to allow that feature only for configurable roles. How can I test if a user has a special role? How about creating a special permission and apply that to rules specified in settings? But if I use the configurationmodel in settings, how can I react on a change (which I would have to do if I use permissionmodel)?
5. I hook base_render_before and test if Sender is the ProfileController. Isn't there a better hook if I want to do something whenever a profile is accessed?
6. I think a logo would be fine once the plugin is finished...
Yes, I admit I'm a bit lazy. I haven't looked at other plugins to find my answers, but I'm a little bit short of time and would like to finish that plugin soon.
Many thanks for any help!
Comments
Number 4. Register a permission and just check for that permission in your hooks, no need to make it configurable in the settings page. Number 5. Use
ProfileController_Render_Before
The rest will have to wait until I can actually look at the plugin code
This sounds like a cool plugin!
Search first
Check out the Documentation! We are always looking for new content and pull requests.
Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.
@hgtonight
cool to code but ...
sounds a bit like eavesdropping to me and personally would turn me off, if everything I viewed is monitored AND displayed. But thats me, I'm sure others will love it.
you could try hgtonights suggestion if that works for you or you could
try this for #5
you could replace
with this and you would actually get the ProfileUserID and act only once.
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.
you could also use public function ProfileController_AfterUserInfo_Handler($Sender) {
to display profile visitors
and use the profile visitor link for your settings.
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.
I really like the idea of this plugin. When I was working in a big company with an internal intranet portal we used to have something similar for our 'employee profile'. Really fun and more interactive.
What if user1 looks at profile of user2 and then few days later comes back and looks again? Another DB entry or an updated DB entry?
What do our DBA's say about it?
There was an error rendering this rich post.
if it were me I would store the date and update the date each time and keep one entry per looker
I would avoid this - lets say someone is debugging their forum and disabling your plugin temporarily - they lose all their data.
I would just entirely remove the OnDisable() function and not delete or drop anything.
what you could do is put a cleanup function if your desire is to clean up data if your plugin is no longer used.
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.
Many thanks for the input right now! I hope I can implement that on the weekend.
@UnderDog: there is only one row for each visitor/visited. So only the time get's updated. I've found two great functions in Garden for exactly that purpose
If you have a table that has the columns UpdateUserID and DateUpdated, function History(TRUE, FALSE) will fill those fields with session user and timestamp!
It will also set fields InsertUserID and DateInserted if they exist and if you use History(TRUE, TRUE). I've changed my original column naming scheme as soon as I've found that function
Function Replace does an insert or an update depending on the existence of a row given by the criteria.
@peregrine: yes, all data will be lost on disable but I don't think that keeping them is a better solution. Both are crappy.
I would love to have an export feature for plugin settings. Wouldn't it be great to have an [Export] and an [Import] button in your plugin screen that will make an export/import of all your config settings and db changes?
Well, it could be implemented, but I haven't seen any help for something like that in the framework right now. Something like functions those functions would be great:
ExportColumn(tablename, array(columns))
ExportTable(tablename)
ExportSettings(Plugins.PluginName)
ImportColumn(tablename, array(columns), overwrite:yes|no)
ImportTable(tablename, overwrite:yes|no)
ImportSettings(Plugins.PluginName, overwrite:yes|no)
All those Export and Import functions must be wrapped into one function each and that would take a file as a parameter. So an admin could export and import plugin settings easily. Well, most things can be done by a simple table backup in phpmysql so it's questionable if such an effort will be worth it.
Another great way would be a two step disabling process: admin hits [Disable] and plugin author could prompt a question and start a function depending on that question. "Do you want to clean up each entry of that plugin? Yes|No" => if yes, drop columns and tables...
LOL! I know a certain 'Don Peregrino' that would be looking to rebuild the Porter Plugin for exactly that purpose, heheh
There was an error rendering this rich post.
@peregrine: not tested yet, but I think I will use something like this in order to solve the purge/keep data dilemma:
I add an option for that in the settings menu. I'm not sure about the default setting, but I tend to follow your preference and set it to unchecked so that data will not be deleted by accident.
By the way: I've looked if it is possible to hook the disabling process in order to show a dialog, but there is only a hook after the plugin has been disabled:
AddonDisabled
. That's too late...I think I'll ask for a
BeforeAddonDisabled
via GitHub Pull request. That way it would be possible to face the admin with a dialogue and ask him to keep or to purge data.That said, I've looked closer at GitHub and now I've seen I wasn't looking at the master branch :-/
There isn't even a function OnDisable in V2.1b2! Argh...
Pull request done
https://github.com/vanillaforums/Garden/pull/1749
r_u sure r_j ?
I like the config option. You could even put it in the readme, instead of settings.
it needs to be ==
or better yet I think
if (C('Plugins.ProfileVisitors.PurgeOnDisable') === TRUE)
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.
It is just not called OnDisable, but yes, it exists.
Thanks for the hint concerning the equal sign. I ran into difficulties with TRUE and FALSE one time but I think it is because I haven't really understood the difference between == and === by now...
http://php.net/manual/en/language.operators.comparison.php
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.
But then I prefer
if (C('Plugins.ProfileVisitors.PurgeOnDisable') == TRUE)
because I've seen TRUE and FALSE saved as 1 and 0 and I want to be fail safe.Creating a profile view that looks like a native view was exceptionally hard for me! That's why I'll explain what I've done and - whenever I can - why I have done what I have done.
First the complete code:
I've only left over the lines you need to show a profile page, full source code is on GitHub.
EditMode
will decide if you see the navigation list for "Change Password", "Notification Preferences", etc or not. I wanted to inform and no input, so I set it to false.$this->Data('Title')
I assume most of you developers have implemented something like that in Garden before but I do not like searching for answers in old threads and only finding questions. So I wanted to complete this thread.
@hgtonight:
'RegisterPermissions' => array('Plugins.ProfileVisitors.View' => 1)
did exactly what I needed@peregrine: I've used
ProfileController_BeforeRenderAsset_Handler
, works perfectly.Now the only thing I have to solve is the CSS question, but that's the smallest problem
(Offtopic: have you noticed that the smiling smiley looks way more excited than the grinning one? vs. Somewhat irritating to me)
I just have a few questions.
You currently override the profile user in
/profile/visitors
to be the session user but link to/profile/visitors/{userID}/{username}
. This means I can visit anyone's profile visits link and will be shown my own profile/visits. Is this the intended effect?Is there a specific reason you chose to hook into the BeforeRenderAsset event rather than the Render_Before event? I only ask because you don't seem to want to tally multiple views for each asset. You even filter it down so it only tallies on the content asset.
Did you want each user to be able to configure their notifications? I see you have it listed as a todo at top. If you want to add in a notification preference, use something like below:
This will add an option on the notification preferences page. If you use the activity model to handle notifications, these preferences will be taken into account automagically.
I am a little confused as to what the CSS issue is. Mind clarifying?
Search first
Check out the Documentation! We are always looking for new content and pull requests.
Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.
Nope, that's sloppy coded. Thanks for pointing me to it.
Lazyness. I've just copied without thinking...
Whoa that's great! I was thinking about adding such a notification. If it is tracked, why not notify when it happens? But I would deactivate it by default because it seems to be a little bit silly to me. It would just be for completeness.
Take a look at the first screenshot: there you can see how activity aligns it's postings so that there seems to be an extra column for user pictures.
If you look at the screenshot of my profile visitor list, you see that the picture destroys the layout. I think I would like to have like it is in the activity stream. Maybe with an additional odd/even color.
Thanks for looking so thoroughly at my code. Your findings are a little bit embarrassing for me, but very, very welcome!
Thanks for the clarification.
You can get the same effect by adding the class 'Activities' to your data list element. As far as the user photos being contained, the activity view cheats a little since the activity is always as tall or taller than the user's photo.
Feeling embarrassed is a good thing in my book. Means you are humble and open to criticism. That said, I didn't mean to embarrass. There are many ways to code a cat, after all.
P.S. I submitted a PR on github with these changes in place.
Search first
Check out the Documentation! We are always looking for new content and pull requests.
Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.
Great. Asked for an event that I can hook when a user presses a button that calls a function of my plugin
@hgtonight: I will try your code tomorrow. I've already thought about adding a
below each line to make it as tall as lines with profile pictures but thought that should be possible with css. But if you've already made a pull request, I assume you already have solved my problemr_j
I don't know if you were referring to this being too late or "how it would be used"
but there is a
$this->FireEvent('AfterDisablePlugin'); in settingscontroller.php in vanilla 2.1b2
it probably won't be insightful if you are already aware, but in case you aren't.
I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.