/**
 * on_object_deleted handler implemenation
 *
 * @param AngieObject $object
 * @return null
 */
function invoicing_handle_on_object_deleted($object)
{
    if (instance_of($object, 'TimeRecord')) {
        db_execute('DELETE FROM ' . TABLE_PREFIX . 'invoice_time_records WHERE time_record_id = ?', $object->getId());
    }
    // if
}
/**
 * Render object tasks section
 * 
 * Parameters:
 * 
 * - object - Selected project object
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_tasks($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $open_tasks = $object->getOpenTasks();
    if (is_foreachable($open_tasks)) {
        foreach ($open_tasks as $open_task) {
            ProjectObjectViews::log($open_task, $smarty->get_template_vars('logged_user'));
        }
        // foreach
    }
    // if
    $completed_tasks = $object->getCompletedTasks(COMPLETED_TASKS_PER_OBJECT);
    if (is_foreachable($completed_tasks)) {
        foreach ($completed_tasks as $completed_task) {
            ProjectObjectViews::log($completed_task, $smarty->get_template_vars('logged_user'));
        }
        // foreach
    }
    // if
    $smarty->assign(array('_object_tasks_object' => $object, '_object_tasks_open' => $open_tasks, '_object_tasks_can_reorder' => (int) $object->canEdit($smarty->get_template_vars('logged_user')), '_object_tasks_completed' => $completed_tasks, '_object_tasks_completed_remaining' => $object->countCompletedTasks() - COMPLETED_TASKS_PER_OBJECT, '_object_tasks_skip_wrapper' => array_var($params, 'skip_wrapper', false), '_object_tasks_skip_head' => array_var($params, 'skip_head', false), '_object_tasks_force_show' => array_var($params, 'force_show', true)));
    return $smarty->fetch(get_template_path('_object_tasks', 'tasks', RESOURCES_MODULE));
}
/**
 * Render select_default_assignment_filter control
 * 
 * Parameters:
 * 
 * - user - User - User using the page
 * - value - integer - ID of selected filter
 * - optional - boolean - Value is optional?
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_select_default_assignment_filter($params, &$smarty)
{
    $user = array_var($params, 'user', null, true);
    $value = array_var($params, 'value', null, true);
    $optional = array_var($params, 'optional', true, true);
    $default_filter_id = (int) ConfigOptions::getValue('default_assignments_filter');
    $default_filter = $default_filter_id ? AssignmentFilters::findById($default_filter_id) : null;
    $options = array();
    if (instance_of($default_filter, 'AssignmentFilter') && $optional) {
        $options[] = option_tag(lang('-- System Default (:filter) --', array('filter' => $default_filter->getName())), '');
    }
    // if
    $grouped_filters = AssignmentFilters::findGrouped($user, true);
    if (is_foreachable($grouped_filters)) {
        foreach ($grouped_filters as $group_name => $filters) {
            $group_options = array();
            foreach ($filters as $filter) {
                $group_options[] = option_tag($filter->getName(), $filter->getId(), array('selected' => $value == $filter->getId()));
            }
            // foreach
            if (count($options) > 0) {
                $options[] = option_tag('', '');
            }
            // if
            $options[] = option_group_tag($group_name, $group_options);
        }
        // foreach
    }
    // if
    return select_box($options, $params);
}
/**
 * Render object reminder information
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_recurring_period($params, &$smarty)
{
    $ticket = array_var($params, 'object');
    if (!instance_of($ticket, 'Ticket')) {
        return 'N/A';
    }
    // if
    $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
    mysql_select_db(DB_NAME);
    $query = "select * from healingcrystals_project_object_misc where object_id='" . (int) $ticket->getId() . "'";
    $result = mysql_query($query, $link);
    if (mysql_num_rows($result)) {
        $info = mysql_fetch_assoc($result);
        $reminder_date = $info['reminder_date'];
        $recurring_period = $info['recurring_period'];
        $recurring_period_type = $info['recurring_period_type'];
    }
    mysql_close($link);
    $resp = '<form name="frmRecurringPeriod" action="' . $ticket->getEditUrl() . '&mode=recurring_period_update_mode" method=post>
                    <input type="text" name="recurring_period" value="' . $recurring_period . '" maxlength="5" style="width:50px;" onchange="this.form.submit();" />&nbsp;
                    <select name="recurring_period_type" style="width:80px;" onchange="this.form.submit();">
                        <option value="D" ' . ($recurring_period_type == 'D' ? ' selected ' : '') . '>Days</option>
			<option value="W" ' . ($recurring_period_type == 'W' ? ' selected ' : '') . '>Weeks</option>
			<option value="M" ' . ($recurring_period_type == 'M' ? ' selected ' : '') . '>Months</option>
			<option value="Y" ' . ($recurring_period_type == 'Y' ? ' selected ' : '') . '>Years</option>
                    </select>
		</form>';
    return $resp;
}
/**
 * Render comments
 * 
 * Parameters:
 * 
 * - comments - comments that needs to be rendered
 * - page - current_page
 * - total_pages - total pages
 * - counter - counter for comment #
 * - url - base URL for link assembly
 * - parent - parent object
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_mobile_access_object_comments($params, &$smarty)
{
    $url_params = '';
    if (is_foreachable($params)) {
        foreach ($params as $k => $v) {
            if (strpos($k, 'url_param_') !== false && $v) {
                $url_params .= '&amp;' . substr($k, 10) . '=' . $v;
            }
            // if
        }
        // foreach
    }
    // if
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $user = array_var($params, 'user');
    if (!instance_of($user, 'User')) {
        return new InvalidParamError('object', $user, '$user is expected to be an instance of User class', true);
    }
    // if
    $page = array_var($params, 'page', 1);
    $page = (int) array_var($_GET, 'page');
    if ($page < 1) {
        $page = 1;
    }
    // if
    $counter = array_var($params, 'counter', 1);
    $counter = ($page - 1) * $object->comments_per_page + $counter;
    list($comments, $pagination) = $object->paginateComments($page, $object->comments_per_page, $user->getVisibility());
    $smarty->assign(array("_mobile_access_comments_comments" => $comments, "_mobile_access_comments_paginator" => $pagination, "_mobile_access_comments_url" => mobile_access_module_get_view_url($object), "_mobile_access_comments_url_params" => $url_params, "_mobile_access_comments_counter" => $counter, "_mobile_access_comments_show_counter" => array_var($params, 'show_counter', true)));
    return $smarty->fetch(get_template_path('_object_comments', null, MOBILE_ACCESS_MODULE));
}
 /**
  * This function saves the wiki page 
  *
  * @return void
  */
 function save()
 {
     if (instance_of($this->new_revision, 'Revision')) {
         // Increase the page revision number
         $this->setColumnValue('revision', $this->getColumnValue('revision') + 1);
         // Remove any other pages in this project which have the default page status
         if ($this->isColumnModified('project_index') && $this->getColumnValue('project_index') == 1) {
             $sql = 'UPDATE ' . $this->getTableName(true) . ' SET `project_index` = 0 WHERE `project_id` = ' . $this->getProjectId();
             DB::execute($sql);
         }
         // Remove any other pages in this project which have sidebar status
         if ($this->isColumnModified('project_sidebar') && $this->getColumnValue('project_sidebar') == 1) {
             $sql = 'UPDATE ' . $this->getTableName(true) . ' SET `project_sidebar` = 0 WHERE `project_id` = ' . $this->getProjectId();
             DB::execute($sql);
         }
         // Save this page with the new revision id
         parent::save();
         // Set the revisions's page Id
         $this->new_revision->setPageId($this->getId());
         //Set the project Id
         $this->new_revision->setProjectId($this->getProjectId());
         // Set the revision number in the revision object
         $this->new_revision->setRevision($this->getColumnValue('revision'));
         // If we have made a new revision of this page, then save the revision
         $this->new_revision->save();
     } else {
         // We haven't made a new revision, so we shouldn't update this page
         return false;
     }
 }
