Add form option in sonata admin class - sonata-admin

How can I add custom option to formmMapper in sonata admin class?
I have form related to entity in admin class. For some reason I want to add my own options to one of the field
$formMapper
->with('tab.dimension')
->add('dimension', 'collection', array(
'type' => 'dimension_product',
'allow_add' => true,
'allow_delete' => true,
'required' => false,
'my_custom_options' => false,
))
->end();
Unfortunatly it is not possible in this way,because this options isn't defined in resolver.
But I have no access to resolver in "normal way".
Sonata defined form builder in two methods:
public function getFormBuilder()
{
$this->formOptions['data_class'] = $this->getClass();
$formBuilder = $this->getFormContractor()->getFormBuilder(
$this->getUniqid(),
$this->formOptions
);
$this->defineFormBuilder($formBuilder);
return $formBuilder;
}
public function defineFormBuilder(FormBuilder $formBuilder)
{
$mapper = new FormMapper($this->getFormContractor(), $formBuilder, $this);
$this->configureFormFields($mapper);
foreach ($this->getExtensions() as $extension) {
$extension->configureFormFields($mapper);
}
$this->attachInlineValidator();
}
Allowed options are defined in this object:
new FormMapper($this->getFormContractor(), $formBuilder, $this);
Could somebody give me advice how can i add my own option?

Little bit late to the party, but it sort of depends on what you want to do with this option.
If you need to add a real custom form option, it is not very much different from working directly with Symfony forms. You can add extra options and functionality to a given form type using a form extension . You could even add functionality to the sonata form types this way.
If you simply need to pass an option from one Admin to a child Admin (which I think you might want to do), you can use the field description options rather than the actual form options:
$formMapper
->with('tab.dimension')
->add('dimension', 'collection', array(
'type' => 'dimension_product',
'allow_add' => true,
'allow_delete' => true,
'required' => false,
), array(
'my_custom_options' => false,
))
->end();
Now in your child Admin you can retrieve these options using
$this->getParentFieldDescription()->getOptions();
To be used to configure your child Admin.

Related

How to have different dashboards based on roles with cakedc plugins / users & acl

