| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 | 
							- <?php
 
- 	/** ISSUEREPORT **/
 
- 	//Récuperation d'une liste de issuereport
 
- 	Action::register('issue_issuereport_search',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			User::check_access('issue','read');
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueReportTag.class.php');
 
- 			$allTags = IssueReportTag::tags();
 
- 			$query = 'SELECT DISTINCT {{table}}.id, {{table}}.*,(SELECT ie.content FROM '.IssueEvent::tableName().' ie WHERE ie.type=? AND ie.issue={{table}}.id ORDER BY id ASC LIMIT 1) as comment,(SELECT COUNT(ie2.id) FROM '.IssueEvent::tableName().' ie2 WHERE ie2.type=? AND ie2.issue={{table}}.id) as comments FROM {{table}} LEFT JOIN '.IssueReportTag::tableName().' t ON t.report={{table}}.id WHERE 1';
 
- 			$data = array(IssueEvent::TYPE_COMMENT,IssueEvent::TYPE_COMMENT);
 
- 			//Recherche simple
 
- 			if(!empty($_['filters']['keyword'])){
 
- 				$query .= ' AND (SELECT ie.content FROM '.IssueEvent::tableName().' ie WHERE ie.type=? AND ie.issue={{table}}.id ORDER BY id ASC LIMIT 1) LIKE ?';
 
- 				$data[] = IssueEvent::TYPE_COMMENT;
 
- 				$data[] = '%'.$_['filters']['keyword'].'%';
 
- 			}
 
- 			$tags = array_filter(explode(',',$_['tags']));
 
- 			if(count($tags)!=0){
 
- 				$query .= ' AND t.tag IN ('.str_repeat('?,',count($tags)-1).'?)';
 
- 				$data = array_merge($data, $tags);
 
- 			}
 
- 			//Recherche avancée
 
- 			if(isset($_['filters']['advanced'])){
 
- 				$_['filters']['advanced'] = filter_alteration($_['filters']['advanced'],'comment',function($filter) use (&$query,&$data){
 
- 					$query .= ' AND (SELECT ie.content FROM '.IssueEvent::tableName().' ie WHERE ie.type=? AND ie.issue={{table}}.id ORDER BY id ASC LIMIT 1) ';
 
- 					
 
- 					switch($filter['operator']){
 
- 						case 'like':
 
- 							$value = '%'.$filter['value'][0].'%';
 
- 							$query .= ' LIKE ? ';
 
- 						break;
 
- 						case 'not like':
 
- 							$value = '%'.$filter['value'][0].'%';
 
- 							$query .= ' NOT LIKE ? ';
 
- 						break;
 
- 						case 'null':
 
- 							$value = null;
 
- 							$query .= ' IS NULL ';
 
- 						break;
 
- 						case 'not null':
 
- 							$value = null;
 
- 							$query .= ' IS NOT NULL ';
 
- 						break;
 
- 						case '=':
 
- 						case '!=':
 
- 							$value = $filter['value'][0];
 
- 							$query .= ' '.$filter['operator'].' ? ';
 
- 						break;
 
- 					}
 
- 					$data[] = IssueEvent::TYPE_COMMENT;
 
- 					if($value!= null) $data[] = $value;
 
- 					return null;
 
- 				});
 
- 				filter_secure_query($_['filters']['advanced'],array('{{table}}.id','from','module','{{table}}.creator','{{table}}.created','assign','browser','ip','state'),$query,$data);
 
- 			}
 
- 			
 
- 			$query .= ' ORDER BY {{table}}.id desc ';
 
- 			$dataPaginate = $data;
 
- 			array_splice($dataPaginate, 0, 2);
 
- 			//Pagination
 
- 			$response['pagination'] = IssueReport::paginate(20,(!empty($_['page'])?$_['page']:0),$query,$dataPaginate);
 
- 			//Récupération des Users
 
- 			$users = array();
 
- 			foreach(User::getAll(array('right'=>false)) as $user)
 
- 				$users[$user->login] = $user;
 
- 			$response['rows'] = array();
 
- 			foreach(IssueReport::staticQuery($query,$data) as $row){
 
- 				//$row = $issueReport->toArray(true);
 
- 				$row['state'] = IssueReport::states($row['state']);
 
- 				$row['relativefrom'] = str_replace(ROOT_URL,'',$row['from']);
 
- 				$row['date'] = date('d-m-Y',$row['created']);
 
- 				$row['hour'] = date('H:i',$row['created']);
 
- 				$row['osIcon'] = 'fas fa-question-circle';
 
- 				$row['browserIcon'] = 'fas fa-question-circle';
 
- 				$row['comments'] = $row['comments']==1 ? false : $row['comments']-1;
 
- 				$row['excerpt'] = isset($row['comment']) ? truncate(strip_tags($row['comment']),150) : 'Aucun commentaire';
 
- 				$row['excerpt'] = preg_replace('/https?:\/\/[^\s]*\?module=issue&page=sheet\.report&id=([0-9]*)/is','<span class="text-muted" title="$0">#$1</span>',$row['excerpt']);
 
- 				$row['belongUser'] = $myUser->login == $row['creator'] || $myUser->can('issue','configure');
 
- 				$row['fullName'] = isset($users[$row['creator']]) ? $users[$row['creator']]->fullName() : $row['creator'];
 
- 				if(strlen($row['os'])>=3 && substr(strtolower($row['os']),0,3) == 'win') $row['osIcon'] = 'fab fa-windows text-primary';
 
- 				if(strlen($row['os'])>=5 && substr(strtolower($row['os']),0,5) == 'linux') $row['osIcon'] = 'fab fa-linux text-danger';
 
- 				if(strlen($row['os'])>=3 && substr(strtolower($row['os']),0,3) == 'mac') $row['osIcon'] = 'fab fa-apple text-secondary';
 
- 				
 
- 				switch($row['browser']){
 
- 					case 'firefox': $row['browserIcon'] = 'fab fa-firefox text-warning'; break;
 
- 					case 'ie': $row['browserIcon'] = 'fab fa-internet-explorer text-danger'; break;
 
- 					case 'edge': $row['browserIcon'] = 'fab fa-edge text-primary'; break;
 
- 					case 'chrome': $row['browserIcon'] = 'fab fa-chrome text-success'; break;
 
- 				}
 
- 				$row['tags'] = array();
 
- 				foreach(IssueReportTag::loadAll(array('report'=>$row['id'])) as $tag){
 
- 					if(!isset($allTags[$tag->tag])) continue;
 
- 					$row['tags'][] = $allTags[$tag->tag];
 
- 				}
 
- 				$response['rows'][] = $row;
 
- 			}
 
- 		
 
- 	});
 