/**
 * Render object subscribers
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_subscriptions($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    js_assign('max_subscribers_count', MAX_SUBSCRIBERS_COUNT);
    require_once SYSTEM_MODULE_PATH . '/helpers/function.user_link.php';
    $subscribers = $object->getSubscribers();
    if (count($subscribers) > MAX_SUBSCRIBERS_COUNT) {
        $smarty->assign(array('_object_subscriptions_list_subscribers' => false, '_object_subscriptions_object' => $object, '_object_subscriptions_subscribers_count' => count($subscribers), '_object_subscription_brief' => array_var($params, 'brief', false), '_object_subscriptions_popup_url' => assemble_url('object_subscribers_widget', array('object_id' => $object->getId()))));
    } else {
        $links = null;
        if (is_foreachable($subscribers)) {
            $links = array();
            foreach ($subscribers as $subscriber) {
                $links[] = smarty_function_user_link(array('user' => $subscriber), $smarty);
            }
            // foreach
        }
        // if
        $smarty->assign(array('_object_subscriptions_list_subscribers' => true, '_object_subscriptions' => $subscribers, '_object_subscriptions_object' => $object, '_object_subscription_links' => $links, '_object_subscription_brief' => array_var($params, 'brief', false), '_object_subscriptions_popup_url' => assemble_url('object_subscribers_widget', array('object_id' => $object->getId()))));
    }
    // if
    return $smarty->fetch(get_template_path('_object_subscriptions', 'subscriptions', RESOURCES_MODULE));
}
/**
 * Show object visibility if it's private
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_visibility($params, &$smarty)
{
    static $ids = array();
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is not valid instance of ProjectObject class', true);
    }
    // if
    if ($object->getVisibility() > VISIBILITY_PRIVATE) {
        return '';
    }
    // if
    $user = array_var($params, 'user');
    if (!instance_of($user, 'User')) {
        return new InvalidParamError('user', $user, '$user is expected to be an instance of User class', true);
    }
    // if
    if (!$user->canSeePrivate()) {
        return '';
    }
    // if
    $id = array_var($params, 'id');
    if (empty($id)) {
        do {
            $id = 'object_visibility_' . make_string(40);
        } while (in_array($id, $ids));
    }
    // if
    $ids[] = $id;
    return open_html_tag('a', array('href' => assemble_url('project_object_visibility', array('project_id' => $object->getProjectId(), 'object_id' => $object->getId())), 'title' => lang('Private :type', array('type' => Inflector::humanize($object->getType()))), 'class' => 'object_visibility', 'id' => $id)) . '<img src="' . get_image_url('private.gif') . '" alt="" /></a><script type="text/javascript">App.widgets.ObjectVisibility.init("' . $id . '");</script>';
}
 /**
  * Return all filters grouped by group name
  *
  * @param User $user
  * @param boolean $skip_private
  * @return array
  */
 function findGrouped($user = null, $skip_private = false)
 {
     $result = null;
     $conditions = null;
     if (instance_of($user, 'User')) {
         $conditions = array('is_private = ? OR (is_private = ? AND created_by_id = ?)', false, true, $user->getId());
     } elseif ($skip_private) {
         $conditions = array('is_private = ?', false);
     }
     // if
     $all = AssignmentFilters::find(array('conditions' => $conditions, 'order' => 'group_name, name'));
     if (is_foreachable($all)) {
         $result = array();
         $other_filters = array();
         foreach ($all as $filter) {
             if ($group_name = $filter->getGroupName()) {
                 if (!isset($result[$group_name])) {
                     $result[$group_name] = array();
                 }
                 // if
                 $result[$group_name][] = $filter;
             } else {
                 $other_filters[] = $filter;
             }
             // if
         }
         // foreach
         if (count($other_filters)) {
             $result[lang('Other')] = $other_filters;
         }
     }
     // if
     return $result;
 }
