How to change a modx revolution users class_key when newly created VIA the manager? - modx-revolution

I'm trying to change a new user's class_key value when they are created VIA the manager.
In a plugin that fires on the onUserSave event:
<?php
$uid = $_POST['id'];
$sql = "update modx_users set `class_key` = 'extUser' where id = $uid;";
$modx->log(modX::LOG_LEVEL_ERROR, 'query = ' . $sql);
$query = $modx->query($sql);
return;
Which works when you EDIT an EXISTING user, but does not work if you try to CREATE a NEW user.
Any thoughts on how to do this?
None of the system events look like they fire when a new user is created.

Looking at the user/create processor, you would need to listen for OnUserFormSave which is fired after saving the new user.
I haven't tested this, but in your plugin you have access to $modx->event. Log the output of this for the OnUserFormSave event, hopefully it should include a 'data' property containing the new user object. The object should contain the new user id.
Let me know how that goes!
Update
I've tested this out. As expected, you have access to the new user id, user object (and much more) in the $modx->event object:
if ($modx->event->name == 'OnUserFormSave') {
// id of user you've just created
$newUserId = $modx->event->name->params->id;
// full modUser object is available here
$newUserObj = $modx->event->name->params->user;
}

In plugin with OnUserSave event:
$scriptProperties['user']->set('class_key','extUser');
That's it nothing more.
You cannot call
$scriptProperties['user']->save();
in OnUserSave as other examples elsewhere have shown.

Related

VTiger Extension Module create custom field for Accounts Module

I'm working on a VTiger 6.4.0 Extension Module that is used to get company data when entering a company name in the Accounts module.
The module is almost finished, i retrieve data from a API and enter them in the input fields using JQuery.
But the problem is that i have some data that is not relative to the existing fields in the account information, so i'm trying to create some new custom fields.
Only i can't seem to figure out how to create a custom field for the Accounts module from within my Extension module.
I googled around and watched some posts on stackoverflow.
I came up with the following part of code, but this doesn't seem to work.
public function addKvkfield(){
$module = new Vtiger_Module();
$module->name = 'Accounts';
$module = $module->getInstance('Accounts');
$blockInstance = new Vtiger_Block();
$blockInstance->label = 'LBL_ACCOUNT_INFORMATION';
$blockInstance = $blockInstance->getInstance($blockInstance->label,$module);
$fieldInstance = new Vtiger_Field();
$fieldInstance->name = 'KvKNummer';
$fieldInstance->table = $module->basetable;
$fieldInstance->column = 'kvknummer';
$fieldInstance->columntype = 'VARCHAR(100)';
$fieldInstance->uitype = 2;
$fieldInstance->typeofdata = 'V~M';
$blockInstance->addField($fieldInstance);
}
The addKvkfield function is being called in the vtlib_handler module.postinstall (Couldn't find any information if this is the right way of doing this within a Extenstion Module)
vtlibhandler:
function vtlib_handler($modulename, $event_type) {
global $log;
if($event_type == 'module.postinstall') {
$this->addJSLinks();
$this->createConfigTable();
$this->addSettingsMenu();
$this->addKvkfield();
$this->updateLabels();
// TODO Handle post installation actions
} else if($event_type == 'module.disabled') {
// TODO Handle actions when this module is disabled.
} else if($event_type == 'module.enabled') {
// TODO Handle actions when this module is enabled.
} else if($event_type == 'module.preuninstall') {
// TODO Handle actions when this module is about to be deleted.
} else if($event_type == 'module.preupdate') {
// TODO Handle actions before this module is updated.
} else if($event_type == 'module.postupdate') {
$this->updateLabels();
// TODO Handle actions after this module is updated.
}
}
Hopefully someone can give me a push in the right direction.
Thanks in advance :)
I managed to succeed in creating the custom fields that i needed in the Accounts Module.
Thanks to the Vtiger Mailing List! :)
What did the trick was a small alteration of the code I've written:
public function addKvkfield(){
$module = Vtiger_Module::getInstance('Accounts');
$blockInstance = Vtiger_Block::getInstance('LBL_ACCOUNT_INFORMATION', $module);
$fieldInstance = new Vtiger_Field();
$fieldInstance->label = 'KvKNummer';
$fieldInstance->name = 'kvknummer';
$fieldInstance->column = $fieldInstance->name; // Good idea to keep name and columnname the same
$fieldInstance->columntype = 'VARCHAR(100)';
$fieldInstance->uitype = 1; // No need to use 2 anymore. Setting "M" below will introduce the Red asterisk
$fieldInstance->typeofdata = 'V~O';
$blockInstance->addField($fieldInstance);
}
The above code will create a (optional)Custom Field in the Account module.
If your writing a new module and never installed this module before you can just call the function in the vtlib_handler as i did in my question.
But in my case this did not work because I've already installed the plugin before adding the code to create the customfields.
So what i needed to do is call the function above on the vtlib_handler module.postupdate (this will add the custom field on a module update)
Only problem with this is that it'll get run every time the extenstion is updated.
So i suggest creating a if statement in the function to check if the field already exists in the vtiger_field dbtable if not run the script.
Hopefully i saved someone else some time by writing this all down :P
Goodluck!
Please refer below link
Add New Field in existing Module
Copy code from My Answer and create a new PHP file with ay name. Place that in CRM's root directory and Run into browser. Your Field will be added into your Module. You have to make sure about the parameters you set in code which you copy.

