/**
 * $Id: README.txt,v 1.1.2.5 2007/11/29 07:23:56 rconstantine Exp $
 * @package Handshake
 * @category NeighborForge
 */
This module allows users to control just how much of their nodeprofile data is shared
with other users on a case-by-case basis.

Attempting to contact an 'unknown' user will allow them to choose to
  a) send them a message, or
  b) initiate a handshake.
  
The 'initiator' has the option to select which fields of his/her own to expose.

The 'acceptor' then has the option of
  1) rejecting the handshake altogether;
  2) accepting the handshake after
    a) checking the fields of theirs they want to share(from the list the first user
       created),
    b) selecting a handshake 'duration';
  3) flagging the request for the admin and writing a note as to why the request may be
     inappropriate or a violation of the user agreement.

Whatever fields are deemed 'okay' by the 'acceptor' are exposed to both parties. (See
the database table to see what information is tracked to make this possible.) A time
limit may be placed on the transaction by either party. A handshake may be revoked at
any time. It may be expanded and extended.

This module can also be considered a 'contacts' module as all users with whom a user
has 'shaken hands' can be listed, sorted, etc. More robust contacts tools will be
added as time allows. The goal is to eventually be able to add contacts like you would
in outlook and import/export to the most popular formats to sync your data. These
features will likely end up as part of this project, but as a separate module so as to
allow selective use via the admin/build/modules page.

--CONTENTS--
  REQUIREMENTS
  INSTALL
  SETUP
  FEATURES
  UNINSTALL
  CREDITS
  
--REQUIREMENTS--
  *This module requires the nodeprofile module and Drupal 5.x.
   [Tested on file version: nodeprofile.module,v 1.7.2.14 2007/04/29 18:34:47]
   
  *You should also use either the standard contact module, or the privatemsg module so 
   users may communicate with each other [optional].

--INSTALL--
  Installation is through the normal Drupal means. Copy the contents to your module
  folder and enable it at admin/build/modules.

