Skip to content
Snippets Groups Projects
Select Git revision
  • 8554b74bb2cc62bda4bdeb8ba6b081fde5f619ce
  • main default protected
  • studip-rector
  • ci-opt
  • course-members-export-as-word
  • data-vue-app
  • pipeline-improvements
  • webpack-optimizations
  • rector
  • icon-renewal
  • http-client-and-factories
  • jsonapi-atomic-operations
  • vueify-messages
  • tic-2341
  • 135-translatable-study-areas
  • extensible-sorm-action-parameters
  • sorm-configuration-trait
  • jsonapi-mvv-routes
  • docblocks-for-magic-methods
19 results

DataFieldRadioEntry.class.php

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    GitLab.php 6.99 KiB
    <?php
    
    namespace Trac2GitLab;
    
    define('USER_FETCH_PAGE_SIZE', 1000);
    define('USER_FETCH_MAX_PAGES', 50);
    
    use Gitlab\Client;
    use Gitlab\Model\Issue;
    use Gitlab\HttpClient\Builder;
    
    /**
     * GitLab communicator class
     *
     * @author  dachaz
     */
    class GitLab
    {
        private $client;
        private $url;
        private $isAdmin;
    
        /**
         * Constructor
         *
         * @param  string    $url         GitLab URL
         * @param  string    $token       GitLab API private token
         * @param  boolean   $isAdmin     Indicates that the GitLab token is from an admin user
         */
    	public function __construct($url, $token, $isAdmin) {
    		$this->url = $url;
            $this->client = Client::create($url . '/api/v4/');
    		$this->client->authenticate($token, Client::AUTH_URL_TOKEN);
    		$this->isAdmin = $isAdmin;
    	}
    
    
    	/**
     	 * Tries to fetch all the users from GitLab. Will get at most
     	 * (USER_FETCH_PAGE_SIZE * USER_FETCH_MAX_PAGES) users. Returns
     	 * a map of {username => userInfoObject}
     	 *
     	 * @return  array
     	 */
    	public function listUsers() {
    		$users = array();
    		$gotAll = false;
    		$page = 1;
    		// Stop when we either have all users or we have exhausted the sane number of attempts
    		while (!$gotAll && $page < USER_FETCH_MAX_PAGES) {
    			$response = $this->client->api('users')->all([], $page++, USER_FETCH_PAGE_SIZE);
    			foreach($response as $user) {
    				$users[$user['username']] = $user;
    				// We assume that 'Administrator' user is in there
    				$gotAll = $user['id'] == 1;
    			}
    		}
    		return $users;
    	}
    
    	/**
    	 * Creates a new issue in the given project. When working in admin mode, tries to create the issue
    	 * as the given author (SUDO) and if that fails, tries creating the ticket again as the admin.
    	 * @param  mixed    $projectId    Numeric project id (e.g. 17) or the unique string identifier (e.g. 'dachaz/trac-to-gitlab')
         * @param  string   $title        Title of the new issue
         * @param  string   $description  Description of the new issue
         * @param  string     $createdAt    Custom creation date
         * @param  int      $assigneeId   Numeric user id of the user asigned to the issue. Can be null.
         * @param  int      $authorId     Numeric user id of the user who created the issue. Only used in admin mode. Can be null.
         * @param  array    $labels       Array of string labels to be attached to the issue. Analoguous to trac keywords.
         * @return  Gitlab\Model\Issue
    	 */
    	public function createIssue($projectId, $title, $description, $createdAt, $assigneeId, $authorId, $labels) {
    		try {
    			// Try to add, potentially as an admin (SUDO authorId)
    			$issue = $this->doCreateIssue($projectId, $title, $description, $createdAt, $assigneeId, $authorId, $labels, $this->isAdmin);
    		} catch (\Gitlab\Exception\RuntimeException $e) {
    			// If adding has failed because of SUDO (author does not have access to the project), create an issue without SUDO (as the Admin user whose token is configured)
    			if ($this->isAdmin) {
    				$issue = $this->doCreateIssue($projectId, $title, $description, $createdAt, $assigneeId, $authorId, $labels, false);
    			} else {
    				// If adding has failed for some other reason, propagate the exception back
    				throw $e;
    			}
    		}
    		return $issue;
    	}
    
        /**
    	 * Closes an issue.
         * @param mixed $projectId project ID or path
         * @param int $issueId issue to close
         * @param string $time time in ISO8601 format
    	 * @param string $author wh closed the issue?
         */
    	public function closeIssue($projectId, $issueId, $time = '', $author = '') {
    		$this->client->api('issues')->update($projectId, $issueId,
    			[
    				'state_event' => 'close',
    				'updated_at' => $time,
    				'closed_at' => $time,
    				'closed_by_id' => $author,
    				'closed_by' => $author
    			]);
    	}
    
    	/**
    	 * Creates a new note in the given project and on the given issue id (NOTE: id, not iid). When working in admin mode, tries to create the note
    	 * as the given author (SUDO) and if that fails, tries creating the note again as the admin.
    	 * @param  mixed    $projectId    Numeric project id (e.g. 17) or the unique string identifier (e.g. 'dachaz/trac-to-gitlab')
         * @param  int      $issueId      Unique identifier of the issue
         * @param  string   $text         Text of the note
         * @param  int      $authorId     Numeric user id of the user who created the issue. Only used in admin mode. Can be null.
         * @return  Gitlab\Model\Note
    	 */
    	public function createNote($projectId, $issueId, $text, $authorId) {
    		try {
    			// Try to add, potentially as an admin (SUDO authorId)
    			$note = $this->doCreateNote($projectId, $issueId, $text, $authorId, $this->isAdmin);
    		} catch (\Gitlab\Exception\RuntimeException $e) {
    			// If adding has failed because of SUDO (author does not have access to the project), create an issue without SUDO (as the Admin user whose token is configured)
    			if ($this->isAdmin) {
    				$note = $this->doCreateNote($projectId, $issueId, $text, $authorId, false);
    			} else {
    				// If adding has failed for some other reason, propagate the exception back
    				throw $e;
    			}
    		}
    		return $note;
    	}
    
        /**
    	 * Attaches a file to an issue.
    	 *
         * @param mixed $projectId numerical ID or path to target project
    	 * @param int $issueId the issue to add the file to
         * @param string $file base64 representation of file, we'll see if that works.
         * @param int $authorId the file author
         */
    	public function createIssueAttachment($projectId, $issueId, $file, $authorId) {
    		try {
    			// First, add file to project.
                $data = $this->client->api('projects')->uploadFile($projectId, $file);
    
    			// Add the uploaded file as a note on the given issue.
                $note = $this->createNote($projectId, $issueId, $data['markdown'], $authorId);
    
    			// Update possible mentions of this file in issue description.
    			$issue = $this->client->api('issues')->show($projectId, $issueId);
    
    			$description = str_replace(
    				'[[br]]',
    				'<br>',
    				preg_replace('/!\[image\]\((.+),.*\)/U', $data['markdown'], $issue['description'])
    			);
    
    			$this->client->api('issues')->update($projectId, $issueId, ['description' => $description]);
    
    			return $note;
    
            } catch (\Gitlab\Exception\RuntimeException $e) {
    			throw $e;
    		}
        }
    
    	// Actually creates the issue
    	private function doCreateIssue($projectId, $title, $description, $createdAt, $assigneeId, $authorId, $labels, $isAdmin) {
    		$issueProperties = array(
    			'title' => $title,
    			'description' => $description,
    			'assignee_id' => $assigneeId,
    			'labels' => $labels,
                'created_at' => $createdAt
    		);
    		if ($isAdmin) {
    			$issueProperties['sudo'] = $authorId;
    		}
    		return $this->client->api('issues')->create($projectId, $issueProperties);
    	}
    
    	// Actually creates the note
    	private function doCreateNote($projectId, $issueId, $text, $authorId, $isAdmin) {
    		$noteProperties = array(
    			'body' => $text
    		);
    		if ($isAdmin) {
    			$noteProperties['sudo'] = $authorId;
    		}
    		return $this->client->api('issues')->addComment($projectId, $issueId, $noteProperties);
    	}
    
    	/**
    	 * Returns the URL of this GitLab installation.
    	 * @return string
    	 */
    	public function getUrl() {
    		return $this->url;
    	}
    }
    ?>