It depends. You can do it like that, but in the end you would need the saveToSerializedColumn method in this case
If just have created a test table and like to save test data, feel free to do it any way you want.
Using a model is the safest way for standard tables, though.
$discussionModel = new DiscussionModel(); // Since we want to save to discussion table...
$discussionModel->saveToSerializedColumn(
'Attributes', // The column name
$sender->RequestArgs[0], // You should find out what this is
'DiscussionBan', // This serves as a internal key so that we can identify our d
[1,2,3,4,5]
);
Now that you've saved to the db, use the discussionModel to get the discussion by its id before the form is displayed (in the other part of the if clause).
Make sure the permission check is working!
After that get the discussion (look at the DiscussionModel to find the right method) and put a decho($discussion, 'Discussion', true); in that if clause.
Here is how I am attempting to get the userid's for the usernames submitted but the query is breaking for some reason:
// Check if usernames sent
if(isset($_POST['UserNames'])){
$UserNames = $_POST['UserNames'];
echo $UserNames."<Br /><br />";
// make array from list of usernames
$UserArray = explode(',', $UserNames); //split string into array seperated by ', '
foreach($UserArray as $value) //loop over values
{
echo "|".$value . "|<br/>"; //print value
//if usernames are sent get their userids
Gdn::sql()->
->select('UserID')
->from('GDN_User')
->where('UserID', $value)
->get();
// populate array with latest id returned
}
My thought is check to see if usernames were submitted, create an array of that, then loop through the array and query for each name ( I will populate to an array for each iteration of querying userid's)
$something->$anything would never work.
The dollar sign is for variables. The -> connector is used to call methods of objects.
I guess $sender is still unclear. When Vanilla calls the method in your plugin, it passes an instance of the current class to your plugin. Since you are using DiscussionController right now, $sender is a DiscussionController object.
The UserModel is a class with methods. So you would have to call class->method() directly.
foreach($UserArray as $value) //loop over values
{
echo "|".$value . "|<br/>"; //print value
//if usernames are sent get their userids
Gdn::sql()->
->select('UserID')
->from('GDN_User')
->where('UserID', $value)
->get();
If you would use decho instead of echo, you would have seen that the result of your query is an object (type dataset).
What you need is a user object. First you would have to create an instance of the user model and afterwards you can call its method getByUserName.
Although normally you would write $userModel = new UserModel();, the user model is a special case and you should use $userModel = Gdn::userModel();. The reason is, as far as I understand, that the user model is only instanciated once and the class gdn has a method usermodel which returns the only instance of the user model.
You don't need to understand that.
Yeah I looked at the Git page you linked and you are right it looks correct against that, but it breaks the code for some reason.
I have this working correctly but it is a kludgey way of doing it.
if(isset($_POST['UserNames'])){
$UserNames = $_POST['UserNames'];
//echo $UserNames;
// make array from list of usernames
$UserNameArray = explode(',', $UserNames); //split string into array seperated by ', '
// create array to store userids in_array
$discBanUsers = array();
// Loop the array
foreach($UserNameArray as $value) //loop over values
{
// echo "|".$value."|<br />";
$UserModel = new UserModel();
$UserData = $UserModel->getByUsername($value);
$count = 0;
foreach($UserData as $field) //loop over user
{
if($count<1){
echo $value." - ".$field."<br/>";
array_push($discBanUsers, $field);
}
$count++;
}
//if usernames are sent get their userids
}
//update the discussion attributes
}
That looks weird and I'm not sure what you are doing...
UserModel->getByUsername returns an object with information about the user. Roughly said, it contains every column of the GDN_User table as a property.
So if you have $user = $userModel->getByUsername($name) you have an object that has a property UserID. You can access object properties like that: $user->UserID.
There is no need to loop through the $UserData variable.
And you should really name that variable $user since it is the result of a method in the user model which gets a user, not a users data
And a more general advice: don't do unnecessary work in a loop, work that only needs to be done once, because it will be done again and again and again...
Check your creation of the user model against that advice
I've also checked it: there is no reason why $userNames = $sender->Form->getFormValue('UserNames', false); shouldn't work. Get away from accessing $_POST directly and make the above code snippet work.
If copy and paste doesn't work, try to type it in manually. "Breaks code" isn't a good description: do you get an error message or a blank page? If it is a blank page you might change your index.php for a short time to show errors so that you get more information (if you change ini_set('display_errors', 0); to ini_set('display_errors', 1); in your index.php, don't forget to revert that change later on!)
And if decho isn't working for you (which again is strange), try to use var_dump or print_r since both give you more information on your variable.
If I do a var_dump on just $sender it returns NULL
here is what the error returned after setting the index display of errors says:
Fatal error: Call to a member function getFormValue() on null in /home/vfroot/public_html/vfforums/plugins/discussionBan/views/discussionban.php on line 28
There should be no logic on the form page at all. Sometimes you have trivial if/else constructs there but all interactions with the model is strongly adviced to happen in the plugin.
There is this if authenticatedPostback condition, where the most important action has to take place.
The form, as you can see it in the GitHub repo, is finished. You might want to change the markup or the css a little bit, but that's everything which is left to do.
Ok I thinkthis is what we are looking for in the serialized comlumn save. I understand that $sender->RequestArgs[0] is the discussionid and i have taken the usernames and gotten an array of userids and then imploded and appended the brackets. I am assuming that we had to create the string for that.
Here is the code I am using:
// This will only be run when the user pressed the button.
$userNames = $sender->Form->getFormValue('UserNames', false);
if ($userNames === false) {
return;
}
$userArray = explode(',', $userNames);
$userIDs = [];
foreach ($userArray as $name) {
$userModel = new UserModel();
$user = $userModel->getByUsername($name);
$userIDs[] = $user->UserID;
}
$userIDs = "[".implode(',', $userIDs)."]";
$discussionModel = new DiscussionModel(); // Since we want to save to discussion table...
$discussionModel->saveToSerializedColumn(
'Attributes', // The column name
$sender->RequestArgs[0], // You should find out what this is
'DiscussionBan', // This serves as a internal key so that we can identify our d
$userIds
);
$sender->informMessage(t("Your changes have been saved."));
Comments
It depends. You can do it like that, but in the end you would need the
saveToSerializedColumn
method in this caseIf just have created a test table and like to save test data, feel free to do it any way you want.
Using a model is the safest way for standard tables, though.
Now that you've saved to the db, use the discussionModel to get the discussion by its id before the form is displayed (in the other part of the if clause).
Make sure the permission check is working!
After that get the discussion (look at the DiscussionModel to find the right method) and put a
decho($discussion, 'Discussion', true);
in that if clause.Here is how I am attempting to get the userid's for the usernames submitted but the query is breaking for some reason:
My thought is check to see if usernames were submitted, create an array of that, then loop through the array and query for each name ( I will populate to an array for each iteration of querying userid's)
Oh some echoing happening there just to see that I have results
Use the UserModels getID to get the users. It makes use of caching which is an advantage
Ok assuming we want to use this function: public function getByUsername($Username)
How do I call it? And I assume an array f user data will be brought back?
I am confused can I not call the usermodel and the function getByUsername() like this?
$something->$anything would never work.
The dollar sign is for variables. The
->
connector is used to call methods of objects.I guess
$sender
is still unclear. When Vanilla calls the method in your plugin, it passes an instance of the current class to your plugin. Since you are using DiscussionController right now, $sender is a DiscussionController object.The UserModel is a class with methods. So you would have to call class->method() directly.
Alright here is some feedback to your code above:
Vanilla has a form class and you should use it.
If you would use
decho
instead ofecho
, you would have seen that the result of your query is an object (type dataset).What you need is a user object. First you would have to create an instance of the user model and afterwards you can call its method getByUserName.
Although normally you would write
$userModel = new UserModel();
, the user model is a special case and you should use$userModel = Gdn::userModel();
. The reason is, as far as I understand, that the user model is only instanciated once and the class gdn has a method usermodel which returns the only instance of the user model.You don't need to understand that.
You need an instance of the user model
Afterwards you can loop through the $userArray
I think I got it.
Oh and of course you replied with a much better concept...
Something is wrong with this line:
Breaks code.
Also decho never seems to return anything for me.
Look at class.form.php and see what you can find on getFormValue. I have written most of the code by heart and the method might be named differently
Yeah I looked at the Git page you linked and you are right it looks correct against that, but it breaks the code for some reason.
I have this working correctly but it is a kludgey way of doing it.
That looks weird and I'm not sure what you are doing...
UserModel->getByUsername returns an object with information about the user. Roughly said, it contains every column of the GDN_User table as a property.
So if you have
$user = $userModel->getByUsername($name)
you have an object that has a property UserID. You can access object properties like that:$user->UserID
.There is no need to loop through the
$UserData
variable.And you should really name that variable
$user
since it is the result of a method in the user model which gets a user, not a users dataAnd a more general advice: don't do unnecessary work in a loop, work that only needs to be done once, because it will be done again and again and again...
Check your creation of the user model against that advice
I've also checked it: there is no reason why
$userNames = $sender->Form->getFormValue('UserNames', false);
shouldn't work. Get away from accessing $_POST directly and make the above code snippet work.If copy and paste doesn't work, try to type it in manually. "Breaks code" isn't a good description: do you get an error message or a blank page? If it is a blank page you might change your index.php for a short time to show errors so that you get more information (if you change
ini_set('display_errors', 0);
toini_set('display_errors', 1);
in your index.php, don't forget to revert that change later on!)And if decho isn't working for you (which again is strange), try to use
var_dump
orprint_r
since both give you more information on your variable.I get a blank page when I try to run it
If I do a var_dump on just $sender it returns NULL
here is what the error returned after setting the index display of errors says:
Hmmm I think I was thinking that it needed to be in the wrong spot.
OMG yeah I am an idiot. I get so caught up in thinking about doing things on the form page.
There should be no logic on the form page at all. Sometimes you have trivial if/else constructs there but all interactions with the model is strongly adviced to happen in the plugin.
There is this
if authenticatedPostback
condition, where the most important action has to take place.The form, as you can see it in the GitHub repo, is finished. You might want to change the markup or the css a little bit, but that's everything which is left to do.
Ok moving on to saving (again)...
Ok I thinkthis is what we are looking for in the serialized comlumn save. I understand that $sender->RequestArgs[0] is the discussionid and i have taken the usernames and gotten an array of userids and then imploded and appended the brackets. I am assuming that we had to create the string for that.
Here is the code I am using: