All i want to do is display the full path of my Taxonomy field....Simple!
I've added this little snippet of XML to my <ArrayOfProperty> within the field i want to apply this property to.
<Property>
<Name>IsPathRendered</Name>
<Value xmlns:q7="http://www.w3.org/2001/XMLSchema" p4:type="q7:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">true</Value>
</Property>
All the settings of the field seems to be applied, I've checked via the GUI and SharePoint mananger and it seems to be applied!
However the does not show the full path....
When i go in to the GUI and save the field all works !?!?!?!
My question is why do i have to go in after my deployment and save the field to get this setting to apply?
Although I also would like to know how to do this in XML, there is an alternative: you can handle it in a feature receiver by setting the IsPathRendered property on a TaxonomyField instance.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using (SPSite site = (SPSite)properties.Feature.Parent)
{
Guid fieldId = new Guid("{YOUR-FIELD'S-GUID-GOES-HERE}");
TaxonomyField field = site.RootWeb.Fields[fieldId] as TaxonomyField;
// Render full taxonomy path, not just the leaf.
field.IsPathRendered = true;
field.Update();
}
}
Related
I have a custom module getting executed right after the PDFGenerator finished. I followed this guide on how to create a custom module
https://stackoverflow.com/a/55799101/9945420
When processing a batch document I want to manipulate the generated PDF file and add a footer to that file. The content of that footer needs to get configured in the Administration module.
So within my project called "StampOnScanProcess" I added a Folder called "Setup" with two files. A Form called "FrmSetup"
public partial class FrmSetup : Form
{
private IBatchClass batchClass;
public FrmSetup()
{
InitializeComponent();
}
public DialogResult ShowDialog(IBatchClass batchClass)
{
this.batchClass = batchClass;
// Load previous Settings ...
return this.ShowDialog();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnSave_Click(object sender, EventArgs e)
{
// Save ...
this.Close();
}
}
and a UserControl called "UserCtrlSetup"
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISetupForm
{
[DispId(1)]
AdminApplication Application { set; }
[DispId(2)]
void ActionEvent(int EventNumber, object Argument, out int Cancel);
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId(CUSTOM_MODULE_NAME_SETUP)]
public partial class UserCtrlSetup : UserControl, ISetupForm
{
private const string CUSTOM_MODULE_NAME_SETUP = "StampOnScanProcess.Setup";
private AdminApplication adminApplication;
public AdminApplication Application
{
set
{
value.AddMenu(CUSTOM_MODULE_NAME_SETUP, CUSTOM_MODULE_NAME_SETUP, "BatchClass");
adminApplication = value;
}
}
public void ActionEvent(int EventNumber, object Argument, out int Cancel)
{
Cancel = 0;
if ((KfxOcxEvent)EventNumber == KfxOcxEvent.KfxOcxEventMenuClicked && (string)Argument == CUSTOM_MODULE_NAME_SETUP)
{
FrmSetup form = new FrmSetup();
form.ShowDialog(adminApplication.ActiveBatchClass);
}
}
}
I modified my registration file and added the setup form to it
[Modules]
StampOnScanProcess
[StampOnScanProcess]
RuntimeProgram=StampOnScanProcess.exe
ModuleID=StampOnScanProcess.exe
Description=...
Version=10.2
SupportsNonImageFiles=True
SupportsTableFields=True
SetupProgram=StampOnScanProcess.Setup
[Setup Programs]
StampOnScanProcess.Setup
[StampOnScanProcess.Setup]
Visible=0
OCXFile=StampOnScanProcess.exe
ProgID=StampOnScanProcess.Setup
When launching the Administration module I head over to the Batch Class Properties => Queues and want to call this setup form by clicking the Properties button in the middle.
Unfortunately the properties button is disabled so I can't open the setup form. This form gets added to the context menu of the batch class
How can I bind this form to the properties button instead? And what is the best way to store configured data and access it when the runtime application gets executed?
I need to think about how to store data because some users have user profiles
and the runtime application currently logs in with no credentials.
public void LoginToRuntimeSession()
{
login = new Login();
login.EnableSecurityBoost = true;
login.Login();
login.ApplicationName = CUSTOM_MODULE_ID;
login.Version = "1.0";
login.ValidateUser($"{CUSTOM_MODULE_ID}.exe", false, "", "");
session = login.RuntimeSession;
}
So it might happen that I have to store the credentials on setup too.
How can I bind this form to the properties button instead?
All interactions with menu entries are handled by ISetupForm.ActionEvent. New entries are added with the AddMenu method of the AdminApplication object. Kofax differentiates between multiple entries by name - imagine that you could have multiple menu entries at the same time, one on batch class level, another one on document class level, and another one in the ribbon - just to name a few examples. Kofax uses the same approach in any component that integrates into Administration (e.g. Custom Modules or Workflow Agents).
This is an example from one of our components. Note that three entries are added on BatchClass level and two more on DocumentClass level.
value.AddMenu("BatchClass.GeneralConfig", "Field Panel - General Configuration", "BatchClass");
value.AddMenu("BatchClass.FieldEditor", "Field Panel - Configure Batch Fields", "BatchClass");
value.AddMenu("DocumentClass.FieldEditor", "Field Panel - Configure Index Fields", "DocumentClass");
value.AddMenu("CopyBatchFieldConfig", "Field Panel - Copy Batch Field Configuration", "BatchClass");
value.AddMenu("PasteBatchFieldConfig", "Field Panel - Paste Batch Field Configuration", "BatchClass");
value.AddMenu("CopyIndexFieldConfig", "Field Panel - Copy Index Field Configuration", "DocumentClass");
value.AddMenu("PasteIndexFieldConfig", "Field Panel - Paste Index Field Configuration", "DocumentClass");
Each entry is no identified by its event text, the first parameter. For example, BatchClass.GeneralConfig is intended to open up a generic configuration dialog - on batch class level.
Now, back to our ActionEvent - this is how I distinguish between the entry selected by the user:
if ((KfxOcxEvent)EventNumber == KfxOcxEvent.KfxOcxEventMenuClicked)
{
AdminForm form = new AdminForm();
switch ((string)Argument)
{
case "BatchClass.GeneralConfig":
ConfigureGeneral(kcApp.ActiveBatchClass);
break;
[I] want to call this setup form by clicking the Properties button in
the middle.
I don't know if you can use this button - I would assume yes - yet personally I tend to put settings either on batch or document class level. For example - your PDF annotation settings may different from document class to class - having an entry on this level seems more natural.
And what is the best way to store configured data and access it when
the runtime application gets executed?
Custom Storage Strings, and you can let your imagination run wild here. The most simplistic approach is to store key-value pairs during setup, and retrieve them in runtime. Here's a generic call (BatchClass is an IBatchClass object, i.e. a pointer to the ActiveBatchClass property of the AdminApplication object):
// set a CSS
BatchClass.set_CustomStorageString(name, value);
// get a CSS
BatchClass.get_CustomStorageString(name)
I usually use a single custom storage string only and store custom object - the object is a base64-encoded serialized XML using XmlSerializer - but again, that's up to you. The only recommendation is to rely on CSS only - don't use external files to store configuration parameters. A CSS is an integral part of your batch class - so, when exporting said class and importing it on a different system, your entire configuration will be there.
I need to think about how to store data because some users have user
profiles
Usually, you don't need to worry about that. The properties for user and password in ValidateUser are entirely optional - and since you're planning to write an unattended module - ideally a Windows Service, credentials should be maintained there. Kofax and Windows would automatically make sure the credentials are passed on, and your module will run under this user's context. Just make sure the user has permissions for the module and all associated batch classes. It's different if you're planning to write an attended module, for example an enhanced Validation module.
I have a customization to the Employee Timecard Entry screen (EP305000) which enables the Excel upload functionality into the Details tab grid. I did this by adding the attribute [PXImport(typeof(EPTimeCard))] to the 'Activities' view re-declaration in a TimeCardMaint BLC extension as follows:
[PXImport(typeof(EPTimeCard))]
[PXViewName(PX.Objects.EP.Messages.TimeCardDetail)]
public PXSelectJoin<EPTimecardDetail,
InnerJoin<CREmployee,
On<CREmployee.userID, Equal<EPTimecardDetail.ownerID>>,
LeftJoin<CRActivityLink,
On<CRActivityLink.noteID, Equal<EPTimecardDetail.refNoteID>>,
LeftJoin<CRCase,
On<CRCase.noteID, Equal<CRActivityLink.refNoteID>>,
LeftJoin<PX.Objects.AR.Customer,
On<PX.Objects.AR.Customer.bAccountID, Equal<CRCase.customerID>>,
LeftJoin<PX.Objects.EP.TimeCardMaint.ContractEx,
On<PX.Objects.EP.TimeCardMaint.ContractEx.contractID, Equal<CRCase.contractID>>,
LeftJoin<PMProject,
On<PMProject.contractID, Equal<EPTimecardDetail.projectID>>>>>>>>,
Where<CREmployee.bAccountID, Equal<Current<EPTimeCard.employeeID>>,
And<EPTimecardDetail.weekID, Equal<Current<EPTimeCard.weekId>>,
And<EPTimecardDetail.trackTime, Equal<True>,
And<EPTimecardDetail.approvalStatus, NotEqual<ActivityStatusListAttribute.canceled>,
And<Where<EPTimecardDetail.timeCardCD, IsNull, Or<EPTimecardDetail.timeCardCD, Equal<Current<EPTimeCard.timeCardCD>>>>>>>>>,
OrderBy<Asc<EPTimecardDetail.date>>> Activities;
I also set the 'AllowImport' property of the grid to 'True'. This seems to work ok, except that the 'ProjectTask' field of the upload does not allow mapping - i.e., if you go through the import process, when you get to the field mapping part, you can't map the Excel field for ProjectTask to the grid's ProjectTask. It just doesn't show up.
Would this be because the source BLC has as delegate method for 'activities' that I didn't reproduce in my extension?
What could be the reason for not allowing mapping to the ProjectTask field?
Since the ProjectTask field is disabled by default, this was solved by adding a parameter to the [ProjectTask] attribute, called "AlwaysEnabled" via the CacheAttached event, as shown below:
public class TimeCardMaint_Extension : PXGraphExtension<TimeCardMaint>
{
[PXDefault(typeof(Search<PMTask.taskID, Where<PMTask.projectID, Equal<Current<TimeCardMaint.EPTimecardDetail.projectID>>, And<PMTask.isDefault, Equal<True>>>>), PersistingCheck = PXPersistingCheck.Nothing)]
[ProjectTask(typeof(TimeCardMaint.EPTimecardDetail.projectID),
BatchModule.TA,
DisplayName = "Project Task",
BqlField = typeof(PMTimeActivity.projectTaskID),
AlwaysEnabled = true)]
protected virtual void EPTimecardDetail_ProjectTaskID_CacheAttached(PXCache cache)
{
}
Good day!
In my Orchard, I have several content types all with my custom part attached. This part defines to what users this content is available. For each logged user there is external service, which defines what content user can or cannot access. Now I need access restriction to apply everywhere where orchard display content lists, this includes results by specific tag from a tag cloud, or results listed from Taxonomy term. I seems can’t find any good way to do it except modifying TaxonomyServices code as well as TagCloud services, to join also my part and filter by it. Is this indeed the only way to do it or there are other solutions? I would like to avoid doing changes to built-in modules if possible but cannot find other way.
Thanks in advance.
I'm currently bumbling around with the same issue. One way I'm currently looking at is to hook into the content manager.
[OrchardSuppressDependency("Orchard.ContentManagement.DefaultContentManager")]
public class ModContentManager : DefaultContentManager, IContentManager
{
//private readonly Lazy<IShapeFactory> _shapeFactory;
private readonly IModAuthContext _modAuthContext;
public ModContentManager(IComponentContext context,
IRepository<ContentTypeRecord> contentTypeRepository,
IRepository<ContentItemRecord> contentItemRepository,
IRepository<ContentItemVersionRecord> contentItemVersionRepository,
IContentDefinitionManager contentDefinitionManager,
ICacheManager cacheManager,
Func<IContentManagerSession> contentManagerSession,
Lazy<IContentDisplay> contentDisplay,
Lazy<ISessionLocator> sessionLocator,
Lazy<IEnumerable<IContentHandler>> handlers,
Lazy<IEnumerable<IIdentityResolverSelector>> identityResolverSelectors,
Lazy<IEnumerable<ISqlStatementProvider>> sqlStatementProviders,
ShellSettings shellSettings,
ISignals signals,
//Lazy<IShapeFactory> shapeFactory,
IModAuthContext modAuthContext)
: base(context,
contentTypeRepository,
contentItemRepository,
contentItemVersionRepository,
contentDefinitionManager,
cacheManager,
contentManagerSession,
contentDisplay,
sessionLocator,
handlers,
identityResolverSelectors,
sqlStatementProviders,
shellSettings,
signals) {
//_shapeFactory = shapeFactory;
_modAuthContext = modAuthContext;
}
public new dynamic BuildDisplay(IContent content, string displayType = "", string groupId = "") {
// So you could do something like...
// var myPart = content.As<MyAuthoPart>();
// if(!myPart.IsUserAuthorized)...
// then display something else or display nothing (I think returning null works for this but
//don't quote me on that. Can always return a random empty shape)
// else return base.BuildDisplay(content, displayType, groupId);
// ever want to display a shape based on the name...
//dynamic shapes = _shapeFactory.Value;
}
}
}
Could also hook into the IAuthorizationServiceEventHandler, which is activated before in the main ItemController and do a check to see if you are rendering a projection or taxonomy list set a value to tell your content manager to perform checks else just let them through. Might help :)
"Cannot save all of the property settings for this Web Part. The
default namespace "http://schemas.microsoft.com/WebPart/v2" is a
reserved namespace for base Web Part properties. Custom Web Part
properties require a unique namespace (specified through an
XmlElementAttribute on the property, or an XmlRootAttribute on the
class)."
No where do I get help regarding this error.
This is when adding custom properties to my webpart, why cant I save the properties when I edit my webpart and click on save/apply? (then I get that error)
Code--
[DefaultProperty("Text"), ToolboxData("<{0}:CustomPropertyWebPart runat=server></{0}:CustomPropertyWebPart>"),
XmlRoot(Namespace = "ExecuteStoreProc")]
public class CustomPropertyWebPart : Microsoft.SharePoint.WebPartPages.WebPart
{
const string c_MyStringDefault = "Sample String";
}
// Create a custom category in the property sheet.
[Category("Custom Properties")]
// Assign the default value.
[DefaultValue(c_MyStringDefault)]
// Property is available in both Personalization
// and Customization mode.
[WebPartStorage(Storage.Personal)]
// The caption that appears in the property sheet.
[FriendlyNameAttribute("Custom String")]
// The tool tip that appears when pausing the mouse pointer over
// the friendly name in the property pane.
[Description("Type a string value.")]
// Display the property in the property pane.
[Browsable(true)]
[XmlElement(ElementName = "MyString")]
// The accessor for this property.
public string MyString
{
get
{
return _myString;
}
set
{
_myString = value;
}
}
Can you try going to Site Settings > Galleries > Web Part > New
In that window, put a checkbox next to the webpart you are trying to add, then click Populate
If its populate correctly then it is working otherwise there is some error in the webpart.
Return to your webpage where you want to add the webpart, try to add the webpart by selecting it in the gallery.
If this works (you were able to add it to your page), you can open the webpart added in your webpart gallery (Site Settings > Galleries > Web Part) and compare it to your own .dwp file to see what you did wrong.
Hope this helps
I am trying to add fields to com.liferay.portal.model.User, an extra attribute using Expando. Can someone explain to me how this method is adding a field because docs don't have much description.
private void addUserCustomAttribute(long companyId, ExpandoTable userExpandoTable, String attributeName, int type) throws PortalException, SystemException {
ExpandoColumnLocalServiceUtil.getColumn(userExpandoTable.getTableId(), attributeName); //should be addColumn(long tableId, String name, int type) ???
} //and where can find type description couse i have very specific type, Map(String,Object) couse in ExpandoColumnConstants didn't see it
I have taken this from Liferay Expando Wiki's Adding User Custom Attributes.
When should I call this all? Where to put this in my project? What change is required or everything needs to be changed to call it.
Some good tutorial will be nice because it's hard to find something from 0 to end, always found only some part with no explanation.
The question is not very clear. But if you simply want to add a custom attribute for your User then you can refer to my answer here and reproduced for your reference:
Custom field for the user-entity can be created through:
Control Panel -> Portal -> Custom Fields -> User.
And programmatically can be created as follows:
user.getExpandoBridge().addAttribute("yourCustomFieldKey");
Then set the value as:
user.getExpandoBridge().setAttribute("yourCustomFieldKey", "valueForCustomField");
If your custom field is already present you can check like this:
if (user.getExpandoBridge().hasAttribute("yourCustomFieldKey")) { ... };
The data is stored in tables prefixed with "EXPANDO":
EXPANDOCOLUMN: stores the custom field key and other settings
(contains the tableId refrences)
EXPANDODATA: stores the custom field value for the key (contains the
columnId and tableId refrences)
EXPANDOTABLE: stores for which liferay entity (user) are you adding
the custom field
EXPANDOROW: stores linking information between a user and its values
(contains tableId and userId refrences)
Hope this helps.
If your custom field is multivalue, you can use this:
String customVal = "yourCustomFieldValue";
user.getExpandoBridge().setAttribute("yourCustomFieldKey", new String[] {customVal }, false);
The last parameter set to "false" avoids permission check.