- 	Action::register('issue_autocomplete',function(&$response){
 
- 	
 
- 		global $myUser,$_;
 
- 		if(!$myUser->connected()) throw new Exception("Vous devez être connecté",401);
 
- 		require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 		require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			$query = IssueReport::staticQuery('SELECT ir.id as id,ie.content as content FROM {{table}} ir LEFT JOIN '.IssueEvent::tableName().' ie ON ie.id=( SELECT id FROM '.IssueEvent::tableName().' ie2 WHERE ir.id=ie2.issue AND ie2.type=? ORDER BY id LIMIT 1) WHERE ie.content LIKE ?',array("comment",'%'.$_['keyword'].'%'));
 
- 			$response['rows'] = array();
 
- 			foreach ($query->fetchAll() as $row) {
 
- 				$response['rows'][] = array(
 
- 					'id' => $row['id'],
 
- 					'name' => $row['id'].' - '.strip_tags($row['content']),
 
- 					'slug' => $row['id']
 
- 				);
 
- 			}
 
- 		
 
- 	});
 
- 	//Gestion avatar drag & drop
 
- 	Action::register('issue_attachments',function(&$response){
 
- 	
 
- 			File::handle_component(array(
 
- 				'namespace' => 'issue', //stockés dans file/summary/*.*
 
- 				'access' => 'issue', // crud sur summary,
 
- 				'size' => '1000000000', // taille max
 
- 				'storage' => 'issue/attachments/{{data.id}}/*' //chemin complet vers le fichier stocké
 
- 			),$response);
 
- 		
 
- 	});
 