--SETUP--
  There are two groups of admin pages. The first deal with setup, the second with flag
  administration. The first set are covered in this section.
  
  Go to admin/user/nf_handshake. There you will see four tabs named 'Overview', 'Choose
  CCK fields', 'Make groupings', and 'Misc settings'.
  
  Upon first visit, the Overview page will be empty except for some minor instructions.
  After this is all setup, this page will show you all used nodeprofile CCK fields and
  their groupings, if you've made any. For now, click on 'Choose CCK fields'.
  
  At the 'Choose CCK fields' page, you will see a simple drop down listing of all CCK
  fields from your existing nodeprofile content types. If you have not created any
  content types and then turned them into lonely nodes by assigning them a population
  maximum of 1, and then checking the box to make it a nodeprofile type, then this page
  may take a dump and give you an error.
  
  If you have created your nodeprofile types correctly, you may select one CCK field at
  a time and then click the 'Add CCK field' button. The added fields will be presented
  in a table above the drop down list and will show the content type it came from and
  the field name.
  
  If you return to the 'Overview' tab, your selections will now be listed. Next click
  on the 'Make groupings' tab. Groupings are NOT required. They exist for one purpose
  only - if you have several content types that contain similar fields and which will
  not all be used by a given user but one of them will be used by that user and where
  all content types will be used by at least one user, then you want to make a grouping.
  Did I lose you there? Let me explain the use case for which this was created and it
  should become clear.
  
  If you are using my nf_registration_mod module, then you will be able to create as
  many 'Membership types' as you like. These membership types collect different info
  from your users depending on the nodeprofile pageroutes you setup [for more details
  on this, see the README for the nf_registration_mod module]. In most cases, you
  will have created several content types that collect similar, but differing info.
  This may be information that you wish your users to share among themselves. Unless
  you group these similar-but-different CCK fields on this 'Make groupings' tab, they
  will not be able to share that information.
  
  A concrete example - Let's say you have two 'Membership Types'. The first is for
  users from the U.S. The second is for international users. Then let's say you have
  used my CCK_address module in creating two content types. The first content type
  will be used for the U.S. member registration and will use a dropdown of the 50
  States. This is one kind of CCK_address field. The second content type will be used
  for the international member registration and all fields will be text fields for
  their addresses. This is a different kind of CCK_address field. After you add these
  cck fields using the previous tab, those users who created U.S. registration info
  will be able to share it with others from the U.S., but not international users.
  
  SO- on the 'Make groupings' page, you can type into the text field the name you
  want for the grouping. Continuing our example, you would type 'Address'. Then,
  expanding the fieldset that is created, you would add the fields you want to group.
  In this drop down, labeled 'fields:', you will notice that the listing is different
  from that on the previous tab. In this listing, you have contenttype::fieldname.
  You would select the US_REG::address field and INT_REG::address field for our
  example if that is how you named your content types and the fields (machine name)
  for the addresses. Then, all users with addresses will be able to share their address
  with other users regardless of which content type they filled out as part of their
  registration.
  
  If you do not use the nf_registration_mod module, you probably may not ever need this.
  However, if you have a case where you want users to expose sets of fields together,
  you could use this for that I suppose. I can't think of a use case for that.
  
  Clicking on the last tab, 'Misc settings', you will find four items. The first is the
  time that an 'acceptor' has to respond to a handshake before it expires. When a
  handshake is initiated, it is given a flag of 'Pending' which signifies that the
  'acceptor' has not yet looked at the handshake. The 'acceptor' may then look at that
  handshake and either respond, or choose to respond later. If they choose to respond
  later, the flag is changed to 'Reviewed'. Both of these flags mean that no choice has
  been made. If the time you set for 'Initiation expiration' lapses, then the flag gets
  changed to 'Expired'. The 'initiator' may then send another request if they so choose.
  During the time that the flag is set to either 'Pending' or 'Reviewed', the initator
  cannot initiate another handshake. This is to aid in the prevention of users pestering
  each other.
  
  The second setting, 'Rejection expiration' is for how old a 'Rejected' handshake must
  be before the 'initiator' may reintitiate a handshake. Typically, you will want to set
  this for some time longer than the 'Initiation expiration' and can be thought of as a
  means to prevent frequent unwanted contact. The 'Rejection' flag is assigned to a
  handshake when the 'acceptor' rejects the request, or when they revoke it after having
  accepted it. The 'initiator' may also revoke the handshake, in which case they become
  the 'acceptor' and the flag is set to 'Rejected'.
  
  The third setting is for preventing users from handshaking with user 1. Presumably,
  user 1 will not be interacting with users in the regular way users do and will not want
  to be involved in handshakes. User 1 cannot initiate handshakes at all anyway as she/he
  can always see a user's account page as per the normal Drupal user page. If user 1
  wants to make handshakes, it is probably best to create and use an alternate account.
  The default for this setting is checked.
  
  The fourth setting is to prevent users from shaking hands with users that have been
  assigned the 'administer handshakes' role. Usually, this will only be user 1 and so this
  checkbox would be redundant. However, should you have more than one admin, you may
  prevent users from shaking hands with them as well if they have been assigned this role.
  The default for this setting is checked. Also note that any user assigned the 'administer
  users' role cannot initiate handshakes and will see the regular user page as user 1 would.
  
  One last thing -- THERE ARE PERMISSIONS THAT MUST BE ASSIGNED TO YOUR USERS -- they are
  called 'initiate handshake', 'accept handshake' and 'view own handshakes'. You will
  normally assign all three to all users. There are also administrative permissions called
  'administer handshakes' and 'view handshakes'. The latter is not implemented yet.
  
  That's it for setup. If you log in as a regular user, and then go to a user's page such as
  user/5, everything should work. See the FEATURES section for what that should mean.
  
