How to properly set onDeleteAssociationPolicy? - alfresco

I have custom content type, which has target association. I want to set up a policy, which perform some action, when association is removed. I wrote this policy as I usualy write another policies, but in some reason it does not work. My init() in OnDeleteAssociationPolicy implementation looks like this:
policyComponent.bindClassBehaviour(
QNAME,
PublishModel.pubWebContent,
new JavaBehaviour(this, QNAME.toPrefixString(), NotificationFrequency.EVERY_EVENT)
);
PublishModel.pubWebContent is qname of my custom content type. Now I think when onDeleteAssociation() is called, I should check which association was deleted. But this method is never called after remove association :(. How to set this policy? Should I provide PublishModel.pubMyAssociation instead of PublishModel.pubWebContent (that does not work too)?

I googled a little bit and found working piece of code, which helped me to get that policy worked. The point is to use bindAssociationBehavior instead of bindClassBehavior method. So working binging should look like this:
policyComponent.bindAssociationBehaviour(
QNAME,
PublishModel.pubWebContent,
PublishModel.pubGroupAssociation,
onDeleteAssociation
);

Related

nativescript-vue cannot read data property in lifecycle hooks

im reading nfc tags through my created hook and I would like to pass them to my data properties.
It shows me that I cannot read or set the property 'currentArticle'. I tried suggestions like
let self = this
self.currentArticle
but it did not work. Some people say you should have access to data variables like:
this.currentArticle
That way doesn't work as well. Any suggestions?
I solved it through declaring let self = this at the beginning of the created hook.
Then I simply used the self.currentArticle as I already talked about the suggestions I have seen about this problem.

Can a plone.behavior be enabled for just some objects of a type?

I would like to set a marker interface to some objects that should have additional fields. If I remove this marker interface again the fields should be removed too.
Now I'm trying to understand plone.behavior. But I'm not sure if a behavior must be enabled for all objects of a type or is it possible to enable it for only a subset of objects of that type?
Take a look at collective.instancebehavior, an add-on aimed to do exactly what you want: to enable behaviors per content type instance.
Unfortunately I don't think there is a solution out of the box.
The simplest thing you can do is working on the form fields by overriding the updateFields method in the form.
This is untested demo code:
def updateFields(self):
if not IMyInterface.providedBy(self.context):
self.fields = (
self.fields.omit('IMyBehaviour.my_field')
)
As a reference have a look to:
https://github.com/plone/plone.app.users/search?utf8=%E2%9C%93&q=def+updateFields

Symfony2: Access Request object in Entity

I'd like to know how to access the Request object in an entity (Symfony2) to modify the user locale.
If someone has found a solution for my problem, please let me know.
It's not possible. This is by design: the entity is just a simple object that should know nothing about the request - it's the responsibility of the controller to interpret the request, and manipulate the entity based on that.
Something like:
//inside your controller:
public function fooBarAction(Request $request)
{
$entity = // get entity
$entity->setLocale($request->getSession()->getLocale());
}
The above is just example code, it won't work if you just copy and paste it. It's just to demonstrate the general idea. The entity should just be a very simple object, who's only responsibility is to hold some data. It shouldn't know where the data is coming from - that keeps it flexible (if you want to set the locale based on something else, you only have to change your controller, not all your entities).
It is possible, but...
What you can but never should do is inject the Request object into the entity (Practically turning your entity into service, see here). Also, even worse idea (but which people still do), you could inject the whole container and get Request from there. The reason why you shouldn't do it is you never should have any code that deals with business rules or any system code in your entities.
You can switch your locale directly in your routes by using _locale custom variable (accessible also from the Request). Or you can create a kernel listener, which will do the required functionality for you. This way you keep your code testable and decoupled.

How do I get an ID after saving an ExtBase Model?

After creating a model and adding it to a repository I want to have the new ID for different purposes (creating a mail, updating other fields outside the Extbase world)
$page = t3lib_div::makeInstance('Tx_MyExt_Domain_Model_Page');
$page->setTitle('Hello World');
$this->pageRepository->add($page);
At this point $page hasn't got an ID yet, uid is null.
$page->getUid(); // returns null
When does it get it? And how can I retrieve in on runtime?
In ExtBase, objects are "managed". This means every persistence transaction (add/remove/update) is simply noted in the underlying logic, but not yet executed until the appropriate time (like the end of processing a request). So, just because you add an object to a repository doesn't mean that it's actually added yet. That actually happens once $persistenceManager->persistAll() is called, which isn't something you need to do manually, ever. The point is, your $page object won't have a UID until it's saved and that's why $page->getUid() returns null. Look here for a great explanation.
I suspect that you are trying to do something outside of the ExtBase object/MVC lifecycle. At least, last time I got null when I tried to get the UID of an object, it was because I wasn't operating within the framework appropriately.
However, if you post some more code and give us a bigger picture of what you're trying to achieve, maybe we can help you get to a point where that object actually has a UID. For instance, if you're in a Controller object, tell us which Action method you're in, or if you're in a Repository object, tell us what you're trying to get from the repository and where/how you plan on using the query results.
EDIT
Just guessing here, but I'm assuming you're executing this code in some action of a controller. Since after the controller is executed a view is rendered, you can just pass the page object to the view:
$this->view->assign('page', $page);
And then in your view you can use the page object in a link:
<f:link.action action="show" arguments="{page:page}">
See this page object
</f:link.action>
And then in the show action of your controller you can show the page:
public function showAction(Tx_MyExt_Domain_Model_Page $page) {
// Do whatever you need to show the page in the `Show.html` template
}
I really am just guessing here. If you can give us a larger picture of what you're trying to do, what your action methods are supposed to do and things like that, we can answer your question a little more confidently.
(I'm also assuming that your page object isn't a replacement for the regular TYPO3 pages and that they are something totally different. It's much easier to deal with those TYPO3 pages through the backend interface than at the php level.)
You can call persistence manager explicitly in Your controller like this
#TYPO3 4.x
$persistenceManager = $this->objectManager->create('Tx_Extbase_Persistence_Manager');
$persistenceManager->persistAll();
#TYPO3 6.x
$persistenceManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
$persistenceManager->persistAll();

Communication between Flex module and Application

Ok, modules in Flex are popular but I have no idea why documentation and examples on the different uses of Flex modules can be so scarce.
Anyway, for this question, I will take the classic Employee/Department example. I have a main.mxml that contains an mx:TabNavigator. Each tab is loaded by an s:ModuleLoader.
Tables: Employees {empID,empName,deptID}, Deparments {deptID,deptName}
The Tab Navigator contains only one tab (for our example) called Employee. I have an Employee.mxml module. In that module, I have a datagrid that is populated with Employee details. I use the getEmployees($deptID) function. This function, as you may guess, returns me an array of Employees who work in a particular department.
Outside the TabNavigator, I have a departmentDropDownList that is populated with departments.deptName.
My objective is to load the Employee module when I select a particular department from the DropDownList. I have a changeHandler for the DropDownList that can give me the deptID.
protected function departmentDropDownList_changeHandler(event:IndexChangeEvent):void
{
MyDeptID=departmentDropDownList.selectedItem.deptID;
//var ichild:*=employeeModule.child as IModuleInfo;
}
Now, the million dollar question is: How do I pass this deptID to the Employees module. The latter has an employee_creationCompleteHandler that calls getEmployees(deptID):
protected function EmployeesDg_creationCompleteHandler(event:FlexEvent):void
// I only need to get the deptID from the departmentDropDownList outside the Employee module.
// If I could create a global variable deptID, that would be great!
getEmployeessResult.token=employeeService.getEmployeess(deptID);
}
I have attempted to use [Bindable] variables but without success.
I would appreciate your suggestions.
You can't really guarantee that the deptID will be set when creationComplete runs--it sounds like you're waiting for a server result--so this is probably not the best way to handle it.
One of the things you need to be careful of is directly referencing the full Module Class from the main Application, because the point of modules is that you should not compile in the module Class into the main Class (to reduce file size/load times).
So what you might want to do is create an Interface. This creates a "contract" between the main application and the Module without carrying all the implementation code with it. That might look something like this
public interface IEmployeeModule {
function set deptID(value:int):void;
}
Then, your Module might have code that's something like this:
protected var _deptID:int;
public function set deptID(value:int):void {
_deptID = value;
var token:AsyncToken=employeeService.getEmployeess(deptID);
token.deptID = value;//in case department id changes, you can determine if you still care
}
Note that, though global variables seem like a wondermous idea when your project is small, they are a very bad habit to get into. It can be almost impossible to repair a project that starts out with these and then grows to the point that no one can figure out exactly which of the hundreds or thousands of Classes that have access to a variable are changing it in the wrong way at the wrong time.
You ESPECIALLY don't want to use global variables with Modules, as they can cause really bad problems when the modules start fighting over the definition.
We solved this problem with the use of Cairngorm v2. Think of it as a message bus for ActionScript, one of several. In your departmentDropDownList_changeHandler method we would create a DeptChanged event with the ID as the payload, and send it on the bus to any and all subscribers to that message type. It worked pretty well for us, and made things more event driven, which in some circles is considered a good thing in itself.
#J_A_X I haven't had good luck with using Robotlegs out of the box with Modules. It seems that something goes wonky with the security contexts, even though it shouldn't. I had to use Joel Hooks' ModuleContext to make it work right, even though my needs were fairly basic.

Resources