- 	Action::register('issue_add_document',function(&$response){
 
- 	
 
- 		global $myUser,$_;
 
- 		if(!$myUser->connected()) throw new Exception("Vous devez être connecté",401);
 
- 		require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 		require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 		$report = IssueReport::provide();
 
- 		$report->save();
 
- 		foreach ($_['files'] as $file) {
 
- 			$name = (get_OS() === 'WIN') ? utf8_decode($file['name']) : $file['name'];
 
- 			$row = File::move(File::temp().$file['path'],'issue'.SLASH.'screens'.SLASH.$report->id.SLASH.$name);
 
- 			$row['url'] = 'action.php?action=issue_download_document&event='.$event->id.'&path='.base64_encode($file['name']);
 
- 			$row['oldPath'] = $file['path'];
 
- 			$response['files'][] = $row;
 
- 		}
 
- 		$response['id'] = $report->id;
 
- 	
 
- 	});
 
- 	//Téléchargement des documents
 
- 	Action::register('issue_download_document',function(&$response){
 
- 		global $myUser,$_;
 
- 		if(!$myUser->connected()) throw new Exception("Vous devez être connecté",401);
 
- 		require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 		$event = IssueEvent::getById($_['event']);
 
- 		$path = str_replace(array('..','/','\\'),'',base64_decode($_['path']));
 
- 		$path = $event->dir().SLASH.$path;
 
- 		File::downloadFile($path);
 
- 	});
 
