ZendAMF 1.11 and the missing source - arraycollection

We are trying to upgrade from an older version of Zend Framework to the most recent one (1.11).
We have to send some ArrayCollections to a Flex-app that I can not access. Previous versions of ZF's Zend_Amf_Value_Messaging_ArrayCollection have a source attribute which the newer versions don't have.
I have tried editing the Zend_Amf_Value_Messaging_ArrayCollection class to have that source property, but it seems like ZF doesn't send objects to the Flex-app (I've noticed that via a debugging proxy). The ArrayCollection still has the correct keys (AFAIK, going from 0 -> 3), but the values are NULL.
This is from a small test-file:
$c = new RoomCategoryVO();
$c->name = 'root';
$c->childCategories = new Zend_Amf_Value_Messaging_ArrayCollection();
$cc1 = new RoomCategoryVO();
$cc1->sortPriority = 2;
$cc1->name = $this->xml->roomService->windows;
$cc1->parentCategory = $c;
$cc1->childItems = new Zend_Amf_Value_Messaging_ArrayCollection();
$re11 = new ElementVO();
$re11->id = "simpleWindow";
$re11->name = $this->xml->roomService->window;
$re11->type = 'SIMPLE_WINDOW';
$re11->icon = 'assets/runtime/images/schemeIcons/simpleWindow.png';
//$cc1->childItems->source[] = $re11;
$cc1->childItems[] = $re11;
//$c->childCategories->source[] = $cc1;
$c->childCategories->append($cc1);
In comments you see the 'old' way of ZendAMF, below them the new way.
Is there any way to get ZendAMF use the source property again without going back to an older version of ZF?

We finally settled on using ZendAMF, with only the Zend_Amf_Value_Messaging_ArrayCollection from the previous version being:
class Zend_Amf_Value_Messaging_ArrayCollection
{
public $source;
}
This allows us still using the source property.

Related

Can't preserve document core metadata (Created By, Modified By) when I import documents to SharePoint Document Library

I'm currently building a tool to migrate from a document management system to use SharePoint Online. The main challenge I'm facing is to preserve the details of document authors and creating time. I have checked bunch of of code online but I didn't get success with any of them.
Here are the approaches I used
SharePoint Rest API
Microsoft Graph API
CSOM (using console application)
Here is the code I have so far in CSOM but I'm still not able to update the Author field
li["Title"] = "Update from CSOM";
li["Created"] = DateTime.Now.AddYears(-5);
li["Author"] = author.Id;
li.UpdateOverwriteVersion();
clientContext.ExecuteQuery();
Any idea for how to do this, or if there is any other approach to achieve my goal?
The code works when I did test in my environment.
using (ClientContext context = new ClientContext("https://xxx.sharepoint.com/sites/lee"))
{
string s = "password";
SecureString passWord = new SecureString();
foreach (var c in s)
passWord.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials("admin#xxx.onmicrosoft.com", passWord);
var author = context.Web.EnsureUser("Lee#xxx.onmicrosoft.com");
context.Load(author);
context.ExecuteQuery();
var _List = context.Web.Lists.GetByTitle("List1");
var li = _List.GetItemById(1);
li["Title"] = "Update from CSOM";
li["Created"] = DateTime.Now.AddYears(-5);
li["Author"] = author.Id;
li.UpdateOverwriteVersion();
context.ExecuteQuery();
}
You will need to update the Author and Editor fields at the same time in order to update the CreatedBy field. If you wish to update additional fields at the same time you can. Using SystemUpdate() does not update the Modified date whereas Update() does update the Modified date. See abbreviated sample below.
FieldUserValue userValue = new FieldUserValue();
User newUser = cc.Web.EnsureUser("newAuthor#xxx.onmicrosoft.com");
cc.Load(newUser);
cc.ExecuteQuery();
userValue.LookupId = newUser.Id;
item["Author"] = userValue;
item["Editor"] = userValue;
item.SystemUpdate();
cc.ExecuteQuery();

Open a libreoffice mail merged textdocument directly with swriter