I am using CakeDC Users & ACL plugins in my CakePhp app. I have different roles for my users in my app and I would like to have different dashboards based on roles after login.
I extend the plugin with my own table and controller based on the documentation here, so I have MyUsersController and MyUsersTable which override the initial files of the plugin, UsersController and UsersTable. Everything works fine. I create an event in my events.php file which contains:
use CakeDC\Users\Controller\Component\UsersAuthComponent;
use Cake\Event\Event;
use Cake\Event\EventManager;
EventManager::instance()->on(
UsersAuthComponent::EVENT_AFTER_LOGIN,
['priority' => 99],
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-f9effb2de026') //the id of my client role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'MyUsers', 'action' => 'index', '_full' => true, 'prefix' => false];
}
}
);
But it seems like the override is not working because I have an error:
Error: CakeDC/Users.MyUsersController could not be found.
In my URL I have /users/my-users instead of /my-users and I don't know why. I have test with a template file which is include in the plugin and the Users controller like this:
function (Event $event) {
if ($event->data['user']['role_id'] === 'bbcb3031-ebed-445e-8507-
f9effb2de026') //the id of role{
return ['plugin' => 'CakeDC/Users', 'controller' => 'Users', 'action' => 'profile';
}
And it works. My URL redirect after login as a client is /profile.
Could someone help me to understand? Please tell me if it's not clear enough and if it's missing parts of codes that might be important to understand my problem.
I specify that I am beginner with Cake.
Your custom controller doesn't live in the CakeDC/Users plugin, hence you must disable the plugin key accordingly, so that the correct URL is being generated (assuming your routes are set up correctly) that connects to your controller, like this:
[
'plugin' => null,
'controller' => 'MyUsers',
'action' => 'index',
'_full' => true,
'prefix' => false
]
That would for example match the default fallback routes, generating a URL like /my-users.
See also:
Cookbook > Routing > Creating Links to Plugin Routes

How to hide a custom user profile field on hook_disable in Drupal 7?

I have created a module that adds a field to the user profile. I used field_create_field and field_create_instance to do this. When I disable the module, I want the field to no longer show up on the user profile, but I do not want to destroy it. I want to be able to enable the module and have the field show up and the data to still be there as originally entered. Can anyone tell me how to accomplish this?
Here is the code I used to create the field:
$field = array(
'field_name' => $field_name,
'type' => 'text',
'visibility' => 1,
'category' => 'API',
);
$field = field_create_field($field);
$field_instance = array(
'field_name' => $field_name,
'entity_type' => 'user',
'bundle' => 'user',
'label' => t('API Token'),
'cardinality' => 1,
'translatable' => 0,
'description' => t('By using this API token, you agree to the site Terms and Conditions and to acknowledge that your submission does not include protected health information or personal identifiers.'),
'widget' => array(
'type' => 'text_textfield',
'weight' => 10,
),
'formatter' => array(
'label' => t('field formatter label'),
'format' => 'text_default'
),
'settings' => array(
),
);
When you have created field using drupal entity like user, node etc then on that entity crud operation automatically apply.
As you have used api to "field_create_field" field then it automatically create field using api of entity vise verse its delete field when you uninstalled module.
First tell me when you uninstall your custom module then your custom field deleted from profile.? If yes then it's difficult to handle your use case. If no then in system table of Drupal you get status of your module whether it's disable or enable if status is 0 then used form alter hook of user profile and hide field
I was not able to accomplish exactly what I wanted, but I ended up installing the field extra widgets module and hiding the field completely on the edit form. Then, I used hook menu alter to create a local task tabs and I display the field on that tab.

Plugin route to a prefixed controller

I'm creating a plugin for my application (using CakePHP 2.6.0) that allows users to login into a user area using the same model as for the admin area, so I'm trying to get the same type of URI scheme as the admin area e.g. /admin/users/login but then for /special/users/login. I have the following route in my plugin's Config/routes.php and added the 'special' prefix to the 'Routing.prefixes' configuration:
Router::connect('/special/:controller/:action', array(
'special' => true,
'prefix' => 'special',
'plugin' => 'Special',
'controller' => ':controller',
'action' => ':action',
));
With above route and entering the following url /special/users/login it would make sense to me right now if Cake went for Plugin/Controller/SpecialUsersController.php (considering namespace conflicts with the main application's UsersController) but instead I get an error Error: Create the class UsersController.
Is there a built-in way for it to load a prefixed controller (without changing the url) based on the plugin? Or is there a better way to neatly extend my main application? Am I going about this the wrong way?
I could not find a built-in way for it to work as I wanted to so I changed the way URL strings were parsed using a custom route class in my app's Routing/Route/ folder:
App::uses('CakeRoute', 'Routing/Route');
/**
* Plugin route will make sure plugin routes get
* redirected to a prefixed controller.
*/
class PluginRoute extends CakeRoute {
/**
* Parses a string URL into an array.
*
* #param string $url The URL to parse
* #return bool False on failure
*/
public function parse($url) {
$params = parent::parse($url);
if($params && !empty($params['controller']) && !empty($params['plugin'])) {
$params['controller'] = $params['plugin'] . ucfirst($params['controller']);
}
return $params;
}
}
And then setting up my plugin routes as:
App::uses('PluginRoute', 'Routing/Route');
Router::connect('/special/:controller/:action', array(
'special' => true,
'prefix' => 'special',
'plugin' => 'Special',
'controller' => ':controller',
'action' => ':action',
), array(
'routeClass' => 'PluginRoute'
));
This resulted in /special/users/login creating the controller I wanted Plugin/Controller/SpecialUsersController.php, no side effects so far. Extending the main application's UsersController is a different story though.
Maybe someone else has use of this or knows a better solution?

How to configure the fields to hide in cakePHP debug() function?

in CakePHP, when applying the debug function on a User model :
debug($user);
we get a result that hide the login or password.
'User' => array(
'login' => '*****',
'id' => (int) 2,
'pwd' => 'fjiogjfdlmgjdomngdjm',
'avatar' => null,
'prenom' => 'Fake',
'nom' => 'Admin',
'email' => 'blabla#domain.fr',
'i18n_code_appli' => '',
'numtel' => ''
),
How could we configure what model has that field hidden or not ?
Like you can see in the example below, as password field named 'pwd', it is not hidden, but login is.
And this is my actual case. I would want to toggle this to view 'login' and hide 'pwd' in debug mode.
As agreed in the comments of OP, I'll add my comment as an answer.
Just use var_dump() instead of debug() if you have to check the password hash. I have had the same problem a long while ago and I thought I'd used var_dump then. I guess you aren't keeping the call to debug() in the code on release so it shouldn't do any harm.
Or you could use the CakePHP Debug Kit. It has a list of all the set variables which you can collapse and extend. That way you have a clear overview of all the data in a deep multidimensional array.

Cakephp validating specific field with specific rule without saving the data from controller

I want to validate fields with Cakephp model validation, without saving the data, for which i am using the following code in controller.
$this->Model->set($this->data);
if ($this->Model->validates()) {
......
}
But here i want to validate only some specific field like 'email_field' and one of its rule 'email'. In model i have specified some other rules for 'email_field' like 'unique' and 'notempty' but i don't want to validate those rules.
How can it be achieved ?
The above will work definitely but it's not an elegant solution when cake has already documented how to validate specific fields of a Model.
if ($this->Model->validates(array('fieldList' => array('field1', 'field2')))) {
// valid
} else {
// invalid
}
For more detail see cookbook
you have different options
you can dynamically unset those other rules:
unset($this->Model->validate['field']['someRuleName']);
or you can assign a completely new rule set to this field
or you can use a different "nonexistent" field for this validation, e.g. "some_other_field" with special rules.
......
$this->Registry->validate = array(
'email_field' => array(
'between' => array(
'rule' => array('between', 10, 100),
'message' => 'Your custom message here',
'required' => true,
),
)
);
$this->Model->set($this->data);
if ($this->Model->validates(array('fieldList' => array('email_field')))) {
......
}

Resources