- 	Action::register('issue_issuereport_meta_save',function(&$response){
 
- 	
 
- 			global $myUser,$_,$conf;
 
- 			User::check_access('issue','edit');
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueReportTag.class.php');
 
- 			if(!array_key_exists($_['state'], IssueReport::states())) throw new Exception("L'état du ticket est invalide");
 
- 			$item = IssueReport::provide();
 
- 			$oldItem = clone $item; 
 
- 			if($item->creator != $myUser->login && !$myUser->can('issue','configure')) throw new Exception("Permissions insuffisantes", 403);
 
- 			//Maj des tags
 
- 			if(empty($_['tags'])) throw new Exception("Le ticket doit avoir au moins un tag");
 
- 			$existingTags = IssueReportTag::loadAll(array('report'=>$item->id));
 
- 			$tags = explode(',',$_['tags']);
 
- 			$tagsAction = false;
 
- 			$similarTags = array();
 
- 			foreach ($existingTags as $existingTag) {
 
- 				if(in_array($existingTag->tag, $tags)){
 
- 					$similarTags[] = $existingTag->tag;
 
- 					continue;
 
- 				}
 
- 				IssueReportTag::deleteById($existingTag->id);
 
- 				$tagsAction = array('action'=>'deleted','tag'=>IssueReportTag::tags($existingTag->tag));
 
- 			}
 
- 			foreach ($tags as $tag) {
 
- 				if(in_array($tag, $similarTags)) continue;
 
- 				$newTag = new IssueReportTag();
 
- 				$newTag->tag = $tag;
 
- 				$newTag->report = $item->id;
 
- 				$newTag->save();
 
- 				$tagsAction = array('action'=>'added','tag'=>IssueReportTag::tags($tag));
 
- 			}
 
- 			
 
- 			if($tagsAction != false){
 
- 				$event = new IssueEvent();
 
- 				$event->type = IssueEvent::TYPE_TAG;
 
- 				$event->issue = $item->id;
 
- 				$event->content = json_encode($tagsAction);
 
- 				$event->save();
 
- 			}
 
- 			if(!$myUser->can('issue','configure')) throw new Exception("Permissions insuffisantes", 403);
 
- 			$item->state = $_['state'];
 
- 			if(!empty($_['assign'])){
 
- 				$item->assign = stripslashes($_['assign']);
 
- 				$item->addFollower($item->assign);
 
- 			}
 
- 			$item->addFollower($myUser->login);
 
- 			$item->save();
 
- 			
 
- 			//Si l'assignation a changée on envoi une notification
 
- 			if($oldItem->assign != $item->assign){
 
- 				$event = new IssueEvent();
 
- 				$event->type = IssueEvent::TYPE_ASSIGNATION;
 
- 				$event->issue = $item->id;
 
- 				$event->content = json_encode(array(
 
- 					'assigned' => $item->assign
 
- 				));
 
- 				$event->save();
 
- 				if($item->assign != $myUser->login){
 
- 					Plugin::callHook("emit_notification", array(array(
 
- 						'label' => '['.PROGRAM_NAME.' ] Le Ticket #'.$item->id.' vous a été assigné',
 
- 						'html' => "Le ticket <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>#".$item->id."</a> vous a été assigné par ".(!empty($myUser->fullName())?$myUser->fullName():$myUser->login)." le ".date('d-m-Y à H:i').".
 
- 						<br>Bonne chance :).",
 
- 						'type' => "issue",
 
- 						'meta' => array('link' => ROOT_URL.'/index.php?module=issue&page=sheet.report&id='.$item->id),
 
- 						'recipients' => array($item->assign)
 
- 					)));
 
- 					Plugin::callHook("emit_notification", array(array(
 
- 						'label' => '['.PROGRAM_NAME.'] Le Ticket #'.$item->id.' a été assigné à '.User::byLogin($item->assign)->fullName(),
 
- 						'html' => "Le ticket <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>#".$item->id."</a> a été assigné à ".User::byLogin($item->assign)->fullName()." par ".(!empty($myUser->fullName())?$myUser->fullName():$myUser->login)." le ".date('d-m-Y à H:i').".",
 
- 						'type' => "issue",
 
- 						'meta' => array('link' => ROOT_URL.'/index.php?module=issue&page=sheet.report&id='.$item->id),
 
- 						'recipients' => array_diff( $item->followers(), array($myUser->login), array($item->assign) ) 
 
- 					)));
 
- 				}
 
- 			}
 
- 			//Si l'etat a changé on envois une notification
 
- 			if($oldItem->state != $item->state){
 
- 				$infos = array(
 
- 					'meta' => array('link' => ROOT_URL.'/index.php?module=issue&page=sheet.report&id='.$item->id),
 
- 					'recipients' => array_diff( $item->followers(), array($myUser->login) ) ,
 
- 					'type' => "notice"
 
- 				);
 
- 				switch ($item->state) {
 
- 					case 'closed':
 
- 						$infos['label'] = "Le Ticket #".$item->id." est résolu";
 
- 						$infos['html'] = "Le ticket d'erreur <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>#".$item->id."</a> a été marqué comme résolu par ".(!empty($myUser->fullName())?$myUser->fullName():$myUser->login).' le '.date('d-m-Y à H:i').'.
 
- 							<br>Il est possible que la résolution de cette erreur ne soit mise en production que dans quelques jours.';
 
- 						
 
- 					break;
 
- 					case 'open':
 
- 							$infos['label'] = "Le Ticket #".$item->id." a été ré-ouvert";
 
- 							$infos['html'] = "Le ticket d'erreur <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>#".$item->id."</a> a été ré-ouvert par ".(!empty($myUser->fullName())?$myUser->fullName():$myUser->login).' le '.date('d-m-Y à H:i').'.
 
- 							<br>Il est possible que la résolution de cette erreur ne soit mise en production que dans quelques jours.';
 
- 						
 
- 					break;
 
- 					case 'canceled':
 
- 							$infos['label'] = "Le Ticket #".$item->id." a été annulé";
 
- 							$infos['html'] = "Le ticket d'erreur <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>#".$item->id."</a> a été annulé ".(!empty($myUser->fullName())?$myUser->fullName():$myUser->login).' le '.date('d-m-Y à H:i').'.
 
- 							<br>Il est possible que ce ticket soit un doublon ou que son contenu soit innaproprié.';
 
- 					break;
 
- 					default:
 
- 						# code...
 
- 					break;
 
- 				}
 
- 				$event = new IssueEvent();
 
- 				$event->type = IssueEvent::TYPE_STATE;
 
- 				$event->issue = $item->id;
 
- 				$event->content = json_encode(array(
 
- 					'old' => $oldItem->state,
 
- 					'new' => $item->state
 
- 				));
 
- 				$event->save();
 
- 				Plugin::callHook("emit_notification", array($infos));
 
- 			}
 
- 		
 
- 	});
 
- 	
 
- 	//Ajout ou modification d'élément issuereport
 
