I need to add phone number to the registration page and need to save it in the db as well. I followed following link.
http://www.jhipster.tech/tips/022_tip_registering_user_with_additional_information.html
But since here Jhispter version is changed code is bit different than the code in above link. So I am bit confusing to go with it. According to the link instructions I did upto "Updating ManagedUserVM". Then after I need the help since code is differed.
It really didn't change that much, and the logic remains the same.
The registerAccount function should look like this now :
public void registerAccount(#Valid #RequestBody ManagedUserVM managedUserVM) {
if (!checkPasswordLength(managedUserVM.getPassword())) {
throw new InvalidPasswordException();
}
userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()).ifPresent(u -> {throw new LoginAlreadyUsedException();});
userRepository.findOneByEmailIgnoreCase(managedUserVM.getEmail()).ifPresent(u -> {throw new EmailAlreadyUsedException();});
User user = userService.registerUser(managedUserVM, managedUserVM.getPassword(), managedUserVM.getPhone());
mailService.sendActivationEmail(user);
}
And the registerUser function in the UserService (which is a rename of the former createUser) :
public User registerUser(UserDTO userDTO, String password, String phone) {
// JHipster code omitted for brevity
...
// Create and save the UserExtra entity
UserExtra newUserExtra = new UserExtra();
newUserExtra.setUser(newUser);
newUserExtra.setPhone(phone);
userExtraRepository.save(newUserExtra);
log.debug("Created Information for UserExtra: {}", newUserExtra);
return newUser;
}
Just note that you may have to manually change your database changelog (if using a SQL database) to correctly link the ids of User and UserExtra, so it looks like this :
<createTable tableName="user_extra">
<column name="phone" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="user_id" type="bigint">
<constraints primaryKey="true" nullable="false" />
</column>
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
</createTable>
Related
I have created a CronJob that works perfectly.
But I want to generate the sending of an email within this Cronjob. I followed a tutorial on the internet.
I start with the creation itemType of ProductsApprovedEmailProcess.
then I created productsApprovedEmailProcess to define the steps be executed by the Process Engine as follow
Then I have added an EmailContext to holds the data to be passed to the email template as follow
public class ProductsApprovedEmailContext extends CustomerEmailContext
{
private String message;
#Override
public void init(final StoreFrontCustomerProcessModel processModel, final EmailPageModel emailPageModel)
{
super.init(processModel, emailPageModel);
if (processModel instanceof ProductsApprovedEmailProcessModel)
{
setMessage(((ProductsApprovedEmailProcessModel) processModel).getMessage());
}
}
public String getMessage()
{
return message;
}
public void setMessage(final String message)
{
this.message = message;
}
}
And I had register ProductsApprovedEmailContext as a bean in Spring as follow
<bean id="productsApprovedEmailContext" class="com.hybris.training.facades.process.email.context.ProductsApprovedEmailContext"
parent="abstractEmailContext"
scope="prototype" >
</bean>
Then I created 2 Velocity templates, one for the email Subject and the other for the Body email-productsapproved-subject.vm and email-productsapproved-body.vm
And the following impex allows you to create RendererTemplates for the Subject and the Body, and attach them to an EmailPageTemplate as follow
$contentCatalog=electronicsContentCatalog
$contentCV=catalogVersion(CatalogVersion.catalog(Catalog.id[default=$contentCatalog]),CatalogVersion.version[default=Online])[default=$contentCatalog:Online]
UPDATE GenericItem[processor=de.hybris.platform.commerceservices.impex.impl.ConfigPropertyImportProcessor];pk[unique=true]
$emailResource=$config-emailResourceValue
$emailPackageName=$config-emailContextPackageName
$lang=en
INSERT_UPDATE RendererTemplate ;code[unique=true] ;contextClass ;templateScript[lang=en,translator=de.hybris.platform.commerceservices.impex.impl.FileLoaderValueTranslator];rendererType(code)[default='velocity']
;email-productsapproved-body ;$emailPackageName.ProductsApprovedEmailContext ;$emailResource/email-productsapproved-body.vm
;email-productsapproved-subject ;$emailPackageName.ProductsApprovedEmailContext ;$emailResource/email-productsapproved-subject.vm
INSERT_UPDATE EmailPage ;$contentCV[unique=true];uid[unique=true] ;masterTemplate(uid,$contentCV) ;approvalStatus(code)[default='approved']
; ;ProductApprovedEmail ;ProductApprovedEmailTemplate ;
And in the Cronjob I added this code !
final ProductsApprovedEmailProcessModel productsApprovedEmailProcessModel = (ProductsApprovedEmailProcessModel) businessProcessService
.createProcess("productsApprovedEmailProcess" + "-" + System.currentTimeMillis(), "productsApprovedEmailProcess");
productsApprovedEmailProcessModel.setMessage("Products approved in csv file");
productsApprovedEmailProcessModel.setSite(baseSiteService.getBaseSiteForUID("electronics"));
productsApprovedEmailProcessModel.setLanguage(CommerceCommonI18NService.getCurrentLanguage());
modelService.save(productsApprovedEmailProcessModel);
businessProcessService.startProcess(productsApprovedEmailProcessModel);
But a acheive this error when I'm strating CronJob using HMC Interface :
Error executing ActionNode with ID [generateProductsApprovedEmail]: HtmlTemplate associated with MasterTemplate of EmailPageModel cannot be null
UPDATE :
Here is my business process :
<process xmlns="http://www.hybris.de/xsd/processdefinition"
start="generateProductsApprovedEmail"
name="productsApprovedEmailProcess"
processClass="com.hybris.training.core.model.process.ProductsApprovedEmailProcessModel"
onError="error">
<action id="generateProductsApprovedEmail" bean="generateProductsApprovedEmail">
<transition name="OK" to="sendEmail"/>
<transition name="NOK" to="error"/>
</action>
<action id="sendEmail" bean="sendEmail">
<transition name="OK" to="removeSentEmail"/>
<transition name="NOK" to="failed"/>
</action>
<action id="removeSentEmail" bean="removeSentEmail">
<transition name="OK" to="success"/>
<transition name="NOK" to="error"/>
</action>
<end id="error" state="ERROR">Something went wrong.</end>
<end id="failed" state="FAILED">Could not send products approved in csv File email.</end>
<end id="success" state="SUCCEEDED">Sent file in email.</end>
After declaring ProductApprovedEmailTemplate (EmailPageTemplate) i got this warn and the mail is not generated :
WARN [TaskExecutor-master-264-ProcessTask [8796715713462]] [GenerateEmailAction] Could not retrieve email page model for ProductApprovedEmail and Electronics Content Catalog:Online, cannot generate email content
Look like, the blog you have followed, it has mentioned each step correctly, but you might be missed something.
Make sure you have followed the below steps correctly.
e.g.
frontendTemplateName should be matched with EmailPageTemplate one
<bean id="generateProductApprovedEmail" parent="abstractGenerateEmailAction">
<property name="frontendTemplateName" value="ProductApprovedEmail"/>
</bean>
Create Email page Template
INSERT_UPDATE EmailPageTemplate ;$contentCV[unique=true];uid[unique=true] ;active ;frontendTemplateName ;subject(code) ;htmlTemplate(code) ;restrictedPageTypes(code)
; ;ProductApprovedEmailTemplate ;true ;ProductApprovedEmail ;email-productsapproved-subject ;email-productsapproved-body ;EmailPage
Create Email Page
INSERT_UPDATE EmailPage ;$contentCV[unique=true];uid[unique=true] ;masterTemplate(uid,$contentCV);approvalStatus(code)[default='approved']
; ;ProductApprovedEmail ;ProductApprovedEmailTemplate ;
I'm learning Shopware and I got to something I can't figure out how to solve.
I'm writing a test plugin that adds an attribute to the customer. I've added the correspondent field to the Registration form and it saves its value to the db automatically, like I read somewhere in the docs.
Now I wanted to let the attribute be editable in the account profile page, after the password field. I managed to put the input there, and even show the value from the db. But when I change the value and save, the value its not updated. I don't know if it is just a matter of getting the field name right, or do I need to override something else. Or is it just not possible? Any help on how to achieve this would be greatly appreciated.
Relevant code below:
plugin bootstrap
public function install(InstallContext $context)
{
$service = $this->container->get('shopware_attribute.crud_service');
$service->update('s_user_attributes', 'test_field', 'string');
$metaDataCache = Shopware()->Models()->getConfiguration()->getMetadataCacheImpl();
$metaDataCache->deleteAll();
Shopware()->Models()->generateAttributeModels(['s_user_attributes']);
return true;
}
register/personal_fieldset.tpl
{extends file="parent:frontend/register/personal_fieldset.tpl"}
{block name='frontend_register_personal_fieldset_password_description'}
{$smarty.block.parent}
<div class="register--test-field">
<input autocomplete="section-personal test-field"
name="register[personal][attribute][testField]"
type="text"
placeholder="Test Field"
id="testfield"
value="{$form_data.attribute.testField|escape}"
class="register--field{if $errorFlags.testField} has--error{/if}"
/>
</div>
{/block}
account/profile.tpl
{extends file="parent:frontend/account/profile.tpl"}
{block name='frontend_account_profile_profile_required_info'}
<div class="profile--test-field">
<input autocomplete="section-personal test-field"
name="profile[attribute][testfield]"
type="text"
placeholder="Test Field"
id="testfield"
value="{$sUserData.additional.user.test_field|escape}"
class="profile--field{if $errorFlags.testField} has--error{/if}"
/>
</div>
{$smarty.block.parent}
{/block}
The form type that it's used on registration isn't the same you have on profile.
If you check \Shopware\Bundle\AccountBundle\Form\Account\PersonalFormType::buildForm, you can see
$builder->add('attribute', AttributeFormType::class, [
'data_class' => CustomerAttribute::class
]);
That means the attributes are included on form and they will be persisted. That's why you can save the value on registration form.
On profile you have \Shopware\Bundle\AccountBundle\Form\Account\ProfileUpdateFormType. And here the attribute isn't added to form builder.
How to extend the ProfileUpdateFormType?
Subscribe Shopware_Form_Builder on Bootstrap (or on a specific Subscriber class)
$this->subscribeEvent('Shopware_Form_Builder', 'onFormBuild');
Create the method onFormBuild to add your logic
public function onFormBuild(\Enlight_Event_EventArgs $event) {
if ($event->getReference() !== \Shopware\Bundle\AccountBundle\Form\Account\ProfileUpdateFormType::class) {
return;
}
$builder = $event->getBuilder();
$builder->add('attribute', AttributeFormType::class, [
'data_class' => CustomerAttribute::class
]);
}
With this approach all attributes are available on your profile form.
Other possibility you have is using the 'additional' property instead of 'attribute' and then subscribe a controller event or hook a controller action to handle your custom data.
my scenario:
I am finally getting around to creating my own blog, and I am trying to learn as much as possible with regards to MVC while doing so. I am trying to display my tags as a custom declarative helper in my "PostView.cshtml" file but my problem is that it isn't in the current context and I don't know how to make it so.
I have had a look at the following 2 questions on SO:
this one is for previous version of MVC (<= 4) and
this one was answered by the guy who asked the question and isn't very explanatory.
I tried the above advice but with no success, hopefully someone can help me out. Here is my code:
Tags.cshtml (in ~/Views/Helpers/):
#helper Tags(System.Web.Mvc.HtmlHelper htmlHelper,
ICollection<MyNamespace.Objects.Tag> tags)
{
foreach (var tag in tags)
{
<div class="tags-div">
#MyNamespace.Extensions.ActionLinkExtensions.TagLink(htmlHelper, tag):
</div>
}
}
ActionLinkExtensions.cs (in ~/Extensions/ActionLinkExtensions/)
namespace MyNamespace.Extensions
{
public static class ActionLinkExtensions
{
public static MvcHtmlString TagLink(this HtmlHelper helper, Tag tag)
{
return helper.ActionLink("", ""); //logic removed for simplicity
}
}
}
PostView.cshtml (in ~/Views/Shared/) //where i want to use my custom helper:
#model MyNamespace.Objects.Post
<!--extra html removed for simplicity-->
<div>
<span>Tags:</span>#Tags(Html, Model.Tags) // '#Tags' doesn't exist in current context
</div>
I also tried adding namespaces to '~/Views/web.config':
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Optimization"/>
<add namespace="System.Web.Routing" />
<add namespace="MyNamespace" />
<add namespace="MyNamespace.Extensions" />
</namespaces>
</pages>
My "full name" for my "Tag.cs" class is MyNamespace.Objects.Tag and "Post".cs" is MyNamespace.Objects.Post.
Any explanations and advice with an answer would be greatly appreciated too, thank you very much in advance.
I decided to try use MVC3 way, I added the App_Code folder manually and followed steps from this great article.
And it worked, I needed to restart Visual Studio for my Intellisense to work (which prolonged finding my solution).
I deleted the folder '~/Views/Shared/'
I Added a file MyHelpers.cshtml into the App_Code folder, inside the file I added my helper method:
#helper Tags(System.Web.Mvc.HtmlHelper htmlHelper,
ICollection<MyNamespace.Objects.Tag> tags)
{
foreach (var tag in tags)
{
<div class="tags-div">
#MyNamespace.Extensions.ActionLinkExtensions.TagLink(htmlHelper, tag)
</div>
}
}
And called it in my PostView.cshtml like so:
#MyHelpers.Tags(Html, Model.Tags)
And Viola works as expected... hopefully this helps someone else who ends up in this situation...
I believe the better and simpler way would be to define a display template for you Tags collection that would be placed in ~Views/Shared/DisplayTemplates:
#model ICollection<MyNamespace.Objects.Tag>
foreach (var tag in Model)
{
<div class="tags-div">
#MyNamespace.Extensions.ActionLinkExtensions.TagLink(htmlHelper, tag)
</div>
}
In your PostView.cshtml you would then just write:
#Html.DisplayFor(model => model.Tags)
I am using Propel schema to create database tables. In a table, i need to create a 'name' column which should hold a 'short string', 'all in lower case', and 'with no spaces', for example:
'join', 'appointment'.
How can I define this column in schema.xml with given constraints? Or do I have to create a custom validator to get it done?
You can define a validate behaviour in your schema.xml.
There are several validators to choose from, you would probably use the Choice Validator.
Example:
<table name='TableName'>
...
<column name='name' type='varchar' size='20' />
<behavior name="validate">
<parameter name="rule1" value="{column: name, validator: Choice, options: {message: Please enter a valid name }}" />
</behavior>
</table>
I am currently exporting a lotus notes database using the C# Interop Domino assembly from NuGet,
I haven't found a way to identify objects or elements in a NotesRichTextItem in the order they were entered, for example, maybe I enter a paragraph first, then a table , then an attachment.
Is there a way to loop through the elements in their respect order ?
I have found a way to find elements with FindFirstElement, but you have to pass what element type you are looking for, this is very difficult as extracting all elements without order would make the content to lose its context.
thanks
There is a way to analyze Notes document's RichText items using DXL - a special XML format for Notes. Use DxlExporter to export a Notes document to DXL format. You can "walk" then through XML and get the content of RichText item with elements in right order.
For this RichText item e.g.
you'd get this DXL
<item name='Body'>
<richtext>
<pardef id='1'/>
<par def='1'>aaaaaaa</par>
<table widthtype='fixedleft' refwidth='1.0667in'>
<tablecolumn width='0.6729in'/>
<tablecolumn width='0.3938in'/>
<tablerow>
<tablecell>
<pardef id='3' keepwithnext='true' keeptogether='true'/>
<par def='3'>111</par></tablecell>
<tablecell>
<pardef id='4' keepwithnext='true' keeptogether='true'/>
<par def='4'>222</par></tablecell>
</tablerow>
<tablerow>
<tablecell><par def='3'>333</par></tablecell>
<tablecell><par def='4'>444</par></tablecell>
</tablerow>
</table>
<pardef id='5' leftmargin='1.2500in' list='bullet'/>
<par def='5'>xxx</par>
<par def='5'>yyy</par>
<par def='5'>zzz</par>
<pardef id='6' leftmargin='1in'/>
<par def='6'>
<attachmentref name='icon16.gif' displayname='icon16.gif'>
<picture height='34px' width='61px'>
<notesbitmap>lQAmAAAAAAAAAAAAA...</notesbitmap>
<caption>icon16.gif</caption>
</picture>
</attachmentref>
</par>
</richtext>
</item>
Here is a Java agent which exports selected documents to a file.
import lotus.domino.*;
public class JavaAgent extends AgentBase {
#Override
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
DocumentCollection dc = agentContext.getUnprocessedDocuments();
String filename = "c:/temp/exportDocs.dxl";
Stream stream = session.createStream();
if (stream.open(filename)) {
stream.truncate();
DxlExporter exporter = session.createDxlExporter();
exporter.setRichTextOption(0);
exporter.setMIMEOption(0);
stream.writeText(exporter.exportDxl(dc));
} else {
System.out.println("Cannot open " + filename);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Unfortunately the API gives you no way to do this:
Navigation is within elements of the same type. You can find or get
the first element of a type, the next element of a type, and the nth
element of a type. You cannot find or get an element regardless of
type.
http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/topic/com.ibm.designer.domino.main.doc/H_NOTESRICHTEXTNAVIGATOR_CLASS.html
UPDATE: I forgot to mention that you may want to check out a third-party tool from Genii Software called MidasLSX that possibly could help you. http://www.geniisoft.com/showcase.nsf/MidasLSX