/**
 * on_object_deleted handler implemenation
 *
 * @param AngieObject $object
 * @return null
 */
function source_handle_on_object_deleted($object)
{
    if (instance_of($object, 'Ticket') || instance_of($object, 'Discussion') || instance_of($object, 'Milestone') || instance_of($object, 'Task')) {
        db_execute('DELETE FROM ' . TABLE_PREFIX . 'commit_project_objects WHERE object_id = ? AND project_id = ?', $object->getId(), $object->getProjectId());
    }
    // if
}
/**
 * Populate quick portal object options
 *
 * @param NamedList $options
 * @param ProjectObject $object
 * @param Portal $portal
 * @param Commit $commit
 * @param string $file
 * @return null
 */
function discussions_handle_on_portal_object_quick_options(&$options, $object, $portal = null, $commit = null, $file = null)
{
    if (instance_of($object, 'Discussion')) {
        $options->beginWith('details', array('text' => lang('Toggle Details'), 'url' => '#'));
    }
    // if
}
/**
 * Handle on on_comment_deleted event
 *
 * @param Comment $comment
 * @param ProjectObject $parent
 * @return null
 */
function resources_handle_on_comment_deleted(&$comment, &$parent)
{
    if (instance_of($parent, 'ProjectObject')) {
        $parent->refreshCommentsCount();
    }
    // if
}
/**
 * Set created_ properties for a given object if not set
 *
 * @param DataObject $object
 * @return null
 */