- 	Action::register('issue_issuereport_save',function(&$response){
 
- 	
 
- 			global $myUser,$_,$conf;
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueReportTag.class.php');
 
- 			if(!$myUser->connected()) throw new Exception("Vous devez être connecté pour laisser un rapport d'erreur",401);
 
- 			$item = IssueReport::provide();
 
- 			if(!$myUser->can('issue','edit') && is_numeric($item->id) &&  $item->id!=0) throw new Exception("Permissions insuffisantes",403);
 
- 			
 
- 			$tags = array_filter(explode(',',$_['tags']));
 
- 			if(count($tags)==0) throw new Exception("Merci de sélectionner au moins une catégorie");
 
- 			if(!isset($_['issue-comment']) || empty($_['issue-comment'])) throw new Exception("Merci de commenter votre ticket");
 
- 			$item->browser = $_['browser'];
 
- 			$item->browserVersion = $_['browserVersion'];
 
- 			$item->online = $_['online'];
 
- 			$item->os = $_['os'];
 
- 			$item->state = 'open';
 
- 			$item->from = $_['from'];
 
- 			$item->width = $_['width'];
 
- 			$item->height = $_['height'];
 
- 			$item->history = $_['history'];
 
- 			$item->ip = ip();
 
- 			$item->addFollower($myUser->login);
 
- 			$item->save();
 
- 			$firstEvent = new IssueEvent();
 
- 			$firstEvent->created =  $item->created;
 
- 			$firstEvent->updated =  $item->updated;
 
- 			$firstEvent->creator =  $item->creator;
 
- 			$firstEvent->updater =  $item->updater;
 
- 			$firstEvent->type =  IssueEvent::TYPE_COMMENT;
 
- 			$firstEvent->content =  preg_replace('/<img.*?(src="data).*?>/', '', wysiwyg_filter(html_entity_decode($_['issue-comment'])));
 
- 			$firstEvent->issue =  $item->id;
 
- 			$firstEvent->save();
 
- 			if (preg_match_all('/<img.*?>/', wysiwyg_filter(html_entity_decode($_['issue-comment'])), $matches)) {
 
- 				foreach ($matches[0] as $index => $imgTag) {
 
- 					if(preg_match('/src="data:image.*base64,.*"/', $imgTag, $imgSrc)) {
 
- 						list($type, $data) = explode(';', $imgSrc[0]);
 
- 						$ext = explode('/', $type)[1];
 
- 						$dataEncode = explode(',', $data);
 
- 						$stream = base64_decode($dataEncode[1]);
 
- 						$attachmentFolder = $firstEvent->dir();
 
- 						if(!file_exists($attachmentFolder)) mkdir($attachmentFolder,0755,true);
 
- 						$screenPath = $firstEvent->dir().SLASH.'image'.$index.'.'.$ext;
 
- 						file_put_contents($screenPath, $stream);
 
- 					} 
 
- 				}
 
- 			}
 
- 			$response['item'] = $item->toArray();
 
- 			
 
- 			IssueReportTag::delete(array('report'=>$item->id));
 
- 			foreach ($tags as $tag) {
 
- 				$reportTag = new IssueReportTag();
 
- 				$reportTag->tag = $tag;
 
- 				$reportTag->report = $item->id;
 
- 				$reportTag->save();
 
- 			}
 
- 			
 
- 			if(!empty($_['screenshot'])){
 
- 				$screenshot = str_replace('data:image/png;base64,', '', $_['screenshot']);
 
- 				$screenshot = str_replace(' ', '+', $screenshot);
 
- 				$stream = base64_decode($screenshot);
 
- 				
 
- 				$attachmentFolder = $firstEvent->dir();
 
- 				if(!file_exists($attachmentFolder)) mkdir($attachmentFolder,0755,true);
 
- 				$screenPath = $attachmentFolder.SLASH.'screenshot.jpg';
 
- 				file_put_contents($screenPath, $stream);
 
- 			}
 
- 			//Ajout fichiers joints
 
- 			if(!empty($_['document']))
 
- 				File::save_component('document', 'issue/attachments/'.$firstEvent->id.'/{{label}}');
 
- 	
 
- 			$data = $item->toArray();
 
- 			$data['comment'] = '<strong>'.$item->creator.': </strong>'.$firstEvent->content;
 
- 			$data['url'] = ROOT_URL.'/index.php?module=issue&page=sheet.report&id='.$data['id'];
 
- 			$data['title'] = 'Le Ticket <a href="'.$data['url'].'">#'.$item->id.'</a> a été ouvert par '.$item->creator;
 
- 			
 
- 			if(!empty($conf->get('issue_report_mails'))){
 
- 				$path = __DIR__.SLASH.'mail.template.php';
 
- 				if(!file_exists($path)) return;
 
- 				$stream = file_get_contents($path);
 
- 				$recipients = array();
 
- 				foreach (explode(',', $conf->get('issue_report_mails')) as $recipient) {
 
- 					if(is_numeric($recipient)){
 
- 						foreach(UserFirmRank::loadAll(array('rank'=>$recipient)) as $ufr)
 
- 							$recipients[] = $ufr->user;
 
- 						continue;
 
- 					}
 
- 					$recipients[] = $recipient;
 
- 				}
 
- 				// Émission d'une notification pour les devs
 
- 				Plugin::callHook("emit_notification", array(array(
 
- 					'label' => 'Ticket #'.$item->id.' ouvert',
 
- 					'html' => template($stream,$data),
 
- 					'type' => "issue",
 
- 					'meta' => array('link' => $data['url']),
 
- 					'recipients' => $recipients
 
- 				)));
 
- 			}
 
- 			// Émission d'une notification pour l'auteur du ticket
 
- 			Plugin::callHook("emit_notification", array(array(
 
- 				'label' => "Votre Ticket #".$item->id." a été envoyé",
 
- 				'html' => "Le ticket <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>#".$item->id."</a> a été créé et sera pris en compte par nos techniciens, vous pouvez consulter
 
- 				son avancement en <a href='".ROOT_URL."/index.php?module=issue&page=sheet.report&id=".$item->id."'>cliquant ici</a>",
 
- 				'type' => "notice",
 
- 				'meta' => array('link' => $data['url']),
 
- 				'recipients' => array($item->creator)
 
- 			)));
 
- 			Log::put('Déclaration d\'un rapport d\'erreur #'.$item->toText(), 'Issue');
 
- 		
 
- 	});
 
