Zend router: combining a list of urls into a single or list - zend-framework

I have several urls:
/dave
/davina
/dave/chris
/davina/peter
I have entries for all of them in my routes, an example of this is:
routes.dave.route = /dave
routes.dave.defaults.module = default
routes.dave.defaults.controller = person
routes.rcp.defaults.action = index
routes.davina.route = /dave/chris
routes.davina.defaults.module = default
routes.davina.defaults.controller = person
routes.davina.defaults.action = index
I think you can see straight away that I have a duplication issue. Is there a way of combining multiple urls into a single route?
I have played around with using /:person but I also have other content aswell not going to person controller.
routes.person.route = /:personname
routes.person.defaults.module = default
routes.person.defaults.controller = person
routes.person.defaults.action = index
routes.person.reqs.personname = "^[a-zA-Z0-9]+$"
Urls such as /search?person=dave which goes off to the search controller is obviously being killed by the expression above.
Can I express the requirement as a list? "dave|davina|etc" or is there another magical zend method of doing this?
UPDATE:
I was playing around and came across this partial solution:
routes.person.route = /:personname
routes.person.defaults.module = default
routes.person.defaults.controller = person
routes.person.defaults.action = index
routes.person.reqs.personname = "(dave|davina)"
routes.person.route = /:person/:personname
routes.person.defaults.module = default
routes.person.defaults.controller = person
routes.person.defaults.action = index
routes.person.reqs.personname = "(chris|peter)"
I am going to run with this for the moment as is satisfies my requirements but I will leave this open(at least for a day) for anyone to offer there advice. The main issues is that both lists are going to grow, which will eventually cause an issue.

I think I may have the anwser for that.
In ZF, the routes are matched in reverse-order. So the last defined route, is the first matched.
In this case, you should define your /:person/:personname route, then define the others static routes like about page, contact page, etc.
If I understand Zend correctly, it should work. This do that in clear:
url=/about
match route "/about"
url=/david/parker
match route "/:person/:personname"
not "/about" or "/contact"

Related

QgsField won't accept parameter typeName

I'm trying to create new vector layer with the same fields as contained in original layer.
original_layer_fields_list = original_layer.fields().toList()
new_layer = QgsVectorLayer("Point", "new_layer", "memory")
pr = new_layer.dataProvider()
However, when I try:
for fld in original_layer_fields_list:
type_name = fld.typeName()
pr.addAttributes([QgsField(name = fld.name(), typeName = type_name)])
new_layer.updateFields()
QgsProject.instance().addMapLayer(new_layer)
I get a layer with no fields in attribute table.
If I try something like:
for fld in original_layer_fields_list:
if fld.type() == 2:
pr.addAttributes([QgsField(name = fld.name(), type = QVariant.Int)])
new_layer.updateFields()
QgsProject.instance().addMapLayer(new_layer)
... it works like charm.
Anyway ... I'd rather like the first solution to work in case if one wants to automate the process and not check for every field type and then find an appropriate code. Besides - I really am not able to find any documentation about codes for data types. I managed to find this post https://gis.stackexchange.com/questions/353975/get-only-fields-with-datatype-int-in-pyqgis where in comments Kadir pointed on this sourcecode (https://codebrowser.dev/qt5/qtbase/src/corelib/kernel/qvariant.h.html#QVariant::Type).
I'd really be thankful for any kind of direction.

ag-Grid set filter and sort model without triggering event

I am updating sort & filter models via api:
this.gridApi.setFilterModel(filterModels);
this.gridApi.setSortModel(sortModels);
The problem with this is I have a server request bound to the change even of both sort & filter so when user changes then the data is updated. This means when I change model on code like restoring a state or resetting the filters it causes multiple requests.
Is there a way to update the filter/sort model without triggering the event?
I see there is a ColumnEventType parameter but couldn't see how it works. Can I specify some variable that I can look for inside my event handlers to get them to ignore calls that are not generated from user?
I am trying to manage URL state so when url query params change my code sets the models in the grids but this ends up causing the page to reload multiple times because the onFilter and onSort events get called when the model is set and there is no way I can conceive to prevent this.
At the time, you are going to have to manage this yourself, ie, just before you call the setModel, somehow flag this in a shared part of your app (maybe a global variable)
Then when you react to these events, check the estate of this, to guess where it came from.
Note that at the moment, we have added source to the column events, but they are not yet for the model events, we are planning to add them though, but we have no ETA
Hope this helps
I had to solve similar issue. I found solution which working for my kind of situation. Maybe this help someone.
for (let j = 0; j < orders.length; j++) {
const sortModelEntry = orders[j];
if (typeof sortModelEntry.property === 'string') {
const column: Column = this.gridColumnApi.getColumn(sortModelEntry.property);
if (column && ! column.getColDef().suppressSorting) {
column.setSort(sortModelEntry.direction.toLowerCase());
column.setSortedAt(j);
}
}
this.gridApi.refreshHeader();
Where orders is array of key-value object where key is name of column and value is sorting directive (asc/desc).
Set filter without refresh was complicated
for (let j = 0; j < filters.length; j++) {
const filterModelEntry = filters[j];
if (typeof filterModelEntry.property === 'string') {
const column: Column = this.gridColumnApi.getColumn(filterModelEntry.property);
if (column && ! column.getColDef().suppressFilter) {
const filter: any = this.gridApi.getFilterApi(filterModelEntry.property);
filter['filter'] = filterModelEntry.command;
filter['defaultFilter'] = filterModelEntry.command;
filter['eTypeSelector'].value = filterModelEntry.command;
filter['filterValue'] = filterModelEntry.value;
filter['filterText'] = filterModelEntry.value;
filter['eFilterTextField'].value = filterModelEntry.value;
column.setFilterActive(true);
}
}
}
Attributes in filter:
property - name of column
command - filter action (contains, equals, ...)
value - value used in filter
For anyone else looking for a solution to this issue in Nov 2020, tapping into onFilterModified() might help. This gets called before onFilterChanged() so setting a value here (eg. hasUserManuallyChangedTheFilters = false, etc.) and checking the same in the filter changed event is a possible workaround. Although, I haven't found anything similar for onSortChanged() event, one that gets called before the sorting is applied to the grid.
I am not sure any clean way to achieve this but I noticed that FilterChangedEvent has "afterFloatingFilter = false" only if filterModel was updated from ui.
my workaround is as below
onFilterChanged = event:FilterChangedEvent) => {
if(event.afterFloatingFilter === undefined) return;
console.log("SaveFilterModel")
}