function system_handle_on_before_object_insert($object)
{
    if ($object->fieldExists('created_on')) {
        if (!isset($object->values['created_on'])) {
            $object->setCreatedOn(new DateTimeValue());
        }
        // if
    }
    // if
    $user =& get_logged_user();
    if (!instance_of($user, 'User')) {
        return;
    }
    // if
    if ($object->fieldExists('created_by_id') && !isset($object->values['created_by_id'])) {
        $object->setCreatedById($user->getId());
    }
    // if
    if ($object->fieldExists('created_by_name') && !isset($object->values['created_by_name'])) {
        $object->setCreatedByName($user->getDisplayName());
    }
    // if
    if ($object->fieldExists('created_by_email') && !isset($object->values['created_by_email'])) {
        $object->setCreatedByEmail($user->getEmail());
    }
    // if
}
/**
 * List object comments
 * 
 * Parameters:
 * 
 * - object - Parent object. It needs to be an instance of ProjectObject class
 * - comments - List of comments. It is optional. If it is missing comments 
 *   will be loaded by calling getCommetns() method of parent object
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_comments_all($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $logged_user = $smarty->get_template_vars('logged_user');
    if (!instance_of($logged_user, 'User')) {
        return '';
    }
    // if
    $visiblity = $logged_user->getVisibility();
    //    if ($object->canView($logged_user) && $object->getVisibility() == VISIBILITY_PRIVATE) {
    if ($object->canView($logged_user)) {
        $visiblity = VISIBILITY_PRIVATE;
    }
    $comments = $object->getComments($visiblity);
    if (is_foreachable($comments)) {
        foreach ($comments as $comment) {
            ProjectObjectViews::log($comment, $logged_user);
            //BOF:task_1260
            $comment->set_action_request_n_fyi_flag($logged_user);
            //EOF:task_1260
        }
        // foreach
    }
    // if
    $count_from = 0;
    $smarty->assign(array('_object_comments_object' => $object, '_object_comments_count_from' => $count_from, '_object_comments_comments' => $comments, '_total_comments' => sizeof($comments)));
    return $smarty->fetch(get_template_path('_object_comments_all', 'comments', RESOURCES_MODULE));
}
 /**
  * Render log details
  *
  * @param TimeRecord $object
  * @param boolean $in_project
  * @return string
  */
 function renderHead($object = null, $in_project = false)
 {
     if ($object === null) {
         $object = $this->getObject();
     }
     // if
     if (instance_of($object, 'TimeRecord')) {
         $created_by = $this->getCreatedBy();
         $variables = array('user_name' => $created_by->getDisplayName(true), 'user_url' => $created_by->getViewUrl(), 'url' => $object->getViewUrl(), 'value' => $object->getValue(), 'status' => $object->isBillable() ? lang('billable') : lang('non-billable'));
         $parent = $object->getParent();
         if (instance_of($parent, 'ProjectObject')) {
             $variables['parent_name'] = $parent->getName();
             $variables['parent_type'] = $parent->getVerboseType(true);
             $variables['parent_url'] = $parent->getViewUrl();
         } else {
             $project = $object->getProject();
             $variables['parent_name'] = $project->getName();
             $variables['parent_type'] = lang('project');
             $variables['parent_url'] = $project->getOverviewUrl();
         }
         // if
         return $object->getValue() == 1 ? lang('<a href=":user_url">:user_name</a> logged <a href=":url">1 :status hour</a> for <a href=":parent_url">:parent_name</a> :parent_type', $variables) : lang('<a href=":user_url">:user_name</a> logged <a href=":url">:value :status hours</a> for <a href=":parent_url">:parent_name</a> :parent_type', $variables);
     }
     // if
     return '';
 }
