Adding users and attributes programatically in Concrete5 version 8 - concrete5

Hi I have recently followed some documentation to create new users from a csv file programatically. According to the Concrete5 docs/api there was method called getByID( $uID ) but this has since be deprecated!
I am creating a new user like so:
$userRegistration = Core::make('user/registration');
$file = fopen("test-users.csv","r");
while (($data = fgetcsv($file)) !== FALSE) {
echo "email address " . $data[0];
$userRegistration->create([
'uName' => $data[0],
'uPassword' => $data[1],
'uEmail' => $data[2],
'uIsValidated' => true,
]);
}
However if I want to add a value to an existing non-core attribute for instance lets call it user_county then how would I change this after programatically adding the user? I may need to do this for several user attributes as well so the values would need to come from the CSV and automatically be looped through to apply the correct value to the corresponding attribute whether it is blank or filled.

The create() method will return a UserInfo object (Concrete\Core\User\UserInfo) after successfully adding a new user. With the returned UserInfo object, you can use the setAttribute() method to set your custom user attribute.
Make sure that you have created the customer user attribute first and check that it is available before setting it, otherwise setting it will throw an error. I believe you can do this using Concrete\Core\Attribute\Key\UserKey::getByHandle('my_user_attribute') and seeing if it returns an object.
The create() method is in the RegistrationService class:
https://github.com/concrete5/concrete5/blob/develop/concrete/src/User/RegistrationService.php#L51-L140

Related

Get WorkflowDesigner from a ModelItem

I am trying to create a custom IExpressionEditor. In order to new one up I need a WorkflowDesigner, All I have is the ModelItem representing my custom activity. Is it possible to access the WorkflowDesigner from a given ModelItem?
List<ModelItem> variables = new List<ModelItem>();
List<ModelItem> nameSpaces = new List<ModelItem>();
// get the activity from the datacontext
CustomActivityDesigner cad = this.DataContext as CustomActivityDesigner;
// try to get the variables
// look for variables collection cant seem to find them
ModelProperty mp = cad.ModelItem.Properties["Variables"];
if(mp != null && mp.PropertyType == typeof(Collection<Variable>))
{
mp.Collection.ToList().ForEach(i => variables.Add(i));
}
// get name spaces
ModelProperty mp2 = cad.ModelItem.Properties["NameSpaces"];
if(mp2 != null && mp2.PropertyType == typeof(Collection<NameSpace>))
{
mp2.Collection.ToList().ForEach(i => nameSpaces.Add(i));
}
// finally need the WorkflowDesigner object
WorkflowDesigner designer = Modelitem.Root....??? as WorkflowDesigner
// now we have what we need we can create the IExpressionEditor
CustomExpressionEditior ce = new CustomExpressionEditior(designer, variables, nameSpaces)
Following the Using a Custom Expression Editor as reference, it seems you should be able to create a Custom Expression Service (which will be creating the Expression Editor instances) and register it to the Services collection on the WorkflowDesigner.
Once it's registered in the WorkflowDesigner's Services collection, you'll be able to:
Get the editing context for the ModelItem by using ModelItemExtensions.GetEditingContext
Access the Services property of the returned EditingContext
Retrieve the Custom Expression Service you registered on the WorkflowDesginer
Hope it helps!

Check each param Symfony

I have a Route to create User, and I need some parameters to get this.
For example my controller is like this:
$dataJson = json_decode($request->getContent(),true);
$data = new \stdClass();
$data->email = $dataJson['email'];
$data->pwd = $dataJson['pwd'];
$data->role = $dataJson['role'];
I need of all of the (email, pwd, role) to create my User.
Do I have to check each param to invalidate my request?
e.g.
$dataJson['email'] == null ? 'error' : $dataJson['email']
$dataJson['pwd'] == null ? 'error' : $dataJson['pwd']
$dataJson['role'] == null ? 'error' : $dataJson['role']
Of course this isn't the right way, but How can I sure that my request is valid?
The approach I would take would be to have a value object and define validation rules for it.
You can load the object manually, for example:
$data = new VO\UserChangeRequest($dataJson['email'], $dataJson['pwd'], $dataJson['role']);
I would then check whether the object is valid:
$violations = $this->get('validator')->validate($data);
$isValid = 0 === count($violations);
The validations rules would be obtained by the validator component from your bundle configuration.
Here's an article explaining validation in Symfony2:
http://symfony.com/doc/current/book/validation.html
P.S For your specific case I would rather use JMSSerializerBundle. It integrates nicely and upon using param converter you will end up with the object automatically instantiated and hydrated for you. It may be a bit challenging to setup at first.

Send Gravity Forms data to redirection page

