How to loop ObjectStorage items on fluid from typo3 - typo3

I have a like feature on my plugin where a user can like an idea, for that I have a mm table where I relate the idea and the user. I want to disable or enable the "like" button depending on if the user has liked the idea or not already.
When I call the $this->votedUsers from my model my fluid template gets this. What is this? Is not an array? How can I loop this to check if the user has liked the idea already.
This is what my $this->votedUsers property from my Idea model contains and I want to loop to check if that FrontendUser has liked the idea already and disable or enable de button.
This is how <f:debug>{_all}</f:debug> looks like

I would do this inside your idea model:
public function isLikedByCurrentUser(): bool
{
$currentUser = GeneralUtility::makeInstance(ObjectManager::class)
->get(FrontendUserRepository::class)
->findByUid($GLOBALS['TSFE']->fe_user->user['uid']);
if ($currentUser) {
return $this->votedUsers->contains($currentUser);
}
return false;
}
After that you can check it in Fluid via <f:if condition="{idea.likedByCurrentUser}"> ... </f:if>.

Related

Prestashop module development - why is this template redirecting not working

On user-registration confirmation I want to show a simple popup. For the moment, in order to simplify I'm happy to show an "Hello World".
This is the template file, views/templates/hook/registrationConfirm.tpl
<div id="idname" class="block">
<h1 class="title_block">HelloWorld</h1>
</div>
In my custom module I have this hook (which I know is being triggered doing debug):
public function hookActionCustomerAccountAdd($params) {
return $this->display(__FILE__, 'registrationConfirm.tpl');
}
It doesn't show anything (I also tried inspect the source code of the rendered page, but I dind't find the "HelloWorld")
Hooks starting by "Action" react to an action but do not display anything, but those starting with "Display" do.
You should also react to the hook displayCustomerAccount
public function hookActionCustomerAccountAdd() {
$this->is_new_account = true;
}
public function hookDisplayCustomerAccount()
{
if ($this->is_new_account) {
return $this->display(__FILE__, 'registrationConfirm.tpl');
}
}
I tried the solution posted by #shagshag but for some reason it doesn't work for me. So I share my solution (it's not pretty, nor efficient I think, but it seem to work for me): in the hookActionCustomerAccountAdd I save on a custom table (newCustomersTmp) email and customer id, because these are the data I need after, in the display Hook. Then in the hookDisplayCustomerAccount I check if an user with the current email ($this->context->customer->email) already exists in my table: if so I retrieve the data, do the actions I need with them and delete the row in the table.

Symfony disable form fields depending on user rol

I'm developing an app in symfony for follow the workflow of a document. In the lifecycle of the document, take part various departments, I mean, people of each department with his own role inside de app (ROLE_USER, ROLE_SYSTEMS...). I have the same form for all of them but in the different states of the lifecycle of the document one of them has to complete specific fields and the rest will be disable or readonly.
I want to know how is the best way to do this in Symfony, check the role and disable the fileds the user can't edit in every moment of the lifecycle.
I have investigated and find something like this for my twig templates, but I will have to do this for each field and each role and I don't know if I can apply this to field attributes like disabled or readonly, is it?.
{{% if is_granted('ROLE_ADMIN') %}
Delete
{% endif %}
I also heard about voters but I don't have very clear how it works and if it is appropriate for my situation.
What do you think?
Easy but ugly way would be different form type classes (just to play around to find out which fields are necessary and which aren't, but it's optional).
The better way would be FormEvents like PRE_SET_DATA where you could add/remove (not sure if modifien also available).
Look here to find out more -> How to Dynamically Modify Forms Using Form Events
Basically you should try following:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Add your general fields which are available for all
//$builder->add(...)
// at the end add an EventListener
$builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']);
}
and in the same form-class create the onPreSetData method:
public function onPreSetData(FormEvent $formEvent)
{
$form = $formEvent->getForm();
$entity = $formEvent->getData();
//if user is admin then $form->add(...) like above in with $buildForm->add(...)
}

TYPO3 extbase extend news controller

TYPO3 6.1
I wanted to call some function on opening of extbase news list view.
For example, if the url to list view contains tx_news_pi1[overwriteDemand][tags]=1, then I want to update that "tags" count by 1 in database.
How this could be possible ? Any help ?
And if You will just extend the class You need ?
config.tx_extbase {
objects {
Tx_FooExt_Controller_OriginalController.className = Tx_MyExt_Controller_OtherController
}
}
It looks like easiest way.
References
http://blog.sebastiaandejonge.com/articles/2013/june/11/class-extension-in-extbase/
http://lists.typo3.org/pipermail/typo3-english/2011-December/078458.html
The easiest way would be to just add a simple user function by TS and do it there