I need help with opening the result of my mail merge operations directly in an new writer document.
Object mailMergeService = mcf.createInstanceWithContext(mailMergePackage, context);
XPropertySet mmProperties = UnoRuntime.queryInterface(XPropertySet.class, mailMergeService);
mmProperties.setPropertyValue("DocumentURL", templatePath);
mmProperties.setPropertyValue("DataSourceName", dbName);
mmProperties.setPropertyValue("CommandType", mmCommandType);
mmProperties.setPropertyValue("Command", mmCommand);
mmProperties.setPropertyValue("OutputType", mmOutputType);
// mmProperties.setPropertyValue("OutputURL", templateDirectory);
// mmProperties.setPropertyValue("FileNamePrefix", mmFileNamePrefix);
// mmProperties.setPropertyValue("SaveAsSingleFile", mmSaveAsSingleFile);
The mmOutputType is set as MailMergeType.SHELL
The LibreOffice API documentation says
"The output is a document shell.
The successful mail marge returns a XTextDocument based component."
So I've tried something like this
XJob job = UnoRuntime.queryInterface(XJob.class, mailMergeService);
Object mergedTextObject = job.execute(new NamedValue[0]);
String url = "private:factory/swriter";
loader.loadComponentFromURL(url, "_blank", 0, new PropertyValue[0]);
XTextDocument mergedText = UnoRuntime.queryInterface(XTextDocument.class, mergedTextObject);
XTextCursor cursor = mergedText.getText().createTextCursor();
cursor.setString(mergedText.getText().getString());
I guess I have to pass the XTextDocument component to the url-argument of the loadComponentFromURL method but I didnt find the right way to do that.
When I change the OutputType to MailMergeType.FILE the result is generated in a given directory and I can open the file and see that the mail merge succeeded. But this is not what my application should do.
Does someone know how I can open the result of the mail merge directly in an new writer document without saving the result to the hard drive?
Sincerly arthur
Hey guys I've found a simple way to open the result of my mail merge process directly.
The relevant snippets are these
XJob job = UnoRuntime.queryInterface(XJob.class, mailMergeService);
Object mergedTextObject = job.execute(new NamedValue[0]);
XTextDocument mergedText = UnoRuntime.queryInterface(XTextDocument.class, mergedTextObject);
mergedText.getCurrentController().getFrame().getContainerWindow().setVisible(true);
The last line of code made the window appear with the filled mail merge result.
I also don't need this line anymore
loader.loadComponentFromURL("private:factory/swriter", "_blank", 0, new PropertyValue[0]);
The document opens as a new instance of a swriter document. If you want to save the result as a file you can do this
mergedText.getCurrentController().getFrame().getContainerWindow().setVisible(true);
XStorable storeMM = UnoRuntime.queryInterface(XStorable.class, mergedText);
XModel modelMM = UnoRuntime.queryInterface(XModel.class, mergedText);
storeMM.storeAsURL(outputDirectory + outputFilename, modelMM.getArgs());
Sincerly
Arthur
What version of LO are you using? The SHELL constant has only been around since LO 4.4, and it is not supported by Apache OpenOffice yet, so it could be that it isn't fully implemented. However this code seems to show a working test.
If it is returning an XTextDocument, then normally I would assume the component is already open. However it sounds like you are not seeing a Writer window appear. Did you start LO in headless mode? If not, then maybe the process needs a few seconds before it can display.
Object mergedTextObject = job.execute(new NamedValue[0]);
Thread.sleep(10000);
Anyway to me it looks like your code has a mistake in it. These two lines would simply insert the text onto itself:
XTextCursor cursor = mergedText.getText().createTextCursor();
cursor.setString(mergedText.getText().getString());
Probably you intended to write something like this instead:
XTextDocument mergedText = UnoRuntime.queryInterface(XTextDocument.class, mergedTextObject);
String url = "private:factory/swriter";
XComponent xComponent = loader.loadComponentFromURL(url, "_blank", 0, new PropertyValue[0]);
XTextDocument xTextDocument = (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class, xComponent);
XText xText = (XText)xTextDocument.getText();
XTextRange xTextRange = xText.getEnd();
xTextRange.setString(mergedText.getText().getString());
One more thought: getString() might just return an empty string if the entire document is in a table. If that is the case then you could use the view cursor or enumerate text content.
EDIT:
To preserve formatting including tables, you can do something like this (adapted from https://blog.oio.de/2010/10/27/copy-and-paste-without-clipboard-using-openoffice-org-api/):
// Select all.
XController xMergedTextController = mergedText.getCurrentController();
XTextViewCursorSupplier supTextViewCursor =
(XTextViewCursorSupplier) UnoRuntime.queryInterface(
XTextViewCursorSupplier.class, xMergedTextController);
XTextViewCursor oVC = supTextViewCursor.getViewCursor();
oVC.gotoStart(False) // This would not work if your document began with a table.
oVC.gotoEnd(True)
// Copy and paste.
XTransferableSupplier xTransferableSupplier = UnoRuntime.queryInterface(XTransferableSupplier.class, xMergedTextController);
XTransferable transferable = xTransferableSupplier.getTransferable();
XController xController = xComponent.getCurrentController();
XTransferableSupplier xTransferableSupplier_newDoc = UnoRuntime.queryInterface(XTransferableSupplier.class, xController);
xTransferableSupplier_newDoc.insertTransferable(transferable);

Umbraco: Update Property on specific member

I'm running a forum with Umbraco 7, and I wish to update a property on a specific member by hes Id.
This is what I tried:
var authorId = Model.Content.GetPropertyValue<int>("postAuthor", 0);
var author = Members.GetById(authorId);
umbraco.cms.businesslogic.member.Member member = umbraco.cms.businesslogic.member.Member.GetMemberFromEmail(author.GetPropertyValue("email").ToString());
member.getProperty("postCounter").Value = Convert.ToInt32(member.getProperty("postCounter")) + 1;
member.Save();
But this dont work and the line below throws this error:
umbraco.cms.businesslogic.member.Member member = umbraco.cms.businesslogic.member.Member.GetMemberFromEmail(author.GetPropertyValue("email").ToString());
It says: Warning: umbraco.cms.businesslogic.member.Member is obsolete: "Use the MemberService and the Umbraco.Core.Models.Member models instead"
Can someone help me solve this?
var memberService = ApplicationContext.Current.Services.MemberService
var member = memberService.GetById(authorId)
member.SetValue("postCounter", newValue);
memberService.Save(member);
Never, ever do this though!!
You need to store counts like this that update really frequently in your own separate table as each time you save a piece of content (and yes, the member object is basically a piece of content as well) you will save a new version in the versions table. All of your custom properties will also be saved again with the new version. Also this is a fairly database-intense operation which is completely unnecessary, just have a table with two columns: the memberId and the count and you're done and it's all very lean and performant.
If you are in razor script you want to do something like:
var authorId = Model.Content.GetPropertyValue<int>("postAuthor", 0);
var ms = ApplicationContext.Current.Services.MemberService;
var member = ms.GetById(authorId);
member.SetValue("postCounter",member.GetValue("postCounter"));
But as sebastian says you probably want to do it differently for performance

Breeze and extraMetadata

I have a strange behavior regarding the extraMetadata (I am using OData)
1. I have created a clone function - I am creating new manager and importing into in an entity which I perform the operation
ctor.prototype.clone = function() {
var clonedManager = this.entityAspect.entityManager.createEmptyCopy(),
exportData = this.entityAspect.entityManager.exportEntities([this], true), //export it to the new manager
cloned;
clonedManager.importEntities(exportData);
cloned = clonedManager.getEntityByKey(this.entityAspect.getKey());
return cloned;
};
how ever I had to add
cloned.entityAspect.extraMetadata = this.entityAspect.extraMetadata;
cause I saw that it isn't being exported/imported
when I get entities using expand, those entities don't hold extraMetadata;
and without the extraMetadata I cannot commit the changes - as I get exception
As of BreezeJs version 1.4.13, available now, this has been fixed.

Rails seeds.db not saving relationships

When I try to use the db/seeds.rb file to prepopulate the database, my code looks like:
now = Time.now.beginning_of_hour
later = Time.now.end_of_hour + 1
sch1 = Schedule.create(start_time: now, stop_time: later)
sch1.channel = channel
sch1.program = cartoon
cartoon.schedules.push(sch1)
sch1.save
cartoon.save
where channel and cartoon are defined earlier in the code with a Channel.create and Program.create with appropriate values.
When I look in the rails console, I see that all three objects (channel, program and schedule) exist, but that no schedule has no program_id. (schedule.program works just fine for some reason). A program's program.schedules is an empty array as well.
As a test, I did the following in the console:
now = Time.now.beginning_of_hour
later = Time.now.end_of_hour + 1
channel = Channel.first
cartoon = Program.first
sch1 = Schedule.create(start_time: now, stop_time: later)
sch1.channel = channel
sch1.program = cartoon
cartoon.schedules.push(sch1)
sch1.save
cartoon.save
and that worked just fine.
What is special about seeds? Do I need to call save before referencing it later or something? the variable is clearly not null...

Resources