- 	
 
- 	Action::register('issue_screenshot_download',function(&$response){
 
- 		global $myUser,$_;
 
- 		if(!$myUser->connected()) throw new Exception("Connexion requise",401);
 
- 		try {
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			$event = IssueEvent::getById($_['id']);
 
- 			File::downloadFile($event->dir().SLASH.'screenshot.jpg');
 
- 		} catch(Exception $e) {
 
- 			File::downloadFile(__ROOT__.'img/default-image-muted.png');
 
- 		}
 
- 	});
 
- 	//Suppression d'élement issuereport
 
- 	Action::register('issue_issuereport_delete',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			$issue = IssueReport::provide();
 
- 			if($issue->creator != $myUser->login && !$myUser->can('issue','configure')) throw new Exception("Permissions insuffisantes", 403);
 
- 			$issue->remove();
 
- 		
 
- 	});
 
- 	//Etre notifié du sujet
 
- 	Action::register('issue_follow_toggle',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			User::check_access('issue','read');
 
- 			$issue = IssueReport::provide();
 
- 			$followers = $issue->followers();
 
- 			$key = array_search($myUser->login, $followers);
 
- 			if($_['state']){
 
- 				if($key===false) $followers[] = $myUser->login;
 
- 			}else{
 
- 				if($issue->creator == $myUser->login) throw new Exception("Vous ne pouvez pas arrêter de suivre un ticket que vous avez créé.");
 
- 				if($key!==false) unset($followers[$key]);
 
- 			}
 
- 			$issue->followers($followers);
 
- 			$issue->save();
 
- 		
 
- 	});
 
- 	
 
- 	//Sauvegarde des configurations de issue
 
- 	Action::register('issue_setting_save',function(&$response){
 
- 	
 
- 			global $myUser,$_,$conf;
 
- 			User::check_access('issue','configure');
 
- 			foreach(Configuration::setting('issue') as $key=>$value){
 
- 				if(!is_array($value)) continue;
 
- 				$allowed[] = $key;
 
- 			}
 
- 			foreach ($_['fields'] as $key => $value)
 
- 				if(in_array($key, $allowed)) $conf->put($key,$value);
 
- 		
 
- 	});
 
- 	/** EVENT **/
 
- 	//Récuperation d'une liste de issueevent
 
