Symfony sfDoctrineGuard plugin sfGuardUser module - php

When using sfDoctrineGuard plugin, it automatically generates the backend administration functionality where I can edit users of the system and assign them permissions.
So I visit http://.../backend_dev.php/sf_guard_user/:id/edit where I am presented with the user's information including the available permissions to select.
By default the permissions are shown as a multiple select box, HTML follows:
<select name="sf_guard_user[permissions_list][]" multiple="multiple" id="sf_guard_user_permissions_list">
<option value="1">Permission1</option>
<option value="2">Permission2</option>
<option value="3">Permission3</option>
<option value="4">Permission4</option>
</select>
What I would prefer is a list of checkboxes. So I searched around and found that if I add the option "expanded" set to true to the following code:
'permissions_list' => new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'sfGuardPermission', 'expanded' => true,)),
The code is part of this file: lib/form/doctrine/sfDoctrineGuardPlugin/base/BasesfGuardUserForm.class.php. I don't think I should've edited this file (potential for changes to be overwritten should sfDoctrineGuard ever be re-installed) but couldn't think of another way to make it work.
The generated HTML is as follows:
<ul class="checkbox_list">
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="1" id="sf_guard_user_permissions_list_1" /> <label for="sf_guard_user_permissions_list_1">Permission1</label></li>
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="2" id="sf_guard_user_permissions_list_2" /> <label for="sf_guard_user_permissions_list_2">Permission2</label></li>
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="3" id="sf_guard_user_permissions_list_3" /> <label for="sf_guard_user_permissions_list_3">Permission3</label></li>
<li><input name="sf_guard_user[permissions_list][]" type="checkbox" value="4" id="sf_guard_user_permissions_list_4" /> <label for="sf_guard_user_permissions_list_4">Permission4</label></li>
</ul>
What I need to do now is split up the permissions based on their prefix. For example if I had permissions named user_action1, user_action2, file_action1, file_action2, they would display like:
User
checkbox (custom label) Action One
checkbox Action Two
File
checkbox (custom label) Action One
checkbox Action Two
but have no idea where to start with this. It would be easy if there was a template to edit but since I'm dealing with the Forms framework it is my understanding that the templates are generated on the fly - I can see them in my symonfy cache folder.
How would I go about this?
I started writing my own sfWidgetFormDoctrineChoicePermission class that extends the same class as sfWidgetFormDoctrineChoice but am struggling to edit the rendering functions correctly for the desired output. Is this the correct way to go about this work?
I also need to integrate my sfGuardUserProfile model into the edit user page (same as above), I read somwhere that editing the generator.yml file for the sfGuardUser plugin module and simply adding the field names from the sfGuardUserProfile table would make it work, but sadly it doesn't.

First of all don't ever edit base classes. The one you are wanting to edit is:
lib/form/doctrine/sfDoctrineGuardPlugin/sfGuardUserForm.class.php
From here you can override the default widget by calling:
$this->setWidget('permissions_list', new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'sfGuardPermission', 'expanded' => true)));
You should be creating your own widget and exdending it from sfWidgetFormDoctrineChoice is the best start. Basically it will return html as php strings which will get echoed. It is simple enough to get your head around eventually.
To include your profile form when editing your main user form it is very simple, in the same sfGuardUserForm class:
$this->embedForm('profile', new sfGuardUserProfileForm($this->getObject->NAME_OF_PROFILE_RELATIONSHIP));
That last call is off the top of my head so the syntax might be wrong so check it out, also replace the relationship with the name of your profile relationship of course.

First off, you have to put the new configure() in UserAdmin form (backend), not the regular User from (frontend).
Then, your configure() method will have the new widget declaration:
$this->setWidget('permission_list', new sfWidgetFormDoctrineChoice(array(
'muliple' => true, // this makes checkboxes (default=false=radio)
'model' => sfGuardPermission,
'expanded' => true // changes from select menu -> radio or check (based on 'multiple' setting)
)));
Good luck:)

Related

TYPO3: Custom AuthService reveals in InvalidControllerNameException

