WP ALL IMPORT with foreach - woocommerce

I am trying to import products with WP ALL IMPORT to my shop. I am importing from XML where tree is like
<SHOPITEM>
<ITEMNAME>
ITEMNAME
</ITEMNAME>
...
<PARAMS>
<PARAM>
<PARAM_NAME>
Name of parameter
</PARAM_NAME>
<VAL>
Value of parameter
</VAL>
</PARAM>
</PARAMS>
<PARAMS>
<PARAM>
<PARAM_NAME>
Name of parameter
</PARAM_NAME>
<VAL>
Value of parameter
</VAL>
</PARAM>
</PARAMS>
<PARAMS>
<PARAM>
<PARAM_NAME>
Name of parameter
</PARAM_NAME>
<VAL>
Value of parameter
</VAL>
</PARAM>
</PARAMS>
</SHOPITEM>
I need to create Attributes foreach of param_name and val
How should looks like code in these inputs? Right now I have this but it doesn't import them.
[FOREACH({PARAMS/PARAM})] {PARAM_NAME[1]} [ENDFOREACH]
[FOREACH({PARAMS/PARAM})] {VAL[1]} [ENDFOREACH]

Related

Spring MVC #RequestParam - empty List vs null

By default Spring MVC assumes #RequestParam to be required. Consider this method (in Kotlin):
fun myMethod(#RequestParam list: List<String>) { ... }
When passing empty list from javaScript, we would call something like:
$.post("myMethod", {list: []}, ...)
In this case however, as the list is empty, there is no way to serialize empty list, so the parameter essentially disappears and so the condition on required parameter is not satisfied. One is forced to use the required: false on the #RequestParam annotation. That is not nice, because we will never receive the empty list, but null.
Is there a way to force Spring MVC always assume empty lists in such case instead of being null?
To get Spring to give you an empty list instead of null, you set the default value to be an empty string:
#RequestParam(required = false, defaultValue = "")
This can be managed in the serialization with ObjectMapper. If you are using jackson in your spring MVC, you can do either the following.
1) Configure your object mapper:
objectMapper.configure(SerializationConfig.Feature.WRITE_EMPTY_JSON_ARRAYS, false);
2) Or if you are using beans via xml config:
<bean name="objectMapper" class="org.springframework.http.converter.json.JacksonObjectMapperFactoryBean" autowire="no">
<property name="featuresToDisable">
<list>
<value type="org.codehaus.jackson.map.SerializationConfig.Feature">WRITE_EMPTY_JSON_ARRAYS</value>
</list>
</property>
</bean>
You can try a WebDataBinder in your controller.
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(List.class, "list", new CustomCollectionEditor( List.class, true));
}
Tried this?
fun myMethod(#RequestParam list: List<String> = listOf()) { ... }

spring validator without using properties file for show error messages

I want configuration for show error messages on jsp using spring validator,but without using this configuration for message.properties.
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>message</value>
</list>
</property>
</bean>
error.rejectValue(String field,
String errorCode,
Object[] errorArgs,
String defaultMessage)
Register a field error for the specified field of the current object (respecting the current nested path, if any), using the given error description.
The field name may be null or empty String to indicate the current object itself rather than a field of it. This may result in a corresponding field error within the nested object graph or a global error if the current object is the top object.
Parameters:
field - the field name (may be null or empty String)
errorCode - error code, interpretable as a message key
errorArgs - error arguments, for argument binding via MessageFormat (can be null)
defaultMessage - fallback default message
reference link
Use
error.rejectvalue with three parameters("name of path variable" , "any name" , "message you want to show");
just like
error.rejectvalue("Name", "msg.name", "please enter name");

Update Document Template Dynamically in Alfresco from property page

I have one document template as like attached screen shot. now my requirement is i want to dynamically update some values of that document when i will upload it in alfresco site. i will either create that Document through node template or upload. I want to provide those values from document property page.
can anyone help me how can i achieve this.
I tried it using java script, but i am getting some problem. so i am thinking for using Alfresco CMIS API. But i am quite new in alfresco cmis. so can any one tell the better way which i can use for this task.
Thanks in advance.
I think you should trigger an custom action by a Rule
When someone update a node (for example by editing properties), your action will be triggered and you will be able to :
get the content of your node
get the properties of your node
use the apache poi library provided by alfresco (my guess is that you use word documents) to find your parameters, and the replace them by the value you find in the property nodes.
Here is an excellent tutorial to learn how to create a custom action.
Note : You may have to keep the original templated document if you want to change a second time your properties (by using versionning for example).
Edit (see discussion below) :
I assume you know how to use rules in alfresco : http://docs.alfresco.com/5.0/tasks/library-folder-rules-define.html
Declare a new action to assign to a rule. This action must be triggered when the excel is dropped or updated
Create an action implementing your need :
public class MyAction extends ActionExecuterAbstractBase {
...
#Override
protected void executeImpl(final Action arg0, final NodeRef arg1) {
// your code here
}
....
}
This action will :
Take the nodeRef parameter (which is the excel file) and load the file
...
Inputstream inputstream = getFileFolderService().getReader(arg1).getContentInputStream();
...
NPOIFSFileSystem fs = null;
HSSFWorkbook workbook = null;
try {
fs = new NPOIFSFileSystem(inputstream);
workbook = new HSSFWorkbook(fs.getRoot(), true);
//get your data with POI
For each row of your excel :
Make a copy of your template :
find it :
getSearchService().query(searchParameters)
copy it :
getFileFolderService().copy(sourceNodeRef, targetParentRef, newName)
Do transformations of your new word content (Find occurrences and replace with poi library).
Update the content of your new file :
ContentWriter writerDoc = getContentService().getWriter(document.getNodeRef(), ContentModel.PROP_CONTENT,
true);
writerDoc.putContent(file/inputStream);
In your context file, declare you action :
<bean id="my-action" class="x.y.z.MyAction" parent="action-executer">
<property name="searchService">
<ref bean="searchService" />
</property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="contentService">
<ref bean="contentService" />
</property>
<property name="fileFolderService">
<ref bean="FileFolderService" />
</property>
....
</bean>
In Share, assign to a folder a rule with the action you have created.

Hibernate Validator: Using constants in constraints.xml

I am using Hibernate Validator as a JSR-303 validation provider and its xml style constraints descriptions.
So, I have a
<bean class="com.my.User" ignore-annotations="true">
<field name="email">
<constraint annotation="javax.validation.constraints.Pattern">
<element name="regexp"><![CDATA[[A-Za-z0-9\._%+-]{1,64}#[A-Za-z0-9.-]+\.[A-Za-
z]{2,4}]]></element>
</constraint>
</field>
.....
</bean>
I also have a separate class, which contains all my patterns
public final class Regexps {
public static final String EMAIL_REGEXP = "A-Za-z0-9\._%+-]{1,64}#[A-Za-z0-9.-]+\.[A-
Za-z]{2,4}";
....
}
So, as you can see, I have two places, where email regexp is present, and I want only one place.
My question:
Is it possible to use the
public static final String EMAIL_REGEXP = "A-Za-z0-9\._%+-]{1,64}#[A-Za-z0-9.-]+\.[A-
Za-z]{2,4}";
field inside the xml, so that
I could just refer to the contant string field.
So I would Like to have something like:
<bean class="com.my.User" ignore-annotations="true">
<field name="email">
<constraint annotation="javax.validation.constraints.Pattern">
<element name="regexp">Regexps.EMAIL_REGEXP</element>
</constraint>
</field>
.....
</bean>
By the way, it is possible via annotations
public class User {
#Pattern(regexp = Regexps.EMAIL_REGEXP)
private String email;
}
But I cannot use annotations, because I use the legacy POJOs which I use for data transfering and cannot change the source code.
Currently it's not possible to reference constraints from within XML constrained mappings. I think it's a good idea, though. Could you open a feature request in our issue tracker so we can discuss the feature there?
If you can't use annotations, you might give Hibernate Validator's API for programmatic constraint declaration a try, you could then work with a shared constant for the pattern.

