In WordPress there is Biographical Info under Profile. I would like to prevent the user from exceeding a maximum length of 400 characters. Also, the number of hyperlinks he can place in the biographical info should not exceed three. How do I do that? I am very familiar with JQuery, if that helps in this question. I am just a newbie with WordPress.
For the Javascript side, you should attach the necessary events to the description field. You can load your script via the wp_enqueue_script hook, and you probably want to do all this in your handler for admin_enqueue_scripts, where you check for the passed $hook_name, which in this case is the page name. It is user-edit.php when an admin edits a user, and profile.php when the user edits their own information (in which case IS_PROFILE_PAGE will also be defined as TRUE).
add_action('admin_enqueue_scripts', 'add_description_validation_script');
function add_description_validation_script($pagename) {
if ($pagename == 'profile.php' || $pagename == 'user-edit.php') {
wp_enqueue_script('description_validation', '/path/to/description_validation.js');
}
}
For the PHP side, you need the pre_user_description filter. This gives you the current biographical text, and your function can change this and return something else.
add_filter('pre_user_description', 'sanitize_description');
function sanitize_description($description)
{
// Do stuff with the description
return $description;
}
If, instead of silently changing the description, you want to show an error, you should look into the user_profile_update_errors hook. There you can validate the given data and return error messages to the user.
You probably want to wrap this all up in a plugin, so you can keep the code together and easily enable or disable it. A plugin is just a file in the /wp-content/plugins/ directory, most likely in a subdirectory named after your plugin.
Related
I try to sync changes from GDrive, So I'm using the changes api. It works like a charm when I'm using it with restrictToMyDrive=true.
But when I tried to expand it to also track shared files restrictToMyDrive=false I encounter some major drawback. I have inconsist results - the parents field is missing sporadically.
Let say that we have user A that share that folder to user B:
rootSharedFolder => subFolder => subSubFolder => File
If user B calls the changes API relatively close to the time that user A share the rootSharedFolder , Then in 3/10 times some of the inner folder will be received without the parents field.
Even trying to use the files.get API on the received changed item , results in empty parents field. But if I wait a minute or two and then call it again , the parents field does exist in the result.
Anyone else encounter this problem , and maybe have a workaround for it?
Thanks!
this behavior happens only when calling the changes api close to the time that the other user share you the items
Parents field may be missing due two factors:
A propagation delay
Insufficient permissions to see the parents
In both cases you'll notice the same: the parents field for the file is missing, at first there is no way to tell in which case you are:
A propagation issue:
This may happen when you request some file details related to a shared file not owned by you right after it was shared to you.
You may not be able to find it's related parents at first glance, this is because changes are still propagating on the file system, this is call a propagation issue, it should not last long and it should be possible to identify and solve this inconvenience by retrieving this field data a couple of minutes after the permission changes.
Not having access to the parents:
In this case you may have access to a certain file, but not to it's parent folder, thus, you can not get to know what parent it has, because it's not been shared with you.
This is on the documentation:
parents — A parent does not appear in the parents list if the requesting user is a not a member of the shared drive and does not have access to the parent. In addition, with the exception of the top level folder, the parents list must contain exactly one item if the file is located within a shared drive.
Side note: you may be interested on using SharedDrives, where files are owned by a organization rather than individual users, simplifying the sharing process and maybe avoiding the problems you are facing here.
https://developers.google.com/drive/api/v3/enable-shareddrives
How to know which case is?
A way to go is to implement an exponential back-off algorithm to try to retrieve the missing parents field, if after a max number of attempts it does not retrieve we are probably on the second case:
exponentialBackoff(getParent, 7, 300, function(result) {
console.log('the result is',result);
});
// A function that keeps trying, "getParent" until it returns true or has
// tried "max" number of times. First retry has a delay of "delay".
// "callback" is called upon success.
function exponentialBackoff(toTry, max, delay, callback) {
console.log('max',max,'next delay',delay);
var result = toTry();
if (result) {
callback(result);
} else {
if (max > 0) {
setTimeout(function() {
exponentialBackoff(toTry, --max, delay * 2, callback);
}, delay);
} else {
console.log('we give up');
}
}
}
function getParent() {
var percentFail = 0.8;
return Math.random() >= 0.8;
}
I'm using the World of warcraft API. And I want to find an EventMessageFilter. I can do so by calling
ChatFrame_GetMessageEventFilters("event")
And to do this I have to pass a chat event, in my case CHAT_MSG_WHISPER_INFORM.
So according to the API located over at
http://wowprogramming.com/docs/api/ChatFrame_GetMessageEventFilters
This function will return a table. So I named the table and tried to print its content with this code
local myNewTable = filterTable = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
for i in pairs(myNewTable) do
print(asd[i])
end
And this then prints out something like
function: 00000312498vn27842934c4
I have checked with
type(asd[i])
and it really is a function. But how can I get the content of it? How do I handle it?
I want to find an EventMessageFilter
Can you elaborate? Whose filter are you looking for and what do you intend to do with it?
it really is a function.
That's what this API does: returns a list of functions that are registered as filters for a particular message type (via ChatFrame_AddMessageEventFilter).
But how can I get the content of it?
You can't. The WoW API doesn't offer you any facilities for decompiling functions.
If your intention is to filter chat messages yourself, you don't need to call this function at all. Just call ChatFrame_AddMessageEventFilter to add your filter.
So I managed to solve my problem by removing to current filters that have been put in place by another addon and then just add my own filter. As Mud pointed out. GMEF was supposed to return functions. I now see how this makes sense. But now I have made the code to remove the functions. If you want to re-add them later on, just store them in a variable until you are done but I won't include this in my answer. I also feel like my answer is kinda half off-topic ish. But to answer my own question. It is supposed to return functions and you can't see the contents of these functions. This is the code I used to remove the functions that were put in there by another addon.
function rekkFilters()
local myFilters = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
for i in pairs(myFilters) do
ChatFrame_RemoveMessageEventFilter("CHAT_MSG_WHISPER_INFORM", myFilters[i])
end
end
local myFilters = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
rekkFilters()
local myFilters = ChatFrame_GetMessageEventFilters("CHAT_MSG_WHISPER_INFORM")
if myFilters[1] ~= nil then
rekkFilters()
end
I need to use MTD with Json to dinamycally create forms, but also i need to check the user input:
Some fields may only accept numbers, and some other have a fixed length etc.
This can be done with an action that checks every EntryElement value against the specified conditions, and then using some messaging to tell the user about the necessary corrections.
If we have a low number of fields this is Ok, but when one has more than 50 fields then this turn out to be very awkward in terms of usability. The ideal solution would be to notify the user about corrections, in the moment the user ends typing in the EntryElement
Now MTD provides some sort of mechanism to do this:
JsonElement jsonElement;
jsonElement = JsonObject.Load("file.json");
((EntryElement) jsonElement["field_1"]).EntryEnded = delegate { doSomething();};
Provided that "field_1" is an EntryElement marked with the id attribute with "field_1" value
The above code works as expected, ie: When i change the focus to another part, the EntryEnded event activates. Now for the million dollar question:
How do i know to which EntryElement does the Event correspond? or in other words. How do i get the ID of the EntryElement when calling the Event?
If none of the above is possible which would be suitable solution?
Thanks in advance for any leads,
Found a way to do it:
((EntryElement)jsonElement ["field_1"]).EntryEnded += (object sender, EventArgs e ) =>
{
NSIndexPath pt = ((EntryElement)sender).IndexPath;
Console.WriteLine("section: "+pt.Section+" row: "+pt.Row);
};
This little thing will print the Section and the Row of the EntryElement that received
the EntryEnded event. This is not exactly as getting the id, but at least now i have information about its location, and from this i can get a lot more info (specially if i took care to save it somewhere else)
This is probably a basic trick, but i didn`t found it anywhere else!
TLDR; I want to enable database-logging of xss_clean() when replacing evil data.
I want to enable database logging of the xss_clean() function in Security.php, basically what I want to do is to know if the input I'm feeding xss_clean() with successfully was identified to have malicious data in it that was filtered out or not.
So basically:
$str = '<script>alert();</script>';
$str = xss_clean($str);
What would happen ideally for me is:
Clean the string from XSS
Return the clean $str
Input information about the evil data (and eventually the logged in user) to the database
As far as I can see in the Security.php-file there is nothing that takes care of this for me, or something that COULD do so by hooks etc. I might be mistaken of course.
Since no logging of how many replaces that were made in Security.php - am I forced to extend Security.php, copy pasting the current code in the original function and altering it to support this? Or is there a solution that is more clean and safe for future updates of CodeIgniter (and especially the files being tampered/extended with)?
You would need to extend the Security class, but there is absolutely no need to copy and paste any code if all you need is a log of the input/output. Something along the lines of the following would allow you to do so:
Class My_Security extends CI_Security {
public function xss_clean($str, $is_image = FALSE) {
// Do whatever you need here with the input ... ($str, $is_image)
$str = parent::xss_clean($str, $is_image);
// Do whatever you need here with the output ... ($str)
return $str;
}
}
That way, you are just wrapping the existing function and messing with the input/output. You could be more forward compatible by using the PHP function get_args to transparently pass around the arguments object, if you were concerned about changes to the underlying method.
I receive input in the form of URL strings (aka controller/action?example=yes), and I'm wondering if I need to escape the content of the string for security.
For example, if I assign the param to a variable:
example = params[:example].to_s
do I need to escape anything? or do I only apply h() when I put the value of :example back in the view file?
It depends on what you are doing with it, if you are worried of SQL injections , then you can trust ActiveRecord, like doing:
Examples.find_by_name params[:example]
or
Examples.find(:conditions=> ["name = ?", params[:example]])
On the other side, the common strategy of filtering is on display side, so you save the input as is, and you filter on display(views) by using h().
If you still want to save some HTML input from the user like when doing in rich editors, then you have to pay extra attention to XSS attacks, and so you have to filter the input. One great gem for filtering HTML is Sanitize, use it to save a modified filtered version of user input to use it in views.