зеркало из https://github.com/nextcloud/server.git
remove Log completely
This commit is contained in:
Родитель
cdf91b6b3e
Коммит
1f1498ceca
|
@ -52,7 +52,7 @@ class OC_App{
|
|||
}
|
||||
|
||||
// Our very own core apps are hardcoded
|
||||
foreach( array( 'admin', 'files', 'log', 'help', 'settings' ) as $app ){
|
||||
foreach( array( 'admin', 'files', 'help', 'settings' ) as $app ){
|
||||
require( $app.'/appinfo/app.php' );
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,6 @@ class OC_Files {
|
|||
die('403 Forbidden');
|
||||
}
|
||||
ob_end_clean();
|
||||
// OC_Log::event($_SESSION['username'],3,"$dir/$files");
|
||||
if($zip){
|
||||
readfile($filename);
|
||||
unlink($filename);
|
||||
|
@ -206,7 +205,6 @@ class OC_Files {
|
|||
$fileHandle=OC_Filesystem::fopen($file, 'w');
|
||||
if($fileHandle){
|
||||
fclose($fileHandle);
|
||||
// OC_Log::event($_SESSION['username'],4,"$dir/$name");
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
|
|
151
lib/log.php
151
lib/log.php
|
@ -1,151 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Frank Karlitschek
|
||||
* @author Jakob Sack
|
||||
* @copyright 2010 Frank Karlitschek karlitschek@kde.org
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* The following SQL statement is just a help for developers and will not be
|
||||
* executed!
|
||||
*
|
||||
* CREATE TABLE `log` (
|
||||
* `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
|
||||
* `moment` DATETIME NOT NULL ,
|
||||
* `appid` VARCHAR( 255 ) NOT NULL ,
|
||||
* `user` VARCHAR( 255 ) NOT NULL ,
|
||||
* `action` VARCHAR( 255 ) NOT NULL ,
|
||||
* `info` TEXT NOT NULL
|
||||
* ) ENGINE = MYISAM ;
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is for logging
|
||||
*/
|
||||
class OC_Log {
|
||||
/**
|
||||
* @brief adds an entry to the log
|
||||
* @param $appid id of the app
|
||||
* @param $subject username
|
||||
* @param $predicate action
|
||||
* @param $object = null; additional information
|
||||
* @returns true/false
|
||||
*
|
||||
* This function adds another entry to the log database
|
||||
*/
|
||||
public static function add( $appid, $subject, $predicate, $object = ' ' ){
|
||||
$query=OC_DB::prepare("INSERT INTO `*PREFIX*log`(moment,appid,`user`,action,info) VALUES(NOW(),?,?,?,?)");
|
||||
$result=$query->execute(array($appid,$subject,$predicate,$object));
|
||||
// Die if we have an error
|
||||
if( PEAR::isError($result)) {
|
||||
$entry = 'DB Error: "'.$result->getMessage().'"<br />';
|
||||
$entry .= 'Offending command was: '.$query.'<br />';
|
||||
error_log( $entry );
|
||||
die( $entry );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetches log entries
|
||||
* @param $filter = array(); array with filter options
|
||||
* @returns array with entries
|
||||
*
|
||||
* This function fetches the log entries according to the filter options
|
||||
* passed.
|
||||
*
|
||||
* $filter is an associative array.
|
||||
* The following keys are optional:
|
||||
* - from: all entries after this date
|
||||
* - until: all entries until this date
|
||||
* - user: username (default: current user)
|
||||
* - app: only entries for this app
|
||||
*/
|
||||
public static function get( $filter = array()){
|
||||
$queryString='SELECT * FROM `*PREFIX*log` WHERE 1=1 ORDER BY moment DESC';
|
||||
$params=array();
|
||||
if(isset($filter['from'])){
|
||||
$queryString.='AND moment>? ';
|
||||
array_push($params,$filter('from'));
|
||||
}
|
||||
if(isset($filter['until'])){
|
||||
$queryString.='AND moment<? ';
|
||||
array_push($params,$filter('until'));
|
||||
}
|
||||
if(isset($filter['user'])){
|
||||
$queryString.='AND `user`=? ';
|
||||
array_push($params,$filter('user'));
|
||||
}
|
||||
if(isset($filter['app'])){
|
||||
$queryString.='AND appid=? ';
|
||||
array_push($params,$filter('app'));
|
||||
}
|
||||
$query=OC_DB::prepare($queryString);
|
||||
$result=$query->execute($params)->fetchAll();
|
||||
if(count($result)>0 and is_numeric($result[0]['moment'])){
|
||||
foreach($result as &$row){
|
||||
$row['moment']=OC_Util::formatDate($row['moment']);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief removes log entries
|
||||
* @param $date delete entries older than this date
|
||||
* @returns true/false
|
||||
*
|
||||
* This function deletes all entries that are older than $date.
|
||||
*/
|
||||
public static function deleteBefore( $date ){
|
||||
$query=OC_DB::prepare("DELETE FROM `*PREFIX*log` WHERE moment<?");
|
||||
$query->execute(array($date));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief removes all log entries
|
||||
* @returns true/false
|
||||
*
|
||||
* This function deletes all log entries.
|
||||
*/
|
||||
public static function deleteAll(){
|
||||
$query=OC_DB::prepare("DELETE FROM `*PREFIX*log`");
|
||||
$query->execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief filter an array of log entries on action
|
||||
* @param array $logs the log entries to filter
|
||||
* @param array $actions an array of actions to filter for
|
||||
* @returns array
|
||||
*/
|
||||
public static function filterAction($logs,$actions){
|
||||
$filteredLogs=array();
|
||||
foreach($logs as $log){
|
||||
if(array_search($log['action'],$actions)!==false){
|
||||
$filteredLogs[]=$log;
|
||||
}
|
||||
}
|
||||
return $filteredLogs;
|
||||
}
|
||||
}
|
28
lib/ocs.php
28
lib/ocs.php
|
@ -402,33 +402,7 @@ class OC_OCS {
|
|||
private static function activityGet($format,$page,$pagesize) {
|
||||
$user=OC_OCS::checkpassword();
|
||||
|
||||
$query = OC_DB::prepare('select count(*) as co from *PREFIX*log');
|
||||
$result = $query->execute();
|
||||
$entry=$result->fetchRow();
|
||||
$totalcount=$entry['co'];
|
||||
|
||||
$query=OC_DB::prepare('select id,timestamp,`user`,type,message from *PREFIX*log order by timestamp desc limit ?,?');
|
||||
$result = $query->execute(array(($page*$pagesize),$pagesize))->fetchAll();
|
||||
|
||||
$itemscount=count($result);
|
||||
|
||||
$url='http://'.substr($_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'],0,-11).'';
|
||||
$xml=array();
|
||||
foreach($result as $i=>$log) {
|
||||
$xml[$i]['id']=$log['id'];
|
||||
$xml[$i]['personid']=$log['user'];
|
||||
$xml[$i]['firstname']=$log['user'];
|
||||
$xml[$i]['lastname']='';
|
||||
$xml[$i]['profilepage']=$url;
|
||||
|
||||
$pic=$url.'/img/owncloud-icon.png';
|
||||
$xml[$i]['avatarpic']=$pic;
|
||||
|
||||
$xml[$i]['timestamp']=date('c',$log['timestamp']);
|
||||
$xml[$i]['type']=1;
|
||||
$xml[$i]['message']=OC_Log::$TYPE[$log['type']].' '.strip_tags($log['message']);
|
||||
$xml[$i]['link']=$url;
|
||||
}
|
||||
//TODO
|
||||
|
||||
$txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize);
|
||||
echo($txt);
|
||||
|
|
|
@ -193,7 +193,6 @@ class OC_User {
|
|||
|
||||
if( $run && self::checkPassword( $uid, $password )){
|
||||
$_SESSION['user_id'] = $uid;
|
||||
OC_Log::add( "core", $_SESSION['user_id'], "login" );
|
||||
OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid ));
|
||||
return true;
|
||||
}
|
||||
|
@ -210,7 +209,6 @@ class OC_User {
|
|||
*/
|
||||
public static function logout(){
|
||||
OC_Hook::emit( "OC_User", "logout", array());
|
||||
OC_Log::add( "core", $_SESSION['user_id'], "logout" );
|
||||
$_SESSION['user_id'] = false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
<?php /*
|
||||
|
||||
OC_App::register( array( "order" => 1, "id" => "log", "name" => "Log" ));
|
||||
OC_App::addSettingsPage( array( "id" => "log", "order" => 999, "href" => OC_Helper::linkTo( "log", "index.php" ), "name" => "Log", "icon" => OC_Helper::imagePath( "log", "logs.png" )));
|
||||
|
||||
*/ ?>
|
Двоичные данные
log/img/logs.png
Двоичные данные
log/img/logs.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 213 B |
107
log/index.php
107
log/index.php
|
@ -1,107 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - ajax frontend
|
||||
*
|
||||
* @author Robin Appelman
|
||||
* @copyright 2010 Robin Appelman icewind1991@gmail.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
//require_once('../../config/config.php');
|
||||
/*
|
||||
require_once('../lib/base.php');
|
||||
|
||||
if( !OC_User::isLoggedIn()){
|
||||
header( 'Location: '.OC_Helper::linkTo( 'index.php' ));
|
||||
exit();
|
||||
}
|
||||
|
||||
//load the script
|
||||
OC_Util::addScript( "log", "log" );
|
||||
|
||||
$allActions=array('login','logout','read','write','create','delete');
|
||||
|
||||
//check for a submitted config
|
||||
if(isset($_POST['save'])){
|
||||
$selectedActions=array();
|
||||
foreach($allActions as $action){
|
||||
if(isset($_POST[$action]) and $_POST[$action]=='on'){
|
||||
$selectedActions[]=$action;
|
||||
}
|
||||
}
|
||||
OC_Preferences::setValue(OC_User::getUser(),'log','actions',implode(',',$selectedActions));
|
||||
OC_Preferences::setValue(OC_User::getUser(),'log','pagesize',$_POST['size']);
|
||||
}
|
||||
//clear log entries
|
||||
elseif(isset($_POST['clear'])){
|
||||
$removeBeforeDate=(isset($_POST['removeBeforeDate']))?$_POST['removeBeforeDate']:0;
|
||||
if($removeBeforeDate!==0){
|
||||
$removeBeforeDate=strtotime($removeBeforeDate);
|
||||
OC_Log::deleteBefore($removeBeforeDate);
|
||||
}
|
||||
}
|
||||
elseif(isset($_POST['clearall'])){
|
||||
OC_Log::deleteAll();
|
||||
}
|
||||
|
||||
OC_App::setActiveNavigationEntry( 'log' );
|
||||
$logs=OC_Log::get();
|
||||
|
||||
|
||||
$selectedActions=explode(',',OC_Preferences::getValue(OC_User::getUser(),'log','actions',implode(',',$allActions)));
|
||||
$logs=OC_Log::filterAction($logs,$selectedActions);
|
||||
|
||||
$pageSize=OC_Preferences::getValue(OC_User::getUser(),'log','pagesize',20);
|
||||
$pageCount=ceil(count($logs)/$pageSize);
|
||||
$page=isset($_GET['page'])?$_GET['page']:0;
|
||||
if($page>=$pageCount){
|
||||
$page=$pageCount-1;
|
||||
}
|
||||
|
||||
$logs=array_slice($logs,$page*$pageSize,$pageSize);
|
||||
|
||||
foreach( $logs as &$i ){
|
||||
$i['date'] =$i['moment'];
|
||||
}
|
||||
|
||||
$url=OC_Helper::linkTo( 'log', 'index.php' ).'?page=';
|
||||
$pager=OC_Util::getPageNavi($pageCount,$page,$url);
|
||||
if($pager){
|
||||
$pagerHTML=$pager->fetchPage();
|
||||
}
|
||||
else{
|
||||
$pagerHTML='';
|
||||
}
|
||||
|
||||
$showActions=array();
|
||||
foreach($allActions as $action){
|
||||
if(array_search($action,$selectedActions)!==false){
|
||||
$showActions[$action]='checked="checked"';
|
||||
}
|
||||
else{
|
||||
$showActions[$action]='';
|
||||
}
|
||||
}
|
||||
|
||||
$tmpl = new OC_Template( 'log', 'index', 'admin' );
|
||||
$tmpl->assign( 'logs', $logs );
|
||||
$tmpl->assign( 'pager', $pagerHTML );
|
||||
$tmpl->assign( 'size', $pageSize );
|
||||
$tmpl->assign( 'showActions', $showActions );
|
||||
$tmpl->printPage();
|
||||
|
||||
*/ ?>
|
|
@ -1,25 +0,0 @@
|
|||
$(document).ready(function() {
|
||||
// Sets the select_all checkbox behaviour :
|
||||
$('#all').click(function() {
|
||||
if($(this).attr('checked')){
|
||||
// Check all
|
||||
$('input.action:checkbox').attr('checked', true);
|
||||
}else{
|
||||
// Uncheck all
|
||||
$('input.action:checkbox').attr('checked', false);
|
||||
}
|
||||
});
|
||||
$('input.action:checkbox').click(function() {
|
||||
if(!$(this).attr('checked')){
|
||||
$('#all').attr('checked',false);
|
||||
}else{
|
||||
if($('input.action:checkbox:checked').length==$('input.action:checkbox').length){
|
||||
$('#all').attr('checked',true);
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#removeBeforeDate').datepicker({
|
||||
dateFormat:'MM d, yy',
|
||||
});
|
||||
});
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Филтър:",
|
||||
"Logins" => "Влизания:",
|
||||
"Logouts" => "Изходи:",
|
||||
"Downloads" => "Тегления",
|
||||
"Uploads" => "Качвания",
|
||||
"Creations" => "Създавания:",
|
||||
"Deletions" => "Изтривания:",
|
||||
"Show:" => "Показва:",
|
||||
"entries per page." => "записа на страница.",
|
||||
"What" => "Какво",
|
||||
"When" => "Кога",
|
||||
"Clear log entries before" => "Изчисти записите от журналите"
|
||||
);
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Filter:",
|
||||
"Logins" => "Logins",
|
||||
"Logouts" => "Logouts",
|
||||
"Downloads" => "Downloads",
|
||||
"Uploads" => "Uploads",
|
||||
"Creations" => "Oprettelser",
|
||||
"Deletions" => "Sletninger",
|
||||
"Show:" => "Vis:",
|
||||
"entries per page." => "poster pr side.",
|
||||
"What" => "Hvilket",
|
||||
"When" => "Hvornår",
|
||||
"Clear log entries before" => "Slet log poster før"
|
||||
);
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Filter:",
|
||||
"Logins" => "Anmeldungen",
|
||||
"Logouts" => "Abmeldungen",
|
||||
"Downloads" => "Downloads",
|
||||
"Uploads" => "Uploads",
|
||||
"Creations" => "Erstellungen",
|
||||
"Deletions" => "Löschungen",
|
||||
"Show:" => "Zeige",
|
||||
"entries per page." => "Einträge pro Seite",
|
||||
"What" => "Was",
|
||||
"When" => "Wann",
|
||||
"Clear log entries before" => "Lösche Einträge vor dem"
|
||||
);
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Filtro:",
|
||||
"Logins" => "Inicios de sesión",
|
||||
"Logouts" => "Cierres de sesión",
|
||||
"Downloads" => "Descargas",
|
||||
"Uploads" => "Subidas",
|
||||
"Creations" => "Creaciones",
|
||||
"Deletions" => "Eliminaciones",
|
||||
"Show:" => "Mostrar",
|
||||
"entries per page." => "Entradas por página.",
|
||||
"What" => "Qué",
|
||||
"When" => "Cuándo",
|
||||
"Clear log entries before" => "Eliminar los registros anteriores a"
|
||||
);
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Filtre :",
|
||||
"Logins" => "Connexions",
|
||||
"Logouts" => "Déconnexions",
|
||||
"Downloads" => "Téléchargements",
|
||||
"Uploads" => "Téléversements",
|
||||
"Creations" => "Créations",
|
||||
"Deletions" => "Suppressions",
|
||||
"Show:" => "Afficher :",
|
||||
"entries per page." => "entrées par page.",
|
||||
"What" => "Quoi",
|
||||
"When" => "Quand",
|
||||
"Clear log entries before" => "Effacer les entrées du journal au préalable"
|
||||
);
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Filter:",
|
||||
"Logins" => "Aanmeldingen",
|
||||
"Logouts" => "Afmeldingen",
|
||||
"Downloads" => "Downloads",
|
||||
"Uploads" => "Uploads",
|
||||
"Creations" => "Creaties",
|
||||
"Deletions" => "Verwijderingen",
|
||||
"Show:" => "Laat",
|
||||
"entries per page." => "resulaten per pagina zien",
|
||||
"What" => "Wat",
|
||||
"When" => "Wanneer",
|
||||
"Clear log entries before" => "Verwijder logboekitem ouder dan"
|
||||
);
|
|
@ -1,14 +0,0 @@
|
|||
<?php $TRANSLATIONS = array(
|
||||
"Filter:" => "Filtr:",
|
||||
"Logins" => "Zalogowania",
|
||||
"Logouts" => "Wylogowani",
|
||||
"Downloads" => "Pobrania",
|
||||
"Uploads" => "Wgrania",
|
||||
"Creations" => "Utworzenia",
|
||||
"Deletions" => "Usunięcia",
|
||||
"Show:" => "Pokaż:",
|
||||
"entries per page." => "wpisów na stronę.",
|
||||
"What" => "Co",
|
||||
"When" => "Kiedy",
|
||||
"Clear log entries before" => "Wyczyść spisy dziennika sprzed"
|
||||
);
|
|
@ -1,53 +0,0 @@
|
|||
<?php /*<div class="controls">
|
||||
<form id="logs_options" method='post'>
|
||||
<p>
|
||||
<span><?php echo $l->t( 'Filter:' ); ?></span>
|
||||
|
||||
<input type="checkbox" checked="" name="all" id="all" /> <label for="all">All</label>
|
||||
<input type="checkbox" class='action' <?php echo $_['showActions']['login']?> name="login" id="logins" /> <label for="logins"><?php echo $l->t( 'Logins' ); ?></label>
|
||||
<input type="checkbox" class='action' <?php echo $_['showActions']['logout']?> name="logout" id="logouts" /> <label for="logouts"><?php echo $l->t( 'Logouts' ); ?></label>
|
||||
<input type="checkbox" class='action' <?php echo $_['showActions']['read']?> name="read" id="downloads" /> <label for="downloads"><?php echo $l->t( 'Downloads' ); ?></label>
|
||||
<input type="checkbox" class='action' <?php echo $_['showActions']['write']?> name="write" id="uploads" /> <label for="uploads"><?php echo $l->t( 'Uploads' ); ?></label>
|
||||
<input type="checkbox" class='action' <?php echo $_['showActions']['create']?> name="create" id="creations" /> <label for="creations"><?php echo $l->t( 'Creations' ); ?></label>
|
||||
<input type="checkbox" class='action' <?php echo $_['showActions']['delete']?> name="delete" id="deletions" /> <label for="deletions"><?php echo $l->t( 'Deletions' ); ?></label>
|
||||
</p>
|
||||
<p>
|
||||
<span><?php echo $l->t( 'Show:' ); ?></span>
|
||||
<input type="text" maxlength="3" size="3" value="<?php echo $_['size']?>" name='size'/> <?php echo $l->t( 'entries per page.' ); ?>
|
||||
<input class="prettybutton" type="submit" name="save" value="Save" />
|
||||
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<table cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $l->t( 'What' ); ?></th>
|
||||
<th><?php echo $l->t( 'When' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($_["logs"] as $entry): ?>
|
||||
<tr>
|
||||
<td class="<?php echo $entry["action"]; ?>"><em><?php echo $entry["action"]; ?> <?php echo $entry["user"]; ?></em> <?php echo $entry["info"]; ?></td>
|
||||
<td class="date"><?php echo $l->l('datetime', $entry["date"] ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php echo $_['pager'];?>
|
||||
|
||||
<div class="controls">
|
||||
<form id="logs_options" method='post'>
|
||||
<p>
|
||||
<span><?php echo $l->t( 'Clear log entries before' ); ?> </span>
|
||||
<input type="date" id="removeBeforeDate" name="removeBeforeDate"/>
|
||||
<input class="prettybutton nofloat" type="submit" name="clear" value="Clear" />
|
||||
<input class="prettybutton" type="submit" name="clearall" value="Clear All" />
|
||||
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
*/ ?>
|
Загрузка…
Ссылка в новой задаче