/**
 * Render object tags
 *
 * Parameters:
 * 
 * - object - Selected object
 * - project - Selected project, if not present we'll get it from 
 *   $object->getProject()
 * 
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_tags($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $project = array_var($params, 'project');
    if (!instance_of($project, 'Project')) {
        $project = $object->getProject();
    }
    // if
    if (!instance_of($project, 'Project')) {
        return new InvalidParamError('project', $project, '$project is expected to be an instance of Project class', true);
    }
    // if
    $tags = $object->getTags();
    if (is_foreachable($tags)) {
        $prepared = array();
        foreach ($tags as $tag) {
            if (trim($tag)) {
                $prepared[] = '<a href="' . Tags::getTagUrl($tag, $project) . '">' . clean($tag) . '</a>';
            }
            // if
        }
        // if
        return implode(', ', $prepared);
    } else {
        return '<span class="no_tags">' . lang('-- No tags --') . '</span>';
    }
    // if
}
/**
 * on_object_deleted handler implemenation
 *
 * @param AngieObject $object
 * @return null
 */
function incoming_mail_handle_on_object_deleted($object)
{
    if (instance_of($object, 'Project')) {
        db_execute('UPDATE ' . TABLE_PREFIX . 'incoming_mailboxes SET enabled=0  WHERE project_id = ?', $object->getId());
    }
    // if
}
 /**
  * Return categories
  *
  * @param string $locale Locale key
  * @return I18nLocaleValue
  */
 function getCategories($locale)
 {
     trace(__FILE__, 'getCategories():begin');
     // Prepare SQL
     $set1 = "(SELECT DISTINCT `category_id` FROM " . $this->getTableName(true) . " WHERE `locale_id` = {$locale->getId()})";
     //$sql = "SELECT * FROM " . I18nCategories::getTableName(true) . " WHERE `id` IN $set1";
     $sql = "SELECT * FROM " . 'pp088_i18n_section' . " WHERE `id` IN {$set1}";
     trace(__FILE__, 'find():' . $sql);
     // Run!
     $rows = DB::executeAll($sql);
     // Empty?
     if (!is_array($rows) || count($rows) < 1) {
         trace(__FILE__, 'find():found 0');
         return null;
     }
     // if
     // If we have one load it, else loop and load many
     trace(__FILE__, 'find():found ' . count($rows));
     $objects = array();
     foreach ($rows as $row) {
         $object = $this->loadFromRow($row);
         if (instance_of($object, $this->getItemClass())) {
             $objects[] = $object;
         }
         // if
     }
     // foreach
     return count($objects) ? $objects : null;
     trace(__FILE__, 'getCategories():end');
 }
 /**
  * Construct company invoices controller
  *
  * @param Request $request
  * @return CompanyInvoicesController
  */
 function __construct($request)
 {
     parent::__construct($request);
     if (!Invoice::canAccessCompanyInvoices($this->logged_user, $this->active_company)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $this->wireframe->current_menu_item = 'invoicing';
     $this->wireframe->page_actions = array();
     $this->wireframe->addBreadCrumb(lang('Invoices'), assemble_url('people_company_invoices', array('company_id' => $this->active_company->getId())));
     $invoice_id = $this->request->getId('invoice_id');
     if ($invoice_id) {
         $this->active_invoice = Invoices::findById($invoice_id);
     }
     // if
     if (instance_of($this->active_invoice, 'Invoice')) {
         if ($this->active_invoice->getCompanyId() != $this->active_company->getId()) {
             $this->httpError(HTTP_ERR_CONFLICT);
         }
         // if
         $this->wireframe->addBreadCrumb($this->active_invoice->getName(), $this->active_invoice->getCompanyViewUrl());
     } else {
         $this->active_invoice = new Invoice();
     }
     // if
     $this->smarty->assign(array('active_invoice' => $this->active_invoice, 'page_tab' => 'invoices'));
     js_assign('invoicing_precision', INVOICE_PRECISION);
 }
/**
 * Render object assignees list
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_mobile_access_object_assignees($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $owner = $object->getResponsibleAssignee();
    if (!instance_of($owner, 'User')) {
        Assignments::deleteByObject($object);
        return lang('No one is responsible');
    }
    // if
    require_once SYSTEM_MODULE_PATH . '/helpers/function.user_link.php';
    $other_assignees = array();
    $assignees = $object->getAssignees();
    if (is_foreachable($assignees)) {
        foreach ($assignees as $assignee) {
            if ($assignee->getId() != $owner->getId()) {
                $other_assignees[] = '<a href="' . mobile_access_module_get_view_url($assignee) . '">' . clean($assignee->getName()) . '</a>';
            }
            // if
        }
        // foreach
    }
    // if
    if (count($other_assignees)) {
        return '<a href="' . mobile_access_module_get_view_url($owner) . '">' . clean($owner->getName()) . '</a> ' . lang('is responsible') . '. ' . lang('Other assignees') . ': ' . implode(', ', $other_assignees);
    } else {
        return '<a href="' . mobile_access_module_get_view_url($owner) . '">' . clean($owner->getName()) . '</a> ' . lang('is responsible') . '.';
    }
    // if
}
/**
 * Render select parent object for provided project
 * 
 * Supported paramteres:
 * 
 * - types - type of of parent objects to be listed
 * - project - Instance of selected project (required)
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_select_project_object($params, &$smarty)
{
    $project = array_var($params, 'project');
    if (!instance_of($project, 'Project')) {
        return new InvalidParamError('project', $project, '$project is expected to be an instance of Project class', true);
    }
    // if
    $value = array_var($params, 'value');
    unset($params['project']);
    $types = array_var($params, 'types', null);
    if (!$types || !is_foreachable($types = explode(',', $types))) {
        $types = array('ticket', 'file', 'discussion', 'page');
    }
    // if
    $id_name_map = ProjectObjects::getIdNameMapForProject($project, $types);
    if (!is_foreachable($id_name_map)) {
        return false;
    }
    // if
    $sorted = array();
    foreach ($id_name_map as $object) {
        $option_attributes = $value == $object['id'] ? array('selected' => true) : null;
        $sorted[strtolower($object['type'])][] = option_tag($object['name'], $object['id'], $option_attributes);
    }
    // foreach
    if (is_foreachable($sorted)) {
        foreach ($sorted as $sorted_key => $sorted_values) {
            $options[] = option_group_tag($sorted_key, $sorted_values);
        }
        // foreach
    }
    // if
    return select_box($options, $params);
}
/**
 * Populate quick object options
 *
 * @param NamedList $options
 * @param ProjectObject $object
 * @param Use $user
 * @return null
 */
function discussions_handle_on_project_object_quick_options(&$options, $object, $user)
{
    if (instance_of($object, 'Discussion')) {
        $options->beginWith('details', array('text' => lang('Toggle Details'), 'url' => '#'));
    }
    // if
}
/**
 * Display user name with a link to users profile
 * 
 * - user - User - We create link for this User
 * - short - boolean - Use short display name
 * 
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_user_link($params, &$smarty)
{
    static $cache = array();
    $user = array_var($params, 'user');
    $short = array_var($params, 'short', false);
    // User instance
    if (instance_of($user, 'User')) {
        if (!isset($cache[$user->getId()])) {
            //BOF:mod 20121030
            /*
            //EOF:mod 20121030
                    $cache[$user->getId()] = '<a href="' . $user->getViewUrl() . '" class="user_link">' . clean($user->getDisplayName($short)) . '</a>';
            //BOF:mod 20121030
            */
            $cache[$user->getId()] = '<a href="' . $user->getViewUrl() . '" class="user_link">' . clean($user->getDisplayName()) . '</a>';
            //EOF:mod 20121030
        }
        // if
        return $cache[$user->getId()];
        // AnonymousUser instance
    } elseif (instance_of($user, 'AnonymousUser') && trim($user->getName()) && is_valid_email($user->getEmail())) {
        return '<a href="mailto:' . $user->getEmail() . '" class="anonymous_user_link">' . clean($user->getName()) . '</a>';
        // Unknown user
    } else {
        return '<span class="unknow_user_link unknown_object_link">' . clean(lang('Unknown user')) . '</span>';
    }
    // if
}
/**
 * Render object assignees list
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_departments($params, &$smarty)
{
    $resp = '--';
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
    mysql_select_db(DB_NAME, $link);
    $query = "select a.category_name, a.id from \n\t\t\t healingcrystals_project_milestone_categories a \n\t\t\t inner join healingcrystals_project_object_categories b on b.category_id=a.id \n\t\t\t inner join healingcrystals_project_objects c on c.id=b.object_id where \n\t\t\t c.id='" . $object->getId() . "' order by a.category_name";
    $result = mysql_query($query, $link);
    if (mysql_num_rows($result)) {
        $resp = '';
        while ($info = mysql_fetch_assoc($result)) {
            if (instance_of($object, 'Milestone')) {
                $resp .= '<a href="' . assemble_url('project_milestones', array('project_id' => $object->getProjectId())) . '&category_id=' . $info['id'] . '">' . $info['category_name'] . '</a>, ';
            } elseif (instance_of($object, 'Ticket')) {
                $resp .= '<a href="' . assemble_url('project_tickets', array('project_id' => $object->getProjectId())) . '&department_id=' . $info['id'] . '">' . $info['category_name'] . '</a>, ';
            } elseif (instance_of($object, 'Page')) {
                $resp .= '<a href="' . assemble_url('project_pages', array('project_id' => $object->getProjectId())) . '&category_id=' . $info['id'] . '">' . $info['category_name'] . '</a>, ';
            } else {
                $resp .= $info['category_name'] . ', ';
            }
        }
        $resp = substr($resp, 0, -2);
    }
    mysql_close($link);
    return $resp;
}
/**
 * Populate quick object options
 *
 * @param NamedList $options
 * @param ProjectObject $object
 * @param Use $user
 * @return null
 */
