/**
  * Copy project items into a destination project
  *
  * @param Project $to
  * @return null
  */
 function copyItems(&$to)
 {
     // Prepare time diff
     $source_starts_on = $this->getStartsOn();
     if (!instance_of($source_starts_on, 'DateValue')) {
         $source_starts_on = $this->getCreatedOn();
     }
     // if
     $target_starts_on = $to->getStartsOn();
     if (!instance_of($target_starts_on, 'DateValue')) {
         $target_starts_on = $to->getCreatedOn();
     }
     // if
     $diff = $target_starts_on->getTimestamp() - $source_starts_on->getTimestamp();
     // Migrate project users
     $project_users = ProjectUsers::findByProject($this);
     if (is_foreachable($project_users)) {
         foreach ($project_users as $project_user) {
             if ($to->getLeaderId() != $project_user->getUserId()) {
                 $user = $project_user->getUser();
                 if (instance_of($user, 'User')) {
                     $to->addUser($user, $project_user->getRole(), $project_user->getPermissions());
                 }
                 // if
             }
             // if
         }
         // foreach
     }
     // if
     // We need to move milestones in order to get milestones map
     $milestones_map = null;
     $milestones = Milestones::findAllByProject($this, VISIBILITY_PRIVATE);
     if (is_foreachable($milestones)) {
         $milestones_map = array();
         foreach ($milestones as $milestone) {
             $copied_milestone = $milestone->copyToProject($to);
             if (instance_of($copied_milestone, 'Milestone')) {
                 $copied_milestone->advance($diff, true);
                 $milestones_map[$milestone->getId()] = $copied_milestone;
             }
             // if
         }
         // foreach
     }
     // if
     // Now move categories
     $categories_map = null;
     $categories = Categories::findByProject($this);
     if (is_foreachable($categories)) {
         foreach ($categories as $category) {
             $copied_category = $category->copyToProject($to, null, null, false);
             if (instance_of($copied_category, 'Category')) {
                 $categories_map[$category->getId()] = $copied_category;
             }
             // if
         }
         // foreach
     }
     // if
     // Let the modules to their thing
     event_trigger('on_copy_project_items', array(&$this, &$to, $milestones_map, $categories_map));
     // Now, lets update due dates
     $completable_types = get_completable_project_object_types();
     if (is_foreachable($completable_types)) {
         foreach ($completable_types as $k => $type) {
             if (strtolower($type) == 'milestone') {
                 unset($completable_types[$k]);
             }
             // if
         }
         // foreach
         if (count($completable_types) > 0) {
             $rows = db_execute_all('SELECT id, due_on FROM ' . TABLE_PREFIX . 'project_objects WHERE project_id = ? AND type IN (?) AND due_on IS NOT NULL', $to->getId(), $completable_types);
             if (is_foreachable($rows)) {
                 foreach ($rows as $row) {
                     $id = (int) $row['id'];
                     $new_date = date(DATE_MYSQL, strtotime($row['due_on']) + $diff);
                     db_execute('UPDATE ' . TABLE_PREFIX . 'project_objects SET due_on = ? WHERE id = ?', $new_date, $id);
                     cache_remove("acx_project_objects_id_{$id}");
                 }
                 // foreach
             }
             // if
         }
         // if
     }
     // if
     // Refresh tasks count, just in case...
     $to->refreshTasksCount();
 }
 /**
  * Process add project form
  *
  * @param void
  * @return null
  */
 function add()
 {
     $this->wireframe->print_button = false;
     if ($this->request->isApiCall() && !$this->request->isSubmitted()) {
         $this->httpError(HTTP_ERR_BAD_REQUEST);
     }
     // if
     if (!Project::canAdd($this->logged_user)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $project_data = $this->request->post('project');
     if (!is_array($project_data)) {
         $project_data = array('leader_id' => $this->logged_user->getId(), 'default_visibility' => VISIBILITY_PRIVATE);
     }
     // if
     $this->smarty->assign('project_data', $project_data);
     if ($this->request->isSubmitted()) {
         db_begin_work();
         $this->active_project = new Project();
         // just in case
         $this->active_project->setAttributes($project_data);
         $this->active_project->setType(PROJECT_TYPE_NORMAL);
         $this->active_project->setStatus(PROJECT_STATUS_ACTIVE);
         $leader = null;
         if ($this->active_project->getLeaderId()) {
             $leader = Users::findById($this->active_project->getLeaderId());
             if (instance_of($leader, 'User')) {
                 $this->active_project->setLeader($leader);
             }
             // if
         }
         // if
         $project_template = null;
         $project_template_id = array_var($project_data, 'project_template_id');
         if ($project_template_id) {
             $project_template = Projects::findById($project_template_id);
         }
         // if
         $save = $this->active_project->save($project_template);
         if ($save && !is_error($save)) {
             // Add user who created a project and leader
             $this->active_project->addUser($this->logged_user, null, null);
             if (instance_of($leader, 'User')) {
                 $this->active_project->addUser($leader, null, null);
             }
             // if
             // Clone project template
             if (instance_of($project_template, 'Project')) {
                 $project_template->copyItems($this->active_project);
             } else {
                 // Auto assign users...
                 $users = Users::findAutoAssignUsers();
                 if (is_foreachable($users)) {
                     foreach ($users as $user) {
                         $this->active_project->addUser($user, $user->getAutoAssignRole(), $user->getAutoAssignPermissions());
                     }
                     // foreach
                 }
                 // if
                 // Create default categories
                 $category_definitions = array();
                 event_trigger('on_master_categories', array(&$category_definitions));
                 if (is_foreachable($category_definitions)) {
                     foreach ($category_definitions as $category_definition) {
                         $default_categories = $category_definition['value'];
                         if (!is_foreachable($default_categories)) {
                             $default_categories = array('General');
                         }
                         // if
                         foreach ($default_categories as $category_name) {
                             if (trim($category_name) != '') {
                                 $category = new Category();
                                 $category->log_activities = false;
                                 // don't log stuff in DB
                                 $category->setName($category_name);
                                 $category->setProjectId($this->active_project->getId());
                                 $category->setCreatedBy($this->logged_user);
                                 $category->setState(STATE_VISIBLE);
                                 $category->setVisibility(VISIBILITY_NORMAL);
                                 $category->setModule($category_definition['module']);
                                 $category->setController($category_definition['controller']);
                                 $category->save();
                             }
                             // if
                         }
                         // foreach
                     }
                     // foreach
                 }
                 // if
             }
             // if
             db_commit();
             if ($this->request->isApiCall()) {
                 $this->serveData($this->active_project, 'project');
             } else {
                 flash_success('Project ":name" has been created. Use this page to add more people to the project...', array('name' => $this->active_project->getName()));
                 $this->redirectToUrl($this->active_project->getPeopleUrl());
             }
             // if
         } else {
             db_rollback();
             if ($this->request->isApiCall()) {
                 $this->serveData($save);
             } else {
                 $this->smarty->assign('errors', $save);
             }
             // if
         }
         // if
     }
     // if
 }
 /**
  * Create a new project.
  * @param $name
  * @param bool $withdefault
  * @param int $userid
  * @return Message
  */
 public function addProject($name, $withdefault = false, $userid = -1)
 {
     if (is_bool($this->getProject($name))) {
         $this->db->insert("project", ["name" => $name]);
         $projectid = $this->getProject($name);
         if (!is_bool($projectid) && is_numeric($projectid)) {
             $project = new Project($projectid);
             if ($withdefault) {
                 $project->addDefaultGroups();
             }
             if ($userid != -1) {
                 $group = $project->getGroup("Managers", true);
                 if (!is_bool($group)) {
                     $project->addUser($userid, $group);
                     return new Message("Created new Project with Default groups. And added the user to Managers.");
                 }
                 if (is_bool($group)) {
                     $project->addGroup("Managers", 1);
                     $project->addUser($userid, "Managers");
                     return new Message("Created new Project with Managers group and added user to it.");
                 }
             }
             return new Message("Created new empty Project");
         } else {
             return new Error(0105, "Error while retrieving project.");
         }
     } else {
         return new Error(0106, "Project already exists.");
     }
 }