Meteor: Best way to create a new document in a collection before visiting a route? - meteor

Every time a user visits a specific route, I'd like for a new document to get created that will act as a "draft" that the user will edit until they decide to publish it.
Another way to think about this is that I want to redirect a user to a new page displaying the document after a successful insert of the document.
When I phrase it like that, I think I've basically answered my own question. In this case I would just call a Meteor method that creates and inserts the new document, then in the callback method I would use iron-router's Router.go method to redirect to the url using the new _id as a parameter. Is there a better way?

It's a bad idea to get collection created automatically upon visiting a route. What happen if user visit the route unintentionally?
Nevertheless, you can achieve it by inserting a document on publish function and it will get created upon Meteor.subscribe.
Meteor.publish('test-draft', function(options){
var _id = Test.insert({a: 'b'});
return Test.find({_id: _id})
})

If I understand what you're doing correctly, I think the easiest thing would be to just create an object and put it in a Session variable and not mess with creating a document in a collection until you're done editing it.
You can create the object and stick it into Session in Templates.myTemplate.rendered = function() { ... }. And then when it's been satisfactorily edited and submitted pass the Session variable to a Method that inserts it as a new document.

Related

UserManager.FindByNameAsync() doesn't return anything at all

I need to get the user with some username but the function call seemingly does nothing. I'm using the exact same call in a different controller and it's working just fine.
This is the line:
var user = await _userManager.FindByNameAsync(username);
When I put a break point on this line and the line below it, the debugger stops on this line, and when I try to go to the next line it just pauses for a bit and skips the rest of the function. As a result the controller function also doesn't return anything. Both controllers where I use call this function have the exact same declarations for _userManager and use it in the same way. Only difference is that the one that works gets its parameter from a passed objects property, whereas the other one just uses a string.
Please help I'm starting to lose my hair.
Ensure that you initially create the user using the CreateAsync method of a Microsoft.AspNetCore.Identity.UserManager instance. If you create the user by adding it directly using Entity Framework, you won't be able to find it using FindByNameAsync.
Note: Anybody facing this issue because they couldn't create users using "CreateAsync" or they have an already existing set of users, apply this solution.
Make sure the users in your database who where not created using the "CreateAsync" method of the user manager pass through the following.
//Get the corresponding user by id
var usr2 = _userManager.FindByIdAsync("youruserid").Result;
//Apply the following updates to the user model in the database
var res = await _userManager.UpdateSecurityStampAsync(usr2);
await _userManager.UpdateNormalizedEmailAsync(usr2);
await _userManager.UpdateNormalizedUserNameAsync(usr2);
await _userManager.SetLockoutEnabledAsync(usr2, true);
Apply the above code to every user in your database that was not created using "CreateAsync".
After these steps, you'll now be able to Find your user by username and email.
Note: If your users weren't assigned claims, don't forget to assign claims in the Database.

Change node author on user deletion

Is there a way to reassign all nodes associated with a user to another user when the first one is deleted instead of it going to anonymous?
To ask another way, I when I go to delete johnsmith, I am looking for the option to reassign all of johnsmith's content to janesmith.
I know this functionality exists within WordPress.
I do not know of any way to do this without coding.
In code I would look at
https://api.drupal.org/api/drupal/modules%21user%21user.api.php/function/hook_user_cancel_methods_alter/7.x
to define and add a new method when cancelling a user. And
https://api.drupal.org/api/drupal/modules%21user%21user.api.php/function/hook_user_cancel/7.x
to act on the new method.

Drupal 7 VBO Update User Not Working

I've created an action programmatically and added a VBO to a view in order to execute the action on one or more users. The action itself simply removes a few roles and adds a new role to the selected users. I call user_save from within the action to save the changes to the roles.
If I look at the user_roles table in the database while the action is running, I can see the role ids for the specific user, changing to the new role in realtime. However, when the VBO is complete, it seems to revert back to the original user object so that none of the old roles have been removed and the new role hasn't been added. It has to be something happening after my action is executed, but I can't imagine what it is.
Oddly enough, if I run the VBO a second time, it seems to work.
My action is defined in hook_action_info as type "user" and triggers is an array with "any" as the only parameter.
If I call the action directly using actions_do, it works perfectly the first time.
Any ideas?
I suggest to use a few users to test the VBO and also implement hook_user_update with dpm (devel module) and debug_backtrace. This could give a hint of what is happening, it's a weird behaviour that you will discover only debugging.
If you have more info please append it to your question so everyone could help.
Hope that helps.