function milestones_handle_on_project_object_quick_options(&$options, $object, $user)
{
    if (instance_of($object, 'Milestone') && $object->canEdit($user)) {
        $options->addAfter('reschedule', array('url' => $object->getRescheduleUrl(), 'text' => lang('Reschedule')), 'edit');
    }
    // if
}
function smarty_function_object_department_selection($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is not valid instance of ProjectObject class', true);
    }
    $select = '';
    $select = '<select onchange="modify_department_association(this);">';
    $select .= '<option value="">-- Select Department --</option>';
    $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
    mysql_select_db(DB_NAME);
    $selected_department_id = '';
    $query = mysql_query("select category_id from healingcrystals_project_object_categories where object_id='" . $object->getId() . "'");
    if (mysql_num_rows($query)) {
        $info = mysql_fetch_assoc($query);
        $selected_department_id = $info['category_id'];
    }
    $query = mysql_query("select id, category_name from healingcrystals_project_milestone_categories where project_id='" . $object->getProjectId() . "' order by category_name");
    while ($entry = mysql_fetch_assoc($query)) {
        $select .= '<option value="' . $entry['id'] . '" ' . ($selected_department_id == $entry['id'] ? ' selected ' : '') . ' >' . $entry['category_name'] . '</option>';
    }
    mysql_close($link);
    $select .= '</select>';
    return $select;
}
/**
 * Handle on_object_deleted event
 *
 * @param ApplicationObject $object
 * @return null
 */