Hiding custom ItemProperties from print. Interop.Outlook

I have written an Outlook plugin that basically allows emails being received through Outlook to be linked with a website so that the email can also be view in the communications feature of the website. I store additional details within the ItemProperties of a MailItem, these details are basically things like the id of the user the email relates to within a website.
The problem I'm having is any ItemProperties I add to a MailItem are being printed when the email is printed. Does anyone know how to exclude custom ItemProperties when printing an email?
Here is the code that is creating the custom ItemProperty:
// Try and access the required property.
Microsoft.Office.Interop.Outlook.ItemProperty property = mailItem.ItemProperties[name];
// Required property doesnt exist so we'll create it on the fly.
if (property == null) property = mailItem.ItemProperties.Add(name, Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText);
// Set the value.
property.Value = value;
I'm working on Outlook extension and sometimes ago we had the same issue.
One of our team members found a solution. You can create some method which is responsible for disable printing. You can see peace of our code below:
public void DisablePrint()
{
long printablePropertyFlag = 0x4; // PDO_PRINT_SAVEAS
string printablePropertyCode = "[DispID=107]";
Type customPropertyType = _customProperty.GetType();
// Get current flags.
object rawFlags = customPropertyType.InvokeMember(printablePropertyCode , BindingFlags.GetProperty, null, _customProperty, null);
long flags = long.Parse(rawFlags.ToString());
// Remove printable flag.
flags &= ~printablePropertyFlag;
object[] newParameters = new object[] { flags };
// Set current flags.
customPropertyType.InvokeMember(printablePropertyCode, BindingFlags.SetProperty, null, _customProperty, newParameters);
}
Make sure that _customProperty it is your property which you created by the following code: mailItem.ItemProperties.Add(name,Microsoft.Office.Interop.Outlook.OlUserPropertyType.olText);
On the low (Extended MAPI) level, each user property definition has a flag that determines whether it is printable (namely, PDO_PRINT_SAVEAS). That flag however is not exposed through the Outlook Object Model.
You can either parse the user properties blob and manually set that flag (user properties blob format is documented, and you can see it in OutlookSpy (I am its author) if you click the IMessage button) or you can use Redemption (I am also its author) and its RDOUserProperty.Printable property.
The following script (VB) will reset the printable property for all user propeties of the currently selected message:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Msg = Session.GetMessageFromID(Application.ActiveExplorer.Selection(1).EntryID)
for each prop in Msg.UserProperties
Debug.Print prop.Name
prop.Printable = false
next
Msg.Save

SfDoctrineGuard Permission

I use SfDoctrine guard in my test project. I use also SfForkedApply for registration and managing accounts. I set 3 type permissions: "user","creator","administrator".
My question is : When i Create account whit sfForkedApply , How to set automaticly "User" permission to this new user .
Don't know your exact details, but your would probably need to override the doSave method of the 'user register' form and set the user permission.
Vlad you help me very much :) In doSave i added 4 rows and evriting is ok :) this is the code. It work :)
public function doSave($con = null)
{
$user = new sfGuardUser();
$user->setUsername($this->getValue('username'));
$user->setPassword($this->getValue('password'));
$user->setEmailAddress( $this->getValue('email') );
// They must confirm their account first
$user->setIsActive(false);
$user->save();
$this->getObject()->setUserId($user->getId());
//THIS LINE I ADDED
$permission = new sfGuardUserPermission();
$permission->setPermissionId('1');
$permission->setUserId($user->getId());
$permission->save();
return parent::doSave($con);
}

