/**
  *  Add new gitolite repository
  * @throws ValidationErrors
  */
 function add_remote_git_repo()
 {
     $project = $this->active_project;
     $project_id = $project->getId();
     $logged_user = $this->logged_user;
     $user_id = $logged_user->getId();
     $web_user = GitoliteAdmin::get_web_user();
     $webuser_pub_key = GitoliteAdmin::get_web_user_key();
     /* echo $webuser_pub_key;
        print_r($webuser_pub_key);
        //die(); */
     $this->response->assign(array('form_action' => Router::assemble('add_remote_git', array('project_slug' => $project->getSlug())), 'web_user' => $web_user, 'webuser_pub_key' => $webuser_pub_key));
     if ($this->request->isSubmitted()) {
         // check for form submission
         try {
             $repository_data = $this->request->post('repository');
             $repo_name = trim($repository_data["name"]);
             $repo_url = trim($this->request->post("remoteurl"));
             $errors = new ValidationErrors();
             $post_data = $this->request->post();
             if ($repo_name == "") {
                 $errors->addError('Please enter repository name', 'repo_name');
             }
             if ($repo_url == "") {
                 $errors->addError('Please enter repository URL', 'repo_name');
             }
             $dup_cnt = ProjectGitolite::check_remote_duplication($project_id, $repository_data, $repo_url);
             /* print_r($dup_cnt);
                die(); */
             if (!$errors->hasErrors()) {
                 if (!preg_match("/^[A-Za-z0-9-]+\$/", $repo_name)) {
                     $errors->addError('Please enter valid repository name.', 'repo_name');
                 }
                 /* if(preg_match('|^[a-z]?:@[a-z0-9]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url))
                    {
                    return ;
                    } */
                 if (strstr($repo_url, "http://") || strstr($repo_url, "https://")) {
                     $errors->addError('HTTP url not allowed to add remote repository', 'repo_url');
                 }
                 /* if(!strstr($repo_url,  "git://github.com/"))
                    {
                    $errors->addError('Please enter valid Git URL', 'repo_url');
                    } */
                 if (count($dup_cnt) == 0) {
                     $errors->addError('Problem occured while saving data, please try again.');
                 } elseif (is_array($dup_cnt) && count($dup_cnt) > 0) {
                     if ($dup_cnt[0]['dup_name_cnt'] > 0) {
                         $errors->addError('Repository with same name is already added');
                     }
                     if ($dup_cnt[1]['dup_name_cnt'] > 0) {
                         $errors->addError('Remote URL already cloned under this project.');
                     }
                 }
             }
             if ($errors->hasErrors()) {
                 throw $errors;
             }
             try {
                 DB::beginWork('Creating a new remote repository @ ' . __CLASS__);
                 $actual_git_repo_name = ProjectGitolite::get_actual_repo_name($repo_url);
                 if (!$actual_git_repo_name) {
                     $errors->addError('Invalid Git Repository.');
                     throw $errors;
                 }
                 // clone remote repo
                 /* echo $actual_git_repo_name;
                    die(); */
                 // path with folder name which is created as same as repo name to avoid same git repo collision
                 $work_git_path = GIT_FILES_PATH . "/";
                 // path with folder name which is created after repo is cloned
                 //
                 //                        /echo $actual_git_repo_name;
                 $git_ext = strpos($actual_git_repo_name, ".git");
                 if ($git_ext) {
                     $actual_git_repo_name = substr($actual_git_repo_name, 0, -4);
                 }
                 $folder_append = "";
                 $chk_actual_name_exists_cnt = ProjectGitolite::check_actual_name_count($actual_git_repo_name);
                 if (is_array($chk_actual_name_exists_cnt) && isset($chk_actual_name_exists_cnt["actual_name_cnt"])) {
                     $cnt = $chk_actual_name_exists_cnt["actual_name_cnt"] > 0 ? $chk_actual_name_exists_cnt["actual_name_cnt"] + 1 : "";
                     $folder_append = $cnt != "" ? "-{$cnt}" : "";
                 } else {
                     $folder_append = "-1";
                 }
                 // if git repsitory name is same , we need to change the folder name while cloning the repository
                 $folder_name = $actual_git_repo_name . $folder_append;
                 $actual_repo_path = GIT_FILES_PATH . "/" . $folder_name . "/";
                 //echo $actual_git_repo_name;
                 $return_status = GitoliteAdmin::clone_remote_repo($repo_url, $work_git_path, $folder_name, $error_message);
                 if (!$return_status) {
                     //$errors->addError('Problem occured while cloning repository.' . $error_message);
                     for ($rCount = 1; count($error_message) > $rCount; $rCount++) {
                         $errors->addError($error_message[$rCount]);
                     }
                     throw $errors;
                 }
                 $repository_path_url = array('repository_path_url' => $actual_repo_path);
                 //echo $work_git_path;
                 $repository_data = array_merge($repository_data, $repository_path_url);
                 /* print_r($repository_data);
                    die(); */
                 $this->active_repository = new GitRepository();
                 $this->active_repository->setAttributes($repository_data);
                 $this->active_repository->setCreatedBy($this->logged_user);
                 $this->active_repository->save();
                 $repo_fk = $this->active_repository->getId();
                 if ($repo_fk) {
                     $clone_url = $repo_url;
                     $body = $clone_url;
                     $this->project_object_repository->setName($this->active_repository->getName());
                     $this->project_object_repository->setBody($body);
                     $this->project_object_repository->setParentId($this->active_repository->getId());
                     $this->project_object_repository->setVisibility($repository_data['visibility']);
                     $this->project_object_repository->setProjectId($this->active_project->getId());
                     $this->project_object_repository->setCreatedBy($this->logged_user);
                     $this->project_object_repository->setState(STATE_VISIBLE);
                     $this->project_object_repository->save();
                     $repo_id = ProjectGitolite::add_remote_repo_details($repo_fk, $user_id, $actual_repo_path, $repo_name, $repo_url, $actual_git_repo_name);
                     if ($repo_id) {
                         ini_set('max_execution_time', 500);
                         $pull_all_branches = ProjectGitolite::pull_branches($actual_repo_path);
                         if (!$pull_all_branches) {
                             @ProjectGitolite::remove_directory($work_git_path);
                             $errors->addError('Error while saving branches.');
                             throw $errors;
                         }
                         //$out = $this->update_remote_repo($repo_fk);
                         /* $branches = $get_branches = exec("cd $actual_repo_path && git branch -a",$output);
                                                       if(is_foreachable($output))
                                                       {
                                                       $array_unique_banch = array();
                                                       foreach ($output as $key => $value)
                                                       {
                                                       $branch_name = substr(strrchr($value, "/"), 1);
                         
                                                       if(!in_array($branch_name, $array_unique_banch))
                                                       {
                                                       exec("cd $actual_repo_path && git checkout -b $branch_name origin/$branch_name && git pull");
                                                       }
                                                       $array_unique_banch[] = $branch_name;
                                                       }
                                                       } */
                         DB::commit('Repository created @ ' . __CLASS__);
                         $out = GitoliteAdmin::update_remote_repo($repo_fk);
                         $this->response->respondWithData($this->project_object_repository);
                     } else {
                         @ProjectGitolite::remove_directory($actual_repo_path);
                         $errors->addError('Error while saving repository');
                         throw $errors;
                     }
                 } else {
                     @ProjectGitolite::remove_directory($actual_repo_path);
                     $errors->addError('Error while saving repository.');
                     throw $errors;
                 }
             } catch (Exception $e) {
                 DB::rollback('Failed to create a repository @ ' . __CLASS__);
                 $this->response->exception($e);
             }
             //$this->response->respondWithData($this->project_object_repository);
             //repo path
             //$repo_path = $sever_user_path."/repositories/".$repository_data['name'].".git";
         } catch (Exception $e) {
             DB::rollback('Failed to create a repository @ ' . __CLASS__);
             $this->response->exception($e);
         }
     }
 }
 /**
  * Delete selected repository, if repository is gitolite repository or remote repository delete that too.
  */
 function delete_git()
 {
     if (($this->request->isAsyncCall() || $this->request->isApiCall()) && $this->request->isSubmitted()) {
         if ($this->active_repository->isLoaded()) {
             if ($this->active_repository->canDelete($this->logged_user)) {
                 try {
                     $repo_table_name = TABLE_PREFIX . "rt_gitolite_repomaster";
                     /* echo "DELETE from $repo_table_name where repo_fk = '".$this->active_repository->getId()."'";
                        die(); */
                     $this->active_repository->delete();
                     $repo_table_name = TABLE_PREFIX . "rt_gitolite_repomaster";
                     $repo_access_table_name = TABLE_PREFIX . "rt_gitolite_access_master";
                     $remote_repo_table_name = TABLE_PREFIX . "rt_remote_repos";
                     $repo_fk = $this->active_repository->getId();
                     $chk_gitolite = ProjectGitolite::is_gitolite_repo($repo_fk);
                     //print_r($chk_gitolite);
                     if (is_array($chk_gitolite) && sizeof($chk_gitolite) > 0 && $chk_gitolite['chk_gitolite'] > 0) {
                         DB::execute("DELETE repo_acc,repo_tb FROM {$repo_table_name} repo_tb\n                        JOIN {$repo_access_table_name} repo_acc ON repo_acc.repo_id = repo_tb.repo_id\n                        WHERE repo_tb.repo_fk = '" . $repo_fk . "'");
                         $repo_path = GIT_FILES_PATH . "/" . $chk_gitolite["repo_name"];
                         @ProjectGitolite::remove_directory($repo_path);
                     } else {
                         $remote_name_arr = DB::executeFirstRow("SELECT remote_repo_name,actual_repo_name from {$remote_repo_table_name} where repo_fk = '" . $repo_fk . "'");
                         if ($remote_name_arr) {
                             $remote_name = $remote_name_arr["actual_repo_name"];
                         }
                         DB::execute("DELETE from {$remote_repo_table_name} where repo_fk = '" . $repo_fk . "'");
                         $repo_path = GIT_FILES_PATH . "/" . $remote_name;
                         if ($remote_name != "") {
                             @ProjectGitolite::remove_directory($repo_path);
                         }
                     }
                     $this->response->respondWithData($this->active_repository, array('as' => 'repository'));
                 } catch (Exception $e) {
                     $this->response->exception($e);
                 }
                 // if
             } else {
                 $this->response->forbidden();
             }
             // if
         } else {
             $this->response->notFound();
         }
         // if
     } else {
         $this->response->badRequest();
     }
     // if
 }
 /**
  * Map conf Repositories with activecollab projects
  * @return string message
  */
 function map_conf_repos()
 {
     $repo_array = array();
     if (count($repo_array) == 0) {
         $conf_file_path = GIT_FILES_PATH . "/gitolite/gitolite-admin/conf/gitolite.conf";
         if (file_exists($conf_file_path)) {
             $conf_file_contents = file($conf_file_path);
             foreach ($conf_file_contents as $key => $value) {
                 if (preg_match('/^repo\\s+(.+)/', $value, $matches) && !preg_match('/^repo\\s+(gitolite-admin)/', $value) && !preg_match('/^repo\\s+(@all)/', $value)) {
                     $repo_name = trim($matches[1]);
                     if (!array_key_exists($repo_name, $conf_parsed)) {
                         $repo_array[$repo_name] = array();
                     }
                 } elseif (preg_match('/(.*)=\\s(.*)/', $value, $matches)) {
                     $pub_key = trim($matches[2]);
                     $pub_key_access = trim($matches[1]);
                     $repo_array[$repo_name][] = array("key_name" => $pub_key, "pub_key_access" => $pub_key_access);
                 }
             }
         }
     }
     if (isset($_GET["prj_name"])) {
         $prj_id = $_GET["prj_name"];
         $repo_name = $_GET["repo_name"];
         $user_id = $this->logged_user->getId();
         $project_obj = new Project($prj_id);
         $users_details = $project_obj->users()->describe($this->logged_user, true, true, STATE_VISIBLE);
         $users_array = array();
         if (is_foreachable($users_details)) {
             foreach ($users_details as $key => $value) {
                 $users_array[] = $value['user']['id'];
             }
         }
         $access_array = array();
         try {
             DB::beginWork('Mapping Repositories @ ' . __CLASS__);
             $selected_prj = new Project($prj_id);
             $repository_data = array('name' => $repo_name, 'update_type' => 1, 'visibility' => 0);
             $settings = GitoliteAdmin::get_admin_settings();
             $clone_url = $settings['gitoliteuser'] . "@" . $settings['gitoliteserveradd'] . ":" . $repo_name;
             $dup_cnt = ProjectGitolite::check_remote_duplication($prj_id, $repository_data, $clone_url);
             if ($dup_cnt[1]['dup_name_cnt'] > 0) {
                 die('Remote URL already cloned under this project.');
             }
             /**
              * Create access data
              * 
              */
             /* define('GITOLITE_NOACCESS', '1');
                define('GITOLITE_READACCESS', '2');
                define('GITOLITE_MANAGEACCESS', '3'); */
             if (is_array($repo_array) && count($repo_array) > 0) {
                 if (array_key_exists($repo_name, $repo_array)) {
                     if (is_foreachable($repo_array[$repo_name])) {
                         foreach ($repo_array[$repo_name] as $key => $value) {
                             //echo $value["key_name"]."====".$value["pub_key_access"];
                             $key_details = GitoliteAc::get_key_details($value["key_name"]);
                             if (is_array($key_details) && in_array($key_details["user_id"], $users_array)) {
                                 $access_array[$key_details["user_id"]] = $value["pub_key_access"] == "RW+" ? 3 : 2;
                             }
                         }
                     }
                 }
             }
             /**
              * Add rrepositories
              */
             $actual_git_repo_name = $repo_name;
             $chk_actual_name_exists_cnt = ProjectGitolite::check_actual_name_count_gitolite($actual_git_repo_name);
             if (is_array($chk_actual_name_exists_cnt) && isset($chk_actual_name_exists_cnt["actual_name_cnt"])) {
                 $cnt = $chk_actual_name_exists_cnt["actual_name_cnt"] > 0 ? $chk_actual_name_exists_cnt["actual_name_cnt"] + 1 : "";
                 $folder_append = $cnt != "" ? "-{$cnt}" : "";
             } else {
                 $folder_append = "-1";
             }
             // if git repsitory name is same , we need to change the folder name while cloning the repository
             $folder_name = $actual_git_repo_name . $folder_append;
             $work_git_path = GIT_FILES_PATH . "/" . $folder_name . "/";
             $repository_path_url = array('repository_path_url' => $work_git_path);
             $repository_data = array_merge($repository_data, $repository_path_url);
             $this->active_repository = new GitRepository();
             $this->active_repository->setAttributes($repository_data);
             $this->active_repository->setCreatedBy($this->logged_user);
             $this->active_repository->save();
             $repo_fk = $this->active_repository->getId();
             if ($repo_fk) {
                 $clone_url = $settings['gitoliteuser'] . "@" . $settings['gitoliteserveradd'] . ":" . $repo_name;
                 $body = $clone_url;
                 $prj_obj = new ProjectSourceRepository();
                 $prj_obj->setName($this->active_repository->getName());
                 $prj_obj->setBody($body);
                 $prj_obj->setVisibility($repository_data['visibility']);
                 $prj_obj->setProjectId($prj_id);
                 $prj_obj->setCreatedBy($this->logged_user);
                 $prj_obj->setType("ProjectSourceRepository");
                 $prj_obj->setModule("source");
                 $prj_obj->setState(STATE_VISIBLE);
                 $prj_obj->setParentId($this->active_repository->getId());
                 $prj_obj->save();
                 $repo_id = ProjectGitolite::add_repo_details($repo_fk, $prj_id, $user_id, $work_git_path, $repository_data, $clone_url);
                 if ($repo_id) {
                     $add_access = ProjectGitolite::add_access_levels($repo_id, serialize($access_array), $user_id, 1);
                     if ($add_access) {
                         DB::commit('Repository mapped @ ' . __CLASS__);
                         $git_server = $settings['git_clone_url'];
                         chdir(GIT_FILES_PATH);
                         //cd ".GIT_FILES_PATH." &&
                         $command = "git clone " . $git_server . $repo_name . " {$folder_name}";
                         //$command = "git clone ".$git_server.":".$repo_name;
                         exec($command, $output, $return_var);
                         $out = GitoliteAdmin::update_remote_repo($repo_fk);
                         ini_set('max_execution_time', 500);
                         $pull_all_branches = ProjectGitolite::pull_branches($actual_repo_path);
                         if (!$pull_all_branches) {
                             @ProjectGitolite::remove_directory($work_git_path);
                             die("Error while saving branches.");
                             throw $errors;
                         }
                         die("ok");
                     } else {
                         DB::rollback('Failed to map repository @ ' . __CLASS__);
                         echo "Error while saving access levels.";
                     }
                 } else {
                     DB::rollback('Failed to map repository @ ' . __CLASS__);
                     echo "Error while saving repository";
                 }
             }
         } catch (Exception $e) {
             DB::rollback('Mapping repositories @ ' . __CLASS__);
             die("Cannot map repository, try again.");
         }
         /**/
     }
 }