In TYPO3 11 LTS I've created a custom FE extension which generates a custom login process. For that I've provided an auth Service with 2 subtypes in ext_localconf.php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addService(
// Extension Key
'mylogin',
// Service type
'auth',
// Service key
'tx_mylogin_login_process_data',
// Info
array(
'subtype' => 'processLoginDataFE,authUserFE',
'available' => true,
'title' => 'Mylogin Authentication',
'description' => 'Services for my login',
'priority' => 85,
'quality' => 85,
'os' => '',
'exec' => '',
'className' => MyLoginAuthenticatorService::class
)
);
MyLoginAuthenticatorService extends TYPO3\CMS\Core\Authentication\AuthenticationService.
Inside MyLoginAuthenticatorService::processLoginData(array &$loginData, $passwordTransmissionStrategy) I check for certain credentials and overwrite the $loginData with the username found by a login_key.
Inside MyLoginAuthenticatorService::authUser(array $user) I get the right/expected fe user array (like in the normal fe_login process). In here I check for a certain circumstance and return an integer 200.
Doing that with some debug I can confirm that I am reaching the point in code with the return 200; and as mentioned above having a filled array with user credentials.
In my extension I use the following Fluid form:
<f:form method="post" action="customlogin" fieldNamePrefix="">
<f:form.hidden name="user" value="{login_key}" />
<f:form.hidden name="pass" value="" />
<f:form.hidden name="logintype" value="login" />
<f:form.hidden name="pid" value="{secure_pid}" />
<f:form.button type="submit">Login</f:form.button>
</f:form>
Now the problem: Without the registered service I can access the customloginAction in my controller. Putting back the service registration after the return 200; my frontend returns:
#1313855173 TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException
The controller "Mycontrollername" is not allowed by plugin "Myloginplugin".
Please check for TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin()
in your ext_localconf.php.
The plugin is the same as the form action and the resulting action is placed in and as mentioned above it all works without the services.
So what is wrong? Is using the auth services even the right way? What do I miss? Is returning 200 in authUserFE enough to trigger all stuff TYPO3 has to do to provide a logged in user?
Edit:
I've found out that going with a <form action="/" ...> the whole solution works perfectly. That form is on the subpage /login. If I do the action="/login" the mentioned InvalidControllerNameException pops up again.
Do you know why that could happen?
you are using <f:form> here which is there for creating extbase forms
it interactis with <f:form...> elements and builds a complex context. in your case you need plain variables so i would sugget just render a regular html form using <form> (no fulid namespace) and regular html elements.
Got it.
It was a deep dive into code / understand what you use problem. Inside my custom AuthenticationService functions I used some functionality right from the ActionController of my custom auth extension.
This causes TYPO3 to build an additional request with no context resulting in the error above. After removing the ActionController stuff from the service context everything works like charm. Yes even with that fluid form:
<f:form method="post" action="customlogin" fieldNamePrefix="">
<f:form.hidden name="user" value="{login_key}" />
<f:form.hidden name="pass" value="" />
<f:form.hidden name="logintype" value="login" />
<f:form.hidden name="pid" value="{secure_pid}" />
<f:form.button type="submit">Login</f:form.button>
</f:form>

How to create manual inputs in CakePHP 2 using SecurityComponent?