How to read UnitPrice from invoice line in QBO API v3 .NET

The bizarre properties in the .NET SDK continue to baffle me. How do I read the UnitPrice from an invoice line?
If I do this:
sild = (SalesItemLineDetail)line.AnyIntuitObject;
ln = new QBInvoiceLine(); // My internal line item class
ln.Description = line.Description;
ln.ItemRef = new QBRef() { Id = sild.ItemRef.Value, Name = sild.ItemRef.name };
if (sild.QtySpecified)
ln.Quantity = sild.Qty;
else
ln.Quantity = 0;
if (sild.ItemElementName == ItemChoiceType.UnitPrice)
ln.Rate = (decimal)sild.AnyIntuitObject; // Exception thrown here
The last line throws an invalid cast exception, even though the debugger shows that the value is 20. I've tried other types but get the same exception no matter what I do. So I finally punted and am calculating the rate like so:
ln.Rate = line.Amount / ln.Quantity;
(With proper rounding and checking for divide by zero, of course)
While we're on the subject... I noticed that in many cases ItemElementName == ItemChoiceType.PriceLevelRef. What's up with that? As far as I know, QBO doesn't support price levels, and I certainly wasn't using a price level with this invoice or customer. In this case I was also able to get what I needed from the Amount property.
Try this-
SalesItemLineDetail a1 = (SalesItemLineDetail)invoice11.Line[0].AnyIntuitObject;
object unitprice = a1.AnyIntuitObject;
decimal quantity = a1.Qty;
PriceLevelRef as an 'entity' is not supported. This means CRUD operations are not supported on this entity.
The service might however be returning readonly values in the transactions sometimes, but since this not mentioned in the docs, please consider it as unsupported.
Check that both request/response are in either json or xml format-
You can use the following code to set that-
ServiceContext context = new ServiceContext(appToken, realmId, intuitServiceType, reqvalidator);
context.IppConfiguration.Message.Request.SerializationFormat = Intuit.Ipp.Core.Configuration.SerializationFormat.Json;
context.IppConfiguration.Message.Response.SerializationFormat = Intuit.Ipp.Core.Configuration.SerializationFormat.Json;
Also, in QBO UI, check if Company->sales settings has Track Quantity and Price/rate turned on.

How to filter AssetType from AssetEntry in liferay 6.1?

I used the following code to retrieve all the journal articles based on a specific category:
long catId = category.getCategoryId();
AssetEntryQuery assetEntryQuery = new AssetEntryQuery();
long[] anyCatIds = {catId};
assetEntryQuery.setAnyCategoryIds(anyCatIds);
// Line A
List<AssetEntry> assetEntryList = AssetEntryLocalServiceUtil.getEntries(assetEntryQuery);
for(AssetEntry ae : assetEntryList)
{
// Line B
JournalArticleResource journalArticleResourceObj = JournalArticleResourceLocalServiceUtil.getJournalArticleResource(ae.getClassPK());
JournalArticle journalArticleObj = JournalArticleLocalServiceUtil.getArticle(themeDisplay.getParentGroupId(), journalArticleResourceObj.getArticleId());
journalArticleList.add(journalArticleObj.getArticleId());
}
Howver, since the AssetEntry will fetch all the entries, including Blogs, and so on, the above code will throw an exception at Line B if I add a blog entry that uses the same category, since the blog entry does not have JournalArticleResource.
So, I was wondering if it is possible to filter only JournalArticle type will be fetch at Line A, then I don't have to worry about Line B anymore.
I have tried but no luck so far.
Does any one have some ideas?
Use assetEntryQuery.setClassName(JournalArticle.class.getName());

How to change WCF Binding and Endpoint properties using AutofacServiceHostFactory

I would like to increase the MaxBufferSize, MaxBufferPoolSize, ReceivedMessageSize, along with the readerQuotas maxDepth="2147483646" maxStringContentLength="2147483646" maxArrayLength="2147483646" maxBytesPerRead="2147483646" maxNameTableCharCount="2147483646", It is my understanding that I must change these parameters in the registration process. But I see no examples anywhere on doing this.
I would appreciate any help on this matter.
Don't know if you found an answer to this or not but it would look something like this:
builder.Register(
container =>
new ChannelFactory<TService>(
new WSHttpBinding { TransactionFlow = supportTransactionFlow,
MaxReceivedMessageSize = 2147483646,
ReaderQuotas = {
MaxStringContentLength = 2147483646,
MaxDepth = 2147483646,
MaxArrayLength= 2147483646 }},
endpointAddress)).InstancePerDependency();