function resources_handle_on_object_deleted($object)
{
    if (instance_of($object, 'User')) {
        AssignmentFilters::cleanByUser($object);
    }
    // if
}
/**
 * Render object assignees list
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_object_owner($params, &$smarty)
{
    $object = array_var($params, 'object');
    if (!instance_of($object, 'ProjectObject')) {
        return new InvalidParamError('object', $object, '$object is expected to be an instance of ProjectObject class', true);
    }
    // if
    $users_table = TABLE_PREFIX . 'users';
    $assignments_table = TABLE_PREFIX . 'assignments';
    $rows = db_execute_all("SELECT {$assignments_table}.is_owner AS is_assignment_owner, {$users_table}.id AS user_id, {$users_table}.company_id, {$users_table}.first_name, {$users_table}.last_name, {$users_table}.email FROM {$users_table}, {$assignments_table} WHERE {$users_table}.id = {$assignments_table}.user_id AND {$assignments_table}.object_id = ? and {$assignments_table}.is_owner='1' ORDER BY {$assignments_table}.is_owner DESC", $object->getId());
    if (is_foreachable($rows)) {
        $owner = null;
        foreach ($rows as $row) {
            if (empty($row['first_name']) && empty($row['last_name'])) {
                $user_link = '<a href="' . assemble_url('people_company', array('company_id' => $row['company_id'])) . '#user' . $row['user_id'] . '">' . clean($row['email']) . '</a>';
            } else {
                $user_link = '<a href="' . assemble_url('people_company', array('company_id' => $row['company_id'])) . '#user' . $row['user_id'] . '">' . clean($row['first_name']) . '</a>';
            }
            // if
            $owner .= $user_link . '&nbsp;';
        }
        // foreach
    }
    // if
    if (empty($owner)) {
        $owner = '--';
    }
    // if
    return $owner;
}
/**
 * on_time_report_footer_options event handler implementation
 *
 * @param TimeReport $report
 * @param array $options
 * @param Project $project
 * @param User $user
 * @return null
 */