I want to create a form in CakePHP whilst having the SecurityComponent active. So far so good, now I want to add custom input elements which I can't generate using the FormHelper. I do however to have these fields included in the security and validation checks.
The main problem is that I can't render radio buttons outside of their labels. So I render them myself like so:
<div class="radio radio-inline">
<input id="genderMALE" type="radio" name="data[User][gender]" value="MALE"/>
<label for="genderMALE">Male</label>
</div>
<div class="radio radio-inline">
<input id="genderFEMALE" type="radio" name="data[User][gender]" value="FEMALE"/>
<label for="genderFEMALE">Female</label>
</div>
Which in itself works perfectly. Yet the FormHelper has no notice of them so the SecurityComponent registers this as tampering with the form. Blackholing my request.
I tried to generate the inputs using the FormHelper but radio support is limited. The format option does not work here since:
Radio buttons cannot have the order of input and label elements controlled with these settings.
-- Cookbook
Next to that I couldn't find any way to render a plain detached radio button. And the only way I found to have the input accepted was through ignoring it in the SecurityComponent.
What is the Cake way to fix this?
Update 14-09 09:16
My current fix/hack would be to create the custom radio buttons in plain HTML as shown above. Then link the value of those radio inputs to an input field created using the FormHelper. Using CSS I can hide this input allowing it to be changed by JavaScript, as opposed to using type="hidden".
Are there any dangers/problems that could occur using this method?
side note: In the end this is a styling issue. Yet I'm forced to use Bootstrap and have only 2 days left to finish my task. And I don't feel like going down the path of writing custom CSS/JS to get this working.
At the point of getting content with the hack solution, I stumbled upon the FormHelper::$fields field. This field keeps track of all inputs created using the FormHelper and is later used by the SecurityComponent to check whether the form has been tampered with.
The solution does require some additional work as you need to implement the following steps:
Add custom form element the the fields array
Restore value from previous submit (if redirect back to form)
Add default option so field won't be omitted from post data
Working CTP
<div class="radio radio-inline">
<input id="genderMALE" type="radio" name="data[User][gender]" value="MALE"
<?= $this->request->data('User.gender') == 'MALE' ? 'checked' : ''?> />
<label for="genderMALE">Male</label>
</div>
<div class="radio radio-inline">
<input id="genderFEMALE" type="radio" name="data[User][gender]" value="FEMALE"
<?= $this->request->data('User.gender') == 'FEMALE' ? 'checked' : ''?> />
<label for="genderFEMALE">Female</label>
</div>
<input type="radio" name="data[User][gender]" value="" class="hidden"
<?= $this->request->data('User.gender') ? '' : 'checked'?> />
<?php $this->Form->fields[] = 'User.gender' ?>
It is far from pretty, yet I recon it is close to the internals of Cake itself. Might want to create a helper instead of manually implementing the inputs every time.

How do I Apply a working Dropdown instead of a Text field in php

I am working on customizing a plugin, however my knowledge is currently lacking on the php side.
currently i have an Ad plugin in which you can sell ads per day, however my predicament is that i want to sell the ads only in packs of 30,60 & 90 days.
In this plugin upon typing a number of days this plugin calculates the amount and gives a result right under without anything pressed, so it is actively reading an input; however the only problem with this plugin is that it allows anyone to type a random number in there.
now the only real solution that i could think of was to make a drop-down with pre-existing values 30, 60, 90
My attempts thus far have been futile as i keep applying HTML <Select> (yes i had changed the wording from <input to <select and then added <option value="value">value wording</option>)techniques and it seems that anytime that i attempt to put a number for the value as one of the choices i get nothing but an empty drop-down, this then made sense to me since this is a PHP form and not an HTML form.
I was able to find where to code the changes, as i was able to find where the field is pulling from; here is the code:
(How should i proceed to make the changes that i want happen?)
<div class="control-group" id="total_days" style="<?php echo $date_dis;?>">
<label class="ad-price-lable control-label" width="40%"><div id="total_days_label"><?php JText::_("TOTAL_DAYS_FOR_RENEWAL");?>:</div> </label>
<div class="controls">
<input type="text" maxlength="5" name="totaldays" class="ad-pricing" id="totaldays" value="<?php echo $ad_totaldays ;?>" onchange="caltotal()" >
<input type="hidden" name="ad_totaldays" id="ad_totaldays" value="<?php echo $ad_totaldays;?>" />
</div>
</div>
now i am also assuming that out of this area, the main thing to be changed would be:
<input type="text" maxlength="5" name="totaldays" class="ad-pricing" id="totaldays" value="<?php echo $ad_totaldays ;?>" onchange="caltotal()" >
of course, i could be wrong, but i really would appreciate help with this!
thank you very much!
Here is how I've always done dropdowns
<select form="examplef">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<form id="examplef">
<input type="submit">
</form>
The php you're looking at is setting a value field for the inputs. This just means that something will be in the box already when you load the page.
Also keep in mind that just because you have predefined options doesn't mean you wont get unexpected input; Changing the options is as easy as right clicking
PHP form vs HTML form
They are the same. The html <form> tag is a way to communicate with php. This tag will (most likely) have an attribute called "action" and "method". The action attribute specifies what to do with the collected information. You can think of it almost as an <a href> that includes data.
The method attribute is a little more complicated. It tells your browser how to send the data entered into the form. The two options are "GET" and "POST". the GET method is data put in the url. I'm sure you've seen youtube links with the ?id=. This is just a GET variable included in the URL. The POST method is for secure data, or data that shouldnt be in the URL. If you would like to read more, W3Schools has a great document here or from Php here and here

