mirror of
https://github.com/moparisthebest/wallabag
synced 2024-11-30 04:42:19 -05:00
commit
05d6dd487c
@ -249,4 +249,75 @@ class Database {
|
|||||||
public function getLastId($column = '') {
|
public function getLastId($column = '') {
|
||||||
return $this->getHandle()->lastInsertId($column);
|
return $this->getHandle()->lastInsertId($column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function retrieveAllTags() {
|
||||||
|
$sql = "SELECT * FROM tags";
|
||||||
|
$query = $this->executeQuery($sql, array());
|
||||||
|
$tags = $query->fetchAll();
|
||||||
|
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function retrieveTag($id) {
|
||||||
|
$tag = NULL;
|
||||||
|
$sql = "SELECT * FROM tags WHERE id=?";
|
||||||
|
$params = array(intval($id));
|
||||||
|
$query = $this->executeQuery($sql, $params);
|
||||||
|
$tag = $query->fetchAll();
|
||||||
|
|
||||||
|
return isset($tag[0]) ? $tag[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function retrieveEntriesByTag($tag_id) {
|
||||||
|
$sql =
|
||||||
|
"SELECT * FROM entries
|
||||||
|
LEFT JOIN tags_entries ON tags_entries.entry_id=entries.id
|
||||||
|
WHERE tags_entries.tag_id = ?";
|
||||||
|
$query = $this->executeQuery($sql, array($tag_id));
|
||||||
|
$entries = $query->fetchAll();
|
||||||
|
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function retrieveTagsByEntry($entry_id) {
|
||||||
|
$sql =
|
||||||
|
"SELECT * FROM tags
|
||||||
|
LEFT JOIN tags_entries ON tags_entries.tag_id=tags.id
|
||||||
|
WHERE tags_entries.entry_id = ?";
|
||||||
|
$query = $this->executeQuery($sql, array($entry_id));
|
||||||
|
$tags = $query->fetchAll();
|
||||||
|
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeTagForEntry($entry_id, $tag_id) {
|
||||||
|
$sql_action = "DELETE FROM tags_entries WHERE tag_id=? AND entry_id=?";
|
||||||
|
$params_action = array($tag_id, $entry_id);
|
||||||
|
$query = $this->executeQuery($sql_action, $params_action);
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function retrieveTagByValue($value) {
|
||||||
|
$tag = NULL;
|
||||||
|
$sql = "SELECT * FROM tags WHERE value=?";
|
||||||
|
$params = array($value);
|
||||||
|
$query = $this->executeQuery($sql, $params);
|
||||||
|
$tag = $query->fetchAll();
|
||||||
|
|
||||||
|
return isset($tag[0]) ? $tag[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createTag($value) {
|
||||||
|
$sql_action = 'INSERT INTO tags ( value ) VALUES (?)';
|
||||||
|
$params_action = array($value);
|
||||||
|
$query = $this->executeQuery($sql_action, $params_action);
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTagToEntry($tag_id, $entry_id) {
|
||||||
|
$sql_action = 'INSERT INTO tags_entries ( tag_id, entry_id ) VALUES (?, ?)';
|
||||||
|
$params_action = array($tag_id, $entry_id);
|
||||||
|
$query = $this->executeQuery($sql_action, $params_action);
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,6 +397,36 @@ class Poche
|
|||||||
Tools::redirect();
|
Tools::redirect();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'add_tag' :
|
||||||
|
$tags = explode(',', $_POST['value']);
|
||||||
|
$entry_id = $_POST['entry_id'];
|
||||||
|
foreach($tags as $key => $tag_value) {
|
||||||
|
$value = trim($tag_value);
|
||||||
|
$tag = $this->store->retrieveTagByValue($value);
|
||||||
|
|
||||||
|
if (is_null($tag)) {
|
||||||
|
# we create the tag
|
||||||
|
$tag = $this->store->createTag($value);
|
||||||
|
$sequence = '';
|
||||||
|
if (STORAGE == 'postgres') {
|
||||||
|
$sequence = 'tags_id_seq';
|
||||||
|
}
|
||||||
|
$tag_id = $this->store->getLastId($sequence);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tag_id = $tag['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
# we assign the tag to the article
|
||||||
|
$this->store->setTagToEntry($tag_id, $entry_id);
|
||||||
|
}
|
||||||
|
Tools::redirect();
|
||||||
|
break;
|
||||||
|
case 'remove_tag' :
|
||||||
|
$tag_id = $_GET['tag_id'];
|
||||||
|
$this->store->removeTagForEntry($id, $tag_id);
|
||||||
|
Tools::redirect();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -430,6 +460,31 @@ class Poche
|
|||||||
);
|
);
|
||||||
Tools::logm('config view');
|
Tools::logm('config view');
|
||||||
break;
|
break;
|
||||||
|
case 'edit-tags':
|
||||||
|
# tags
|
||||||
|
$tags = $this->store->retrieveTagsByEntry($id);
|
||||||
|
$tpl_vars = array(
|
||||||
|
'entry_id' => $id,
|
||||||
|
'tags' => $tags,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'tag':
|
||||||
|
$entries = $this->store->retrieveEntriesByTag($id);
|
||||||
|
$tag = $this->store->retrieveTag($id);
|
||||||
|
$tpl_vars = array(
|
||||||
|
'tag' => $tag,
|
||||||
|
'entries' => $entries,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'tags':
|
||||||
|
$token = $this->user->getConfigValue('token');
|
||||||
|
$tags = $this->store->retrieveAllTags();
|
||||||
|
$tpl_vars = array(
|
||||||
|
'token' => $token,
|
||||||
|
'user_id' => $this->user->getId(),
|
||||||
|
'tags' => $tags,
|
||||||
|
);
|
||||||
|
break;
|
||||||
case 'view':
|
case 'view':
|
||||||
$entry = $this->store->retrieveOneById($id, $this->user->getId());
|
$entry = $this->store->retrieveOneById($id, $this->user->getId());
|
||||||
if ($entry != NULL) {
|
if ($entry != NULL) {
|
||||||
@ -443,12 +498,16 @@ class Poche
|
|||||||
|
|
||||||
# flattr checking
|
# flattr checking
|
||||||
$flattr = new FlattrItem();
|
$flattr = new FlattrItem();
|
||||||
$flattr->checkItem($entry['url'],$entry['id']);
|
$flattr->checkItem($entry['url'], $entry['id']);
|
||||||
|
|
||||||
|
# tags
|
||||||
|
$tags = $this->store->retrieveTagsByEntry($entry['id']);
|
||||||
|
|
||||||
$tpl_vars = array(
|
$tpl_vars = array(
|
||||||
'entry' => $entry,
|
'entry' => $entry,
|
||||||
'content' => $content,
|
'content' => $content,
|
||||||
'flattr' => $flattr
|
'flattr' => $flattr,
|
||||||
|
'tags' => $tags
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -859,9 +918,9 @@ class Poche
|
|||||||
$_SESSION['poche_user']->setConfig($currentConfig);
|
$_SESSION['poche_user']->setConfig($currentConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateFeeds($token, $user_id, $type = 'home')
|
public function generateFeeds($token, $user_id, $tag_id, $type = 'home')
|
||||||
{
|
{
|
||||||
$allowed_types = array('home', 'fav', 'archive');
|
$allowed_types = array('home', 'fav', 'archive', 'tag');
|
||||||
$config = $this->store->getConfigUser($user_id);
|
$config = $this->store->getConfigUser($user_id);
|
||||||
|
|
||||||
if (!in_array($type, $allowed_types) ||
|
if (!in_array($type, $allowed_types) ||
|
||||||
@ -876,7 +935,13 @@ class Poche
|
|||||||
$feed->setChannelElement('updated', date(DATE_RSS , time()));
|
$feed->setChannelElement('updated', date(DATE_RSS , time()));
|
||||||
$feed->setChannelElement('author', 'poche');
|
$feed->setChannelElement('author', 'poche');
|
||||||
|
|
||||||
$entries = $this->store->getEntriesByView($type, $user_id);
|
if ($type == 'tag') {
|
||||||
|
$entries = $this->store->retrieveEntriesByTag($tag_id);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$entries = $this->store->getEntriesByView($type, $user_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (count($entries) > 0) {
|
if (count($entries) > 0) {
|
||||||
foreach ($entries as $entry) {
|
foreach ($entries as $entry) {
|
||||||
$newItem = $feed->createNewItem();
|
$newItem = $feed->createNewItem();
|
||||||
|
@ -88,39 +88,16 @@ class Tools
|
|||||||
|
|
||||||
public static function getTplFile($view)
|
public static function getTplFile($view)
|
||||||
{
|
{
|
||||||
$default_tpl = 'home.twig';
|
$views = array(
|
||||||
|
'install', 'import', 'export', 'config', 'tags',
|
||||||
switch ($view) {
|
'edit-tags', 'view', 'login', 'error', 'tag'
|
||||||
case 'install':
|
);
|
||||||
$tpl_file = 'install.twig';
|
|
||||||
break;
|
if (in_array($view, $views)) {
|
||||||
case 'import';
|
return $view . '.twig';
|
||||||
$tpl_file = 'import.twig';
|
|
||||||
break;
|
|
||||||
case 'export':
|
|
||||||
$tpl_file = 'export.twig';
|
|
||||||
break;
|
|
||||||
case 'config':
|
|
||||||
$tpl_file = 'config.twig';
|
|
||||||
break;
|
|
||||||
case 'view':
|
|
||||||
$tpl_file = 'view.twig';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'login':
|
|
||||||
$tpl_file = 'login.twig';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'error':
|
|
||||||
$tpl_file = 'error.twig';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$tpl_file = $default_tpl;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tpl_file;
|
return 'home.twig';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getFile($url)
|
public static function getFile($url)
|
||||||
|
@ -77,7 +77,8 @@ if (isset($_GET['login'])) {
|
|||||||
$poche->generateToken();
|
$poche->generateToken();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$poche->generateFeeds($_GET['token'], $_GET['user_id'], $_GET['type']);
|
$tag_id = (isset($_GET['tag_id']) ? intval($_GET['tag_id']) : 0);
|
||||||
|
$poche->generateFeeds($_GET['token'], $_GET['user_id'], $tag_id, $_GET['type']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,4 +31,19 @@ CREATE TABLE IF NOT EXISTS `users_config` (
|
|||||||
`name` varchar(255) NOT NULL,
|
`name` varchar(255) NOT NULL,
|
||||||
`value` varchar(255) NOT NULL,
|
`value` varchar(255) NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE tags (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`value` varchar(255) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE tags_entries (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`entry_id` int(11) NOT NULL,
|
||||||
|
`tag_id` int(11) NOT NULL,
|
||||||
|
FOREIGN KEY(entry_id) REFERENCES entries(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY(tag_id) REFERENCES tags(id) ON DELETE CASCADE,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
Binary file not shown.
@ -27,4 +27,15 @@ CREATE TABLE users_config (
|
|||||||
user_id integer NOT NULL,
|
user_id integer NOT NULL,
|
||||||
name varchar(255) NOT NULL,
|
name varchar(255) NOT NULL,
|
||||||
value varchar(255) NOT NULL
|
value varchar(255) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tags (
|
||||||
|
id bigserial primary key,
|
||||||
|
value varchar(255) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE tags_entries (
|
||||||
|
id bigserial primary key,
|
||||||
|
entry_id integer NOT NULL,
|
||||||
|
tag_id integer NOT NULL
|
||||||
|
)
|
@ -2,6 +2,7 @@
|
|||||||
<li><a href="./" {% if view == 'home' %}class="current"{% endif %}>{% trans "home" %}</a></li>
|
<li><a href="./" {% if view == 'home' %}class="current"{% endif %}>{% trans "home" %}</a></li>
|
||||||
<li><a href="./?view=fav" {% if view == 'fav' %}class="current"{% endif %}>{% trans "favorites" %}</a></li>
|
<li><a href="./?view=fav" {% if view == 'fav' %}class="current"{% endif %}>{% trans "favorites" %}</a></li>
|
||||||
<li><a href="./?view=archive" {% if view == 'archive' %}class="current"{% endif %}>{% trans "archive" %}</a></li>
|
<li><a href="./?view=archive" {% if view == 'archive' %}class="current"{% endif %}>{% trans "archive" %}</a></li>
|
||||||
|
<li><a href="./?view=tags" {% if view == 'tags' %}class="current"{% endif %}>{% trans "tags" %}</a></li>
|
||||||
<li><a href="./?view=config" {% if view == 'config' %}class="current"{% endif %}>{% trans "config" %}</a></li>
|
<li><a href="./?view=config" {% if view == 'config' %}class="current"{% endif %}>{% trans "config" %}</a></li>
|
||||||
<li><a href="./?logout" title="{% trans "logout" %}">{% trans "logout" %}</a></li>
|
<li><a href="./?logout" title="{% trans "logout" %}">{% trans "logout" %}</a></li>
|
||||||
</ul>
|
</ul>
|
@ -176,6 +176,12 @@ a:visited {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#article .tags {
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #888;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.backhome {
|
.backhome {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
20
themes/default/edit-tags.twig
Normal file
20
themes/default/edit-tags.twig
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{% extends "layout.twig" %}
|
||||||
|
{% block title %}edit tags{% endblock %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include '_menu.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
{% if tags is empty %}
|
||||||
|
no tags
|
||||||
|
{% endif %}
|
||||||
|
<ul>
|
||||||
|
{% for tag in tags %}<li>{{ tag.value }} <a href="./?action=remove_tag&tag_id={{ tag.id }}&id={{ entry_id }}">✘</a></li>{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<form method="post" action="./?action=add_tag">
|
||||||
|
<label for="value">New tags: </label><input type="text" id="value" name="value" required="required" />
|
||||||
|
<p>{% trans "you can type several tags, separated by comma" %}</p>
|
||||||
|
<input type="hidden" name="entry_id" value="{{ entry_id }}" />
|
||||||
|
<input type="submit" value="add tags" />
|
||||||
|
</form>
|
||||||
|
<a href="./?view=view&id={{ entry_id }}">{% trans "back to the article" %}</a>
|
||||||
|
{% endblock %}
|
BIN
themes/default/img/default/rss.png
Normal file
BIN
themes/default/img/default/rss.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 288 B |
33
themes/default/tag.twig
Normal file
33
themes/default/tag.twig
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{% extends "layout.twig" %}
|
||||||
|
{% block title %}tag {% endblock %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include '_menu.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h3>{% trans "Tag" %} {{ tag.value }}</h3>
|
||||||
|
{% if entries is empty %}
|
||||||
|
<div class="messages warning"><p>{% trans "No link available here!" %}</p></div>
|
||||||
|
{% else %}
|
||||||
|
{% block pager %}
|
||||||
|
{% if nb_results > 1 %}
|
||||||
|
<div class="results">
|
||||||
|
<div class="nb-results">{{ nb_results }} {% trans "results" %}</div>
|
||||||
|
{{ page_links | raw }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
{% for entry in entries %}
|
||||||
|
<div id="entry-{{ entry.id|e }}" class="entrie">
|
||||||
|
<h2><a href="index.php?view=view&id={{ entry.id|e }}">{{ entry.title|raw }}</a></h2>
|
||||||
|
<ul class="tools">
|
||||||
|
<li><a title="{% trans "toggle mark as read" %}" class="tool {% if entry.is_read == 0 %}archive-off{% else %}archive{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span>{% trans "toggle mark as read" %}</span></a></li>
|
||||||
|
<li><a title="{% trans "toggle favorite" %}" class="tool {% if entry.is_fav == 0 %}fav-off{% else %}fav{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span>{% trans "toggle favorite" %}</span></a></li>
|
||||||
|
<li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span>{% trans "delete" %}</span></a></li>
|
||||||
|
<li><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}" class="tool link"><span>{{ entry.url | e | getDomain }}</span></a></li>
|
||||||
|
<li><a target="_blank" title="{% trans "estimated reading time:" %} {{ entry.content| getReadingTime }} min" class="reading-time"><span>{{ entry.content| getReadingTime }} min</span></a></li>
|
||||||
|
</ul>
|
||||||
|
<p>{{ entry.content|striptags|slice(0, 300) }}...</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
8
themes/default/tags.twig
Normal file
8
themes/default/tags.twig
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{% extends "layout.twig" %}
|
||||||
|
{% block title %}tags{% endblock %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include '_menu.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
{% for tag in tags %}<a href="./?view=tag&id={{ tag.id }}">{{ tag.value }}</a> {% if token != '' %}<a href="?feed&type=tag&user_id={{ user_id }}&tag_id={{ tag.id }}&token={{ token }}" target="_blank"><img src="{{ poche_url }}/themes/{{ theme }}/img/{{ theme }}/rss.png" /></a>{% endif %} {% endfor %}
|
||||||
|
{% endblock %}
|
@ -20,6 +20,9 @@
|
|||||||
<header class="mbm">
|
<header class="mbm">
|
||||||
<h1>{{ entry.title|raw }}</h1>
|
<h1>{{ entry.title|raw }}</h1>
|
||||||
</header>
|
</header>
|
||||||
|
<aside class="tags">
|
||||||
|
tags: {% for tag in tags %}<a href="./?view=tag&id={{ tag.id }}">{{ tag.value }}</a> {% endfor %}<a href="./?view=edit-tags&id={{ entry.id|e }}" title="{% trans "edit tags" %}">✎</a>
|
||||||
|
</aside>
|
||||||
<article>
|
<article>
|
||||||
{{ content | raw }}
|
{{ content | raw }}
|
||||||
</article>
|
</article>
|
||||||
|
Loading…
Reference in New Issue
Block a user