function invoicing_handle_on_time_report_footer_options(&$report, &$options, &$project, &$user)
{
    if (Invoice::canAdd($user)) {
        $options[] = array('url' => instance_of($project, 'Project') ? assemble_url('invoices_add', array('time_report_id' => $report->getId(), 'project_id' => $project->getId())) : assemble_url('invoices_add', array('time_report_id' => $report->getId())), 'text' => lang('New Invoice'), 'icon' => get_image_url('create-invoice.gif', INVOICING_MODULE));
    }
    // if
}
/**
 * Display user's location by ip address if logged in
 * 
 * - user - User
 * 
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_user_location_by_ipaddress($params, &$smarty)
{
    $user = array_var($params, 'user');
    $resp = array();
    // User instance
    if (instance_of($user, 'User')) {
        $reference = new DateTimeValue("-30 minutes");
        $link = mysql_connect(DB_HOST, DB_USER, DB_PASS);
        mysql_select_db(DB_NAME);
        $query = "SELECT a.user_ip from " . TABLE_PREFIX . "user_sessions a inner join " . TABLE_PREFIX . "users b on a.user_id=b.id WHERE b.id='" . $user->getId() . "' and b.last_activity_on>'" . $reference . "'";
        $result = mysql_query($query, $link);
        if (mysql_num_rows($result)) {
            $info = mysql_fetch_assoc($result);
            $ip_address = $info['user_ip'];
            //link for any references in future http://www.geoplugin.com/webservices/php
            $data = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip=' . $ip_address));
            return $data['geoplugin_countryName'] . ' (' . $data['geoplugin_countryCode'] . '), ' . $data['geoplugin_city'];
        } else {
            return '--';
        }
        mysql_close($link);
    }
    // if
    return '--';
}