<?php

  /**
   * Framework level assignment management class
   *
   * @package angie.frameworks.assignees
   * @subpackage models
   */
  class FwAssignments {
    
    /**
     * Returns true if $user is assigneed to $object
     *
     * @param User $user
     * @param IAssignees $object
     * @return boolean
     */
    static function isAssignee(User $user, IAssignees $parent) {
      return Assignments::isResponsible($user, $parent) || DB::executeFirstCell('SELECT COUNT(*) FROM ' . TABLE_PREFIX . 'assignments WHERE parent_type = ? AND parent_id = ? AND user_id = ?', get_class($parent), $parent->getId(), $user->getId());
    } // isAssignee
    
    /**
     * Returns true if $user is assigned to $parent and set as main assignee
     *
     * @param User $user
     * @param IAssignees $parent
     * @return unknown
     */
    static function isResponsible(User $user, IAssignees $parent) {
      return $parent->getAssigneeId() && $parent->getAssigneeId() == $user->getId();
    } // isResponsible
  
    /**
     * Return all users assigned to a specific object
     *
     * @param ProjectObject $object
     * @return array
     */
    static function findAssigneesByObject($object) {
      $cache_id = 'object_assignments_' . $object->getId();
      
      $cached_values = cache_get($cache_id);
      if(is_array($cached_values)) {
        return count($cached_values) > 0 ? Users::findByIds($cached_values) : null;
      } // if
      
      $users_table = TABLE_PREFIX . 'users';
      $assignments_table = TABLE_PREFIX . 'assignments';
      
      $cached_values = DB::executeFirstCell("SELECT $users_table.id FROM $users_table, $assignments_table WHERE $assignments_table.parent_type = ? AND $assignments_table.parent_id = ? AND $assignments_table.user_id = $users_table.id", get_class($object), $object->getId());
      cache_set($cache_id, $cached_values);
      
      return count($cached_values) > 0 ? Users::findByIds($cached_values) : null;
    } // findAssigneesByObject
    
    /**
     * Return muber of users assigned to a given object
     *
     * @param ProjectObject $object
     * @return integer
     */
    static function countAssigneesByObject($object) {
      return (integer) DB::executeFirstCell('SELECT COUNT(*) FROM ' . TABLE_PREFIX . 'assignments WHERE parent_type = ? AND parent_id = ?', get_class($object), $object->getId());
    } // countAssigneesByObject
    
    /**
     * Delete assignmnets by project object
     *
     * @param IAssignees $parent
     * @return boolean
     */
    static function deleteByParent(IAssignees $parent) {
      cache_remove('object_assignments_' . $parent->getId());
      cache_remove('object_assignments_' . $parent->getId() . '_rendered');
      
      return DB::execute('DELETE FROM ' . TABLE_PREFIX . 'assignments WHERE parent_type = ? AND parent_id = ?', get_class($parent), $parent->getId());
    } // deleteByParent
    
    /**
     * Delete assignments by User
     *
     * @param User $user
     * @return boolean
     */
    static function deleteByUser(User $user) {
      cache_remove('user_assignments_' . $user->getId());
      cache_remove('user_responsible_' . $user->getId());
      
      return DB::execute('DELETE FROM ' . TABLE_PREFIX . 'assignments WHERE user_id = ?', $user->getId());
    } // deleteByUser
    
    /**
     * Delete entries by parents
     * 
     * $parents is an array where key is parent type and value is array of 
     * object ID-s of that particular parent
     * 
     * @param array $parents
     */
    static function deleteByParents($parents) {
      if(is_foreachable($parents)) {
        foreach($parents as $parent_type => $parent_ids) {
          DB::execute('DELETE FROM ' . TABLE_PREFIX . 'assignments WHERE parent_type = ? AND parent_id IN (?)', $parent_type, $parent_ids);
        } // foreach
      } // if
    } // deleteByParents
    
    /**
     * Delete by parent types
     * 
     * @param array $types
     */
    static function deleteByParentTypes($types) {
      return DB::execute('DELETE FROM ' . TABLE_PREFIX . 'assignments WHERE parent_type IN (?)', $types);
    } // deleteByParentTypes
    
  }