I have a very simple form created with Gravity Forms;
It submits two numbers and then redirects to a different result page.
How do I retrieve those two numbers on the result page?
add_filter("gform_confirmation_4", "custom_confirmation", 3, 4 );
function custom_confirmation($confirmation, $form, $lead, $ajax)
Gives a custom confirmation. Each field value can be retrieved by using $lead[{field ID}]
I have a solution for this based on using a combination of form submission hooks and the GForms API. It's a horrible plugin so I apologise for the messiness of the logic flow. It's important to use the framework methods rather than processing the data yourself since there are a good amount of hacks and shonky things going on in there to correctly match field IDs and so forth.
I will provide a solution to pass a submission from one form to pre-populate another. Changing the destination for POST data is pretty straightforward, they have an example for it on their gform_form_tag hook documentation page. Yes, that really is the only way of doing it.
Without further ado here is the code. I've set it up to work off form configuration to make things simpler for the end user, so it works like this:
Select "allow field to be populated dynamically" in your destination form field's advanced settings and choose a parameter name for each.
Add matching CSS classes on the source fields of the other form(s) to setup the associations.
Add a CSS class to the source forms themselves so that we can quickly check if the redirection is necessary.
.
$class = 'GForms_Redirector';
add_filter('gform_pre_submission', array($class, 'checkForSubmissionRedirection'), 10, 1);
add_filter('gform_confirmation', array($class, 'performSubmissionRedirection'), 10, 4);
abstract class GForms_Redirector
{
const SOURCE_FORMS_CLASS_MATCH = 'submission-redirect';
const DEST_PAGE_SLUG = 'submit-page-slug';
const DEST_FORM_ID = 1;
protected static $submissionRedirectUrl;
// first, read sent data and generate redirection URL
function checkForSubmissionRedirection($form)
{
if (false !== preg_match('#\W' . self::SOURCE_FORMS_CLASS_MATCH . '\W#', $form['cssClass'])) {
// load page for base redirect URL
$destPage = get_page_by_path(self::DEST_PAGE_SLUG);
// load form for reading destination form config
$destForm = RGFormsModel::get_form_meta(self::DEST_FORM_ID, true);
$destForm = RGFormsModel::add_default_properties($destForm);
// generate submission data for this form (there seem to be no hooks before gform_confirmation that allow access to this. DUMB.)
$formData = GFFormsModel::create_lead($form);
// create a querystring for the new form based on mapping dynamic population parameters to CSS class names in source form
$queryVars = array();
foreach ($destForm['fields'] as $destField) {
if (empty($destField['inputName'])) {
continue;
}
foreach ($form['fields'] as $field) {
if (preg_match('#(\s|^)' . preg_quote($destField['inputName'], '#') . '(\s|$)#', $field['cssClass'])) {
$queryVars[$destField['inputName']] = $formData[$field['id']];
break;
}
}
}
// set the redirect URL to be used later
self::$submissionRedirectUrl = get_permalink($destPage) . "?" . http_build_query($queryVars);
}
}
// when we get to the confirmation step we set the redirect URL to forward on to
function performSubmissionRedirection($confirmation, $form, $entry, $is_ajax = false)
{
if (self::$submissionRedirectUrl) {
return array('redirect' => self::$submissionRedirectUrl);
}
return $confirmation;
}
}
If you wanted to pass the form values someplace else via the querystring then you'd merely need to cut out my code from the callback and build your own URL to redirect to.
This is a very old question, now you can send it using a Query String on the confirmation settings.
They have the documentation on this link:
How to send data from a form using confirmations
Just follow the first step and it will be clear to you.

Symfony sfGuard pull a field in a specific user's profile

I'm trying to have a "product" page display a specific user's blurb and picture. The code I have is below but it keeps pulling the currently logged on user's blurb and picture which is not what I want. As soon as I log out, I get the Call to a member function getBlurb() on a non-object error message. Is there a way to pull up a specific user's "blurb" and "Picture" fields?
public function executeShow(sfWebRequest $request)
{
$this->car = $this->getRoute()->getObject();
$seller_id = $this->car->getSeller_id();
$this->seller = $this->getUser()->getGuardUser($seller_id);
$this->blurb = $this->seller->getBlurb();
$this->picture = $this->seller->getPicture();
}
$this->seller is not an object because $this->getUser()->getGuardUser($seller_id); don't accept any parameters, it only retrieves current user. Look at that method definition at sfGuardSecurityUser.
You have to do it like:
Doctrine: $this->seller = $this->car->getSeller();
Propel: $this->seller = SfGuardUserPeer::retrieveByPK($seller_id);

How to get Tridion item ID after created using Core Service

I am creating a new item using the Core Service in this post. However, the URI of the newly created item is tcm:0-0-0 instead of the actual TCM URI. the Title property is correct (and not New Component) but the WebDav path returns 'New Component' while .
What is the best way to get the URI of my newly created item?
client.Create(newComponent, null);
string newItemUri = newComponent.Id; // returns tcm:0-0-0
string webDavUrl = newComponent.LocationInfo.WebDavUrl; // returns New%20Component
string title = newComponent.Title; // correct
Second parameter of Create method are ReadOptions. They are used to specify how the item will be read back. In your example you have it set to null, meaning you will not read it back. What you should do is set ReadOptions and assign item read back to a variable, like this:
newComponent = (ComponentData) client.Create(newComponent, new ReadOptions());
Check out Ryan's code at http://blog.building-blocks.com/uploading-images-using-the-core-service-in-sdl-tridion-2011. He uses client.Save to get the saved Component, from which he's able to access the ID.

Resources