Documentation is available at helpdesk.php
- <?php
- /**
- * Customer Support module.
- * @package helpdesk
- * @author Frederic G. MARAND <fgm@osinet.fr>
- * Copyright OSI 2005. All rights reserved.
- * It is expected that version 1.0 will be GPLed, but this interim work
- * is kept closed until 1.0 is ready.
- * @todo make it work first
- * @version $Id
- * 20051005
- * - Completed _helpdesk_user and affiliated functions
- * 20050920
- * - Added _helpdesk_block_view_CUSTOMEROPENTICKETS
- * 20050919
- * - Added _helpdesk_block_view_MYOPENTICKETS
- * - Added access control to _helpdesk_block_view
- * 20050918
- * - Added _helpdek_block_view_ALLOPENTICKETS
- */
- $_helpdesk_saved_er = error_reporting (E_ALL || E_STRICT) ;
- /**
- * Import helpdesk-related classes and functions
- */
- require_once("misc.php") ;
- require_once("contract.php") ;
- require_once("customer.php") ;
- require_once("event.php") ;
- require_once("timeinfo.php") ;
- define ('HELPDESKDEBUGALLFUNCTIONS', TRUE) ;
- /**
- * Constants for helpdesk node types
- */
- define ('HELPDESKNODECONTRACT', 'helpdesk-contra') ;
- define ('HELPDESKNODETICKET', 'helpdesk-ticket') ;
- define ('HELPDESKNODEFOLLOWUP', 'helpdesk-follow') ;
- define ('HELPDESKTITLECONTRACT', 'Helpdesk > Contract') ;
- define ('HELPDESKTITLETICKET', 'Helpdesk > Ticket') ;
- define ('HELPDESKTITLEFOLLOWUP', 'Helpdesk > Followup') ;
- /**
- * Constants for HELPDESK perms
- */
- define ("HELPDESKPERMUSER", 'Helpdesk > User' ) ;
- define ("HELPDESKPERMCUSTOMER", 'Helpdesk > Customer') ;
- define ("HELPDESKPERMTECH", 'Helpdesk > Tech') ;
- define ("HELPDESKPERMMAX", HELPDESKPERMTECH) ;
- /**
- * Constants for HELPDESK block deltas
- */
- define ("HELPDESKBLOCKMYOPENTICKETS", 0) ;
- define ("HELPDESKBLOCKMYLATESTTICKETS", 1) ;
- define ("HELPDESKBLOCKCUSTOMEROPENTICKETS", 2) ;
- define ("HELPDESKBLOCKCUSTOMERBALANCE", 3) ;
- define ("HELPDESKBLOCKALLOPENTICKETS", 4) ;
- define ("HELPDESKBLOCKMAX", HELPDESKBLOCKALLOPENTICKETS) ;
- /**
- * Constants for Drupal variables
- */
- define ("HELPDESKVARSHOWROLES", 'helpdesk_show_roles') ;
- define ("HELPDESKVARTICKETPREFIX", 'helpdesk_ticket_prefix') ; // Unused part of the ticket number
- define ("HELPDESKVARTICKETOFFSET", 'helpdesk_ticket_base') ; // Number to be added to nid to build ticket number
- /**
- * Constants for hook_access
- */
- define ("HELPDESKHOOKACCESSCREATE", "create") ;
- define ("HELPDESKHOOKACCESSDELETE", "delete") ;
- define ("HELPDESKHOOKACCESSUPDATE", "update") ;
- define ("HELPDESKHOOKACCESSVIEW", "view") ;
- /**
- * Helpdesk access control
- * User may create an issue, read and close his own issues, add followups to his issues
- * Customer has User rights, extended to all users bound to him, and can perform some actions on his contracts
- * Tech can do anything HELPDESK-related
- * @param string $op create | delete | update | view
- * @param object $node the node on which "op" is to be performed
- * @return mixed boolean or NULL
- * @link http://drupaldocs.org/api/head/function/hook_access Drupal API
- */
- function helpdesk_access ($op, $node)
- {
- global $user ;
- $ret = FALSE ;
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- {
- $log = "<pre>HELPDESK_ACCESS ($op, " . _helpdesk_get_node_property($node, 'nid') ;
- }
- /* By default, node_access is set to just one row :
- nid == gid == 0
- realm == "all"
- grant_update == grant_delete == 0
- grant_view == 1
- gid appears to be unused in 4.6.*
- */
- switch ($op)
- {
- case HELPDESKHOOKACCESSCREATE:
- {
- // In this case, $node is a string containing the node type, not a node object
- // Issue and Followup may be created from the HELPDESK User level, but only HELPDESK Techs can create contracts
- switch ($node)
- {
- case HELPDESKNODECONTRACT :
- $ret = user_access (HELPDESKPERMTECH) ;
- // echo "<p>Create/Contract, ret = $ret</p>" ;
- break ;
- case HELPDESKNODETICKET :
- case HELPDESKNODEFOLLOWUP :
- $ret = user_access (HELPDESKPERMUSER) || user_access (HELPDESKPERMCUSTOMER) || user_access (HELPDESKPERMTECH) ;
- // echo "<p>Create/Ticket of Followup, ret = $ret</p>" ;
- break ;
- default: // Don't worry about other types
- echo "<pre>Anomalie dans helpdesk_access/create: node = " ; print_r ($node) ; echo "</pre>" ;
- $ret = TRUE ;
- break ;
- }
- break ;
- }
- case HELPDESKHOOKACCESSDELETE:
- {
- // For contract traceability, only techs may delete Issue or Followups
- $ret = user_access (HELPDESKPERMTECH) ;
- echo "<p>helpdesk_access/delete, ret = $ret</p>" ;
- break ;
- }
- case HELPDESKHOOKACCESSUPDATE:
- {
- /* For traceability, only techs may update Issue or Followups
- Users and customers wishing to update a ticket must issue a Followup
- Modifiying the status of an issue is handled by creating a
- followup with the new status */
- $ret = user_access (HELPDESKPERMTECH) ;
- //echo "<p>helpdesk_access/update, ret = $ret</p>" ;
- break ;
- }
- case HELPDESKHOOKACCESSVIEW:
- {
- // For this op, node is supposed to be already assigned
- $ret = FALSE ;
- /* Helpdesk User may see his own events,
- Helpdesk Customer may see the events of his users
- Helpdesk tech may view anything */
- $ret |= (user_access (HELPDESKPERMUSER) && ($user->uid == $node->uid)) ;
- // TODO : HELPDESK Customer access will have to be computed from the HELPDESK users bound to him
- $ret |= user_access (HELPDESKPERMCUSTOMER) ; // Will have to be restricted to the tickets of bound users.
- $ret |= user_access (HELPDESKPERMTECH) ;
- echo "<p>helpdesk_access/view, ret = $ret</p>" ;
- break ;
- }
- default: die ('<p><code>helpdesk_access</code> invoked with an unauthorized value: $op. Aborting.</p>') ;
- }
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "$log) = " . $ret . "</pre>" ; }
- return $ret ;
- }
- /**
- * Implementation of hook_help : provides and manages the helpdesk blocks.
- * @param op the operation from the URL (Drupal: list, view, configure, save. ?)
- * - 'list': A list of all blocks defined by the module
- * - 'configure': A configuration form
- * - 'view': Save the configuration options
- * - save': Information about a particular block
- * @param delta offset
- * @return mixed type depends on $op.
- * @link http://drupaldocs.org/api/head/function/hook_block Drupal API
- * @see _helpdesk_block_list()
- * @see _helpdesk_block_configure()
- * @see _helpdesk_block_view()
- * @see _helpdesk_block_save()
- */
- function helpdesk_block ($op = 'list', $delta = 0)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HELPDESK_BLOCK (op = $op, delta = $delta)</pre>" ; }
- // listing of blocks, such as on the admin/block page
- switch ($op)
- {
- case 'list': { return _helpdesk_block_list ($delta) ; }
- case 'configure': { return _helpdesk_block_configure ($delta) ; }
- case 'save': { return _helpdesk_block_save ($delta) ; }
- case 'view': { return _helpdesk_block_view ($delta) ; } // Information about a particular block
- default: die('helpdesk_block called with invalid op: $op') ;
- }
- } // end helpdesk_block
- /**
- * HELPDESK actions to be performed when a HELPDESK node is deleted
- * @param object $node the node to be deleted after this function
- * @return void
- * @link http://drupaldocs.org/api/head/function/hook_delete
- */
- function helpdesk_delete ($node)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HELPDESK_DELETE (node = " ; print_r ($node) ; echo ")</pre>" ; }
- /* This function must:
- - either allow the db to become inconsistent (events without contracts, followups without tickets)
- - or delete related nodes (followups for a ticket node, tickets and followups for a contract node), causing loss of traceability
- In the first version, it will allow the db to become inconsistent: contract numbers are node, and as such
- are not reused anyway, so there is no overload risk.
- */
- switch (_helpdesk_node_type($node))
- {
- case HELPDESKNODECONTRACT :
- $q = 'DELETE FROM {hd_contract} WHERE nid = %d ';
- $res = db_query($q, $node->nid);
- unset ($q);
- unset ($res);
- break ;
- case HELPDESKNODETICKET :
- case HELPDESKNODEFOLLOWUP :
- break; // Not yet implemented
- }
- }
- /**
- * Helpdesk data entry form. Used for both node add and edit
- * testing for $node->nid allows the code to define whether the node is to be created of modified
- * @param object $node the node to be entered
- * @return string HTML
- */
- function helpdesk_form (&$node) //XXXwas helpdesk_form(&$node)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HELPDESK_FORM (node = " ; print_r ($node) ; echo ")</pre>" ; }
- $output = '' ;
- // In order to be able to attach taxonomy terms to this node, we need
- // to display the appropriate form elements.
- if (function_exists('taxonomy_node_form'))
- {
- $output .= implode('', taxonomy_node_form('helpdesk', $node));
- }
- else
- { theme_error('helpdesk cannot find taxonomy_node_form. Have you activated taxonomy.module') ; }
- switch (_helpdesk_node_type($node))
- {
- case HELPDESKNODECONTRACT:
- if (!isset($node->{HELPDESKNODECONTRACT})) // Happens at the first step of node creation
- {
- $node->{HELPDESKNODECONTRACT} = new helpdeskContract();
- $node->{HELPDESKNODECONTRACT}->init($node, FALSE); // $node is always set at this point, load from it, not from DB
- }
- $output = $node->{HELPDESKNODECONTRACT}->form();
- break;
- case HELPDESKNODETICKET:
- $output = helpdeskTicket::createForm ($node) ;
- break ;
- case HELPDESKNODEFOLLOWUP:
- $output = helpdeskFollowup::createForm () ;
- break ;
- default:
- echo "<p>Anomaly: helpdesk_form called for type " . _helpdesk_node_type($node) . "</p>" ;
- break;
- }
- // echo "<p>In helpdesk_form</p>" ;
- return $output ;
- } // helpdesk_form
- /**
- * Display help and module information
- * Documented values as of 4.6.3 and HEAD on 2005/08/21
- * @param string $section Drupal URL path (or: menu item) the help is being requested for, e.g. admin/node or user/edit. Recognizes special descriptors after a "#" sign
- * @return help text for section
- */
- function helpdesk_help ($section = '')
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD HELP (section = $section), " ; }
- $output = '' ;
- switch ($section)
- {
- /* // The name of a module (unused, but there)
- case "admin/modules#name" :
- break; */
- // The description found on the admin/system/modules page.
- case "admin/modules#description":
- $output = t ("Enable Helpdesk/ticketing functions") ;
- break;
- // The module's help text, displayed on the admin/help page and through the module's individual help link.
- case "admin/help#helpdesk":
- $output = t ("This module allows for the generation of tickets, and management of helpdesk calls. "
- . "It enables tickets to be bound to support contracts and managed by a "
- . "helpdesk contract administrator. Various types of charging are available, "
- . "included unlimited, time spent, number of tickets, and date limit.") ;
- break ;
- /* // The help for a distributed authorization module (if applicable).
- case "user/help#helpdesk":
- break ;*/
- // The description of a node type (if applicable).
- case "node/add#" . HELPDESKNODECONTRACT:
- $output = t("Define a new helpdesk contract for an existing helpdesk customer") ;
- break ;
- case "node/add#" . HELPDESKNODETICKET:
- $output = t("Obtain a helpdesk ticket for a new helpdesk issue") ;
- break ;
- case "node/add#" . HELPDESKNODEFOLLOWUP:
- $output = t("Add a followup to an existing helpdesk ticket") ;
- break ;
- }
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- echo "output : $output</pre>" ;
- return $output;
- } // function helpdesk_help
- /**
- * Upon creation of a helpdesk-related node, perform insertions on our private tables
- * We're not supposed to test for access here, as it's already been done earlier in node_add (?)
- * @param object $node the node being inserted
- * @return void
- */
- function helpdesk_insert ($node)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD INSERT (node = " ; print_r ($node) ; echo ")</pre>" ; }
- switch ($node->type)
- {
- case HELPDESKNODECONTRACT:
- $o = new helpdeskContract();
- $o->init($node, FALSE); // Not yet in DB, load from $node
- $o->insert();
- break ;
- case HELPDESKNODETICKET:
- echo "<pre>Inserting ticket</pre>" ;
- break ;
- case HELPDESKNODEFOLLOWUP:
- echo "<pre>Inserting followup</pre>" ;
- break ;
- default :
- echo "<pre>helpdesk_insert: insertion d'un type non supporté: $node->type</pre>" ;
- break ;
- }
- }
- /**
- * This hook enables modules to add links to many parts of Drupal.
- * Links may be added in nodes or in the navigation block, for example.
- * In our case, this will allow followups to be added to either issues or followups (threading)
- * @param string $type An identifier declaring what kind of link is being requested. Possible values:
- * - node: Links to be placed below a node being viewed.
- * - comment: Links to be placed below a comment being viewed.
- * @param int $node A node object passed in case of node links.
- * @param int $teaser In case of node link: a 0/1 flag depending on whether the node is displayed with its teaser or its full form (on a node/nid page)
- * @return array array of links
- * @link http://drupaldocs.org/api/head/function/hook_link Drupal API
- */
- function helpdesk_link($type, $node = NULL, $teaser = FALSE)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD LINK ($type, $node->nid, $teaser)</pre>" ; }
- if ((!isset($type)) || ($type == 'comment'))
- return NULL ;
- if (!isset($node))
- die("helpdesk_link('node', NULL, $teaser) invoked: invalid set of parameters") ;
- /**
- * @todo Access should be tested
- * @todo It should be possibly to add a followup to the original issue from a followup
- **/
- switch ($node->type)
- {
- case HELPDESKNODETICKET:
- $links[] = l(t('add followup'), ('helpdesk/followup/' . $node->nid),
- array('title' => t('Add a followup to this ticket.')));
- break;
- case HELPDESKNODEFOLLOWUP:
- $links[] = l(t('add followup'), 'helpdesk/followup/' . $node->nid,
- array('title' => t('Add a followup to this followup (threaded answer).')));
- break;
- case HELPDESKNODECONTRACT:
- $links[] = l(t('new ticket'), 'node/add/' . HELPDESKNODETICKET . '/' . $node->nid,
- array('title' => t('Obtain a ticket for an issue covered by this contract.')));
- break;
- default:
- $links = NULL ; // die("helpdesk_link('node', $node->nid, $teaser) invoked, but node is of type: $node->type");
- }
- return $links ;
- }
- /**
- * load auxiliary data for HD nodes. We wrap the returned object in an array to prevent mixing with
- * other modules and drupal core.
- * @param object $node the node being loaded
- * @return object the properties to be added to the passed node object
- * @link http://drupaldocs.org/api/4.6/function/hook_load Drupal API
- */
- function helpdesk_load($node)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD LOAD (" . _helpdesk_get_node_property($node, 'nid') . ")</pre>\r\n" ; }
- $output = NULL ;
- switch ($node->type) // Is supposed to be assigned and valid
- {
- case HELPDESKNODECONTRACT : // Load attributes from hd_contract/hd_timeinfo
- $o = new helpdeskContract();
- $o->init($node, TRUE); // Load from DB
- break ;
- case HELPDESKNODETICKET : // Load attributes and thread from hd_event/hd_timeinfo
- break ;
- case HELPDESKNODEFOLLOWUP : // Load attributes and thread from hd_event/hd_timeinfo
- break ;
- default :
- die("helpdesk_load invoked for node $node->nid, incorrect type $node->type");
- }
- if (isset($o))
- {
- $output = array();
- $output [$node->type] = $o ;
- }
- else
- return NULL ;
- return $output ; // Should contain the auxiliary data
- }
- /**
- * HELPDESK menu is enabled for all users with HELPDESK
- * @return array of menu definitions
- */
- function helpdesk_menu($may_cache) {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo '<pre>HD MENU</pre>' ; }
- $items = array();
- if ($may_cache)
- {
- $items[] = array('path' => 'node/add/' . HELPDESKNODECONTRACT,
- 'title' => t(HELPDESKTITLECONTRACT),
- 'access' => helpdesk_access('create', HELPDESKNODECONTRACT));
- $items[] = array('path' => 'node/add/' . HELPDESKNODETICKET,
- 'title' => t(HELPDESKTITLETICKET),
- 'access' => helpdesk_access('create', HELPDESKNODETICKET));
- $items[] = array('path' => 'node/add/' . HELPDESKNODEFOLLOWUP,
- 'title' => t(HELPDESKTITLEFOLLOWUP),
- 'access' => helpdesk_access('create', HELPDESKNODEFOLLOWUP));
- $items[] = array('path' => 'helpdesk/followup/',
- 'title' => t(HELPDESKTITLEFOLLOWUP),
- 'access' => helpdesk_access('create', HELPDESKNODEFOLLOWUP),
- 'type' => MENU_CALLBACK); // This is to allow followups to a known node, so it must be called from a node, not from the menu
- }
- // echo "<pre>helpdesk_menu: " ; print_r ($items) ; echo ", may_cache: " . ($may_cache ? "TRUE" : "FALSE") . "</pre>" ;
- return $items;
- }
- /**
- * Implementation of hook_nodeapi, for tracing purposes only
- *
- * @param object $node
- * @param string $op
- * @param boolean $teaser
- * @param boolean $page
- */
- function helpdesk_nodeapi(&$node, $op, $teaser = NULL, $page = NULL)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD NODEAPI(node $node->nid, op = $op, teaser = $teaser, page = $page)</pre>\r\n" ; }
- }
- /**
- * Name our node names. See also helpdesk_node_types
- * @param mixed node either a string (node type ) or node object
- * @return string the human-readable node name
- */
- function helpdesk_node_name ($node)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- {
- $ret = "<pre>HD NODE_NAME (" ;
- if (is_object($node))
- $ret .= "OBJ: nid = " . (isset($node->nid) ? $node->nid : 'new node') . ", type = $node->type" ;
- else
- $ret .= "Plain: $node" ;
- $ret .= ")</pre>\r\n" ;
- print ($ret);
- }
- switch (is_string ($node) ? $node : (is_array($node) ? $node['type'] : $node->type))
- {
- case HELPDESKNODECONTRACT: return t (HELPDESKTITLECONTRACT) ;
- case HELPDESKNODETICKET: return t (HELPDESKTITLETICKET) ;
- case HELPDESKNODEFOLLOWUP: return t (HELPDESKTITLEFOLLOWUP) ;
- }
- return NULL;
- }
- /**
- * Define our node types
- * @return array the array of our node types
- */
- function helpdesk_node_types ()
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo '<pre>HD NODE_TYPES</pre>' ; }
- return array (
- HELPDESKNODECONTRACT,
- HELPDESKNODETICKET,
- HELPDESKNODEFOLLOWUP) ;
- }
- /**
- * Valid permissions for this module
- * @return array An array of valid permissions for the helpdesk module
- */
- function helpdesk_perm ()
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo '<pre>HELPDESK_PERM</pre>' ; }
- return array (
- HELPDESKPERMUSER,
- HELPDESKPERMCUSTOMER,
- HELPDESKPERMTECH
- ) ;
- } // function helpdesk_perm()
- /**
- * Module configuration settings
- * @return string settings HTML or deny access
- */
- function helpdesk_settings ()
- {
- $output = '' ;
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HELPDESK_SETTINGS</pre>" ; }
- // only HELPDESK Tech support can access this module
- if (!user_access (HELPDESKPERMTECH))
- {
- return message_access () ;
- }
- $output .= form_checkbox // checked, description, attributes, required
- (
- t ("Show users their current roles"), // title
- HELPDESKVARSHOWROLES, // name
- TRUE, // value
- variable_get (HELPDESKVARSHOWROLES, FALSE), // checked
- t ("Allow users to see their Drupal roles on their \"My account/edit\" page, \"user roles\" local task."),
- NULL, // attributes
- FALSE
- ) ;
- $output .= form_textfield // checked, description, attributes, required
- (
- t ("Ticket prefix"), // title
- HELPDESKVARTICKETPREFIX, // name
- variable_get(HELPDESKVARTICKETPREFIX, ''), // initial value
- 8, // size of field
- 8, // max length
- t ("The prefix to be prepended to the node number to build ticket numbers as seen by customers."), // description
- NULL, // attributes
- FALSE
- ) ;
- $output .= form_textfield // checked, description, attributes, required
- (
- t ("Ticket offset"), // title
- HELPDESKVARTICKETOFFSET, // name
- variable_get(HELPDESKVARTICKETOFFSET, 0), // initial value
- 8, // size of field
- 8, // max length
- t ("The number to be added to the node number to build ticket numbers as seen by customers."), // description
- NULL, // attributes
- FALSE
- ) ;
- return $output;
- }
- /**
- * Specs: Respond to node updating. This is a hook used by node modules. It is called to allow the module to take action when an edited node is being updated in the database by, for example, updating information in related tables.
- * @param object $node The node being updated
- * @return void
- * @todo see source
- */
- function helpdesk_update($node)
- {
- /* For all our nodes:
- - copy the node/created, node/changed timestaps to hd_timeinfo
- - copy the additional properties to hd_contract, hd_event
- */
- return ;
- }
- /**
- * Per the docs: This is a hook used by node modules.
- * It allows a module to define a custom method of displaying its nodes,
- * usually by displaying extra information particular to that node type.
- * @param object $node
- * @param string $teaser
- * @param int $page
- * @return void
- */
- function helpdesk_view(&$node, $teaser = FALSE, $page = FALSE)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HELPDESK_VIEW (node = " . _helpdesk_get_node_property($node, 'nid') . ", teaser = $teaser, page = $page)</pre>" ; }
- $output = '' ;
- $node = node_prepare ($node, $teaser) ; // Filter according to node filter settings
- if ($teaser)
- {
- $output = 'We are working on the teaser' ;
- $node->teaser = $output ;
- $node->body = '' ;
- unset ($output) ;
- }
- else
- {
- switch ($node->type)
- {
- case HELPDESKNODETICKET:
- if (!isset($node->{$node->type})) // Not coming from a form (hence not a preview). Can come from DB
- {
- $node->{$node->type} = new helpdeskTicket();
- $node->{$node->type}->init($node, TRUE);
- }
- $onode = $node->{$node->type};
- $output = theme_placeholder($onode->getTicket ()) ;
- $node->body = $onode->view() . $node->body ;
- $node->body = theme_box (sprintf (t('Ticket number %s'), $output), $node->body, 'main') ;
- break ;
- case HELPDESKNODEFOLLOWUP:
- // Same as above
- break ;
- case HELPDESKNODECONTRACT:
- if (!isset($node->{$node->type}))
- {
- $node->{$node->type} = new helpdeskContract();
- $node->{$node->type}->init($node, FALSE);
- }
- $output .= $node->{$node->type}->view();
- $output = theme_box(t('Contract details'), $output, 'main');
- $output .= theme_box(t('Contract description'), $node->body, 'main');
- $node->body = $output ;
- break ;
- }
- $node->body .= theme_placeholder (t('Notice: for traceability reasons, helpdesk-related nodes cannot be edited by users and customers. To modify, just add a followup.')) ;
- unset($o) ;
- $node->teaser = 'No teaser when \$teaser is not 1' ;
- }
- /* $themed_node = theme ('node', $node) ; */
- }
- /**
- * Act on user account actions.
- * This hook allows modules to react when operations are performed on user accounts.
- * Sequence of calls for high-level functions:
- * - creation: validate, load, insert, load. We don't care, yet.
- * - prepare update: categories, load, form
- * - perform update: load, validate, update, load
- * - prepare deletion: categories, load
- * - perform deletion: categories, load, delete(confirm=1). We should do something about tickets/issues.
- * @param string $op Operation to be performed on user
- * @param array $edit array of form values submitted by the user
- * @param object $account The user object on which the operation is being performed.
- * @param string $category The active category of user information being edited.
- * @return mixed
- * @see _helpdesk_user_load()
- */
- function helpdesk_user ($op, $edit, $account, $category = NULL) //XXX edit and author should be passed by ref
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD USER (op = $op, "
- . (isset($edit)
- ? (is_array($edit)
- ? (array_key_exists('uid', $edit) ? ("edit[uid] = " . $edit['uid']) : print_r($edit, True))
- : ("edit: string = [$edit]")
- )
- : 'edit not set')
- . ", user name = "
- . (is_object($account)
- ? (isset($account->name)
- ? $account->name
- : 'name not set'
- )
- : 'not object'
- )
- .", category = $category)</pre>" ;
- }
- global $user ; // Masks the user parameter !
- $output = NULL ;
- switch ($op)
- {
- case 'view': // The user's account information is being displayed.
- { $output = _helpdesk_user_view($user); break ; }
- case 'categories': // A set of user information categories is requested.
- { $output = _helpdesk_user_categories(); break ; }
- case 'load': // The user account is being loaded. The module may respond to this and insert additional information into the user object.
- /* in our case, this means loading the linked customer info if we need it later on */
- {
- if (isset($edit) && is_array($edit) && array_key_exists('uid', $edit))
- _helpdesk_user_load($user, $edit['uid']);
- $output = NULL ; // user_load is void
- break;
- }
- case 'form': // The user account edit form is about to be displayed. The module should present the form elements it wishes to inject into the form.
- { $output = _helpdesk_user_form($edit, $category); break; }
- case 'delete': // The user account is being deleted.
- /**
- * @todo If this user has tickets, followups, or helpdesk contracts, they will be orphaned. The module should grant them to someone else or delete them
- */
- { $output = NULL; break; }
- case "insert": // The user account is being added. As long as we don't store default user information, we needn't care
- { $output = NULL; break; }
- case "login": // The user just logged in. We don't care.
- { $output = NULL; break; }
- case "logout": // The user just logged out. We don't care. At some point, this could allow automatic timestamping of pending nodes
- { $output = NULL; break; }
- case "update": // The user account is being changed. Normally, we shouldn't care as long as we don't store user information
- { $output = NULL; break; }
- case "validate": // The user account is about to be modified. Normally, we shouldn't care as long as we don't store user information.
- { $output = NULL; break; }
- }
- return $output;
- }
- /**
- * Verify a node editing form. This is a hook used by node modules.
- * It is called to allow the module to verify that the node is in a format valid to post
- * to the site. It can also be used to make changes to the node before submission, such
- * as node-type-specific formatting. Errors should be set with form_set_error().
- *
- * @param object $node The node to be validated.
- */
- function helpdesk_validate(&$node)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD VALIDATE (node: " . print_r ($node, TRUE) . ")</pre>" ; }
- /* Checks to be performed:
- - date validity, absolute and relative
- - status and severity having valid values
- */
- }
- /* ----- Private functions ------------------------------------------------------------ */
- /**
- * Defines the name of the blocks attached to a delta
- * @param int $delta the block number
- * @return string the name of the block
- * @see helpdesk_block()
- */
- function _helpdesk_block_list ($delta)
- {
- if ($delta > HELPDESKBLOCKMAX)
- return NULL ;
- // No need to test for HELPDESKPERMUSER as access won't be granted if if is absent
- $block [HELPDESKBLOCKMYOPENTICKETS] ["info"] = t('Helpdesk > My current tickets') ;
- $block [HELPDESKBLOCKMYLATESTTICKETS] ["info"] = t('Helpdesk > My latest tickets') ;
- if (user_access (HELPDESKPERMCUSTOMER))
- {
- $block [HELPDESKBLOCKCUSTOMEROPENTICKETS]["info"] = t('Helpdesk > Customer\'s current tickets') ;
- $block [HELPDESKBLOCKCUSTOMERBALANCE] ["info"] = t('Helpdesk > Customer\'s contracts balance') ;
- }
- if (user_access (HELPDESKPERMTECH))
- {
- $block [HELPDESKBLOCKALLOPENTICKETS] ["info"] = t('Helpdesk > Oldest active tickets') ;
- }
- return $block ;
- }
- /**
- * Subroutine for helpdesk_block/configure
- * @param int $delta
- * @return string HTML for the configuration form
- * @see helpdesk_block()
- */
- function _helpdesk_block_configure ($delta)
- {
- $output = '' ;
- $msg = t("This block (%d) doesn't have any configuration option") ;
- switch ($delta)
- {
- case HELPDESKBLOCKMYOPENTICKETS: $output .= sprintf ($msg, $delta) ; break ;
- case HELPDESKBLOCKMYLATESTTICKETS: $output .= sprintf ($msg, $delta) ; break ;
- case HELPDESKBLOCKCUSTOMEROPENTICKETS: $output .= sprintf ($msg, $delta) ; break ;
- case HELPDESKBLOCKCUSTOMERBALANCE: $output .= sprintf ($msg, $delta) ; break ;
- case HELPDESKBLOCKALLOPENTICKETS: $output .= sprintf ($msg, $delta) ; break ;
- default: t("You requested an unavailable block.") ;
- }
- return $output ;
- }
- /**
- * Subroutine for helpdesk_block/save
- * @param int $delta
- * @return void
- * @see helpdesk_block()
- */
- function _helpdesk_block_save ($delta)
- {
- // variable_set (HELPDESKCONFVAR, $_REQUEST ['edit'][HELPDESKCONFVAR]) ; // No longer used
- /* $ret = "REQUEST: <pre>" . var_export ($_REQUEST ['edit'], True) . "</pre>" ;
- echo $ret ; */
- }
- /**
- * Checks whether or not the current user is a customer
- * Does not depend on bound users or contracts
- * @return boolean
- */
- function _helpdesk_iscustomer ()
- {
- $s = HELPDESKPERMCUSTOMER ;
- // echo "<pre>Perm requested: $s</pre>" ;
- return (user_access ($s)) ;
- }
- /**
- * Returns the contracts owned by a customer
- * @param int $uidcustomer The UID of the customer being examined. Not necessarily the current user
- * @return mixed NULL in case an error (presumably access limitation) happens, array of contracts otherwise, possibly empty
- */
- function _helpdesk_getnidcontracts ($uidcustomer)
- {
- /* Can be checked only by tech for any uidcustomer, and by customer for own contracts
- */
- global $user;
- if ((!user_access(HELPDESKPERMTECH)) && (!(user_access(HELPDESKPERMCUSTOMER) && ($user->uid == $uidcustomer))))
- return NULL ;
- else
- {
- $q = '
- SELECT
- n.nid, n.title
- FROM {node} n
- INNER JOIN {hd_contract} hdc on n.nid = hdc.nid
- WHERE
- hdc.uidcustomer = %d
- ORDER BY
- 2
- ' ;
- $res = db_query($q, $uidcustomer);
- while ($o = db_fetch_object($res))
- {
- $ret[] = $o ;
- }
- return $ret ;
- }
- }
- /**
- * Subroutine for helpdesk_block/view
- * @param int $delta
- * @return array array of HTML blocks
- * @see helpdesk_block()
- */
- function _helpdesk_block_view ($delta)
- {
- $block = array() ;
- if ($delta > HELPDESKBLOCKMAX)
- return $block;
- switch ($delta)
- {
- case HELPDESKBLOCKMYOPENTICKETS:
- if (user_access(HELPDESKPERMUSER) || user_access(HELPDESKPERMCUSTOMER) || user_access(HELPDESKPERMTECH))
- {
- $block['subject'] = t('My open tickets');
- $block['content'] = _helpdesk_block_view_MYOPENTICKETS();
- }
- break ;
- case HELPDESKBLOCKMYLATESTTICKETS:
- if (user_access(HELPDESKPERMUSER) || user_access(HELPDESKPERMCUSTOMER) || user_access(HELPDESKPERMTECH))
- {
- $block['subject'] = t('My latest tickets');
- $block['content'] = _helpdesk_block_view_MYLATESTTICKETS();
- }
- break ;
- case HELPDESKBLOCKCUSTOMEROPENTICKETS:
- if (user_access(HELPDESKPERMCUSTOMER) || user_access(HELPDESKPERMTECH))
- {
- $block['subject'] = t('Customer\'s open tickets');
- $block['content'] = _helpdesk_block_view_CUSTOMEROPENTICKETS();
- }
- break ;
- case HELPDESKBLOCKCUSTOMERBALANCE:
- if (user_access(HELPDESKPERMCUSTOMER) || user_access(HELPDESKPERMTECH))
- {
- $block['subject'] = t('Customer\'s contract balance');
- $block['content'] = t('(none)') ;
- }
- break ;
- case HELPDESKBLOCKALLOPENTICKETS:
- if (user_access(HELPDESKPERMTECH))
- {
- $block['subject'] = t('All open tickets');
- $block['content'] = _helpdesk_block_view_ALLOPENTICKETS();
- }
- break ;
- }
- return $block ;
- }
- /**
- * Build a block returning a list of the current user's open tickets.
- * - Open tickets are those for which tidstatus matches the first entry in the helpdesk_status vocabulary.
- * - SECURITY: relies on _helpdesk_block_view to filter requests. Does not implement security on its own.
- * @see _helpdesk_block_view()
- * @return string HTML code for the list
- */
- function _helpdesk_block_view_MYOPENTICKETS()
- {
- global $user ;
- $output = '' ;
- $csq = "
- SELECT n.nid, n.title
- FROM {hd_event} hde
- INNER JOIN {node} n on hde.nid = n.nid
- WHERE
- (n.uid = %d)
- and (hde.tidstatus <>
- (
- SELECT min(td.tid)
- FROM term_data td
- INNER JOIN vocabulary v on td.vid = v.vid
- WHERE
- v.name = 'helpdesk_status'
- ))
- " ;
- $q = db_query ($csq, array($user->uid)) ;
- while ($o = db_fetch_object ($q))
- {
- $output .= l($o->title, 'node/' . $o->nid) . '<br/>' ;
- }
- unset ($q);
- unset ($csq) ;
- return _helpdesk_notempty($output, t('none')) ;
- }
- /**
- * Build a block returning a list of all open tickets.
- * - Open tickets are those for which tidstatus matches the first entry in the helpdesk_status vocabulary.
- * - SECURITY: relies on _helpdesk_block_view to filter requests. Does not implement security on its own. User is assumed to have HELPDESKPERMTECH perm checked by the caller
- * @see _helpdesk_block_view()
- * @return string HTML code for the list
- */
- function _helpdesk_block_view_ALLOPENTICKETS()
- {
- $output = '' ;
- $csq = "
- SELECT n.nid, n.title
- FROM {hd_event} hde
- INNER JOIN {node} n on hde.nid = n.nid
- WHERE
- hde.tidstatus <>
- (
- SELECT min(td.tid)
- FROM term_data td
- INNER JOIN {vocabulary} v on td.vid = v.vid
- WHERE
- v.name = 'helpdesk_status'
- )
- " ;
- $q = db_query ($csq) ;
- while ($o = db_fetch_object ($q))
- {
- $output .= l($o->title, 'node/' . $o->nid) . '<br/>' ;
- }
- unset ($q);
- unset ($csq) ;
- return _helpdesk_notempty($output, t('none')) ;
- }
- /**
- * Build a block returning a list of the latest tickets for the current user, be they open or not
- * - SECURITY: relies on _helpdesk_block_view to filter requests. Does not implement security on its own. User is assumed to have HELPDESKPERMCUSTOMER perm checked by caller
- * @see _helpdesk_block_view()
- * @return string HTML code for the list
- */
- function _helpdesk_block_view_MYLATESTTICKETS()
- {
- global $user ;
- $output = '' ;
- $csq = "
- SELECT n.nid, n.title
- FROM {hd_event} hde
- INNER JOIN {node} n on hde.nid = n.nid
- WHERE
- (n.uid = %d)
- ORDER BY
- n.changed DESC, n.created DESC
- " ;
- $q = db_query ($csq, array($user->uid)) ;
- while ($o = db_fetch_object ($q))
- {
- $output .= l($o->title, 'node/' . $o->nid) . '<br/>' ;
- }
- unset ($q);
- unset ($csq) ;
- return _helpdesk_notempty($output, t('none')) ;
- }
- /**
- * Build a block returning a list of all open tickets for the users linked to this customer.
- * - Open tickets are those for which tidstatus matches the first entry in the helpdesk_status vocabulary.
- * - SECURITY: relies on _helpdesk_block_view to filter requests. Does not implement security on its own. User is assumed to have HELPDESKPERMCUSTOMER perm checked by caller
- * @see _helpdesk_block_view()
- * @return string HTML code for the list
- */
- function _helpdesk_block_view_CUSTOMEROPENTICKETS()
- {
- global $user ;
- $output = '' ;
- $csq = "
- SELECT n.nid, n.title
- FROM {hd_event} hde
- INNER JOIN {node} n on hde.nid = n.nid
- INNER JOIN {hd_user} hdu on n.uid = hdu.uid
- WHERE
- (n.type = '%s')
- AND (hdu.uidcustomer = %d)
- AND hde.tidstatus <>
- (
- SELECT min(td.tid)
- FROM term_data td
- INNER JOIN {vocabulary} v on td.vid = v.vid
- WHERE
- v.name = 'helpdesk_status'
- )
- " ;
- $q = db_query($csq, array(HELPDESKNODETICKET, $user->uid)) ;
- while ($o = db_fetch_object ($q))
- {
- $output .= l($o->title, 'node/' . $o->nid) . '<br/>' ;
- }
- unset ($q);
- unset ($csq) ;
- return _helpdesk_notempty($output, t('none')) ;
- }
- /**
- * Build the public form of the node number from the actual nid
- *
- * @param int $nid The internal node number for the ticket
- * @return string The public form of the ticket number
- * @see _helpdesk_decode_nid()
- */
- function _helpdesk_encode_nid($nid)
- {
- $prefix = variable_get(HELPDESKVARTICKETPREFIX, '') ;
- $offset = variable_get(HELPDESKVARTICKETOFFSET, 0) ;
- $ticketnumber = $prefix . ($nid + $offset) ;
- unset($prefix);
- unset($offset);
- return $ticketnumber;
- }
- /**
- * Extract the actual $node->nid from the public form of the ticket number
- * @param string $ticketnumber The public form of the ticket number
- * @return int The internal node number value for the ticket
- * @see _helpdesk_encode_nid()
- */
- function _helpdesk_decode_nid($ticketnumber)
- {
- $prefix = variable_get(HELPDESKVARTICKETPREFIX, '') ;
- $nid = substr($ticketnumber, strlen($prefix)) ;
- $offset = variable_get(HELPDESKVARTICKETOFFSET, 0) ;
- $nid -= $offset ;
- unset($prefix);
- unset($offset);
- return $nid ;
- }
- /**
- * auxiliary function for helpdesk_user('view')
- * @param object $user
- * @return array An associative array of strings to display, keyed by category name
- * @see helpdesk_user
- * @todo display global account balance, pointer to the list of contracts (for customers),
- * @todo display global ticket starts, pointer to the list of tickets, followups (for users)
- */
- function _helpdesk_user_view($user)
- {
- $ret = NULL;
- $output = NULL;
- if (isset($user->uidCustomer)) // Can't use user_access(HELPDESKPERMUSER): admin will always get info even if he is not a HD user.
- {
- $ret .= t('<p>Helpdesk access managed by %customer-link</p>',
- array('%customer-link' => l($user->customerName, 'user/' . $user->uidCustomer)));
- }
- if ($user->uidCustomer == $user->uid) // we are a customer
- {
- $ret .= "<p></p>";
- $oc = new helpdeskCustomer();
- $oc->uid = $user->uid ;
- $oc->uidCustomer = $user->uidCustomer ;
- $arUsers = $oc->uidUsers();
- foreach($arUsers as $ou)
- {
- $arItems[] = l($ou->name, "user/$ou->uid", NULL) ;
- }
- $ret .= theme_item_list ($arItems, t('Managing helpdesk access for users:')) ;
- unset($arItems);
- unset($arUsers);
- $arContracts = _helpdesk_getnidcontracts($user->uidCustomer); // User has already been checked as a customer: there must be a result
- foreach($arContracts as $oc)
- {
- $arItems[] = l($oc->title, "node/$oc->nid", NULL) ;
- }
- $ret .= theme_item_list ($arItems, t('Holder of contracts:')) ;
- }
- if (isset($ret))
- {
- $ret .= t('Future versions will display more information, like '
- . 'users\' stats: account balance, #tickets, and so on.') ;
- $output = array ('Helpdesk account' => $ret) ;
- }
- return $output;
- }
- /**
- * auxiliary function for helpdesk_user('categorie'). Currently, this displays the user roles and admin status if the module has been set up to do so.
- * @return array
- * @see helpdesk_user
- */
- function _helpdesk_user_categories()
- {
- if (variable_get (HELPDESKVARSHOWROLES, FALSE))
- {
- return array (
- array (
- "name" => "helpdeskroles",
- "title" => t("user roles"),
- "weight" => 1
- )
- ) ;
- }
- else
- return NULL;
- }
- /**
- * auxiliary function for helpdeks_user('form'), to be displayed when user tries to display/edit his own data:
- * @param array $edit array of form values submitted by the user
- * @param string $category The category of personal information to be displayed/edited
- * @return array
- * @see helpdesk_user
- */
- function _helpdesk_user_form($edit, $category)
- {
- global $user;
- if (($category == 'helpdeskroles') && variable_get (HELPDESKVARSHOWROLES, FALSE)) // default category: account
- {
- $output = array
- (
- array
- (
- 'title' => t ('You have been assigned roles:'),
- 'data' => '<li>' . implode ('</li><li>', $edit ['roles']) . '</li>',
- 'weight'=> 0
- )
- ) ;
- if ($user->uid == 1)
- $output [0]['data'] .= t ("<li><em>sysop</em></li>") ;
- if (isset($output))
- $output [0]['data'] = '<ul>' . $output [0]['data'] . "</ul>" ;
- }
- else
- $output = NULL;
- return $output;
- }
- /**
- * implements helpdesk_user('load') : load customer/hd user data upon user load
- * do not load list of bound users for customers: this could be too heavy for something rarely (?) used
- * @param object &$user already loaded core user object
- * @param int $uid user id
- * @return void
- * @see helpdesk_user()
- */
- function _helpdesk_user_load(&$user, $uid)
- {
- if (HELPDESKDEBUGALLFUNCTIONS == TRUE)
- { echo "<pre>HD USER_LOAD (uid = $uid)</pre>" ; }
- $uo = new helpdeskUser();
- $uo->init($uid) ;
- if (isset($uo->uidCustomer))
- {
- $user->uidCustomer = $uo->uidCustomer ;
- $user->customerName = $uo->customerName;
- }
- unset($uo);
- }
- /* ----- End of code, restore entry conditions ---------------------------------------- */
- error_reporting ($_helpdesk_saved_er) ;
- unset ($_helpdesk_saved_er) ;
- //===== Remarks ==========================================================================
- /* To page content, use this type of code:
- $block_content .= "<div class=\"more-link\">"
- . l (t ("more"), "helpdesk", array ("title" => t ("More events on this day.")))
- . "</div>"; */
- /*
- 22/09/05 wnorrix chx: i have written a ticket module, is there a way i can send out a email when there is a comment added a) to the person who filled the ticket b) support team
- /**
- * @todo dans _view_*, mieux formater les blocs
- */
- ?>
Documentation generated on Tue, 01 Nov 2005 23:15:02 +0100 by phpDocumentor 1.3.0RC3