mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-05-19 05:44:39 -04:00
Auto-label (#5954)
Add labels automatically to incoming articles fix https://github.com/FreshRSS/FreshRSS/issues/2380 fix https://github.com/FreshRSS/FreshRSS/issues/2420 fix https://github.com/FreshRSS/FreshRSS/issues/3279 fix https://github.com/FreshRSS/FreshRSS/discussions/4947 fix https://github.com/FreshRSS/FreshRSS/issues/5728 fix https://github.com/FreshRSS/FreshRSS/issues/5599
This commit is contained in:
committed by
GitHub
parent
1e5f5078ed
commit
70e71b8364
@@ -679,29 +679,81 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
|
||||
return [$updated_feeds, reset($feeds) ?: null, $nb_new_articles];
|
||||
}
|
||||
|
||||
public static function commitNewEntries(): bool {
|
||||
$entryDAO = FreshRSS_Factory::createEntryDao();
|
||||
if (!$entryDAO->inTransaction()) {
|
||||
$entryDAO->beginTransaction();
|
||||
}
|
||||
|
||||
$newUnreadEntriesPerFeed = $entryDAO->newUnreadEntriesPerFeed();
|
||||
if ($entryDAO->commitNewEntries()) {
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
$feeds = $feedDAO->listFeedsOrderUpdate(-1);
|
||||
foreach ($feeds as $feed) {
|
||||
if (!empty($newUnreadEntriesPerFeed[$feed->id()]) && $feed->keepMaxUnread() !== null &&
|
||||
($feed->nbNotRead() + $newUnreadEntriesPerFeed[$feed->id()] > $feed->keepMaxUnread())) {
|
||||
Minz_Log::debug('New unread entries (' . ($feed->nbNotRead() + $newUnreadEntriesPerFeed[$feed->id()]) . ') exceeding max number of ' .
|
||||
$feed->keepMaxUnread() . ' for [' . $feed->url(false) . ']');
|
||||
$feed->markAsReadMaxUnread();
|
||||
/**
|
||||
* @param array<int,int> $newUnreadEntriesPerFeed
|
||||
* @return int|false The number of articles marked as read, of false if error
|
||||
*/
|
||||
private static function keepMaxUnreads(array $newUnreadEntriesPerFeed) {
|
||||
$affected = 0;
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
$feeds = $feedDAO->listFeedsOrderUpdate(-1);
|
||||
foreach ($feeds as $feed) {
|
||||
if (!empty($newUnreadEntriesPerFeed[$feed->id()]) && $feed->keepMaxUnread() !== null &&
|
||||
($feed->nbNotRead() + $newUnreadEntriesPerFeed[$feed->id()] > $feed->keepMaxUnread())) {
|
||||
Minz_Log::debug('New unread entries (' . ($feed->nbNotRead() + $newUnreadEntriesPerFeed[$feed->id()]) . ') exceeding max number of ' .
|
||||
$feed->keepMaxUnread() . ' for [' . $feed->url(false) . ']');
|
||||
$n = $feed->markAsReadMaxUnread();
|
||||
if ($n === false) {
|
||||
$affected = false;
|
||||
break;
|
||||
} else {
|
||||
$affected += $n;
|
||||
}
|
||||
}
|
||||
$feedDAO->updateCachedValues();
|
||||
}
|
||||
if ($feedDAO->updateCachedValues() === false) {
|
||||
$affected = false;
|
||||
}
|
||||
return $affected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-add labels to new articles.
|
||||
* @param int $nbNewEntries The number of top recent entries to process.
|
||||
* @return int|false The number of new labels added, or false in case of error.
|
||||
*/
|
||||
private static function applyLabelActions(int $nbNewEntries) {
|
||||
$tagDAO = FreshRSS_Factory::createTagDao();
|
||||
$labels = $tagDAO->listTags() ?: [];
|
||||
$labels = array_filter($labels, static function (FreshRSS_Tag $label) {
|
||||
return !empty($label->filtersAction('label'));
|
||||
});
|
||||
if (count($labels) <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($entryDAO->inTransaction()) {
|
||||
$entryDAO->commit();
|
||||
$entryDAO = FreshRSS_Factory::createEntryDao();
|
||||
/** @var array<array{id_tag:int,id_entry:string}> $applyLabels */
|
||||
$applyLabels = [];
|
||||
foreach (FreshRSS_Entry::fromTraversable($entryDAO->selectAll($nbNewEntries)) as $entry) {
|
||||
foreach ($labels as $label) {
|
||||
$label->applyFilterActions($entry, $applyLabel);
|
||||
if ($applyLabel) {
|
||||
$applyLabels[] = [
|
||||
'id_tag' => $label->id(),
|
||||
'id_entry' => $entry->id(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $tagDAO->tagEntries($applyLabels);
|
||||
}
|
||||
|
||||
public static function commitNewEntries(): bool {
|
||||
$entryDAO = FreshRSS_Factory::createEntryDao();
|
||||
$newUnreadEntriesPerFeed = $entryDAO->newUnreadEntriesPerFeed();
|
||||
$nbNewEntries = array_sum($newUnreadEntriesPerFeed);
|
||||
if ($nbNewEntries > 0) {
|
||||
if (!$entryDAO->inTransaction()) {
|
||||
$entryDAO->beginTransaction();
|
||||
}
|
||||
if ($entryDAO->commitNewEntries()) {
|
||||
self::keepMaxUnreads($newUnreadEntriesPerFeed);
|
||||
self::applyLabelActions($nbNewEntries);
|
||||
}
|
||||
if ($entryDAO->inTransaction()) {
|
||||
$entryDAO->commit();
|
||||
}
|
||||
}
|
||||
|
||||
$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
|
||||
|
||||
@@ -21,7 +21,6 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController {
|
||||
$this->ajax = Minz_Request::paramBoolean('ajax');
|
||||
if ($this->ajax) {
|
||||
$this->view->_layout(null);
|
||||
Minz_Request::_param('ajax');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +83,51 @@ class FreshRSS_tag_Controller extends FreshRSS_ActionController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This action updates the given tag.
|
||||
*/
|
||||
public function updateAction(): void {
|
||||
if (Minz_Request::paramBoolean('ajax')) {
|
||||
$this->view->_layout(null);
|
||||
}
|
||||
|
||||
$tagDAO = FreshRSS_Factory::createTagDao();
|
||||
|
||||
$id = Minz_Request::paramInt('id');
|
||||
$tag = $tagDAO->searchById($id);
|
||||
if ($id === 0 || $tag === null) {
|
||||
Minz_Error::error(404);
|
||||
return;
|
||||
}
|
||||
$this->view->tag = $tag;
|
||||
|
||||
FreshRSS_View::prependTitle($tag->name() . ' · ' . _t('sub.title') . ' · ');
|
||||
|
||||
if (Minz_Request::isPost()) {
|
||||
invalidateHttpCache();
|
||||
$ok = true;
|
||||
|
||||
if ($tag->name() !== Minz_Request::paramString('name')) {
|
||||
$ok = $tagDAO->updateTagName($tag->id(), Minz_Request::paramString('name')) !== false;
|
||||
}
|
||||
|
||||
if ($ok) {
|
||||
$tag->_filtersAction('label', Minz_Request::paramTextToArray('filteractions_label'));
|
||||
$ok = $tagDAO->updateTagAttributes($tag->id(), $tag->attributes()) !== false;
|
||||
}
|
||||
|
||||
invalidateHttpCache();
|
||||
|
||||
$url_redirect = ['c' => 'tag', 'a' => 'update', 'params' => ['id' => $id]];
|
||||
if ($ok) {
|
||||
Minz_Request::good(_t('feedback.tag.updated'), $url_redirect);
|
||||
} else {
|
||||
Minz_Request::bad(_t('feedback.tag.error'), $url_redirect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getTagsForEntryAction(): void {
|
||||
if (!FreshRSS_Auth::hasAccess() && !FreshRSS_Context::systemConf()->allow_anonymous) {
|
||||
Minz_Error::error(403);
|
||||
|
||||
@@ -50,7 +50,7 @@ class FreshRSS_Entry extends Minz_Model {
|
||||
}
|
||||
|
||||
/** @param array{'id'?:string,'id_feed'?:int,'guid'?:string,'title'?:string,'author'?:string,'content'?:string,'link'?:string,'date'?:int|string,'lastSeen'?:int,
|
||||
* 'hash'?:string,'is_read'?:bool|int,'is_favorite'?:bool|int,'tags'?:string|array<string>,'attributes'?:string,'thumbnail'?:string,'timestamp'?:string} $dao */
|
||||
* 'hash'?:string,'is_read'?:bool|int,'is_favorite'?:bool|int,'tags'?:string|array<string>,'attributes'?:?string,'thumbnail'?:string,'timestamp'?:string} $dao */
|
||||
public static function fromArray(array $dao): FreshRSS_Entry {
|
||||
FreshRSS_DatabaseDAO::pdoInt($dao, ['id_feed', 'date', 'lastSeen', 'is_read', 'is_favorite']);
|
||||
|
||||
@@ -98,6 +98,17 @@ class FreshRSS_Entry extends Minz_Model {
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Traversable<array{'id'?:string,'id_feed'?:int,'guid'?:string,'title'?:string,'author'?:string,'content'?:string,'link'?:string,'date'?:int|string,'lastSeen'?:int,
|
||||
* 'hash'?:string,'is_read'?:bool|int,'is_favorite'?:bool|int,'tags'?:string|array<string>,'attributes'?:?string,'thumbnail'?:string,'timestamp'?:string}> $daos
|
||||
* @return Traversable<FreshRSS_Entry>
|
||||
*/
|
||||
public static function fromTraversable(Traversable $daos): Traversable {
|
||||
foreach ($daos as $dao) {
|
||||
yield FreshRSS_Entry::fromArray($dao);
|
||||
}
|
||||
}
|
||||
|
||||
public function id(): string {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ SQL;
|
||||
private $addEntryPrepared = false;
|
||||
|
||||
/** @param array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'lastSeen':int,'hash':string,
|
||||
* 'is_read':bool|int|null,'is_favorite':bool|int|null,'id_feed':int,'tags':string,'attributes':array<string,mixed>} $valuesTmp */
|
||||
* 'is_read':bool|int|null,'is_favorite':bool|int|null,'id_feed':int,'tags':string,'attributes'?:null|string|array<string,mixed>} $valuesTmp */
|
||||
public function addEntry(array $valuesTmp, bool $useTmpTable = true): bool {
|
||||
if ($this->addEntryPrepared == null) {
|
||||
$sql = static::sqlIgnoreConflict(
|
||||
@@ -693,19 +693,22 @@ SQL;
|
||||
}
|
||||
|
||||
/** @return Traversable<array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'lastSeen':int,
|
||||
* 'hash':string,'is_read':?bool,'is_favorite':?bool,'id_feed':int,'tags':string,'attributes':array<string,mixed>}> */
|
||||
public function selectAll(): Traversable {
|
||||
* 'hash':string,'is_read':bool,'is_favorite':bool,'id_feed':int,'tags':string,'attributes':?string}> */
|
||||
public function selectAll(?int $limit = null): Traversable {
|
||||
$content = static::isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content';
|
||||
$hash = static::sqlHexEncode('hash');
|
||||
$sql = <<<SQL
|
||||
SELECT id, guid, title, author, {$content}, link, date, `lastSeen`, {$hash} AS hash, is_read, is_favorite, id_feed, tags, attributes
|
||||
FROM `_entry`
|
||||
SQL;
|
||||
if (is_int($limit) && $limit >= 0) {
|
||||
$sql .= ' ORDER BY id DESC LIMIT ' . $limit;
|
||||
}
|
||||
$stm = $this->pdo->query($sql);
|
||||
if ($stm != false) {
|
||||
while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
|
||||
/** @var array{'id':string,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,'lastSeen':int,
|
||||
* 'hash':string,'is_read':?bool,'is_favorite':?bool,'id_feed':int,'tags':string,'attributes':array<string,mixed>} $row */
|
||||
* 'hash':string,'is_read':bool,'is_favorite':bool,'id_feed':int,'tags':string,'attributes':?string} $row */
|
||||
yield $row;
|
||||
}
|
||||
} else {
|
||||
@@ -727,7 +730,7 @@ FROM `_entry` WHERE id_feed=:id_feed AND guid=:guid
|
||||
SQL;
|
||||
$res = $this->fetchAssoc($sql, [':id_feed' => $id_feed, ':guid' => $guid]);
|
||||
/** @var array<array{'id':string,'id_feed':int,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,
|
||||
* 'is_read':int,'is_favorite':int,'tags':string,'attributes'?:string}> $res */
|
||||
* 'is_read':int,'is_favorite':int,'tags':string,'attributes':?string}> $res */
|
||||
return isset($res[0]) ? FreshRSS_Entry::fromArray($res[0]) : null;
|
||||
}
|
||||
|
||||
@@ -740,7 +743,7 @@ FROM `_entry` WHERE id=:id
|
||||
SQL;
|
||||
$res = $this->fetchAssoc($sql, [':id' => $id]);
|
||||
/** @var array<array{'id':string,'id_feed':int,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,
|
||||
* 'is_read':int,'is_favorite':int,'tags':string,'attributes'?:string}> $res */
|
||||
* 'is_read':int,'is_favorite':int,'tags':string,'attributes':?string}> $res */
|
||||
return isset($res[0]) ? FreshRSS_Entry::fromArray($res[0]) : null;
|
||||
}
|
||||
|
||||
@@ -1167,7 +1170,7 @@ SQL;
|
||||
while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
|
||||
if (is_array($row)) {
|
||||
/** @var array{'id':string,'id_feed':int,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,
|
||||
* 'hash':string,'is_read':int,'is_favorite':int,'tags':string,'attributes'?:string} $row */
|
||||
* 'hash':string,'is_read':int,'is_favorite':int,'tags':string,'attributes'?:?string} $row */
|
||||
yield FreshRSS_Entry::fromArray($row);
|
||||
}
|
||||
}
|
||||
@@ -1212,7 +1215,7 @@ SQL;
|
||||
while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
|
||||
if (is_array($row)) {
|
||||
/** @var array{'id':string,'id_feed':int,'guid':string,'title':string,'author':string,'content':string,'link':string,'date':int,
|
||||
* 'hash':string,'is_read':int,'is_favorite':int,'tags':string,'attributes'?:string} $row */
|
||||
* 'hash':string,'is_read':int,'is_favorite':int,'tags':string,'attributes':?string} $row */
|
||||
yield FreshRSS_Entry::fromArray($row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,7 @@ trait FreshRSS_FilterActionsTrait {
|
||||
$filterActions = $this->filterActions();
|
||||
for ($i = count($filterActions) - 1; $i >= 0; $i--) {
|
||||
$filterAction = $filterActions[$i];
|
||||
if ($filterAction != null && $filterAction->booleanSearch() != null &&
|
||||
$filterAction->actions() != null && in_array($action, $filterAction->actions(), true)) {
|
||||
if (in_array($action, $filterAction->actions(), true)) {
|
||||
$filters[] = $filterAction->booleanSearch();
|
||||
}
|
||||
}
|
||||
@@ -120,7 +119,11 @@ trait FreshRSS_FilterActionsTrait {
|
||||
$this->_filterActions($filterActions);
|
||||
}
|
||||
|
||||
public function applyFilterActions(FreshRSS_Entry $entry): void {
|
||||
/**
|
||||
* @param bool $applyLabel Parameter by reference, which will be set to true if the callers needs to apply a label to the article entry.
|
||||
*/
|
||||
public function applyFilterActions(FreshRSS_Entry $entry, ?bool &$applyLabel = null): void {
|
||||
$applyLabel = false;
|
||||
foreach ($this->filterActions() as $filterAction) {
|
||||
if ($entry->matches($filterAction->booleanSearch())) {
|
||||
foreach ($filterAction->actions() as $action) {
|
||||
@@ -135,7 +138,7 @@ trait FreshRSS_FilterActionsTrait {
|
||||
$entry->_isFavorite(true);
|
||||
break;
|
||||
case 'label':
|
||||
//TODO: Implement more actions
|
||||
$applyLabel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
class FreshRSS_Tag extends Minz_Model {
|
||||
use FreshRSS_AttributesTrait;
|
||||
use FreshRSS_AttributesTrait, FreshRSS_FilterActionsTrait;
|
||||
|
||||
private int $id = 0;
|
||||
private string $name;
|
||||
|
||||
@@ -300,6 +300,35 @@ SQL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<array{id_tag:int,id_entry:string}> $addLabels Labels to insert as batch
|
||||
* @return int|false Number of new entries or false in case of error
|
||||
*/
|
||||
public function tagEntries(array $addLabels) {
|
||||
$hasValues = false;
|
||||
$sql = 'INSERT ' . $this->sqlIgnore() . ' INTO `_entrytag`(id_tag, id_entry) VALUES ';
|
||||
foreach ($addLabels as $addLabel) {
|
||||
$id_tag = (int)($addLabel['id_tag'] ?? 0);
|
||||
$id_entry = $addLabel['id_entry'] ?? '';
|
||||
if ($id_tag > 0 && ctype_digit($id_entry)) {
|
||||
$sql .= "({$id_tag},{$id_entry}),";
|
||||
$hasValues = true;
|
||||
}
|
||||
}
|
||||
$sql = rtrim($sql, ',');
|
||||
if (!$hasValues) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$affected = $this->pdo->exec($sql);
|
||||
if ($affected !== false) {
|
||||
return $affected;
|
||||
}
|
||||
$info = $this->pdo->errorInfo();
|
||||
Minz_Log::error('SQL error ' . __METHOD__ . json_encode($info));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int,array{'id':int,'name':string,'id_entry':string,'checked':bool}>|false
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,7 @@ class FreshRSS_View extends Minz_View {
|
||||
/** @var array<FreshRSS_Category> */
|
||||
public array $categories;
|
||||
public ?FreshRSS_Category $category;
|
||||
public ?FreshRSS_Tag $tag;
|
||||
public string $current_user;
|
||||
/** @var iterable<FreshRSS_Entry> */
|
||||
public $entries;
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Štítek „%s“ byl vytvořen.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Název štítku již existuje.',
|
||||
'renamed' => 'Štítek „%s“ byl přejmenován na „%s“.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS bude nyní aktualizováno na <strong>verzi %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Nástroje odběrů',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Název',
|
||||
'new_name' => 'Nový název',
|
||||
'old_name' => 'Starý název',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label „%s“ wurde erstellt.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Label-Name existiert bereits.',
|
||||
'renamed' => 'Das Label „%s“ wurde umbenannt in „%s“.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS wird nun auf die <strong>Version %s</strong> aktualisiert.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Abonnement-Tools',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Name', // IGNORE
|
||||
'new_name' => 'Neuer Name',
|
||||
'old_name' => 'Alter Name',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label “%s” has been created.', // TODO
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Label name already exists.', // TODO
|
||||
'renamed' => 'Label “%s” has been renamed to “%s”.', // TODO
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.', // DIRTY
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Subscription tools', // TODO
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Name', // TODO
|
||||
'new_name' => 'New name', // TODO
|
||||
'old_name' => 'Old name', // TODO
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label “%s” has been created.', // IGNORE
|
||||
'error' => 'Label could not be updated!', // IGNORE
|
||||
'name_exists' => 'Label name already exists.', // IGNORE
|
||||
'renamed' => 'Label “%s” has been renamed to “%s”.', // IGNORE
|
||||
'updated' => 'Label has been updated.', // IGNORE
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS will now be updated to the <strong>version %s</strong>.', // IGNORE
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Subscription tools', // IGNORE
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // IGNORE
|
||||
'name' => 'Name', // IGNORE
|
||||
'new_name' => 'New name', // IGNORE
|
||||
'old_name' => 'Old name', // IGNORE
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label “%s” has been created.',
|
||||
'error' => 'Label could not be updated!',
|
||||
'name_exists' => 'Label name already exists.',
|
||||
'renamed' => 'Label “%s” has been renamed to “%s”.',
|
||||
'updated' => 'Label has been updated.',
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'An update of FreshRSS is available: <strong>Version %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Subscription tools',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles',
|
||||
'name' => 'Name',
|
||||
'new_name' => 'New name',
|
||||
'old_name' => 'Old name',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Se ha creado la etiqueta “%s”.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'El nombre de la etiqueta ya existe.',
|
||||
'renamed' => 'La etiqueta “%s” ha sido renombrada a “%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS se va a actualizar a la <strong>versión %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Herramientas de suscripción',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Nombre',
|
||||
'new_name' => 'Nuevo nombre',
|
||||
'old_name' => 'Nombre antiguo',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => ' برچسب "%s" ایجاد شده است.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => ' نام برچسب از قبل وجود دارد.',
|
||||
'renamed' => ' برچسب "%s" به "%s" تغییر نام داده است.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => ' بهروزرسانی FreshRSS موجود است: <strong>نسخه %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'ابزارهای اشتراک',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => ' نام',
|
||||
'new_name' => ' نام جدید',
|
||||
'old_name' => ' نام قدیمی',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'L’étiquette <em>%s</em> a été créée.',
|
||||
'name_exists' => 'L’étiquette existe déjà.',
|
||||
'error' => 'L’étiquette n’a pas pu être modifiée',
|
||||
'name_exists' => 'L’étiquette existe déjà!',
|
||||
'renamed' => 'L’étiquette <em>%s</em> a été renommée en <em>%s</em>.',
|
||||
'updated' => 'L’étiquette a été mise à jour.',
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS va maintenant être mis à jour vers la <strong>version %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Outils d’abonnement',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Ajoute l’étiquette aux nouveaux articles',
|
||||
'name' => 'Nom',
|
||||
'new_name' => 'Nouveau nom',
|
||||
'old_name' => 'Ancien nom',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label “%s” has been created.', // TODO
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Label name already exists.', // TODO
|
||||
'renamed' => 'Label “%s” has been renamed to “%s”.', // TODO
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS will be now updated to the <strong>version %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Subscription tools', // TODO
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Name', // TODO
|
||||
'new_name' => 'New name', // TODO
|
||||
'old_name' => 'Old name', // TODO
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Címke “%s” létrehozva.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Címke név már létezik.',
|
||||
'renamed' => 'Címke “%s” átnevezve “%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'Egy FreshRSS frissítés elérhető : <strong>Verzió %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Hírforrás eszközök',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Név',
|
||||
'new_name' => 'Új név',
|
||||
'old_name' => 'Régi név',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label “%s”has been created.', // DIRTY
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Label name already exists.', // TODO
|
||||
'renamed' => 'Label “%s”has been renamed to “%s”.', // DIRTY
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'An update of FreshRSS is available: <strong>Version %s</strong>.', // TODO
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Subscription tools', // TODO
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Name', // TODO
|
||||
'new_name' => 'New name', // TODO
|
||||
'old_name' => 'Old name', // TODO
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Il Tag “%s” è stato creato.', // DIRTY
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Il nome del tag è già presente.', // DIRTY
|
||||
'renamed' => 'Il Tag “%s” è stato rinominato in “%s”.', // DIRTY
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS verrà aggiornato alla <strong>versione %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Strumenti di sottoscrizione',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Nome',
|
||||
'new_name' => 'Nuovo nome',
|
||||
'old_name' => 'Vecchio nome',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => '“%s” タグが作成されました',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'このタグ名は既に存在します',
|
||||
'renamed' => '“%s”タグは“%s”に改名されました',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSSは<strong>バージョン %s</strong>に更新されます。',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => '購読ツール',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => '名前',
|
||||
'new_name' => '新しい名前',
|
||||
'old_name' => '古い名前',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => '“%s” 태그가 생성되었습니다.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => '같은 이름의 태그가 이미 존재합니다.',
|
||||
'renamed' => '“%s” 태그가 “%s” (으)로 이름이 변경되었습니다.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS가 <strong>%s</strong> 버전으로 업데이트됩니다.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => '구독 도구',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => '이름',
|
||||
'new_name' => '새 이름',
|
||||
'old_name' => '이전 이름',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Birka “%s” tika uztaisīta.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Birkas nosaukums jau pastāv.',
|
||||
'renamed' => 'Birka “%s” tika pārdēvēts par “%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS tagad būs atjaunots uz <strong>%s versiju</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Abonamentu rīki',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Vārds',
|
||||
'new_name' => 'Jaunais vārds',
|
||||
'old_name' => 'Vecais vārds',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Label „%s” aangemaakt.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Label bestaat al.',
|
||||
'renamed' => 'Label „%s” hernoemd naar „%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS word nu bijgewerkt naar <strong>versie %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Hulpmiddelen voor abonnementen',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Naam',
|
||||
'new_name' => 'Nieuwe naam',
|
||||
'old_name' => 'Oude naam',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'L’etiqueta « %s » es estada creada.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Lo nom de l’etiqueta existís ja.',
|
||||
'renamed' => 'L’etiqueta « %s » es estada renomenada en « %s ».',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS es per èsser mes a jorn en <strong>version %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Aisinas d’abonament',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Nom',
|
||||
'new_name' => 'Nom novèl',
|
||||
'old_name' => 'Nom ancian',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Etykieta “%s” została stworzona.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Etykieta o podanej nazwie już istnieje.',
|
||||
'renamed' => 'Etykieta “%s” została zmieniona na “%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS zostanie zaktualizowany do <strong>wersji %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Narzędzia subskrypcji',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Nazwa',
|
||||
'new_name' => 'Nowa nazwa',
|
||||
'old_name' => 'Poprzednia nazwa',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'A Tag “%s” foi criada.', // DIRTY
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'O nome da tag já existe.', // DIRTY
|
||||
'renamed' => 'A Tag “%s” foi renomeada para “%s”.', // DIRTY
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'O FreshRSS será atualizado para a <strong>versão %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Ferramentas de inscrição',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Nome',
|
||||
'new_name' => 'Nome novo',
|
||||
'old_name' => 'Nome antigo',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Метка “%s” создана.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Метка с таким названием уже существует.',
|
||||
'renamed' => 'Метка “%s” переименована в “%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS будет обновлён до <strong>версии %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Инструменты подписки',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Название',
|
||||
'new_name' => 'Новое название',
|
||||
'old_name' => 'Старое название',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => 'Štítok “%s” bol vytvorený.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Názov štítku už existuje.',
|
||||
'renamed' => 'Štítok “%s” bol premenovaný na “%s”.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS sa teraz aktualizuje <strong>na verziu %s</strong>.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Nástroje na odoberanie kanálov',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'Názov',
|
||||
'new_name' => 'Nový názov',
|
||||
'old_name' => 'Starý názov',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => '“%s” etiketi oluşturuldu.',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => 'Etiket zaten mevcut.',
|
||||
'renamed' => '“%s” isimli etiketin ismi “%s” olarak değiştirildi.',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS <strong>%s sürümüne</strong> güncellenecek.',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => 'Abonelik araçları',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => 'İsim',
|
||||
'new_name' => 'Eski isim',
|
||||
'old_name' => 'Yeni isim',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => '标签 “%s” 已创建。',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => '标签名已存在。',
|
||||
'renamed' => '标签 “%s” 已被重命名为 “%s”。',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS 将更新到 <strong>版本 %s</strong>。',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => '订阅工具',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => '名称',
|
||||
'new_name' => '新名称',
|
||||
'old_name' => '旧名称',
|
||||
|
||||
@@ -116,8 +116,10 @@ return array(
|
||||
),
|
||||
'tag' => array(
|
||||
'created' => '標簽 “%s” 已創建。',
|
||||
'error' => 'Label could not be updated!', // TODO
|
||||
'name_exists' => '標簽名已存在。',
|
||||
'renamed' => '標簽 “%s” 已被重命名為 “%s”。',
|
||||
'updated' => 'Label has been updated.', // TODO
|
||||
),
|
||||
'update' => array(
|
||||
'can_apply' => 'FreshRSS 將更新到 <strong>版本 %s</strong>。',
|
||||
|
||||
@@ -196,6 +196,7 @@ return array(
|
||||
'subscription_tools' => '訂閱工具',
|
||||
),
|
||||
'tag' => array(
|
||||
'auto_label' => 'Add this label to new articles', // TODO
|
||||
'name' => '名稱',
|
||||
'new_name' => '新名稱',
|
||||
'old_name' => '舊名稱',
|
||||
|
||||
@@ -153,9 +153,7 @@
|
||||
<script id="tag_config_template" type="text/html">
|
||||
<ul class="dropdown-menu">
|
||||
<li class="item">
|
||||
<button class="as-link confirm" disabled="disabled"
|
||||
form="mark-read-aside" formaction="<?= _url('tag', 'delete', 'id_tag', '------') ?>"
|
||||
type="submit"><?= _t('gen.action.remove') ?></button>
|
||||
<a class="configure open-slider" href="<?= _url('tag', 'update', 'id', '------') ?>"><?= _t('gen.action.manage') ?></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="dropdown-close" href="#close">❌</a>
|
||||
|
||||
@@ -27,60 +27,12 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2><?= _t('sub.title.rename_label') ?></h2>
|
||||
<?php
|
||||
$disabled = '';
|
||||
if (count($this->tags) < 1) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
} ?>
|
||||
<form id="rename_tag" method="post" action="<?= _url('tag', 'rename') ?>" autocomplete="off">
|
||||
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="id_tag"><?= _t('sub.tag.old_name') ?></label>
|
||||
<div class="group-controls">
|
||||
<select name="id_tag" id="id_tag"<?= $disabled?>>
|
||||
<?php foreach ($this->tags as $tag): ?>
|
||||
<option value="<?= $tag->id() ?>"><?= $tag->name() ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="rename_new_name"><?= _t('sub.tag.new_name') ?></label>
|
||||
<div class="group-controls">
|
||||
<input id="rename_new_name" name="name" type="text" autocomplete="off"<?= $disabled?>/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<?php if (!$disabled) { ?>
|
||||
<button type="submit" class="btn btn-attention confirm"><?= _t('gen.action.rename') ?></button>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2><?= _t('sub.title.delete_label') ?></h2>
|
||||
<form id="delete_tag" method="post" action="<?= _url('tag', 'delete') ?>" autocomplete="off">
|
||||
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="id_tag_delete"><?= _t('sub.tag.name') ?></label>
|
||||
<div class="group-controls">
|
||||
<select name="id_tag" id="id_tag_delete"<?= $disabled?>>
|
||||
<?php foreach ($this->tags as $tag): ?>
|
||||
<option value="<?= $tag->id() ?>"><?= $tag->name() ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<?php if (!$disabled) { ?>
|
||||
<button type="submit" class="btn btn-attention confirm"><?= _t('gen.action.remove') ?></button>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php if (count($this->tags) > 0): ?>
|
||||
<h2><?= _t('gen.action.manage') ?></h2>
|
||||
<ul>
|
||||
<?php foreach ($this->tags as $tag): ?>
|
||||
<li><a href="<?= _url('tag', 'update', 'id', $tag->id()) ?>"><?= $tag->name() ?></a></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
69
app/views/tag/update.phtml
Normal file
69
app/views/tag/update.phtml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/** @var FreshRSS_View $this */
|
||||
|
||||
if (!Minz_Request::paramBoolean('ajax')) {
|
||||
$this->partial('aside_subscription');
|
||||
}
|
||||
if ($this->tag === null) {
|
||||
throw new FreshRSS_Context_Exception('Tag not initialised!');
|
||||
}
|
||||
?>
|
||||
<div class="post">
|
||||
<h2>
|
||||
<?= $this->tag->name() ?>
|
||||
</h2>
|
||||
|
||||
<div>
|
||||
<a href="<?= _url('index', 'index', 'get', 't_' . $this->tag->id()) ?>"><?= _i('link') ?> <?= _t('gen.action.filter') ?></a>
|
||||
</div>
|
||||
|
||||
<form method="post" action="<?= _url('tag', 'update', 'id', $this->tag->id(), '#', 'slider') ?>" autocomplete="off">
|
||||
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
|
||||
|
||||
<legend><?= _t('sub.category.information') ?></legend>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="name"><?= _t('sub.tag.name') ?></label>
|
||||
<div class="group-controls">
|
||||
<input type="text" name="name" id="name" value="<?= $this->tag->name() ?>" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<button type="submit" class="btn btn-important"><?= _t('gen.action.submit') ?></button>
|
||||
<button type="reset" class="btn"><?= _t('gen.action.cancel') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<legend><?= _t('sub.feed.filteractions') ?></legend>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="filteractions_label"><?= _t('sub.tag.auto_label') ?></label>
|
||||
<div class="group-controls">
|
||||
<textarea name="filteractions_label" id="filteractions_label" class="w100"><?php
|
||||
foreach ($this->tag->filtersAction('label') as $filterRead) {
|
||||
echo $filterRead->getRawInput(), PHP_EOL;
|
||||
}
|
||||
?></textarea>
|
||||
<p class="help"><?= _i('help') ?> <?= _t('sub.feed.filteractions.help') ?></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<button type="submit" class="btn btn-important"><?= _t('gen.action.submit') ?></button>
|
||||
<button type="reset" class="btn"><?= _t('gen.action.cancel') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2><?= _t('sub.title.delete_label') ?></h2>
|
||||
<form id="delete_tag" method="post" action="<?= _url('tag', 'delete', 'id_tag', $this->tag->id()) ?>">
|
||||
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
|
||||
<div class="form-group form-actions">
|
||||
<div class="group-controls">
|
||||
<button type="submit" class="btn btn-attention confirm"><?= _t('gen.action.remove') ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -30,7 +30,7 @@ la machine sur laquelle est installée votre instance de FreshRSS.
|
||||
|
||||
Le script qui permet de mettre à jour les articles s’appelle
|
||||
*actualize_script.php* et se trouve dans le répertoire *app* de votre
|
||||
instance de FreshRSS. La syntaxe des tâches planifiées ne sera pas expliqué
|
||||
instance de FreshRSS. La syntaxe des tâches planifiées ne sera pas expliquée
|
||||
ici, cependant voici [une introduction rapide à
|
||||
crontab](http://www.adminschoice.com/crontab-quick-reference/) qui peut vous
|
||||
aider.
|
||||
@@ -205,48 +205,48 @@ the search field.
|
||||
Il est possible d’utiliser le champ de recherche pour raffiner les résultats :
|
||||
|
||||
* par ID de flux : `f:123` ou plusieurs flux (*ou*) : `f:123,234,345`
|
||||
* par auteur : `author:nom` or `author:'nom composé'`
|
||||
* par titre : `intitle:mot` or `intitle:'mot composé'`
|
||||
* par URL: `inurl:mot` or `inurl:'mot composé'`
|
||||
* par tag: `#tag`
|
||||
* par texte libre : `mot` or `'mot composé'`
|
||||
* by date of discovery, using the [ISO 8601 time interval format](http://en.wikipedia.org/wiki/ISO_8601#Time_intervals): `date:<date-interval>`
|
||||
* From a specific day, or month, or year:
|
||||
* par auteur : `author:nom` ou `author:'nom composé'`
|
||||
* par titre : `intitle:mot` ou `intitle:'mot composé'`
|
||||
* par URL : `inurl:mot` ou `inurl:'mot composé'`
|
||||
* par tag : `#tag`
|
||||
* par texte libre : `mot` ou `'mot composé'`
|
||||
* par date d’ajout, en utilisant le [format ISO 8601 d’intervalle entre deux dates](https://fr.wikipedia.org/wiki/ISO_8601#Intervalle_entre_deux_dates) : `date:<intervalle-de-dates>`
|
||||
* D’un jour spécifique, ou mois, ou année :
|
||||
* `date:2014-03-30`
|
||||
* `date:2014-03` or `date:201403`
|
||||
* `date:2014`
|
||||
* From a specific time of a given day:
|
||||
* D’une heure spécifiée d’un jour donné :
|
||||
* `date:2014-05-30T13`
|
||||
* `date:2014-05-30T13:30`
|
||||
* Between two given dates:
|
||||
* Entre deux dates :
|
||||
* `date:2014-02/2014-04`
|
||||
* `date:2014-02--2014-04`
|
||||
* `date:2014-02/04`
|
||||
* `date:2014-02-03/05`
|
||||
* `date:2014-02-03T22:00/22:15`
|
||||
* `date:2014-02-03T22:00/15`
|
||||
* After a given date:
|
||||
* Après une date donnée :
|
||||
* `date:2014-03/`
|
||||
* Before a given date:
|
||||
* Avant une date donnée :
|
||||
* `date:/2014-03`
|
||||
* For a specific duration after a given date:
|
||||
* Pour une certaine durée après une date donnée :
|
||||
* `date:2014-03/P1W`
|
||||
* For a specific duration before a given date:
|
||||
* Pour une certaine durée avant une date donnée :
|
||||
* `date:P1W/2014-05-25T23:59:59`
|
||||
* For the past duration before now (the trailing slash is optional):
|
||||
* `date:P1Y/` or `date:P1Y` (past year)
|
||||
* `date:P2M/` (past two months)
|
||||
* `date:P3W/` (past three weeks)
|
||||
* `date:P4D/` (past four days)
|
||||
* `date:PT5H/` (past five hours)
|
||||
* `date:PT30M/` (past thirty minutes)
|
||||
* `date:PT90S/` (past ninety seconds)
|
||||
* `date:P1DT1H/` (past one day and one hour)
|
||||
* par date de publication, avec la même syntaxe: `pubdate:<date-interval>`
|
||||
* Pour une certaine durée avant maintenant (la barre oblique finale est facultative) :
|
||||
* `date:P1Y/` or `date:P1Y` (depuis un an)
|
||||
* `date:P2M/` (depuis deux mois)
|
||||
* `date:P3W/` (depuis trois semaines)
|
||||
* `date:P4D/` (depuis quatre jours)
|
||||
* `date:PT5H/` (depuis cinq heures)
|
||||
* `date:PT30M/` (depuis trente minutes)
|
||||
* `date:PT90S/` (depuis 90 secondes)
|
||||
* `date:P1DT1H/` (depuis un jour et une heure)
|
||||
* par date de publication, avec la même syntaxe : `pubdate:<date-interval>`
|
||||
* par ID d’étiquette : `L:12` ou de plusieurs étiquettes : `L:12,13,14` ou avec n’importe quelle étiquette : `L:*`
|
||||
* par nom d’étiquette : `label:étiquette`, `label:"mon étiquette"` ou d’une étiquette parmis une liste (*ou*) : `labels:"mon étiquette,mon autre étiquette"`
|
||||
* par nom d’étiquette : `label:étiquette`, `label:"mon étiquette"` ou d’une étiquette parmi une liste (*ou*) : `labels:"mon étiquette,mon autre étiquette"`
|
||||
* par plusieurs noms d’étiquettes (*et*) : `label:"mon étiquette" label:"mon autre étiquette"`
|
||||
* par ID d’article (entrée) : `e:1639310674957894` ou de plusieurs articles (*ou*): `e:1639310674957894,1639310674957893`
|
||||
* par ID d’article (entrée) : `e:1639310674957894` ou de plusieurs articles (*ou*) : `e:1639310674957894,1639310674957893`
|
||||
* par nom de filtre utilisateur (recherche enregistrée) : `search:maRecherche`, `search:"Ma recherche"` ou par ID de recherche : `S:3`
|
||||
* en interne, ces références sont remplacées par le filtre utilisateur correspondant dans l’expression de recherche
|
||||
|
||||
|
||||
@@ -8818,7 +8818,7 @@ msgstr ""
|
||||
#. type: Bullet: '* '
|
||||
#: en/./users/10_filter.md:93
|
||||
msgid "by free-text: `keyword` or `'composed keyword'`"
|
||||
msgstr "par texte libre : `mot` or `'mot composé'`"
|
||||
msgstr "par texte libre : `mot` ou `'mot composé'`"
|
||||
|
||||
#. type: Bullet: '* '
|
||||
#: en/./users/10_filter.md:93
|
||||
|
||||
Reference in New Issue
Block a user