How do I get an ID after saving an ExtBase Model?

After creating a model and adding it to a repository I want to have the new ID for different purposes (creating a mail, updating other fields outside the Extbase world)
$page = t3lib_div::makeInstance('Tx_MyExt_Domain_Model_Page');
$page->setTitle('Hello World');
$this->pageRepository->add($page);
At this point $page hasn't got an ID yet, uid is null.
$page->getUid(); // returns null
When does it get it? And how can I retrieve in on runtime?
In ExtBase, objects are "managed". This means every persistence transaction (add/remove/update) is simply noted in the underlying logic, but not yet executed until the appropriate time (like the end of processing a request). So, just because you add an object to a repository doesn't mean that it's actually added yet. That actually happens once $persistenceManager->persistAll() is called, which isn't something you need to do manually, ever. The point is, your $page object won't have a UID until it's saved and that's why $page->getUid() returns null. Look here for a great explanation.
I suspect that you are trying to do something outside of the ExtBase object/MVC lifecycle. At least, last time I got null when I tried to get the UID of an object, it was because I wasn't operating within the framework appropriately.
However, if you post some more code and give us a bigger picture of what you're trying to achieve, maybe we can help you get to a point where that object actually has a UID. For instance, if you're in a Controller object, tell us which Action method you're in, or if you're in a Repository object, tell us what you're trying to get from the repository and where/how you plan on using the query results.
EDIT
Just guessing here, but I'm assuming you're executing this code in some action of a controller. Since after the controller is executed a view is rendered, you can just pass the page object to the view:
$this->view->assign('page', $page);
And then in your view you can use the page object in a link:
<f:link.action action="show" arguments="{page:page}">
See this page object
</f:link.action>
And then in the show action of your controller you can show the page:
public function showAction(Tx_MyExt_Domain_Model_Page $page) {
// Do whatever you need to show the page in the `Show.html` template
}
I really am just guessing here. If you can give us a larger picture of what you're trying to do, what your action methods are supposed to do and things like that, we can answer your question a little more confidently.
(I'm also assuming that your page object isn't a replacement for the regular TYPO3 pages and that they are something totally different. It's much easier to deal with those TYPO3 pages through the backend interface than at the php level.)
You can call persistence manager explicitly in Your controller like this
#TYPO3 4.x
$persistenceManager = $this->objectManager->create('Tx_Extbase_Persistence_Manager');
$persistenceManager->persistAll();
#TYPO3 6.x
$persistenceManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
$persistenceManager->persistAll();

How do I create and populate a Plone object in the portal_factory?

I need to create an (archetypes) object from a View of a second object (object2 - which is not the parent of the new object). It needs to be prepopulated with data from the Request, and from object2.
The simple solution would seem to be to use "default_method" on the schema fields, and that can work for the data from the Request, but I don't believe I have access to the View from there, and therefore not to object2, either. In any case, one of the fields is a ReferenceField to object2 and I've read that ReferenceField ignores "default_method".
The other option is to create it inside the portal_factory, set its defaults, and then display the Add page, allowing the user to modify the content as required, or to exit without actually creating the object. Perfect, except that, of the multitude of methods available to create an object, (invokeFactory(), _createObjectByType(), _constructInstance() & createObject(), that I know of), only createObject actually leaves the object in the portal_factory - and since it only returns a string (the URL of the object's Add page), won't accept keyword arguments, and doesn't seem to notify any events (certainly not IObjectCreatedEvent), I can't see how to modify that with my data before directing the user to the edit page.
This is the pattern that I recommend when is not possible to use createObject:
_id = self.context.generateUniqueId("Document")
_id = self.context.invokeFactory(type_name=type_name, id=_id)
ob = self.context[_id]
ob.edit(
description = "text...",
subject = ('tag1', 'tag2'),
title = "some title...",
)
ob._renameAfterCreation(check_auto_id=True)
_id = ob.getId()
Doh. Finally figured it out.
createObject doesn't, in any real sense, create an object. It really is just a URL to the creation form.
Call .createObject(), get the URL for the form, attach the values you want as query parameters:
url = folder.createObject(type_name='xxx')
url += ?title=abc&description=def...'
self.request.RESPONSE.redirect(url)
will do it.

Resources