Sharing asp.net resource files between web applications

I have multiple projects that need to share resource files (.resx) Suggestions have been made to move resource files to a separate assembly and have web projects reference it. Is there an example of how to do this?
Do I create a new Class Library project and move App_GlobalResource folder inside of that? I don't think that will work because code classes that are generated for resource files are marked as 'internal' which means that they can not be accessed outside of this assembly.
In the properties window of Visual Studio, you should be able to set the access modifier of the resource file to public. You won't, however, be able to access the resources in aspx files using the normal <%$ Resources:... %> syntax, since it does not support resources in referenced assemblies. I had the same problem and solved it by implementing a custom ExpressionBuilder, but I don't have access to my source code at the moment. If it's still needed then, I can look up the code tonight.
EDIT: OK, here's how I solved that problem:
Step 1: Move the resx files into the class library. They do not need to be in a specific folder. In the visual designer of the resx file, set the "Access Modifier" (upper right-hand corner) to "Public"
You should now be able to
reference the resources in C#/VB code (in the library as well as in the web project), e.g., Dim myMessage As String = [Namespace.]Resources.NameOfResx.NameOfResource
reference the resource as inline code in aspx pages, e.g., <h1><%= [Namespace.]Resources.NameOfResx.MyTitle %></h1>.
What won't work at this point is to use Resources expression, e.g., <asp:Button runat="server" Text="<%$ Resources:NameOfResx,MyButtonText %>" />. Unfortunately, you cannot simply replace this with inline code, since it's inside the property of a server side control.
Step 2: Let's make a custom ExpressionBuilder in our library, which interprets arbitrary code expressions. Fortunately, we can let the powerful classes of the .net Framework do all the work for us:
Imports System.Web.Compilation
Imports System.Resources
Imports System.CodeDom
<ExpressionPrefix("Code")> _
Public Class CodeExpressionBuilder
Inherits ExpressionBuilder
Public Overrides Function GetCodeExpression(ByVal entry As System.Web.UI.BoundPropertyEntry, ByVal parsedData As Object, ByVal context As System.Web.Compilation.ExpressionBuilderContext) As System.CodeDom.CodeExpression
Return New CodeSnippetExpression(entry.Expression)
End Function
End Class
Then we need to register this ExpressionBuilder in the web.config:
<system.web>
...
<compilation ...>
<expressionBuilders>
<add expressionPrefix="Code" type="NamespaceOfYourLibrary.CodeExpressionBuilder" />
</expressionBuilders>
</compilation>
</system.web>
Now you should be able to do the following:
<asp:Button runat="server" Text="<%$ Code:[Namespace.]Resources.NameOfResx.MyButtonText %>" />
Credit: I got the idea for the CodeExpressionBuilder from the Infinites Loop blog. If you're more into C# than VB, you can have a look at the code examples there.
We had a already developed application where we had to have 2 copies of all the resource files, one for services and one for the asp.net project, also the project relied on the <%$ Resources:NameOfResx,MyButtonText %> syntax, so changing syntax was no option.
After some time i found the ExpressionBuilder and came up with the following solution:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Web.Compilation;
using System.Resources;
using System.CodeDom;
using System.Reflection;
/// <summary>
/// This class allows asp.net Resource lookups to different assembly
/// </summary>
[ExpressionPrefix("Resources")]
public class ResourceExpressionBuilder : ExpressionBuilder
{
static readonly Dictionary<string, ResourceManager> mResourceManagers = new Dictionary<string, ResourceManager>(StringComparer.OrdinalIgnoreCase);
static ResourceExpressionBuilder()
{
Assembly resourceAssembly = Assembly.GetAssembly(typeof(OneTypeInResourceAssembly));
const string suffix = ".resources";
string assemblyName = resourceAssembly.GetName().Name;
foreach (string resource in resourceAssembly.GetManifestResourceNames()) {
if ((resource.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))) {
string resourceName = resource.Substring(0, resource.Length - suffix.Length);
string resourceFriendlyName = resourceName.Substring(assemblyName.Length + 1, resourceName.Length - (assemblyName.Length + 1));
mResourceManagers.Add(resourceFriendlyName, new ResourceManager(resourceName, resourceAssembly));
}
}
}
/// <summary>
/// When overridden in a derived class, returns a value indicating whether the current <see cref="T:System.Web.Compilation.ExpressionBuilder" /> object supports no-compile pages.
/// </summary>
/// <returns>true if the <see cref="T:System.Web.Compilation.ExpressionBuilder" /> supports expression evaluation; otherwise, false.</returns>
public override bool SupportsEvaluate {
get { return true; }
}
/// <summary>
/// When overridden in a derived class, returns an object that represents an evaluated expression.
/// </summary>
/// <param name="target">The object containing the expression.</param>
/// <param name="entry">The object that represents information about the property bound to by the expression.</param>
/// <param name="parsedData">The object containing parsed data as returned by <see cref="M:System.Web.Compilation.ExpressionBuilder.ParseExpression(System.String,System.Type,System.Web.Compilation.ExpressionBuilderContext)" />.</param>
/// <param name="context">Contextual information for the evaluation of the expression.</param>
/// <returns>
/// An object that represents the evaluated expression; otherwise, null if the inheritor does not implement <see cref="M:System.Web.Compilation.ExpressionBuilder.EvaluateExpression(System.Object,System.Web.UI.BoundPropertyEntry,System.Object,System.Web.Compilation.ExpressionBuilderContext)" />.
/// </returns>
public override object EvaluateExpression(object target, System.Web.UI.BoundPropertyEntry entry, object parsedData, System.Web.Compilation.ExpressionBuilderContext context)
{
if ((parsedData != null && object.ReferenceEquals(parsedData.GetType(), typeof(string)))) {
return GetRequestedValue(Convert.ToString(parsedData));
}
return base.EvaluateExpression(target, entry, parsedData, context);
}
/// <summary>
/// When overridden in a derived class, returns code that is used during page execution to obtain the evaluated expression.
/// </summary>
/// <param name="entry">The object that represents information about the property bound to by the expression.</param>
/// <param name="parsedData">The object containing parsed data as returned by <see cref="M:System.Web.Compilation.ExpressionBuilder.ParseExpression(System.String,System.Type,System.Web.Compilation.ExpressionBuilderContext)" />.</param>
/// <param name="context">Contextual information for the evaluation of the expression.</param>
/// <returns>
/// A <see cref="T:System.CodeDom.CodeExpression" /> that is used for property assignment.
/// </returns>
public override System.CodeDom.CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, System.Web.Compilation.ExpressionBuilderContext context)
{
CodeExpression[] inputParams = new CodeExpression[] { new CodePrimitiveExpression(entry.Expression.Trim()) };
return new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(this.GetType()), "GetRequestedValue", inputParams);
}
/// <summary>
/// Gets the requested value.
/// </summary>
/// <param name="expression">The expression.</param>
/// <returns></returns>
public static object GetRequestedValue(string expression)
{
string[] parts = expression.Split(new char[] { ',' }, 2, StringSplitOptions.None);
if ((parts.Length != 2)) {
throw new ArgumentException("Expression must contain ,");
}
string resourceFile = parts[0].Trim();
string resourceName = parts[1].Trim();
return mResourceManagers[resourceFile].GetString(resourceName);
}
}
Replace OneTypeInResourceAssembly with a type in the assembly containing the resources.
After that you can just add the following to web.config and it should just work..
<system.web>
<compilation>
<expressionBuilders>
<remove expressionPrefix="Resources" />
<add expressionPrefix="Resources" type="Assembly.ResourceExpressionBuilder" />
</expressionBuilders>
</compilation>
</system.web>

Resources