Magento field has a permanent style="display:none" and missing value "required" in class

I've been trying to figure out how is Magento 1.9 changing attributes for one element (region_id, overriden from original forms) from a custom extension made fro Magento 1.7. The code generated is like this:
<div class="field" style="display: none;">
<label class="" for="billing:region_id"></label>
<div class="input-box">
<select id="billing:region_id" class="" title="State/Province" name="billing[region_id]" defaultvalue="499"></select>
<!-- a lot of option elements -->
<input id="billing:region" class="input-text" type="text" style="display:none;" title="State/Province" value="Miranda" name="billing[region]"></input>
</div>
</div>
Notice the style="display:none;" in one div tag and the lack of a value in the class attribute in the corresponding label tag.
I've been following every single tutorial about extensions, adding the field where is supposed to be (besides the fact is already a Magento field), but there's no change at all in the corresponding form.
Any idea?
Solved! this is really embarrising... the solution was in the Admin Panel all the time.
Magento gives the option to choose the country of the states list (and if you want to set that field as required, too). In my case is was setted to United States (which is NOT the country where the store is located).
So, in the Admin Panel, just went to System > Configuration > General > States Options > State is required for > [Country Name] and chose the right country, clicked in the Save Config button... and that's it!.

Kohana sorting filter implementation

i am trying to implement a kohana sorting filter for a virtual store, meaning that whenever i want to sort some products (after price, etc)i must only select the sorting criteria from a list. i dont want to implement the sorting in another view, so that when one chooses a sort option, he must not be redirected in another page.
so i have a list:
<form name="ordering" id="ordering" method="post" action="">
<input type="hidden" id="ordering" value="0">
<select id="ordering" name="ordering">
<option value=0>All products</option>
<option value=1>Ascending Price</option>
<option value=2>Descending price</option>
</select>
</form>
i want then to take that hidden value in the controller, for being able to manipulate it in the view. (is it correct?)
i need this variable in order to be able to make a switch and to determine which sorting option has been choosen by a user.
in the controller, i try to 'catch' the variable with a $ordering = $_POST['ordering']; but i receive an error, or with a
if (Request::$is_post){
$ordering = $_POST['ordering'];
}
but it never gets there (at that bunch of code).
where i am wrong?
thank you!
Given the documentation of Request object and this example, you could try the following in your controller :
if (Request::$method == 'POST') {
$ordering = $_POST['ordering'];
// ...
}
Note: it's recommended to put quotes around HTML tag parameters
<option value="0">All products</option>
instead of
<option value=0>All products</option>
HTH
#dana: Have a look at -- http://www.ajaxlines.com/ajax/stuff/article/jquery_and_kohana_unobtrusive_ajax.php -- for an example and some direction on how to do what you wish to without having the page refresh when a user submits the form.
First, check your HTML code, you have 3 IDs named "ordering".
I don't know how you wrote your Javascript stuff, but I wouldn't be surprised if that doesn't work, IDs should be unique.
Anyway, you say you want to get the value of the hidden field, but it doesn't have any name. So you can't access to it via PHP (unless you do it with Javascript)
According to Kohana 3.1 (the last comment was linking the 3.0 documentation), to get the value you should do the following:
$this->request->post('ordering');
What version of Kohana are you working with ?

Categories