/**
 * Source module on_project_object_quick_options event handler
 *
 * @package activeCollab.modules.source
 * @subpackage handlers
 * @param NamedList $options
 * @param ProjectObject $object
 * @param User $user
 * @return null
 */
function source_handle_on_project_object_quick_options(&$options, $object, $user)
{
    /**
     * Add a quick option which links to the list of commits related to the object
     */
    if ((instance_of($object, 'Ticket') || instance_of($object, 'Discussion') || instance_of($object, 'Milestone')) && $object->canView($user)) {
        $object_commits_count = CommitProjectObjects::countByObject($object);
        if ($object_commits_count > 0) {
            $options->add('new_revision', array('text' => lang('Commits (:object_commits)', array('object_commits' => $object_commits_count)), 'url' => assemble_url('repository_project_object_commits', array('project_id' => $object->getProjectId(), 'object_id' => $object->getId()))));
        }
        // if
    }
    // if
}
 /**
  * Get all commits related to a project object
  *
  * @param integer $object_id
  * @return array
  */
 function findCommitsByObject($object)
 {
     $parent_object_ids = array();
     $parent_object_ids[] = $object->getId();
     /**
      * Try to find commits related to children objects
      */
     $task_ids = array();
     if (instance_of($object, 'Ticket')) {
         $tasks = db_execute_all("SELECT id FROM " . TABLE_PREFIX . "project_objects WHERE parent_id = " . $object->getid() . " AND `type` = 'Task'");
         if (is_foreachable($tasks)) {
             foreach ($tasks as $task) {
                 $task_ids[] = $task['id'];
             }
             // foreach
         }
         // if
     }
     // if
     $objects_ids = array_merge($parent_object_ids, $task_ids);
     $commit_project_objects = CommitProjectObjects::find(array('conditions' => array("object_id IN(" . implode(',', $objects_ids) . ")"), 'order' => 'repository_id ASC, revision DESC'));
     if (is_foreachable($commit_project_objects)) {
         $commits = array();
         $revisions = array();
         foreach ($commit_project_objects as $commit_project_object) {
             if (!in_array($commit_project_object->getRevision(), $revisions)) {
                 // prevent commits from showing more than once
                 $revisions[] = $commit_project_object->getRevision();
                 $commit = Commits::findByRevision($commit_project_object->getRevision(), Repositories::findById($commit_project_object->getRepositoryId()));
                 if (instance_of($commit, 'Commit')) {
                     $commit->repository = Repositories::findById($commit->getProjectId());
                     $commits[] = $commit;
                 }
                 // if
             }
             // if
         }
         // foreach
         return group_by_date($commits);
     } else {
         return false;
     }
     // if
 }
 /**
  * Find project objects in commit message, make them links and
  * save the relations to database
  *
  * @param string $commit_message
  * @param string $commit_author
  * @param integer $revision
  * @param Repository $repository
  * @param Project $project
  * @return string
  */
 function analyze_message($commit_message, $commit_author, $revision, $repository, $project)
 {
     if (define('PURIFY_HTML') && PURIFY_HTML) {
         $commit_message = purify_html($commit_message);
         // Clean!
     }
     // if
     $pattern = '/((complete[d]*)[\\s]+)?(ticket|milestone|discussion|task)[s]*[\\s]+[#]*\\d+/i';
     if (preg_match_all($pattern, $commit_message, $matches)) {
         $i = 0;
         $search = array();
         $replace = array();
         $matches_unique = array_unique($matches['0']);
         foreach ($matches_unique as $key => $match) {
             $match_data = preg_split('/[\\s,]+/', $match, null, PREG_SPLIT_NO_EMPTY);
             // check if the object got completed by this commit
             $object_completed = false;
             if (strpos(strtolower($match_data['0']), 'complete') !== false) {
                 $object_completed = true;
                 unset($match_data['0']);
                 $match_data = array_values($match_data);
             }
             // if
             $object_class_name = $match_data['0'];
             $module_name = Inflector::pluralize($object_class_name);
             $object_id = trim($match_data['1'], '#');
             $search[$i] = $match;
             if (class_exists($module_name) && class_exists($object_class_name)) {
                 $object = null;
                 switch (strtolower($module_name)) {
                     case 'tickets':
                         $object = Tickets::findByTicketId($project, $object_id);
                         break;
                     case 'discussions':
                         $object = Discussions::findById($object_id);
                         break;
                     case 'milestones':
                         $object = Milestones::findById($object_id);
                         break;
                     case 'tasks':
                         $object = Tasks::findById($object_id);
                         break;
                 }
                 // switch
                 if (instance_of($object, $object_class_name)) {
                     $link_already_created = CommitProjectObjects::count("object_id = '" . $object->getId() . "' AND revision = '{$revision}'") > 0;
                     if (!$link_already_created) {
                         $comit_project_object = new CommitProjectObject();
                         $comit_project_object->setProjectId($object->getProjectId());
                         $comit_project_object->setObjectId($object->getId());
                         $comit_project_object->setObjectType(ucfirst($object_class_name));
                         $comit_project_object->setRepositoryId($repository->getId());
                         $comit_project_object->setRevision($revision);
                         db_begin_work();
                         $save = $comit_project_object->save();
                         if ($save && !is_error($save)) {
                             db_commit();
                         } else {
                             db_rollback();
                         }
                         // if save
                     }
                     // if
                     $replace[$i] = ($object_completed ? 'Completed ' : '') . '<a href="' . $object->getViewUrl() . '">' . $match_data['0'] . ' ' . $match_data['1'] . '</a>';
                     // set the object as completed
                     if ($object_completed && !instance_of($object, 'Discussion')) {
                         $completed_by = $repository->getMappedUser($commit_author);
                         $object->complete($completed_by);
                     }
                     // if
                 } else {
                     $replace[$i] = ($object_completed ? 'Completed ' : '') . '<a href="#" class="project_object_missing" title="' . lang('Project object does not exist in this project') . '">' . $match_data['0'] . ' ' . $match_data['1'] . '</a>';
                 }
                 // if instance_of
                 $i++;
             }
             // if module loaded
         }
         // foreach
         return str_ireplace($search, $replace, htmlspecialchars($commit_message));
         // linkify
     }
     // if preg_match
     return $commit_message;
 }
 /**
  * Delete repository
  * 
  * @param null
  * @return void
  *
  */
 function delete()
 {
     if (!$this->active_repository->canEdit($this->logged_user)) {
         $this->httpError(HTTP_ERR_FORBIDDEN);
     }
     // if
     $delete = $this->active_repository->delete(true);
     CommitProjectObjects::delete("repository_id = '" . $this->active_repository->getId() . "'");
     SourceUsers::delete("repository_id = '" . $this->active_repository->getId() . "'");
     if ($delete && !is_error($delete)) {
         flash_success('Repository has been successfully deleted');
         $this->redirectToUrl(source_module_url($this->active_project));
     } else {
         $this->smarty->assign('errors', $delete);
     }
     // if
 }