- 	Action::register('issue_issue_event_search',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			User::check_access('issue','read');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			$events = IssueEvent::loadAll(array('issue'=>$_['issue']),array('id ASC'));
 
- 			foreach($events as $i=>$event){
 
- 				$row = $event->toArray();
 
- 				$creator = User::byLogin($event->creator);
 
- 				$row['edit_rights'] = ($myUser->login == $event->creator || $myUser->superadmin);
 
- 				$row['creator'] = $creator->toArray();
 
- 				$row['avatar'] = $creator->getAvatar(); 
 
- 				$row['fullName'] = $creator->fullName(); 
 
- 				$row['created'] = date('d/m/Y H:i', $event->created);
 
- 				$row['createdRelative'] = relative_time($event->created, null, 6, true);
 
- 				switch($event->type){
 
- 					case 'comment':
 
- 						$row['classes'] = $i == 0 ? 'issue-first-comment' : '';
 
- 						$row['files'] = array();
 
- 						foreach (glob($event->dir().SLASH.'*') as $key => $value){
 
- 							$file = array();
 
- 							$file['extension'] = getExt($value);
 
- 							$file['label'] = mt_basename($value);
 
- 							$file['labelExcerpt'] = truncate($file['label'],35);
 
- 							$file['type'] = in_array($file['extension'], array('jpg','png','jpeg','bmp','gif','svg')) ? 'image' : 'file';
 
- 							$file['url'] = 'action.php?action=issue_download_document&event='.$event->id.'&path='.base64_encode(basename($value)); 
 
- 							$file['icon'] = getExtIcon($file['extension']);
 
- 							$row['files'][] = $file;
 
- 						}
 
- 					
 
- 						if($creator->login == $myUser->login || $myUser->can('issue','configure'))  $row['classes'] .=' editable';
 
- 						$row['comment'] =  empty($event->content) ? 'Pas de commentaire': $event->content; 
 
- 						$row['comment'] = preg_replace('/https?:\/\/[^\s]*\?module=issue&page=sheet\.report&id=([0-9]*)/is','<a href="$0">#$1</a>',$row['comment']);
 
- 						$row['hasfiles'] = count($row['files']) > 0 ? true : false;
 
- 					break;
 
- 					case IssueEvent::TYPE_STATE:
 
- 						$infos = json_decode($row['content'],true);
 
- 						$row['oldstate'] = IssueReport::states($infos['old']);
 
- 						$row['state'] = IssueReport::states($infos['new']);
 
- 					break;
 
- 					case IssueEvent::TYPE_TAG:
 
- 						$infos = json_decode($row['content'],true);
 
- 						
 
- 						$row['action'] = $infos['action'] == 'added' ? 'ajouté' :'supprimé';
 
- 						$row['tag'] = $infos['tag'];
 
- 					break;
 
- 					case IssueEvent::TYPE_ASSIGNATION:
 
- 						$infos = json_decode($row['content'],true);
 
- 						$assigned = User::byLogin($infos['assigned']);
 
- 						$row['assigned'] = array(
 
- 							'fullName' => $assigned->fullName(),
 
- 							'avatar' => $assigned->getAvatar()
 
- 						);
 
- 					break;
 
- 				}
 
- 				$response['rows'][] = $row;
 
- 			}
 
- 		
 
- 	});
 
- 	
 
- 	//Ajout ou modification d'élément issueevent
 