--FEATURES--
  Read the SETUP section above to understand the setup and admin features of this module
  not covered in the flag administration paragraphs below.
  
  1) When a user tries to visit another user's profile page for the first time (such as
     user/5), instead of the normal Drupal profile page, they will be presented with a choice
     form. Their choices will be to 'Initiate a handshake', 'Contact user' or 'Cancel'.
     
     a) Initiate a handshake - The user becomes the 'initiator'. If they do not abort the
        process, two table entries will be made and they will be tracked by their user ID
        as IUID. On the form they are presented with, they will be shown the fields from
        their own nodeprofile nodes with a checkbox next to each. Those fields from non-
        required content types that they have not filled out will be disabled (grayed out)
        and will note that they haven't filled that data out yet. The user may check those
        fields that they wish to share and that they hope the other user will agree to share.
        Above that table, is a text area for the 'initiator' to specify a purpose for the
        handshake. Submitting the form creates the table entries.
        
     b) Contact user - This simply links to the site's standard contact method. If both
        privatemsg and contact modules are enabled, the preference is for privatemsg. Contact
        module can still be used by clicking the 'contact' tab on the user's profile view or
        going to user/UID/contact.
        
     c) Cancel - Returns the user to the site's main page.
        
  2) A user primarily sees what is going on with their handshakes at
     user/<THEIR UID>/nf_handshake/inbox. From here, they can see the contents of both their
     inbox and their outbox. Accepting a handshake is explained below followed by descriptions
     of the in/outboxes.
     
     a) Accept a handshake - When a user is sent a handshake, it will show up in their
        'handshake inbox' and will also show as a number on the 'Handshakes' menu
        subitem of their 'My account' menu. The menu item will look like this:
          Handshakes (X)(Y), where X is the number of new/non-reviewed handshakes and/or
          flagged handshakes (see below) and Y is the number of reviewed handshakes.
          [The inbox will be described below.]
        If there are items that would show up in the number counts for X or Y, then a visit
        to their user/UID/nf_handshake/inbox page will present them with both their in and
        out boxes and the inbox will be expanded. Cliking on the 'reply' link next to a
        given request will present the user with a form similar to the one filled out by
        the 'initiator', but will contain the 'acceptor's' data, and not that of the
        'initiator' since the handshake has not been finished. Only those fields that the
        'initiator' selected will be presented as handshakes will go to the lowest common
        denomination of fields selected.
        
        The 'acceptor' has three choices and one sub-choice; these are 'Accept handshake',
        [with or without adjusting the 'Duration'], 'Reject handshake', and 'Flag handshake'.
        
        I) 'Accept handshake' is the most simple. In this case, after the user selects the
           fields to share, they simply click this button without changing the default
           'Duration' of 'Forever' (not really forever, but something like 30 years). This
           completes the handshake so now when either user visits the other's page, they
           will see the agreed-upon fields of the other party.
        II) 'Accept handshake' with 'Duration' adjustment is straight forward. The user
            simply selects the time unit ('Days', 'Weeks', 'Months' or 'Years') and the
            number to go with it. The numbers are not currently dynamic, so they range from
            0 to 31 at present. All numbers are valid even though some make more sense than
            others depending on the unit choice. This will be changed at a leter date. The
            result is the same as (I), above, but with an expiration date now set.
        III) 'Reject handshake' is also simple and requires no other settings. This sets the
             handshake flag to 'Rejected' and neither user will be able to see the other's
             data, nor initiate another handshake until the 'Rejection expiration' time has
             passed -OR- the 'acceptor' changes their mind (see below). This will also change
             the user's page and will remove the button to initiate a handshake. Contact may
             still be made through the site's chosen tool (contact or privatemsg).
        IV) Expanding the 'Flag this request?' fieldset presents the user with a sub-form.
            The user may choose from several flag options and must then comment as to why
            they are flagging the handshake for administrative review. Clicking on 'Flag
            handshake' finishes this process and send the handshake to the review queue.
    
     b) Handshake inbox - The inbox is perhaps a little complicated, but it is hoped that
        with regular use, it isn't too bad.
        
        The inbox is divided into two sections, a top and a bottom. The top and bottom
        contain those items that are requests for which the user is the 'acceptor'. These
        are presented in four groups - 'New handshake requests', 'Reviewed handshake 
        requests', 'Flagged requests', and 'Handshake upgrade requests'. The data shown for
        each of these is 'Status', 'Date initiated', 'From username', 'Stated purpose', and
        'Operation'.
        
        The status is the flag such as 'Pending', or 'Unanswered'. If the 'Operation' column
        is not empty, there will be a text link which will take the user to a page where they
        can affect the handshake in some way. Usually, new and reviewed handshakes will show
        a 'reply' link, flags will show a 'reply' link as well, and so will upgrade requests.
        The link for both new and reviewed handshakes is explained above in 'Accept a handshake'
        while the others are explained below.
        
        The bottom section of the inbox is for two groups of items. The first is those for
        which the other user has requested a handshake 'Duration' extension. The second is for
        the handshakes the user has rejected, but which have not yet expired and so can be
        un-rejected. The data shown for each of these is 'Status', 'Expiration date', 'From
        username', and 'Operation'.
        
        The subsections are labeled in itallics in both the top and bottom sections. The groups
        are either listed in the order discussed, or have a note letting the user know there
        are no outstanding items in that group.
        
     c) Handshake outbox - The outbox is found on the same page as the inbox and is a separate
        field group. It looks nearly identical to the inbox, with a couple of exceptions. First,
        neither new or reviewed handshake requests will have an operation as the ball is now in
        the 'acceptor's' court for these. They are displayed here so that the user can know
        whether the user they have initiated with has looked at the request yet or not. Flags
        will have the same 'reply' option. Upgrade requests will likewise have no operation as
        again, the ball is in the court of the 'acceptor'.
        
        The bottom section of the outbox is also similar to that of the inbox, but there are no
        operations possible for either 'Duration' extension requests or 'rejected' handshakes.
        In the first case, this is the user that initiated the extension request and so logically
        can't do another until the first has been responded to. The second case shows handshakes
        which have been rejected. As only the 'acceptor' can change thier mind at a later date
        (before expiration), this user can't do anything.
        
  3) The other main page a user will visit is user/<THEIR UID>/nf_handshake/view_contacts. This
     is described below under 'Handshake contacts'. Each user's profile page with which a user
     has shaken hands will also naturally be visited by the user. These URLs look like user/UID.
     As explained above, once a handshake is complete, the initiation/contact/cancel form is
     replaced by a presentation of the known data of the user. This is described below as 'User
     view' and is included in this section because both 'User view' and 'Handshake contacts'
     share most of their operations. Consequently, these operations are also described in this
     section.
        
     a) User view - Once a handshake has been successfully completed (initiated and accepted),
        users may visit each other's user page and will no longer see the form that makes them
        choose to initiate a handshake or not. Instead, they will see:
        
        I) A table of the other user's data with fieldnames on the left and data on the right.
        
        II) The date the handshake was initiated and the date it will expire.
        
        III) A listing of links for each operation that may be performed on this handshake.
             These include 'Send this user a message', 'Revoke this handshake', 'Extend
             expiration date', 'Request handshake upgrade (expose more fields)', and
             'Downgrade handshake (hide fields)'. These operations are explained below.
             
     b) Handshake contacts - This is a tab under the user's 'My account' menu item (i.e. their
        own user page). This tab presents all of the users with which the user has an existing
        handshake in a viewable condition (i.e. no problems preventing the viewing such as flags,
        rejections, and so on). The table lists the 'Username', 'Created' date, 'Expires' date,
        and 'Operations'. The table can be sorted according to the first three fields. The
        username is a link to the user's page. The operations listed are- 'Contact' which will
        send the user to the contact page of the site's messaging system (privatemsg or contact);
        'Revoke' which will take the user to a confirmation page; either 'Extend expiration' or
        'Request extension' depending on handshake role in this instance (in the first
        case, a form for just the duration is shown and the result is ADDED to the existing
        duarion. In the second case, the request is sent with no further input by the user);
        'Request upgrade' where the user will be presented with a form similar to the initiation
        request form; and 'Downgrade' where the user is presented with a form similar to the
        acceptance form.
        
        Of these operations (which are the same as those found on the 'User view' but with shorter
        names) only a few need further explanation. See the following sections:
        
         * Extend expiration/Extend expiration date
         * Request upgrade/Request handshake upgrade (expose more fields)
         * Downgrade/Downgrade handshake (hide fields)
        
     c) Extend expiration/Extend expiration date - A user gets to this form three ways. First, as
        an 'acceptor', they can click on either 'Extend expiration' from the 'Handshake contacts'
        page, or the 'Extend expiration date' from the user of interest's profile page ('User view').
        Also, there would appear a link in the 'Handshake inbox' labeled 'extend expiration' that
        could be used as well.
        
        All that is presented to the user is a small form which is allows them to choose a time unit
        and a number from 0 to 31 as a multiplier. The result is added to the current expiration date.
        
     d) Request upgrade/Request handshake upgrade (expose more fields) - This can be arrived at from
        either the 'Handshake contacts' or the 'User view' pages respectively. This is a modified
        version of the handshake initiation form. The user must state a purpose for the upgrade request.
        The current fields are shown checked and disabled. All other available fields are shown. If the
        user has not filled out all nodeprofile forms completely, some fields may be disabled and the
        data column will read 'No Value Entered'. Fields which have values and which are not yet part
        of the handshake will be checkable.
        
        Submitting this form is similar to a regular handshake request except that the existing data is
        still viewable to both parties while this request is pending.
        
        One thing to note is that a request like this may reverse the roles of the users. The original
        'initiator' will remain the 'initiator' if they are the one to propose this upgrade. However,
        the original 'acceptor' will become the 'initiator' (which makes the original 'initiator'
        become the new 'acceptor') if the 'acceptor' makes the request. All privileges of being an
        'acceptor' are therfore transfered from one user to the other.
        
     e) Downgrade/Downgrade handshake (hide fields) - This can be arrived at from either the
        'Handshake contacts' or the 'User view' pages respectively. Either user can do this at any time.
        The form presented is a simple table showing the user's current handshake fieldnames and their
        values. A checkbox next to each is initially empty. The user chceks the boxes of those fields
        to KEEP in the handshake. Empty boxes are for those items to be excluded going forward.
  
  4) Flag administration is done via admin/user/nf_handshake_flags and is designed to handle users that
     bother other users. What is there now is a first pass and may be changed in the future if needed.
     There are three pages that the admin will use. The first I just named and is also the 'Overview'
     tab. The second is the 'Decisions' tab and then there are the individual flag 'view' pages. All
     are described in this section.
     
     Possible user flags are : AGE_INAPPROPRIATE, SPAM, HARASSMENT, QUESTIONABLE_PURPOSE, or OTHER. At
     a later date, these may be admin-specifiable. For now, they aren't. At almost 3700 lines of code,
     this is a good enough first version.
     
     a) Overview - This page shows the flags which have not had a decision pronounced upon them yet by
        the admin and need to be dealt with. At a later date, a block will be created to allow the admin
        to see what needs to be done without visiting the page.
        
        The data is shown in a table. The columns listed are 'IUser', 'AUser', 'Purpose', 'Flag',
        'Explanation', and 'Operations'. All columns except 'Operations' are sortable. 'IUser' is the
        initiating user. 'AUser' is the accepting user. 'Purpose' is the purpose listed by the 'IUser'.
        'Flag' is the flag the 'AUser' used. 'Explanation' is the reason the 'AUser' gave for flagging
        the handshake request.
        
     b) Decisions - This page shows the same data as the 'Overview' tab, but for those flagged handshakes
        where the admin has pronounced a decision. An additional 'Decision' column is placed just before
        the 'Operations' column and lists the admin flag that was the decision. These flags are described
        in the next section - 'View'.
        
     c) View - Currently, the only operation that can be performed on a flagged handshake is to view it.
        A link in the 'Operations' column on either the 'Overview' or 'Decisions' page will take you to
        that handshake's flag view page (admin/user/nf_handshake_flags/view/<IUID>/<AUID>). Moving from
        the top of the display to the bottom, the following items are displayed:
        
        I) General information - an unlabeled, single row of a table contains the IUser's username, the
           AUser's username, the date the handshake was initiated, the expiration date, and the initial
           date that the admin looked at this flag (and acted in some manner).
           
        II) Purpose - The stated purpose of the IUser is shown.
        
        III) User flag - The flag that the AUser used is shown.
        
        IV) User flag explanation - The explanation the AUser gave as to why the handshake was flagged.
        
        V) A table of the conversation between all parties involved (IUser, AUser, and admin(s)). The
           table has three columns: 'Datestamp', 'UID', and 'Message'. How a message is created is described
           below. The admin sees all messages in chronological order.
           
        VI) Admin flag - The admin can choose between several action and decision flags. The action flags
            are: 'Further admin review', 'Send to IUID for comment' and 'Send to AUID for comment'. The
            decision flags are: 'T&S Violation', 'First warning', 'Second warning', 'Suspend user', and
            'Alert parents'. It is likely that most sites will not have both parents and children on a
            site and will not have the ability to alert parents of an issue. If that is your case, ignore
            it. As with the user flags, these will likely become admin-specifiable.
            
            * Further admin review - You should probably make a note, even if this requires waiting just
              so you don't forget why you are waiting, or in the case you have multiple admins.
            * Send to IUID for comment & Send to AUID for comment - You can allow the users to comment
              regarding the flag. The fact that they have a handshake flagged shows in their in/outbox
              immediately, so they will likely look for an opportunity to comment when they can. A link
              will become active for them to click on in their respective in/outbox when you set this flag.
              The user will only see their own side of the conversation along with the admin's so if there
              are points the second user makes that you want the first to know about, add them to your note.
            * T&S Violation - This is for when someone has violated your Terms of Service agreement or other
              legal docs they agreed to in order to use your site. This is a note to you to follow up
              according to what was laid down in those documents.
            * First warning & Second warning - If you want to implement a warning system, you can. These
              are for your information only. This will be shown to the user in their in/outbox, but no
              other actions taken.
            * Alert parents - Again, this for your info only as you will need to handle any parent alerting
              yourself.
            * Suspend user - This sets the user account of the 'initiator' to 'blocked'.
            
            NOTE: Again, in the future, all flags will possibly be setable by admin. If/when that happens,
                  I would also like to provide a bunch of options/actions the admin can choose to happen
                  for each admin flag setting. For example, perhaps a user will not be blocked but could
                  lose the ability to create some kinds of content, send messages via privatemsg, can't
                  comment, or whatever. The admin would then check one or more option for each flag.
              
        VII)  Add a comment - This is where you add your comments regarding this flag issue.
        
        VIII) Save/Cancel - Add your comment or back out of it.
        
     d) User responses - Users will ba able to provide responses to questions and comments made to them
        by the admin. Their 'Respond to flagging' page looks almost identical to the admin's 'View' page
        as described above. The difference, of course, is that the user doesn't set admin flags or make
        admin notes. Aside from renaming the fields to be more user friendly, the only difference is the
        removal of the admin flag drop down list. The 'Message' field remains but is renames to 'Response'
        The 'Save' and 'Cancel' buttons remain also. The messages that the user sees are only those from
        the admin and himself/herself.
        
  5) Privileges - As an 'acceptor', a user has certain privileges that the 'initiator' does not.
     --The user may extend the duration of the handshake at any time.
     --The user may un-reject a rejected handshake so long as it hasn't expired yet.
     
  6) Did I forget something? Let me know. Post a documentation issue on the issue queue.
  
--UNINSTALL--
  Disable and then uninstall via the normal Drupal procedure. This will remove the two
  database tables and the 
  
--CREDITS--
  This module was created by Ryan Constantine (drupal id rconstantine)