Forum for discussing general topics related to Couch.
18 posts Page 2 of 2
Hi KK!

Following what tim's reply :
tim wrote: Cool tags, @KK. But for this use, I think the cms:random_name is the best choice.


Is there any ways to trim the random_name's output into lets say 10 chars ?



Thx!
As soon as possible!

Touch me up : abada[dot]zulma[at]gmail[dot]com
GoingMarryAsap wrote: Hi KK!


Hi, mate :D
I hope KK would release next Couch faster, if has some more time, so I will sneak in to answer :D
function random_name( $params, $node ){
global $AUTH;
if( count($node->children) ) {die("ERROR: Tag \"".$node->name."\" is a self closing tag");}

return md5( $AUTH->hasher->get_random_bytes(16) );
}

This is the function itself (couch/tags.php)
So, md5 function always creates 32 symbols. If we disable md5, the output of random bytes would be sometimes unreadable, with special symbols (not suitable for couch names).
Instead we might replace md5 with base64, and set the number of symbols to more suitable count. Base64 is much shorter, however it also contains non-Couch symbols, like '=,+'. We can safely replase them with more appropriate letters. This is now fully working solution:
function random_name( $params, $node ){
global $AUTH;
if( count($node->children) ) {die("ERROR: Tag \"".$node->name."\" is a self closing tag");}

return strtr(base64_encode( $AUTH->hasher->get_random_bytes(5) ) , '+/=', '-_0');
}

The only problem here would be modification of source codes of Couch. So, maybe it will be better to listen to KK, as he would suggest creating an addon to kfunctions.php instead.
Hope it helps, if you are okay with the modification of the line 5900 :)

Examples:
3xPLGTw0
vH3BNjs0
3oM3e2k0

To increase/decrease number of symbols - set more suitable number here:
get_random_bytes(5)

;)
The random_name tag is easy because it's built in. It's pretty long and ugly though. If you want something more elegant, why not use k_user_id and obscure it with some random characters? You don't need cryptographic complexity here, just a little obfuscation.

For a more or less random unique identifier, add a field to the user profile called 'user_id'.
Code: Select all
    <cms:editable name='user_id'
        label="User ID" desc="determined automatically"
        type='text' />

Add the following to your db_persist_form tag in the signup process to create the unique user id.
Code: Select all
        <cms:set unique_id = "<cms:concat show k_user_id "I<cms:random_name/>" />" />
        <cms:set unique_id = "<cms:php>echo mb_strimwidth( \"<cms:show unique_id/>\", 0, 10);</cms:php>" />

            <cms:db_persist_form
            ...
            ...
            user_id=unique_id />

This gives a string of 10 characters' length. You can see the place in the code to change that. All this does is add a random string after the k_user_id, but I think it's enough for this purpose, isn't it?

EDIT:
Actually there's no need for an additional field. Just make this the k_page_name.
Code: Select all
        <cms:set unique_id = "<cms:concat show k_user_id "I<cms:random_name/>" />" />
        <cms:set unique_id = "<cms:php>echo mb_strimwidth( \"<cms:show unique_id/>\", 0, 10);</cms:php>" />

            <cms:db_persist_form
            ...
            ...
            k_page_name=unique_id />


One More Thing: :lol:
I noticed that it's possible, if unlikely, that a unique id could repeat a previous one using my first method. That would break the form submission. By adding a marker between the id and random characters, we can block that. I changed the code above to reflect that. I used a capital 'i' which blends in but is not one of the random characters used by cms:random_name.
tim wrote: I noticed that it's possible, if unlikely, that a unique id could repeat a previous one using my first method. That would break the form submission.

If (rarely) autogenerated name is not unique, why bother user with it? Can we check if existed and regenerate it upon form submission.. Would it be more difficult?
Just check if existed and regenerate it upon form submission.. Would it be more difficult?
That would be another way, but making sure it's unique in the first place seems cleaner. But I like the way you spelled out above better, anyway.

Here's how you would make a custom tag for the solution you created. Add this code to couch/addons/kfunctions.php.
Code: Select all
class CustomTags{
    function my_random_name( $params, $node ){
        global $AUTH;
        if( count($node->children) ) {die("ERROR: Tag \"".$node->name."\" is a self closing tag");}
        return strtr(base64_encode( $AUTH->hasher->get_random_bytes(5) ) , '+/=', '-_0');
    }
}
   
$FUNCS->register_tag( 'my_random_name', array('CustomTags', 'my_random_name') );
@tim, @trendoman, I thought you might like knowing a (hitherto not discussed) technique that could be useful with your code.

Couch provides a way to actually override *all* its core tags.

So, if instead of creating a brand-new tag <cms:my_random_name /> (as you have done above), you'd like to modify the existing core <cms:random_name /> tag, here is how we can do that.

Place the following (slightly) modified version of your code in kfunctions.php file -
Code: Select all
class CustomTags{
    function my_random_name( $tag_name, $params, $node, &$html ){
        global $AUTH;
        if( count($node->children) ) {die("ERROR: Tag \"".$node->name."\" is a self closing tag");}
        $html = strtr(base64_encode( $AUTH->hasher->get_random_bytes(5) ) , '+/=', '-_0');

        return 1; // prevent the original tag from executing as we have set the output above
    }
}
$FUNCS->add_event_listener( 'alter_tag_random_name_execute', array('CustomTags', 'my_random_name') );

With the above code in place, now when the original tag <cms:random_name /> is used, the custom code above gets executed thus completely overriding the core code in Couch.

To explain the code, while executing any tag Couch first fires an event (alter_tag_<tag_name>_execute) to allow any custom code to override the behavior of that tag.

In our case the tag being overridden is 'random_name', so the event thrown would be 'alter_tag_random_name_execute'.

Following line of the code hooks your code onto that event -
Code: Select all
$FUNCS->add_event_listener( 'alter_tag_random_name_execute', array('CustomTags', 'my_random_name') );

Your original tag-handler function needs two minor modifications.
1. The original function signature changes from
function my_random_name( $params, $node )

to -
function my_random_name( $tag_name, $params, $node, &$html )

2. The overriding function (unlike the original tag functions) cannot simply return the HTML to be outputted. It has to set this output in the $html parameter instead -
original:
return strtr(base64_encode( $AUTH->hasher->get_random_bytes(5) ) , '+/=', '-_0');

modified:
$html = strtr(base64_encode( $AUTH->hasher->get_random_bytes(5) ) , '+/=', '-_0');

The return value is instead interpreted as a signal for Couch to skip calling the original tag-handler after our custom code -
return 1; // prevent the original tag from executing as we have set the output above

With this technique, we can avoid making direct changes to Couch's core code (which risks losing the modifications when an update occurs).

Finally, apologies if this suggestion seems completely unsolicited (and perhaps unnecessary in the context being discussed) but it appeared to me a good place to introduce a concept that could be vital in many other contexts.

Hope it helps.
Dang! Now, @KK, this is some serious shit..
I could make cms:pages read aloud, cms:dump send mail replies and cms:zebra mAkE mY rEaDeRs CrY :lol: :lol: :lol:

Apart from jOkEs,
this is very clean, as usual!
awesome300x300.png
awesome300x300.png (76.4 KiB) Viewed 4615 times
Voila, new cms:md5 tag:

Usage: <cms:md5 'blablabla' />

Download: https://github.com/trendoman/Tweakus-Di ... gs-new/md5
18 posts Page 2 of 2