Both sides previous revisionPrevious revisionNext revision | Previous revision |
opac-devel:catalog_development [2008/01/29 14:52] – Nope, they shouldn't be consts as they're used in the catalog and const is not implemented by IE. booo 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''. |