How to hide certain fields on the User Edit form in Drupal?

So I have three types of users - admin, LA admin and users. I am trying to set it up so that admins and LA admins cannot edit the username, password and timezone for users. I am talking about the default user edit form for admins and the form ID is "user-profile-form".
I have created a custom module but this doesn't seem to be working. Any idea what I might be doing wrong?
Even the var_dump does not seem to be outputting. I have cleared the cache and verified that the module is enabled.
function profile_change_form_alter(&$form, $form_state, $form_id) {
if ($form_id === 'user-profile-form') {
var_dump ($form);
hide($form['account']['pass']);
hide($form['account']['current_pass_required_values']);
hide($form['account']['current_pass']);
}
}
If you use hide() you will remove the field, but hide is more for "delaying" field rendering... Like you hide it, but then (in template file) you print it at some other place.
Because, if you don't print it later it won't be rendered in the page, won't be saved, if it's mandatory you'll get validation error and so on.
If you want to hide it, so user can not see it but you want the form to keep previous value of the field use something like:
$form['field_yourfield']['#access'] = FALSE;
and if you want it to be visible, but disabled (user can't change it's value) then:
$form['field_yourfield']['#disabled'] = TRUE;
I am assuming you module name is PROFILE_CHANGE & so that you have used it in the format of hook_form_alter(), where you have replaced hook with your module name profile_change.
You have put 3 '=' sign where you are giving condition to check form id, which is user-profile-form. I have put simple equal sign which is '==' & it's working.
function profile_change_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'user-profile-form') {
hide($form['account']['pass']);
hide($form['account']['current_pass_required_values']);
hide($form['account']['current_pass']);
}
}
Don't use var_dump(), You should always use DEVEL & check the output of $form like dpm($form) just after your hook function for form alter. This will give you all info about form, where ever you have a form on your page.
function profile_change_form_alter(&$form, $form_state, $form_id) {
dpm($form);
}
Actually I just had to change user-profile-form to user_profile_form in my code for it to work. For some reason, drupal requires underscores.

Test to see if you are in a specific content block in TinyMCE and not allow a plugin to add to that content block if in it

So I have a TinyMCE form on my page and it is pre-filled with "sections" (divs with specific class names).
I have a couple of plugins that will add to TinyMCE with more "sections".
I need it so when I push the plugin button it will test to make sure the cursor is not inside a "section" and paste a "section" inside another "section".
Not sure the direction I need to take to accomplish this. Any help would be great.
more info:
So below is an example of a plugin that adds a button that just inserts a simple dov into the editor at the selection/cursor.
ed.addButton('pluginbutton', {
title : 'MyPlugin',
image : 'img/test.png',
onclick : function() {
ed.selection.setContent('<div>test</div>');
}
});
I am currently thinking that onBeforeSetContent is the API event handler I need to set to process whether or not I am in another section and if so send a message to the screen. If not just do the setContent method. I am not sure exactly how to set that up though so I am still figuring that out. Any help here?
Since it seems like you have control over the plugin, here is how I would edit it to work.
Note: I am using the jQuery method closest. I figured since you are on the jQuery core team, you are probably using it for this project. If not, just refactor that line as needed. The important part is that selection.getNode() returns the DOM element that is the parent of both the start and end selection points.:
ed.addButton('pluginbutton', {
title : 'MyPlugin',
image : 'img/test.png',
onclick : function() {
if( !$(ed.selection.getNode()).closest('div.section').length ){
ed.selection.setContent('<div class="section">test</div>');
}
}
});
Additional thoughts
Also, to make your plugin aware enough so it won't put a div as the child of a p tag, you could do something like this:
Replace onclick above with this:
onclick: function(){
var $node = $(ed.selection.getNode());
if( !$node.closest('div.section').length ){
// Get highest element that is a direct child of the `body` tag:
var $parent = $node.closest('body > *');
// Wrap with our special section div
if($parent.length) $parent.wrap('<div class="section"></div>');
}
}
I don't know TinyMCE specifically, but it should be possible to extract the current DOM element from ed.selection. If that is possible (I'm sure it is using some sort of getter function or property), you should be able to do the following:
Mark a "forbidden" area using an id or class ("<div class='protected'> ")
traverse through the selection's ancestry (using the parentNode property of the element) and check whether one of the parent elements has the "protected" class or ID.
If the ID was found, do not execute setContent(); otherwise execute it.