Problems, need help? Have a tip or advice? Post it here.
7 posts Page 1 of 1
Hello!

I have made a lot of searches on the forum and can't figure it out.
Is there a way to check if a variable contains a specific string of words?

Something like :

<cms if variable1 contains="Eric">Hi, Eric!</cms:if>

The way I want to use it is to allow sharing entries with other users in the backend.
I am using extended user roles, and created a "Extended role" dropdown variable.
There's some checkboxes with each users name on the entry page only visible to the super-admin. I want to make it so that if the users name is checked, he can access the edit page of this entry.

What I did (which was working fine until there's more than 1 user checked) is :
(the "vendeur" extended role is there because I want this rule to apply only if the user has the "Vendeur" extended role)

Code: Select all
<cms:if (k_user_title != "<cms:show author/>") && (user_extended_role='Vendeur')>
<cms:abort>
Access denied.
</cms:abort>


Like I said, it's working perfectly if there's only one "author". So the "k_user_title" comparaison with author works.
But when there's 2 users checked, "author" will become for example "John Doe|Jane Doe". So of course, the "if k_user_title" will always remain false. Even though the name is part of the "Author" array.

What I would like to achieve would be :

Code: Select all
<cms:if (k_user_title DOESN'T CONTAIN "<cms:show author/>") && (user_extended_role='Vendeur')>
<cms:abort>
Access denied.
</cms:abort>


Any help would be greatly appreciated.
Hi,

Could you please share the code defining the 'author' checkbox region?
Hello,

Sure :

Code: Select all
<cms:editable name='author' label='Author' opt_values='list_authors.htm' opt_selected = 'current_author.htm' dynamic='opt_values | opt_selected' type='checkbox' class='col-xs-6' search_type='text'/>


And the "list_authors.htm" file is :

Code: Select all
<cms:php>
    global $DB;
    $str = '';
    $rs = $DB->select( K_TBL_USERS, array('title') );
    if( count($rs) ){
        foreach( $rs as $rec ){
            $str .= '|' . $rec['title'];
        }
    }   
    echo( $str );
</cms:php>
I also tried this, but the result seems to be the same :

Code: Select all
<cms:each author sep='|' >

<cms:if (item !=k_user_title) && (user_extended_role='Vendeur')>
    <cms:abort>
            DENIED
    </cms:abort>
<cms:else/>
        OK
</cms:if>

</cms:each>


I thought of setting up a variable that would change from "pending" to "true" if there's a line in the "cms:each" that matches the current logged in user's name...but I'm having a hard time with how to set it up.
I tried:

Code: Select all
<cms:set accept_share="pending" scope='global'/>


And then

Code: Select all
<cms:each author sep='|' >

<cms:if (item = k_user_title) && (user_extended_role='Vendeur')>
<cms:set accept_share="true"/>
<cms:else/>
<cms:set accept_share="false"/>
           <cms:abort>
            DENIED
    </cms:abort>
</cms:if>

</cms:each>


But since when there's multiple authors checked, it there's multiple items in the "cms:each" block, the variable will be set to "true" for one, but will not for the other, so will change to "false".

I'm kind of lost here to be honest. Any help will be highly appreciated.

Again, what I'm trying to achieve is to check if a string of text (value of a variable) CONTAINS specific words (in what I'm trying to achieve, the current logged in user name). Not "exatly equals", but if it "contains" it, then turn the condition to "true" .

Thanks a lot!
Faced with a string potentially having false-positives (Dick, Dickens) I'd convert it to an array. Tag <cms:is> will quickly report if the array happens to contain exactly the searched name.

Tag cms:is is a shorter alias for <cms:arr_val_exists>. Helps to check if a value exists in a simple non-associative array.
It accepts 2 parameters: key, in.

For example -
Code: Select all
<cms:is 'fr' in=rec />

<cms:arr_val_exists 'fr' in=rec />

Arrays were introduced with a ton of examples in topic Multi-value variables (or Arrays).
Thanks a lot Anton!

I managed to make it work thanks to you.

Here's what I came up with

I started with creating a an array of all elements checked within that checkbox field (which in my case, were all the users in the CMS).

Code: Select all
<cms:capture into='user_access_list' is_json='1'>
{
  <cms:each author sep='|'>
    "Username<cms:show k_count/>" : "<cms:show item/>"<cms:if "<cms:not k_last_item />">,</cms:if>
  </cms:each>
}
</cms:capture>


Then I created a variable called "permission", set to "pending".

Code: Select all
<cms:set permission='pending'/>


And created a condition that would switch the value of "permission" to "true" if the currently logged user's name was found in the "user_access_list" array :

Code: Select all
 <cms:if "<cms:arr_val_exists k_user_title in=user_access_list />">
<cms:set permission='true'/>
</cms:if>


Finally, I added this part to show a blank page with the "access denied" message if the "permission" value was not set to "true", and that the user extended role was set to "Salesman" :

Code: Select all
<cms:if (permission != 'true') && (user_extended_role='Salesman')>
    <cms:abort>
       <h1>Access denied</h1>
    </cms:abort>
</cms:if>


That way, for example as an admin, even if his name is not checked in the authors list field, he can still access the page since his role is not "Salesman". So basically, this rule will only be applied if you are a "Salesman" using the CRM.

Hopefully this will help some people!
Thanks again everyone
You are welcome :)

Anyone coming to this thread should use arr_val_exists / is -- only with non-assotiative arrays.
Example of setting a non-associative array in Couch -

Code: Select all
<cms:set rec='["de", "fr", "es"]' is_json='1' />

Example of setting an associative array in Couch -
Code: Select all
<cms:set rec='{"name":"John", "age":30, "cars":[ "Ford", "BMW", "Fiat" ]}' is_json='1' />

Example of checking a value under some key -
Code: Select all
<cms:arr_val_exists 'BMW' in=rec.cars />
7 posts Page 1 of 1