| Next revision | Previous revision |
| opac-devel:catalog_development [2008/01/29 13:23] – created dbs | opac-devel:catalog_development [2022/02/10 13:34] (current) – external edit 127.0.0.1 |
|---|
| | ======OPAC development====== |
| | I'm writing this as I deconstruct how the current OPAC (as of January 2008) works, largely for my own memory, but perhaps this will be helpful to others. |
| |
| | =====How the OPAC makes OpenSRF calls===== |
| | I needed to figure out which OpenSRF call was being made by a function in the OPAC so that I could adjust its behavior. The problem was that an OpenSRF call was returning a string literal of '0' for a "username not found" result, which in JavaScript's type coercion environment could easily be interpreted as a numeric 0, which would map to another user's ID and cause further confusion. We wanted to change the call to return an explicit ''null'' instead. Here's how I figured out what needed to change: |
| | |
| | - The problem was occurring on the "My OPAC" page, with a URL of ''https://localhost/opac/en-US/skin/default/xml/myopac.xml''. I viewed the source and found the following chunk of code implementing the "change username" widget:<code html><tr id='myopac_update_username_row' class='hide_me'> |
| | <td class='myopac_update_cell' colspan='3'> |
| | <span class='myopac_update_span'>Enter new username: </span> |
| | <input type='text' size='24' id='myopac_new_username' onkeydown='if(userPressedEnter(event)) myOPACUpdateUsername();'></input> |
| | <span class='myopac_update_span'> |
| | <button onclick='myOPACUpdateUsername();'>Submit</button> |
| | </span> |
| | <span class='myopac_update_span'> |
| | <button onclick='hideMe($("myopac_update_username_row"));'>Cancel</button> |
| | </span> |
| | </td> |
| | </tr></code> From this, I was able to determine that the JavaScript method of interest was ''myOPACUpdateUsername()''. |
| | - Then I grepped for the function definition of that method. There are two main directories containing JavaScript files of interest to the OPAC:<code bash>dan@denials:~/source/Evergreen-trunk$ grep "function\s*myOPACUpdateUsername" Open-ILS/web/opac/common/js/*js |
| | dan@denials:~/source/Evergreen-trunk$ grep "function\s*myOPACUpdateUsername" Open-ILS/web/opac/skin/default/js/*js |
| | Open-ILS/web/opac/skin/default/js/myopac.js:function myOPACUpdateUsername() { |
| | </code> Okay -- success, it's in ''Open-ILS/web/opac/skin/default/js/myopac.js''! |
| | - The pertinent chunk of code in the function definition is as follows: <code javascript>function myOPACUpdateUsername() { |
| | var username = $('myopac_new_username').value; |
| | |
| | ... |
| | |
| | /* first see if the requested username is taken */ |
| | var req = new Request(CHECK_USERNAME, G.user.session, username); |
| | req.send(true); |
| | var res = req.result(); |
| | if( res && res == G.user.id() ) { |
| | alertId('myopac_username_dup'); |
| | return; |
| | }</code> Calls to OpenSRF methods from JavaScript are routed through a ''Request'' object. The ''Request'' object is defined in ''Open-ILS/web/opac/common/js/opac_utils.js''. |
| | - The first parameter in the ''Request'' object initializer is a variable defined in ''Open-ILS/web/common/js/config.js''.<code javascript> |
| | var CHECK_USERNAME = 'open-ils.actor:open-ils.actor.username.exists'; |
| | </code> This is the OpenSRF method of interest. So now we just have to find it and change its behaviour. |
| | - So we're back to grepping the source code. At this point, most of the OpenSRF methods are defined in Perl, so let's start there:<code bash> |
| | dan@denials: $ find Open-ILS/src/perlmods/OpenILS/ -name "*.pm" -exec grep -H open-ils.actor.username.exists {} \; |
| | Open-ILS/src/perlmods/OpenILS/Application/Actor.pm: api_name => 'open-ils.actor.username.exists' |
| | </code> Bingo! |
| | - The relevant Perl code that implements that method is:<code perl> |
| | __PACKAGE__->register_method( |
| | method => 'usrname_exists', |
| | api_name => 'open-ils.actor.username.exists', |
| | signature => q/ |
| | Returns 1 if the requested username exists, returns 0 otherwise |
| | / |
| | ); |
| | |
| | sub usrname_exists { |
| | my( $self, $conn, $auth, $usrname ) = @_; |
| | my $e = new_editor(authtoken=>$auth); |
| | return $e->event unless $e->checkauth; |
| | my $a = $e->search_actor_user({usrname => $usrname, deleted=>'f'}, {idlist=>1}); |
| | return $$a[0] if $a and @$a; |
| | return 0; |
| | }</code> To make this method return ''null'' if the username does not exist, we change the final ''return 0;'' to ''return undef;'' to return an empty payload from the method. We also adjust the method documentation accordingly. |
| | - We adjust the code in ''myopac.js'' to handle the new expectations and sprinkle some comments while we're there:<code javascript> |
| | function myOPACUpdateUsername() { |
| | var username = $('myopac_new_username').value; |
| | ... |
| | /* first see if the requested username is taken */ |
| | var req = new Request(CHECK_USERNAME, G.user.session, username); |
| | req.send(true); |
| | var res = req.result(); |
| | /* If the username does not already exist, res will be null; |
| | * we can move on to updating the username. |
| | * |
| | * If the username does exist, then res will be the user ID. |
| | * G.user.id() gives us the currently authenticated user ID. |
| | * If res == G.user.id(), we try to update the username anyways. |
| | */ |
| | if( res != null && res != G.user.id() ) { |
| | alertId('myopac_username_dup'); |
| | return; |
| | }</code> Then we test it out -- and find that it works successfully. Hurray! |
| | - Now let's find any other places that method is called and repair them accordingly. First we'll check for the OpenSRF method name:<code bash> |
| | dan@denials: $ find . -exec grep -H "open-ils.actor.username.exists" {} \; | grep -v svn |
| | ./Open-ILS/src/perlmods/OpenILS/Application/Actor.pm: api_name => 'open-ils.actor.username.exists', |
| | ./Open-ILS/xul/staff_client/build/chrome/content/OpenILS/util/config.js:var CHECK_USERNAME = 'open-ils.actor:open-ils.actor.username.exists';</code> These are innocuous. |
| | - Now we check for the ''CHECK_USERNAME'' constant in JavaScript files:<code bash> |
| | dan@denials: $ find . -exec grep -H "CHECK_USERNAME" {} \; | grep -v svn |
| | ./Evergreen/xul/staff_client/server/patron/ue_config.js: var req = new Request(CHECK_USERNAME, SESSION, usrname); |
| | ./Open-ILS/xul/staff_client/server/patron/ue_config.js: var req = new Request(CHECK_USERNAME, SESSION, usrname); |
| | ./Open-ILS/xul/staff_client/build/server/patron/ue_config.js: var req = new Request(CHECK_USERNAME, SESSION, usrname); |
| | ./Open-ILS/xul/staff_client/build/chrome/content/OpenILS/util/config.js:var CHECK_USERNAME = 'open-ils.actor:open-ils.actor.username.exists'; |
| | ./Open-ILS/web/opac/skin/default/js/myopac.js: var req = new Request(CHECK_USERNAME, G.user.session, username); |
| | ./Open-ILS/web/opac/common/js/config.js:var CHECK_USERNAME = 'open-ils.actor:open-ils.actor.username.exists'; |
| | </code> So we have a few instances of the call being made from the staff client. We'll modify these the same way as we did ''myopac.js''. |