Additional criteria to symfony filter

i'm working on a symfony project to manage a database. First i explain how it works:
In the database, all elements are associated to an unique element 'scene'. When a user accesses the application, chooses what scene he wants to see (it saves that in a user parameter). So when listing elements, the application should only list elements associated with the scene selected by the user.
*Note: all elements have an scene attribute in the table definition.
So my problem comes here:
I developed a listing of an element entities using the help of a sfPropelPager class to paginate. Also added some filters to search in the list, and for that i used the filter system provided by symfony (<element>FormFilter.class.php and stuff).
Now i want the list to not show elements from other scenes than the selected by the user.
How can i do to add additional criteria to the criteria given by the filter class?
or How would you solve the problem?
here is my action code:
public function executeUnidadfilter(sfWebRequest $request){
$this->filter = new BaUnidadorganizativaTblFormFilter();
$c = $this->filter->getCriteria();
$this->filter->bind($request->getParameter($this->filter->getName()));
if($this->filter->isValid()){
$this->pager = new sfPropelPager('BaUnidadorganizativaTbl',$this->sfPropelPagerLines);
echo $this->getUser()->getEscenario();
$this->pager->setCriteria($c);
$this->pager->init();
}else{
$this->pager = new sfPropelPager('BaUnidadorganizativaTbl',$this->sfPropelPagerLines);
$this->pager->init();
}
$this->setTemplate('Unidadlist');
}
*Note: 'scene' mentioned below is Escenario in the code
thank you very much for your time
I solved the problem. The trouble was that i assigned the formfilter generated criteria to my criteria var Before the filter was filled. That's why of the error.
The resulting code is that:
public function executeUnidadfilter(sfWebRequest $request){
$this->filter = new BaUnidadorganizativaTblFormFilter();
$this->filter->bind($request->getParameter($this->filter->getName()));
if($this->filter->isValid()){
$this->pager = new sfPropelPager('BaUnidadorganizativaTbl',$this->sfPropelPagerLines);
$esc = $this->getUser()->getEscenario();
$c = new Criteria();
$c = $this->filter->getCriteria();
$c->addAnd('codigo_escenario',$esc);
$this->pager->setCriteria($c);
$this->pager->init();
}else{
$this->pager = new sfPropelPager('BaUnidadorganizativaTbl',$this->sfPropelPagerLines);
$this->pager->setCriteria($this->filter->getCriteria());
$this->pager->init();
}
$this->message=null;
$this->messageType=null;
$this->setTemplate('Unidadlist');
}

"Reply " to message in symfony forms

I use symfony 1.4.11 with Doctrine. I have private messages in my site, And I want to make possibility , that user can "reply" for a message. I try change "edit" method, but I do not now is this a good idea. How to make it?Now I have
$this->forward404Unless(
$messages = Doctrine_Core::getTable('Messages')->find(array($request->getParameter('id'))),
sprintf('Object messages does not exist (%s).', $request->getParameter('id'))
);
$messages->setMessage('') ;
$messages->setTitle('Re:'.$messages->getTitle()) ;
$messages->setRecipientId($messages->getSenderId()) ;
$this->form = new MessagesForm($messages);
But it do not create new message , it only edit...
Add a reply action:
public function executeReply(sfWebRequest $request)
{
$originalMessage = Doctrine_Core::getTable('Messages')->find(array($request['id']));
$this->forward404Unless($originalMessage, sprintf('Object messages does not exist (%s).', $request['id']));
$reply = new Message();
$reply->setTitle('Re:'.$originalMessage->getTitle());
$reply->setRecipientId($originalMessage->getSenderId());
$this->form = new MessagesForm($reply);
}
Additional notes:
You could modify your existing new action and add check to see if an original message id is provided.
It's a database convention to always name your objects in the singular. So your model should be called Message not Messages.
If there are many properties of the original message that should be copied, you can use the copy method on Doctrine_Record instead of making a new one.
You probably want to add a self relation as mentioned by dxb so that you can track what the message is a reply to. You may want to track both the thread and the reply to, depending on what your requirements are.
Maybe you have to design a self referenced table message : a reply is a new message which refer to the previous.
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/defining-models/ru#relationships:join-table-associations:self-referencing-nest-relations:equal-nest-relations

Resources