/**
  * Save project
  * 
  * $template is used when project is created to indicate wether project is 
  * being created from template or not
  *
  * @param Project $template
  * @return boolean
  */
 function save($template = null)
 {
     $modified_fields = $this->modified_fields;
     $is_new = $this->isNew();
     event_trigger('on_before_save_project', array('project' => &$this));
     $save = parent::save();
     if ($save && !is_error($save)) {
         if ($is_new) {
             // Add leader to project
             $project_user = new ProjectUser();
             $project_user->setProjectId($this->getId());
             $project_user->setUserId($this->getLeaderId());
             $project_user->save();
             clean_project_permissions_cache($this);
             event_trigger('on_project_created', array(&$this, &$template));
         } else {
             clean_project_permissions_cache($this);
             event_trigger('on_project_updated', array(&$this));
         }
         // if
         if (in_array('name', $modified_fields) || in_array('overview', $modified_fields)) {
             $content = $this->getName();
             if ($overview = $this->getOverview()) {
                 $content .= "\n\n" . $overview;
             }
             // if
             search_index_set($this->getId(), 'Project', $content);
         }
         // if
     }
     // if
     return $save;
 }
 /**
  * Save user into the database
  *
  * @param void
  * @return boolean
  */
 function save()
 {
     $modified_fields = $this->modified_fields;
     $is_new = $this->isNew();
     if ($is_new && $this->getToken() == '') {
         $this->resetToken();
     }
     // if
     $save = parent::save();
     if ($save && !is_error($save)) {
         if ($is_new || in_array('email', $modified_fields) || in_array('first_name', $modified_fields) || in_array('last_name', $modified_fields)) {
             $content = $this->getEmail();
             if ($this->getFirstName() || $this->getLastName()) {
                 $content .= "\n\n" . trim($this->getFirstName() . ' ' . $this->getLastName());
             }
             // if
             search_index_set($this->getId(), 'User', $content);
             cache_remove_by_pattern('object_assignments_*_rendered');
         }
         // if
         // Role changed?
         if (in_array('role_id', $modified_fields)) {
             clean_user_permissions_cache($this);
         }
         // if
     }
     // if
     return $save;
 }
 /**
  * Save this object into the database
  *
  * @param void
  * @return boolean
  * @throws DBQueryError
  * @throws ValidationErrors
  */
 function save()
 {
     $is_new = $this->isNew();
     $modified_fields = $this->modified_fields;
     $old_values = $this->old_values;
     if ($is_new) {
         $this->setType(get_class($this));
     }
     // if
     if ($this->isModified()) {
         $this->setVersion($this->getVersion() + 1);
         // increment object version on save...
     }
     // if
     db_begin_work();
     $save = parent::save();
     if (!$save || is_error($save)) {
         db_rollback();
         return $save;
     }
     // if
     // Log activities...
     if ($this->log_activities) {
         if ($is_new) {
             if ($this->log_creation) {
                 if (instance_of($this, 'File')) {
                     $activity_log = new NewFileActivityLog();
                 } else {
                     $activity_log = new ObjectCreatedActivityLog();
                 }
                 // if
                 $activity_log->log($this, $this->getCreatedBy());
             }
             // if
         } else {
             if ($this->log_update || $this->log_move_to_trash || $this->log_restore_from_trash) {
                 $trashed = false;
                 $restored = false;
                 if (is_array($this->modified_fields) && in_array('state', $modified_fields)) {
                     if (isset($old_values['state']) && $old_values['state'] == STATE_DELETED && $this->getState() == STATE_VISIBLE) {
                         $restored = true;
                     }
                     // if
                     if (isset($old_values['state']) && $old_values['state'] == STATE_VISIBLE && $this->getState() == STATE_DELETED) {
                         $trashed = true;
                     }
                     // if
                 }
                 // if
                 if ($trashed) {
                     if ($this->log_move_to_trash) {
                         $activity_log = new ObjectTrashedActivityLog();
                         $activity_log->log($this);
                     }
                     // if
                 } elseif ($restored) {
                     if ($this->log_restore_from_trash) {
                         $activity_log = new ObjectRestoredActivityLog();
                         $activity_log->log($this);
                     }
                     // if
                 } else {
                     if ($this->log_update) {
                         $activity_log = new ObjectUpdatedActivityLog();
                         $activity_log->log($this);
                     }
                     // if
                 }
                 // if
             }
             // if
         }
         // if
     }
     // if
     // Pending files
     if ($this->can_have_attachments && is_foreachable($this->pending_files)) {
         foreach ($this->pending_files as $pending_file) {
             $attachment = new Attachment();
             $attachment->setParent($this);
             if (isset($pending_file['created_by']) && (instance_of($pending_file['created_by'], 'User') || instance_of($pending_file['created_by'], 'AnonymousUser'))) {
                 $attachment->setCreatedBy($pending_file['created_by']);
             } else {
                 $attachment->setCreatedBy($this->getCreatedBy());
             }
             // if
             $attachment->setName($pending_file['name']);
             $attachment->setLocation(substr($pending_file['location'], strlen(UPLOAD_PATH) + 1));
             $attachment->setMimeType($pending_file['type']);
             $attachment->setSize($pending_file['size']);
             if (instance_of($this, 'File')) {
                 $attachment->setAttachmentType(ATTACHMENT_TYPE_FILE_REVISION);
             }
             // if
             $save_attachment = $attachment->save();
             if (is_error($save_attachment)) {
                 db_rollback();
                 return $save_attachment;
             }
             // if
         }
         // foreach
         $this->pending_files = array();
         // no more pending files
     }
     // if
     // Set assignees
     if ($this->can_have_assignees && $this->new_assignees !== false) {
         $this->old_assignees = $is_new ? array(array(), 0) : Assignments::findAssignmentDataByObject($this);
         //BOF: mod
         list($old_subscribers, ) = $this->old_assignees;
         if (count($old_subscribers)) {
             foreach ($old_subscribers as $old_subscriber_id) {
                 Subscriptions::unsubscribe(new User($old_subscriber_id), $this);
             }
         }
         //EOF: mod
         Assignments::deleteByObject($this);
         $object_id = $this->getId();
         if (is_array($this->new_assignees)) {
             list($assignees, $owner_id) = $this->new_assignees;
             if (is_foreachable($assignees)) {
                 $user_ids = array();
                 $to_insert = array();
                 foreach ($assignees as $user_id) {
                     if (in_array($user_id, $user_ids)) {
                         continue;
                     }
                     // if
                     $is_owner = $user_id == $owner_id ? 1 : 0;
                     $to_insert[] = "({$user_id}, {$object_id}, {$is_owner})";
                     $user_ids[] = $user_id;
                 }
                 // foreach
                 // Insert assignments
                 $insert = db_execute('INSERT INTO ' . TABLE_PREFIX . 'assignments VALUES ' . implode(', ', $to_insert));
                 if (is_error($insert) && !$insert) {
                     db_rollback();
                     return $insert;
                 }
                 // if
                 // Not array... Empty...
             } else {
                 $assignees = array();
                 $owner_id = 0;
             }
             // if
             // Clean up assignments cache
             clean_assignments_cache();
             // Make sure that all assignees are subscribed
             Subscriptions::subscribeUsers($assignees, $this, false);
             // Check if object is reassigned
             if (!$is_new) {
                 $reassigned = false;
                 if (is_array($this->old_assignees)) {
                     list($old_assignees, $old_owner_id) = $this->old_assignees;
                 } else {
                     $old_assignees = array();
                     $old_owner_id = 0;
                 }
                 // if
                 if ($owner_id != $old_owner_id) {
                     $reassigned = true;
                 } else {
                     if (count($assignees) != count($old_assignees)) {
                         $reassigned = true;
                     } else {
                         foreach ($assignees as $assignee_id) {
                             if (!in_array($assignee_id, $old_assignees)) {
                                 $reassigned = true;
                             }
                             // if
                         }
                         // foerach
                     }
                     // if
                 }
                 // if
                 if ($reassigned) {
                     event_trigger('on_project_object_reassigned', array(&$this, $this->old_assignees, array($assignees, $owner_id)));
                 } else {
                     $this->old_assignees = false;
                 }
                 // if
             }
             // if
         }
         // if
         $this->new_assignees = false;
         // reset
     }
     // if
     // Search index
     if (is_foreachable($this->searchable_fields)) {
         $update_search_index = false;
         // Do we need to update search index?
         foreach ($this->searchable_fields as $field) {
             if (in_array($field, $modified_fields)) {
                 $update_search_index = true;
                 break;
             }
             // if
         }
         // foreach
         // We do... Prepare and if content is empty remove it from the index
         if ($update_search_index) {
             $content = '';
             foreach ($this->searchable_fields as $field) {
                 $value = $this->getFieldValue($field);
                 if ($value) {
                     $content .= $value . "\n\n";
                 }
                 // if
             }
             // foreach
             if ($content) {
                 search_index_set($this->getId(), 'ProjectObject', $content);
             } else {
                 search_index_remove($this->getId(), 'ProjectObject');
             }
             // if
         }
         // if
     }
     // if
     // Update properties of child elements
     if (!$is_new) {
         $properties = array();
         if (in_array('visibility', $modified_fields)) {
             $properties['setVisibility'] = $this->getVisibility();
         }
         // if
         if (in_array('milestone_id', $modified_fields)) {
             $properties['setMilestoneId'] = $this->getMilestoneId();
         }
         // if
         $types = array();
         if ($this->can_have_comments) {
             $types[] = 'Comment';
         }
         // if
         if ($this->can_have_tasks) {
             $types[] = 'Task';
         }
         // if
         if ($this->getHasTime()) {
             $types[] = 'TimeRecord';
         }
         // if
         ProjectObjects::updatePropertiesByParent($this, $properties, $types);
     }
     // if
     if (!$is_new && in_array('project_id', $modified_fields)) {
         ActivityLogs::updateProjectIdCache($this);
     }
     // if
     // Commit and done!
     db_commit();
     return true;
 }