- 	Action::register('issue_issue_event_save',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			$item = IssueEvent::provide('id',1);
 
- 			$isNew = empty($item->id);
 
- 			if($myUser->login != $item->creator && !$myUser->can('issue','edit')) throw new Exception("Permissions insuffisantes", 403);
 
- 			
 
- 			if(!isset($_['content']) || empty($_['content'])) throw new Exception("Vous devez spécifier un commentaire");
 
- 			$item->type = IssueEvent::TYPE_COMMENT;
 
- 			$item->content = wysiwyg_filter(html_entity_decode($_['content']));
 
- 			$item->issue = $_['issue'];
 
- 			$mentionned = array();
 
- 			if($item->id == 0){
 
- 				preg_match_all('|data-mention-value="([^"]*)"|isU', $item->content, $matches,PREG_SET_ORDER);
 
- 				foreach ($matches as $match) {
 
- 					$mentionned[] = $match[1];
 
- 				}
 
- 			}
 
- 			$item->save();
 
- 			if(!empty($_['event-files']))
 
- 				File::save_component('event-files', 'issue/attachments/'.$item->id.'/{{label}}');
 
- 		
 
- 			$issue = IssueReport::getById($item->issue);
 
- 			$issue->addFollower($myUser->login);
 
- 			$issue->save();
 
- 			$path = __DIR__.SLASH.'mail.template.php';
 
- 			if(!file_exists($path)) return;
 
- 			$stream = file_get_contents($path);
 
- 			$data = $item->toArray();
 
- 			$data['comment'] = '<strong>'.$item->creator.': </strong>'.$item->content;
 
- 			$data['url'] = ROOT_URL.'/index.php?module=issue&page=sheet.report&id='.$data['issue'];
 
- 			$data['title'] = 'Le Ticket <a href="'.$data['url'].'">#'.$item->issue.'</a> a été commenté par '.$item->creator;
 
- 			$recipients = array_diff($issue->followers(), array($myUser->login));
 
- 			// Émission d'une notification pour les acteurs du rapport 
 
- 			Plugin::callHook("emit_notification", array(array(
 
- 				'label' => 'Ticket #'.$item->issue.': '.($isNew?'Nouveau commentaire':'Édition d\'un commentaire')  ,
 
- 				'html' => template($stream,$data),
 
- 				'type' => "issue",
 
- 				'meta' => array('link' => $data['url']),
 
- 				'recipients' => $recipients
 
- 			)));
 
- 			// Émission d'une notification pour les acteurs spécifiquement mentionnés 
 
- 			if(count($mentionned)){
 
- 				$data['comment'] = 'Vous avez été mentionné dans le commentaire suivant : <br>'.$data['comment'];
 
- 				$data['url'] = ROOT_URL.'/index.php?module=issue&page=sheet.report&id='.$data['issue'].'#issue-comment-'.$item->id;
 
- 				$data['title'] = 'Vous avez été mentionné par '.$item->creator.' dans le ticket <a href="'.$data['url'].'">#'.$item->issue.'</a>';
 
- 				Plugin::callHook("emit_notification", array(array(
 
- 					'label' => 'Vous avez été mentionné par '.$item->creator.' dans le ticket #'.$item->issue.':'  ,
 
- 					'html' => template($stream,$data),
 
- 					'type' => "issue",
 
- 					'meta' => array('link' => $data['url']),
 
- 					'recipients' => $mentionned 
 
- 				)));
 
- 			}
 
- 		
 
- 	});
 
- 	
 
- 	//Récuperation ou edition d'élément issueevent
 
- 	Action::register('issue_issue_event_edit',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			User::check_access('issue','edit');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			$event = IssueEvent::getById($_['id'],1);
 
- 			if($event->type != 'comment') throw new Exception("Vous ne pouvez pas éditer cet événement");
 
- 			if($myUser->login != $event->creator && !$myUser->superadmin) throw new Exception("Permissions insuffisantes", 403);
 
- 			$response = $event->toArray(true);
 
- 		
 
- 	});
 
- 	//Suppression d'élement issueevent
 
- 	Action::register('issue_issue_event_delete',function(&$response){
 
- 	
 
- 			global $myUser,$_;
 
- 			require_once(__DIR__.SLASH.'IssueReport.class.php');
 
- 			require_once(__DIR__.SLASH.'IssueEvent.class.php');
 
- 			$event = IssueEvent::getById($_['id'],1);
 
- 			if($event->type != 'comment') throw new Exception("Vous ne pouvez pas supprimer cet événement");
 
- 			$issue = $event->join('issue');
 
- 			if($event->creator != $myUser->login && !$myUser->can('issue','configure')) throw new Exception("Permissions insuffisantes", 403);
 
- 			$event->remove();
 
- 			if(IssueEvent::rowCount(array('issue'=>$issue->id)) == 0){
 
- 				if($issue->creator != $myUser->login && !$myUser->can('issue','configure')) throw new Exception("Permissions insuffisantes", 403);
 
- 				$issue->remove(false);
 
- 				$response['redirect'] = 'index.php?module=issue&page=list.issue';
 
- 			}
 
- 		
 
- 	});
 
- ?>
 
 
  |