mirror of
https://github.com/FreshRSS/FreshRSS.git
synced 2026-04-23 15:57:36 -04:00
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
*/.git
|
||||
*/data
|
||||
*/docs
|
||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,5 +1,25 @@
|
||||
# FreshRSS changelog
|
||||
|
||||
## 2018-03-04 FreshRSS 1.10.1
|
||||
|
||||
* Deployment
|
||||
* New Docker image, smaller (based on Alpine Linux) and newer (with PHP 7.1) [#1813](https://github.com/FreshRSS/FreshRSS/pull/1813)
|
||||
* with [automated build](https://hub.docker.com/r/freshrss/freshrss/) for x86-64 (AMD64) architectures
|
||||
* CLI
|
||||
* New command `./cli/prepare.php` to make the needed sub-directories of the `./data/` directory [#1813](https://github.com/FreshRSS/FreshRSS/pull/1813)
|
||||
* Bug fixing
|
||||
* Fix API bug for EasyRSS [#1799](https://github.com/FreshRSS/FreshRSS/issues/1799)
|
||||
* Fix login bug when using double authentication (HTTP + Web form) [#1807](https://github.com/FreshRSS/FreshRSS/issues/1807)
|
||||
* Fix database upgrade for FreshRSS versions older than 1.1.1 [#1803](https://github.com/FreshRSS/FreshRSS/issues/1803)
|
||||
* Fix cases of double port in FreshRSS public URL [#1815](https://github.com/FreshRSS/FreshRSS/pull/1815)
|
||||
* UI
|
||||
* Add tooltips on share configuration buttons [#1805](https://github.com/FreshRSS/FreshRSS/pull/1805)
|
||||
* Misc.
|
||||
* Move `./data/shares.php` to `./app/shares.php` to facilitate updates [#1812](https://github.com/FreshRSS/FreshRSS/pull/1812)
|
||||
* Show article author email when there is no author name [#1801](https://github.com/FreshRSS/FreshRSS/pull/1801)
|
||||
* Improve translation tools [#1808](https://github.com/FreshRSS/FreshRSS/pull/1808)
|
||||
|
||||
|
||||
## 2018-02-24 FreshRSS 1.10.0
|
||||
|
||||
* API
|
||||
|
||||
@@ -44,6 +44,7 @@ People are sorted by name so please keep this order.
|
||||
* [Nicolas Lœuillet](https://github.com/nicosomb): [contributions](https://github.com/FreshRSS/documentation/commits?author=nicosomb), [Web](http://www.loeuillet.org/)
|
||||
* [Nicola Spanti](https://github.com/RyDroid): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:RyDroid), [Web](http://www.nicola-spanti.info/)
|
||||
* [Olivier Dossmann](https://github.com/blankoworld): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=blankoworld), [Web](https://olivier.dossmann.net)
|
||||
* [perrinjerome](https://github.com/perrinjerome): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:perrinjerome)
|
||||
* [plopoyop](https://github.com/plopoyop): [contributions](https://github.com/FreshRSS/FreshRSS/commits?author=plopoyop)
|
||||
* [Paulius Šukys](https://github.com/psukys): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:psukys), [Web](http://sukys.eu)
|
||||
* [purexo](https://github.com/purexo): [contributions](https://github.com/FreshRSS/FreshRSS/pulls?q=is:pr+author:purexo), [Web](https://purexo.mom/)
|
||||
|
||||
22
Docker/Dockerfile
Normal file
22
Docker/Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM alpine:3.7
|
||||
|
||||
RUN apk add --no-cache \
|
||||
apache2 php7-apache2 \
|
||||
php7 php7-curl php7-gmp php7-intl php7-mbstring php7-xml php7-zip \
|
||||
php7-ctype php7-dom php7-fileinfo php7-json php7-session \
|
||||
php7-pdo_sqlite \
|
||||
php7-pdo_mysql \
|
||||
php7-pdo_pgsql
|
||||
|
||||
ENV FRESHRSS_ROOT /var/www/FreshRSS
|
||||
RUN mkdir -p ${FRESHRSS_ROOT} /run/apache2/
|
||||
WORKDIR ${FRESHRSS_ROOT}
|
||||
|
||||
COPY . ${FRESHRSS_ROOT}
|
||||
COPY ./Docker/*.Apache.conf /etc/apache2/conf.d/
|
||||
|
||||
EXPOSE 80
|
||||
CMD php -f ./cli/prepare.php > /dev/null && \
|
||||
chown -R :www-data ${FRESHRSS_ROOT} && \
|
||||
chmod -R g+r ${FRESHRSS_ROOT} && chmod -R g+w ${FRESHRSS_ROOT}/data/ && \
|
||||
exec httpd -D FOREGROUND
|
||||
27
Docker/FreshRSS.Apache.conf
Normal file
27
Docker/FreshRSS.Apache.conf
Normal file
@@ -0,0 +1,27 @@
|
||||
<IfModule !deflate_module>
|
||||
LoadModule deflate_module modules/mod_deflate.so
|
||||
</IfModule>
|
||||
<IfModule !expires_module>
|
||||
LoadModule expires_module modules/mod_expires.so
|
||||
</IfModule>
|
||||
<IfModule !headers_module>
|
||||
LoadModule headers_module modules/mod_headers.so
|
||||
</IfModule>
|
||||
<IfModule !mime_module>
|
||||
LoadModule mime_module modules/mod_mime.so
|
||||
</IfModule>
|
||||
<IfModule !rewrite_module>
|
||||
LoadModule rewrite_module modules/mod_rewrite.so
|
||||
</IfModule>
|
||||
|
||||
ServerName freshrss.localhost
|
||||
Listen 0.0.0.0:80
|
||||
DocumentRoot /var/www/FreshRSS/p/
|
||||
ErrorLog /dev/stderr
|
||||
TransferLog /dev/stdout
|
||||
AllowEncodedSlashes On
|
||||
|
||||
<Directory /var/www/FreshRSS/p>
|
||||
AllowOverride AuthConfig FileInfo Indexes Limit
|
||||
Require all granted
|
||||
</Directory>
|
||||
119
Docker/README.md
Normal file
119
Docker/README.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Deploy FreshRSS with Docker
|
||||
* See also:
|
||||
* https://hub.docker.com/r/freshrss/freshrss/
|
||||
* https://cloud.docker.com/app/freshrss/repository/docker/freshrss/freshrss
|
||||
|
||||
## Install Docker
|
||||
|
||||
```sh
|
||||
curl -fsSL https://get.docker.com/ -o get-docker.sh
|
||||
sh get-docker.sh
|
||||
```
|
||||
|
||||
## Optional: Build Docker image of FreshRSS
|
||||
Optional, as a *less recent* online image can be automatically fetched during the next step (run),
|
||||
but online images are not available for as many platforms as if you build yourself.
|
||||
|
||||
```sh
|
||||
# First time only
|
||||
git clone https://github.com/FreshRSS/FreshRSS.git
|
||||
|
||||
cd ./FreshRSS/
|
||||
git pull
|
||||
sudo docker pull alpine:3.7
|
||||
sudo docker build --tag freshrss/freshrss -f Docker/Dockerfile .
|
||||
```
|
||||
|
||||
## Run FreshRSS
|
||||
|
||||
Example using SQLite, and exposing FreshRSS on port 8080. You may have to adapt the network parameters to fit your needs.
|
||||
|
||||
```sh
|
||||
# You can optionally run from the directory containing the FreshRSS source code:
|
||||
cd ./FreshRSS/
|
||||
|
||||
# The data will be saved on the host in `./data/`
|
||||
mkdir -p ./data/
|
||||
|
||||
sudo docker run -dit --restart unless-stopped --log-opt max-size=10m \
|
||||
-v $(pwd)/data:/var/www/FreshRSS/data \
|
||||
-p 8080:80 \
|
||||
--name freshrss freshrss/freshrss
|
||||
```
|
||||
|
||||
### Examples with external databases
|
||||
|
||||
You may want to use other link methods such as Docker bridges, and use Docker volumes for the data, but here are some simple examples:
|
||||
|
||||
#### MySQL
|
||||
See https://hub.docker.com/_/mysql/
|
||||
|
||||
```sh
|
||||
sudo docker run -d -v /path/to/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=rootpass -e MYSQL_DATABASE=freshrss -e MYSQL_USER=freshrss -e MYSQL_PASSWORD=pass --name mysql mysql
|
||||
sudo docker run -dit --restart unless-stopped --log-opt max-size=10m \
|
||||
-v $(pwd)/data:/var/www/FreshRSS/data \
|
||||
--link mysql -p 8080:80 \
|
||||
--name freshrss freshrss/freshrss
|
||||
```
|
||||
|
||||
#### PostgreSQL
|
||||
See https://hub.docker.com/_/postgres/
|
||||
|
||||
```sh
|
||||
sudo docker run -d -v /path/to/pgsql-data:/var/lib/postgresql/data -e POSTGRES_DB=freshrss -e POSTGRES_USER=freshrss -e POSTGRES_PASSWORD=pass --name postgres postgres
|
||||
sudo docker run -dit --restart unless-stopped --log-opt max-size=10m \
|
||||
-v $(pwd)/data:/var/www/FreshRSS/data \
|
||||
--link postgres -p 8080:80 \
|
||||
--name freshrss freshrss/freshrss
|
||||
```
|
||||
|
||||
## Update
|
||||
|
||||
```sh
|
||||
# Rebuild an image (see build section above) or get a new online version:
|
||||
sudo docker pull freshrss/freshrss
|
||||
# And then
|
||||
sudo docker stop freshrss
|
||||
sudo docker rename freshrss freshrss_old
|
||||
# See the run section above for the full command
|
||||
sudo docker run ...
|
||||
# If everything is working, delete the old container
|
||||
sudo docker rm freshrss_old
|
||||
```
|
||||
|
||||
## Command line
|
||||
|
||||
```sh
|
||||
sudo docker exec --user apache -it freshrss php ./cli/list-users.php
|
||||
```
|
||||
|
||||
See the [CLI documentation](../cli/) for all the other commands.
|
||||
|
||||
### Cron job to refresh feeds
|
||||
Set a cron job up on your host machine, calling the `actualize_script.php` inside the FreshRSS Docker instance.
|
||||
|
||||
#### Example on Debian / Ubuntu
|
||||
Create `/etc/cron.d/FreshRSS` with:
|
||||
|
||||
```
|
||||
7,37 * * * * root docker exec --user apache -it freshrss php ./app/actualize_script.php > /tmp/FreshRSS.log 2>&1
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
```sh
|
||||
# See FreshRSS data (it is on the host)
|
||||
cd ./data/
|
||||
# See Web server logs
|
||||
sudo docker logs -f freshrss
|
||||
|
||||
# Enter inside FreshRSS docker container
|
||||
sudo docker exec -it freshrss sh
|
||||
## See FreshRSS root inside the container
|
||||
ls /var/www/FreshRSS/
|
||||
```
|
||||
|
||||
## Deployment in production
|
||||
|
||||
Use a reverse proxy on your host server, such as [Træfik](https://traefik.io/) or [nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/),
|
||||
with HTTPS, for instance using [Let’s Encrypt](https://letsencrypt.org/).
|
||||
@@ -55,6 +55,8 @@ Nous sommes une communauté amicale.
|
||||
7. Avec Apache, activer [`AllowEncodedSlashes`](https://httpd.apache.org/docs/trunk/mod/core.html#allowencodedslashes) pour une meilleure compatibilité avec les clients mobiles.
|
||||
|
||||
## Installation automatisée
|
||||
* [Docker](./Docker/)
|
||||
* [](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
|
||||
* [](https://dfabric.github.io/DPlatform-ShellCore)
|
||||
* [YunoHost](https://github.com/YunoHost-Apps/freshrss_ynh)
|
||||
|
||||
@@ -172,7 +174,7 @@ Voir le [dépôt dédié à ces extensions](https://github.com/FreshRSS/Extensio
|
||||
* [password_compat](https://github.com/ircmaxell/password_compat)
|
||||
|
||||
|
||||
# [Clients compatibles](https://freshrss.github.io/FreshRSS/en/users/06_Mobile_access.html)
|
||||
# [Clients compatibles](https://freshrss.github.io/FreshRSS/fr/users/06_Mobile_access.html)
|
||||
Tout client supportant une API de type Google Reader. Sélection :
|
||||
|
||||
* Android
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
[![Build Status][travis-badge]][travis-link]
|
||||
|
||||
* Read this document on [github.com/FreshRSS/FreshRSS/](https://github.com/FreshRSS/FreshRSS/blob/master/README.md) to get the correct links and pictures.
|
||||
* [Version française](README.fr.md)
|
||||
|
||||
# FreshRSS
|
||||
@@ -46,7 +47,7 @@ We are a friendly community.
|
||||
# Documentation
|
||||
* https://freshrss.github.io/FreshRSS/en/
|
||||
|
||||
# [Installation](https://freshrss.github.io/FreshRSS/en/users/01_Installation.html)
|
||||
# [Installation](https://freshrss.github.io/FreshRSS/en/admins/02_Installation.html)
|
||||
1. Get FreshRSS with git or [by downloading the archive](https://github.com/FreshRSS/FreshRSS/archive/master.zip)
|
||||
2. Dump the application on your server (expose only the `./p/` folder)
|
||||
3. Add write access on `./data/` folder to the webserver user
|
||||
@@ -59,7 +60,8 @@ We are a friendly community.
|
||||
More information about installation and server configuration can be found in [our documentation](https://freshrss.github.io/FreshRSS/en/admins/02_Installation.html).
|
||||
|
||||
## Automated install
|
||||
* [](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
|
||||
* [Docker](./Docker/)
|
||||
* [](https://cloudron.io/button.html?app=org.freshrss.cloudronapp)
|
||||
* [](https://dfabric.github.io/DPlatform-ShellCore)
|
||||
* [YunoHost](https://github.com/YunoHost-Apps/freshrss_ynh)
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
|
||||
$nb_month_old = max(FreshRSS_Context::$user_conf->old_entries, 1);
|
||||
$date_min = time() - (3600 * 24 * 30 * $nb_month_old);
|
||||
|
||||
$entryDAO = FreshRSS_Factory::createEntryDao();
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
$feeds = $feedDAO->listFeeds();
|
||||
$nb_total = 0;
|
||||
@@ -182,7 +183,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
|
||||
}
|
||||
|
||||
if ($feed_history >= 0) {
|
||||
$nb = $feedDAO->cleanOldEntries($feed->id(), $date_min, $feed_history);
|
||||
$nb = $entryDAO->cleanOldEntries($feed->id(), $date_min, $feed_history);
|
||||
if ($nb > 0) {
|
||||
$nb_total += $nb;
|
||||
Minz_Log::debug($nb . ' old entries cleaned in feed [' . $feed->url() . ']');
|
||||
|
||||
@@ -408,7 +408,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
|
||||
$entryDAO->beginTransaction();
|
||||
}
|
||||
|
||||
$nb = $feedDAO->cleanOldEntries($feed->id(),
|
||||
$nb = $entryDAO->cleanOldEntries($feed->id(),
|
||||
$date_min,
|
||||
max($feed_history, count($entries) + 10));
|
||||
if ($nb > 0) {
|
||||
|
||||
@@ -128,7 +128,7 @@ class FreshRSS extends Minz_FrontController {
|
||||
}
|
||||
header("X-Content-Type-Options: nosniff");
|
||||
|
||||
FreshRSS_Share::load(join_path(DATA_PATH, 'shares.php'));
|
||||
FreshRSS_Share::load(join_path(APP_PATH, 'shares.php'));
|
||||
self::loadStylesAndScripts();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ class FreshRSS_Auth {
|
||||
$login_ok = $current_user != '';
|
||||
if ($login_ok) {
|
||||
Minz_Session::_param('currentUser', $current_user);
|
||||
Minz_Session::_param('REMOTE_USER', $current_user);
|
||||
}
|
||||
return $login_ok;
|
||||
case 'none':
|
||||
@@ -102,6 +101,7 @@ class FreshRSS_Auth {
|
||||
}
|
||||
|
||||
Minz_Session::_param('loginOk', self::$login_ok);
|
||||
Minz_Session::_param('REMOTE_USER', httpAuthUser());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +133,7 @@ class FreshRSS_Auth {
|
||||
self::$login_ok = false;
|
||||
Minz_Session::_param('loginOk');
|
||||
Minz_Session::_param('csrf');
|
||||
Minz_Session::_param('REMOTE_USER');
|
||||
$system_conf = Minz_Configuration::get('system');
|
||||
|
||||
$username = '';
|
||||
|
||||
@@ -560,6 +560,33 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
|
||||
return $affected;
|
||||
}
|
||||
|
||||
public function cleanOldEntries($id_feed, $date_min, $keep = 15) { //Remember to call updateCachedValue($id_feed) or updateCachedValues() just after
|
||||
$sql = 'DELETE FROM `' . $this->prefix . 'entry` '
|
||||
. 'WHERE id_feed=:id_feed AND id<=:id_max '
|
||||
. 'AND is_favorite=0 ' //Do not remove favourites
|
||||
. 'AND `lastSeen` < (SELECT maxLastSeen FROM (SELECT (MAX(e3.`lastSeen`)-99) AS maxLastSeen FROM `' . $this->prefix . 'entry` e3 WHERE e3.id_feed=:id_feed) recent) ' //Do not remove the most newly seen articles, plus a few seconds of tolerance
|
||||
. 'AND id NOT IN (SELECT id FROM (SELECT e2.id FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=:id_feed ORDER BY id DESC LIMIT :keep) keep)'; //Double select: MySQL doesn't support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
$stm = $this->bd->prepare($sql);
|
||||
|
||||
if ($stm) {
|
||||
$id_max = intval($date_min) . '000000';
|
||||
$stm->bindParam(':id_feed', $id_feed, PDO::PARAM_INT);
|
||||
$stm->bindParam(':id_max', $id_max, PDO::PARAM_STR);
|
||||
$stm->bindParam(':keep', $keep, PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
if ($stm && $stm->execute()) {
|
||||
return $stm->rowCount();
|
||||
} else {
|
||||
$info = $stm == null ? array(0 => '', 1 => '', 2 => 'syntax error') : $stm->errorInfo();
|
||||
if ($this->autoUpdateDb($info)) {
|
||||
return $this->cleanOldEntries($id_feed, $date_min, $keep);
|
||||
}
|
||||
Minz_Log::error('SQL error cleanOldEntries: ' . $info[2]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function searchByGuid($id_feed, $guid) {
|
||||
// un guid est unique pour un flux donné
|
||||
$sql = 'SELECT id, guid, title, author, '
|
||||
|
||||
@@ -355,7 +355,7 @@ class FreshRSS_Feed extends Minz_Model {
|
||||
$this->id(),
|
||||
$item->get_id(false, false),
|
||||
$title === null ? '' : $title,
|
||||
$author === null ? '' : html_only_entity_decode(strip_tags($author->name)),
|
||||
$author === null ? '' : html_only_entity_decode(strip_tags($author->name == null ? $author->email : $author->name)),
|
||||
$content === null ? '' : $content,
|
||||
$link === null ? '' : $link,
|
||||
$date ? $date : time()
|
||||
|
||||
@@ -353,30 +353,6 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
|
||||
return $affected;
|
||||
}
|
||||
|
||||
public function cleanOldEntries($id, $date_min, $keep = 15) { //Remember to call updateCachedValue($id) or updateCachedValues() just after
|
||||
$sql = 'DELETE FROM `' . $this->prefix . 'entry` '
|
||||
. 'WHERE id_feed=:id_feed AND id<=:id_max '
|
||||
. 'AND is_favorite=0 ' //Do not remove favourites
|
||||
. 'AND `lastSeen` < (SELECT maxLastSeen FROM (SELECT (MAX(e3.`lastSeen`)-99) AS maxLastSeen FROM `' . $this->prefix . 'entry` e3 WHERE e3.id_feed=:id_feed) recent) ' //Do not remove the most newly seen articles, plus a few seconds of tolerance
|
||||
. 'AND id NOT IN (SELECT id FROM (SELECT e2.id FROM `' . $this->prefix . 'entry` e2 WHERE e2.id_feed=:id_feed ORDER BY id DESC LIMIT :keep) keep)'; //Double select: MySQL doesn't support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
$stm = $this->bd->prepare($sql);
|
||||
|
||||
if ($stm) {
|
||||
$id_max = intval($date_min) . '000000';
|
||||
$stm->bindParam(':id_feed', $id, PDO::PARAM_INT);
|
||||
$stm->bindParam(':id_max', $id_max, PDO::PARAM_STR);
|
||||
$stm->bindParam(':keep', $keep, PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
if ($stm && $stm->execute()) {
|
||||
return $stm->rowCount();
|
||||
} else {
|
||||
$info = $stm == null ? array(2 => 'syntax error') : $stm->errorInfo();
|
||||
Minz_Log::error('SQL error cleanOldEntries: ' . $info[2]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function daoToFeed($listDAO, $catID = null) {
|
||||
$list = array();
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Sdílení',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Více informací',
|
||||
'print' => 'Tisk',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Jméno pro zobrazení',
|
||||
'share_url' => 'Jakou URL použít pro sdílení',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Teilen',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'E-Mail',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Weitere Informationen',
|
||||
'print' => 'Drucken',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Anzuzeigender Teilen-Name',
|
||||
'share_url' => 'Zu verwendende Teilen-URL',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Sharing',
|
||||
'add' => 'Add a sharing method',
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'More information',
|
||||
'print' => 'Print',
|
||||
'remove' => 'Remove sharing method',
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Share name to display',
|
||||
'share_url' => 'Share URL to use',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Compartir',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Más información',
|
||||
'print' => 'Print',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Compartir nombre a mostrar',
|
||||
'share_url' => 'Compatir URL a usar',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Partage',
|
||||
'add' => 'Ajouter une méthode de partage',
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Courriel',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Plus d’informations',
|
||||
'print' => 'Print',
|
||||
'remove' => 'Supprimer la méthode de partage',
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Nom du partage à afficher',
|
||||
'share_url' => 'URL du partage à utiliser',
|
||||
|
||||
@@ -123,6 +123,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'שיתוף',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'דואר אלקטרוני',
|
||||
@@ -130,6 +131,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'מידע נוסף',
|
||||
'print' => 'הדפסה',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'שיתוף שם לתצוגה',
|
||||
'share_url' => 'לשימוש שתפו URL',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Condivisione',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Ulteriori informazioni',
|
||||
'print' => 'Stampa',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Nome condivisione',
|
||||
'share_url' => 'URL condivisione',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => '공유',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => '메일',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => '자세한 정보',
|
||||
'print' => '인쇄',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => '표시할 이름',
|
||||
'share_url' => '사용할 공유 URL',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Delen',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Meer informatie',
|
||||
'print' => 'Afdrukken',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Gedeelde naam om weer te geven',
|
||||
'share_url' => 'Deel URL voor gebruik',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Compartilhando',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Mais informação',
|
||||
'print' => 'Imprimir',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Nome de visualização para compartilhar',
|
||||
'share_url' => 'URL utilizada para compartilhar',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Sharing',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'More information',
|
||||
'print' => 'Print',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Share name to display',
|
||||
'share_url' => 'Share URL to use',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => 'Paylaşım',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => 'Daha fazla bilgi',
|
||||
'print' => 'Yazdır',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => 'Paylaşım ismi',
|
||||
'share_url' => 'Paylaşım URL si',
|
||||
|
||||
@@ -126,6 +126,7 @@ return array(
|
||||
),
|
||||
'sharing' => array(
|
||||
'_' => '分享',
|
||||
'add' => 'Add a sharing method', // TODO
|
||||
'blogotext' => 'Blogotext',
|
||||
'diaspora' => 'Diaspora*',
|
||||
'email' => 'Email',
|
||||
@@ -133,6 +134,7 @@ return array(
|
||||
'g+' => 'Google+',
|
||||
'more_information' => '更多信息',
|
||||
'print' => '打印',
|
||||
'remove' => 'Remove sharing method', // TODO
|
||||
'shaarli' => 'Shaarli',
|
||||
'share_name' => '名称',
|
||||
'share_url' => '地址',
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<div class="stick">
|
||||
<input type="text" id="share_##key##_name" name="share[##key##][name]" class="extend" value="" placeholder="<?php echo _t('conf.sharing.share_name'); ?>" size="64" />
|
||||
<input type="url" id="share_##key##_url" name="share[##key##][url]" class="extend" value="" placeholder="<?php echo _t('conf.sharing.share_url'); ?>" size="64" />
|
||||
<a href="#" class="remove btn btn-attention" data-remove="group-share-##key##"><?php echo _i('close'); ?></a></div>
|
||||
<a href="#" class="remove btn btn-attention" data-remove="group-share-##key##" title="<?php echo _t('conf.sharing.remove'); ?>"><?php echo _i('close'); ?></a></div>
|
||||
<a target="_blank" rel="noreferrer" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="##help##"><?php echo _i('help'); ?></a>
|
||||
</div></div>'>
|
||||
<input type="hidden" name="_csrf" value="<?php echo FreshRSS_Auth::csrfToken(); ?>" />
|
||||
@@ -39,7 +39,7 @@
|
||||
<?php } else { ?>
|
||||
<input type="url" id="share_<?php echo $key; ?>_url" name="share[<?php echo $key; ?>][url]" class="extend" value="<?php echo $share->baseUrl(); ?>" placeholder="<?php echo _t('gen.short.not_applicable'); ?>" size="64" disabled/>
|
||||
<?php } ?>
|
||||
<a href='#' class='remove btn btn-attention' data-remove="group-share-<?php echo $key; ?>"><?php echo _i('close'); ?></a>
|
||||
<a href='#' class='remove btn btn-attention' data-remove="group-share-<?php echo $key; ?>" title="<?php echo _t('conf.sharing.remove'); ?>"><?php echo _i('close'); ?></a>
|
||||
</div>
|
||||
<?php if ($share->formType() === 'advanced') { ?>
|
||||
<a target="_blank" rel="noreferrer" class="btn" title="<?php echo _t('conf.sharing.more_information'); ?>" href="<?php echo $share->help(); ?>"><?php echo _i('help'); ?></a>
|
||||
@@ -57,7 +57,7 @@
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<a href='#' class='share add btn'><?php echo _i('add'); ?></a>
|
||||
<a href='#' class='share add btn' title="<?php echo _t('conf.sharing.add'); ?>"><?php echo _i('add'); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ Options in parenthesis are optional.
|
||||
```sh
|
||||
cd /usr/share/FreshRSS
|
||||
|
||||
./cli/prepare.php
|
||||
# Ensure the needed directories in ./data/
|
||||
|
||||
./cli/do-install.php --default_user admin ( --auth_type form --environment production --base_url https://rss.example.net/ --language en --title FreshRSS --allow_anonymous --api_enabled --db-type mysql --db-host localhost:3306 --db-user freshrss --db-password dbPassword123 --db-base freshrss --db-prefix freshrss )
|
||||
# --auth_type can be: 'form' (default), 'http_auth' (using the Web server access control), 'none' (dangerous)
|
||||
# --db-type can be: 'sqlite' (default), 'mysql' (MySQL or MariaDB), 'pgsql' (PostgreSQL)
|
||||
|
||||
@@ -32,6 +32,7 @@ class I18nData {
|
||||
* Add a new language. It's a copy of the reference language.
|
||||
*
|
||||
* @param string $language
|
||||
* @throws Exception
|
||||
*/
|
||||
public function addLanguage($language) {
|
||||
if (array_key_exists($language, $this->data)) {
|
||||
@@ -45,6 +46,7 @@ class I18nData {
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @throws Exception
|
||||
*/
|
||||
public function addKey($key, $value) {
|
||||
if (array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
|
||||
@@ -53,10 +55,29 @@ class I18nData {
|
||||
$this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value for a key for the selected language.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @param string $language
|
||||
* @throws Exception
|
||||
*/
|
||||
public function addValue($key, $value, $language) {
|
||||
if (!in_array($language, $this->getAvailableLanguages())) {
|
||||
throw new Exception('The selected language does not exist.');
|
||||
}
|
||||
if (!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
|
||||
throw new Exception('The selected key does not exist for the selected language.');
|
||||
}
|
||||
$this->data[$language][$this->getFilenamePrefix($key)][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a key from the reference language to all other languages
|
||||
*
|
||||
* @param string $key
|
||||
* @throws Exception
|
||||
*/
|
||||
public function duplicateKey($key) {
|
||||
if (!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
|
||||
@@ -68,7 +89,7 @@ class I18nData {
|
||||
continue;
|
||||
}
|
||||
if (array_key_exists($key, $this->data[$language][$this->getFilenamePrefix($key)])) {
|
||||
throw new Exception(sprintf('The selected key already exist in %s.', $language));
|
||||
continue;
|
||||
}
|
||||
$this->data[$language][$this->getFilenamePrefix($key)][$key] = $value;
|
||||
}
|
||||
@@ -78,6 +99,7 @@ class I18nData {
|
||||
* Remove a key in all languages
|
||||
*
|
||||
* @param string $key
|
||||
* @throws Exception
|
||||
*/
|
||||
public function removeKey($key) {
|
||||
if (!array_key_exists($key, $this->data[static::REFERENCE_LANGUAGE][$this->getFilenamePrefix($key)])) {
|
||||
|
||||
@@ -36,8 +36,7 @@ class i18nFile {
|
||||
}
|
||||
foreach ($file as $name => $content) {
|
||||
$filename = $dir . DIRECTORY_SEPARATOR . $name;
|
||||
$fullContent = var_export($this->unflatten($content), true);
|
||||
file_put_contents($filename, sprintf('<?php return %s;', $fullContent));
|
||||
file_put_contents($filename, $this->format($content));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,4 +88,32 @@ class i18nFile {
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an array of translation
|
||||
*
|
||||
* It takes an array of translation and format it to be dumped in a
|
||||
* translation file. The array is first converted to a string then some
|
||||
* formatting regexes are applied to match the original content.
|
||||
*
|
||||
* @param array $translation
|
||||
* @return string
|
||||
*/
|
||||
private function format($translation) {
|
||||
$translation = var_export($this->unflatten($translation), true);
|
||||
$patterns = array(
|
||||
'/array \(/',
|
||||
'/=>\s*array/',
|
||||
'/ {2}/',
|
||||
);
|
||||
$replacements = array(
|
||||
'array(',
|
||||
'=> array',
|
||||
"\t", // Double quoting is mandatory to have a tab instead of the \t string
|
||||
);
|
||||
$translation = preg_replace($patterns, $replacements, $translation);
|
||||
|
||||
// Double quoting is mandatory to have new lines instead of \n strings
|
||||
return sprintf("<?php\n\nreturn %s;\n", $translation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ if (array_key_exists('h', $options)) {
|
||||
help();
|
||||
}
|
||||
|
||||
if (1 === $argc || 4 < $argc) {
|
||||
if (1 === $argc || 5 < $argc) {
|
||||
help();
|
||||
}
|
||||
|
||||
@@ -25,12 +25,21 @@ switch ($argv[1]) {
|
||||
}
|
||||
$i18nData->addKey($argv[2], $argv[3]);
|
||||
break;
|
||||
case 'add_value':
|
||||
if (4 === $argc) {
|
||||
help();
|
||||
}
|
||||
$i18nData->addValue($argv[2], $argv[3], $argv[4]);
|
||||
break;
|
||||
case 'duplicate_key' :
|
||||
$i18nData->duplicateKey($argv[2]);
|
||||
break;
|
||||
case 'delete_key' :
|
||||
$i18nData->removeKey($argv[2]);
|
||||
break;
|
||||
case 'format' :
|
||||
$i18nFile->dump($i18nData);
|
||||
break;
|
||||
default :
|
||||
help();
|
||||
}
|
||||
@@ -48,7 +57,7 @@ NAME
|
||||
%s
|
||||
|
||||
SYNOPSIS
|
||||
php %s [OPTION] [OPERATION] [KEY] [VALUE]
|
||||
php %s [OPTION] [OPERATION] [KEY] [VALUE] [LANGUAGE]
|
||||
|
||||
DESCRIPTION
|
||||
Manipulate translation files. Available operations are
|
||||
@@ -64,6 +73,10 @@ OPERATION
|
||||
add_key add a new key in the referential. This operation needs a KEY and
|
||||
a VALUE.
|
||||
|
||||
add_value
|
||||
add a value in the referential. This operation needs a KEY, a
|
||||
VALUE, and a LANGUAGE.
|
||||
|
||||
duplicate_key
|
||||
duplicate a referential key in other languages. This operation
|
||||
needs only a KEY.
|
||||
@@ -72,6 +85,8 @@ OPERATION
|
||||
delete a referential key from all languages. This operation needs
|
||||
only a KEY.
|
||||
|
||||
format format i18n files.
|
||||
|
||||
HELP;
|
||||
$file = str_replace(__DIR__ . '/', '', __FILE__);
|
||||
echo sprintf($help, $file, $file);
|
||||
|
||||
37
cli/prepare.php
Executable file
37
cli/prepare.php
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
require(__DIR__ . '/_cli.php');
|
||||
|
||||
$dirs = array(
|
||||
'/',
|
||||
'/cache',
|
||||
'/extensions-data',
|
||||
'/favicons',
|
||||
'/PubSubHubbub',
|
||||
'/PubSubHubbub/feeds',
|
||||
'/PubSubHubbub/keys',
|
||||
'/tokens',
|
||||
'/users',
|
||||
'/users/_',
|
||||
);
|
||||
|
||||
$ok = true;
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
@mkdir(DATA_PATH . $dir, 0770, true);
|
||||
$ok &= touch(DATA_PATH . $dir . '/index.html');
|
||||
}
|
||||
|
||||
if (!is_file(DATA_PATH . '/config.php')) {
|
||||
$ok &= touch(DATA_PATH . '/do-install.txt');
|
||||
}
|
||||
|
||||
file_put_contents(DATA_PATH . '/.htaccess',
|
||||
"Order Allow,Deny\n" .
|
||||
"Deny from all\n" .
|
||||
"Satisfy all\n"
|
||||
);
|
||||
|
||||
accessRights();
|
||||
|
||||
done($ok);
|
||||
@@ -2,7 +2,7 @@
|
||||
//NB: Do not edit; use ./constants.local.php instead.
|
||||
|
||||
//<Not customisable>
|
||||
define('FRESHRSS_VERSION', '1.10.0');
|
||||
define('FRESHRSS_VERSION', '1.10.1');
|
||||
define('FRESHRSS_WEBSITE', 'https://freshrss.org');
|
||||
define('FRESHRSS_WIKI', 'https://freshrss.github.io/FreshRSS/');
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ You need to verify that your server can run FreshRSS before installing it. If yo
|
||||
| Web server | **Apache 2** | Nginx |
|
||||
| PHP | **PHP 5.5+** | PHP 5.3.8+ |
|
||||
| PHP modules | Required: libxml, cURL, PDO_MySQL, PCRE and ctype. \\ Required (32-bit only): GMP \\Recommanded: JSON, Zlib, mbstring, iconv, ZipArchive | |
|
||||
| Database | **MySQL 5.0.3+** | SQLite 3.7.4+ |
|
||||
| Database | **MySQL 5.5.3+** | SQLite 3.7.4+ |
|
||||
| Browser | **Firefox** | Chrome, Opera, Safari, or IE11+ |
|
||||
|
||||
## Important notice
|
||||
|
||||
@@ -33,3 +33,14 @@ Here is a list of feeds which don't work:
|
||||
* http://foulab.org/fr/rss/Foulab_News: is not a W3C valid feed (November 2014)
|
||||
* http://eu.battle.net/hearthstone/fr/feed/news: is not a W3C valid feed (Novembre 2014)
|
||||
* http://webseriesmag.blogs.liberation.fr/we/atom.xml: is not working for the user but succeed on all the described validations (November 2014)
|
||||
|
||||
## How to change a forgotten password?
|
||||
|
||||
Since [1.10.0](https://github.com/FreshRSS/FreshRSS/releases/tag/1.10.0) release, admins are able to change user passwords directly from the interface. This interface is available under ```Administration → Manage users```.
|
||||
Select a user, enter a password, and validate.
|
||||
|
||||
Since [1.8.0](https://github.com/FreshRSS/FreshRSS/releases/tag/1.8.0) release, admins are able to change user passwords using a terminal. It worth mentioning that it must have access to PHP CLI. Open a terminal, and type the following command:
|
||||
```sh
|
||||
./cli/update_user.php --user <username> --password <password>
|
||||
```
|
||||
For more information on that matter, there is a [dedicated documentation](../../cli/README.md).
|
||||
@@ -9,7 +9,7 @@ Il est toutefois de votre responsabilité de vérifier que votre hébergement pe
|
||||
| Serveur web | **Apache 2** | Nginx |
|
||||
| PHP | **PHP 5.5+** | PHP 5.3.8+ |
|
||||
| Modules PHP | Requis : libxml, cURL, PDO_MySQL, PCRE et ctype \\ Requis (32 bits seulement) : GMP \\ Recommandé : JSON, Zlib, mbstring et iconv, ZipArchive | |
|
||||
| Base de données | **MySQL 5.0.3+** | SQLite 3.7.4+ |
|
||||
| Base de données | **MySQL 5.5.3+** | SQLite 3.7.4+ |
|
||||
| Navigateur | **Firefox** | Chrome, Opera, Safari, or IE 11+ |
|
||||
|
||||
## Note importante
|
||||
|
||||
@@ -33,3 +33,14 @@ Voici une liste des flux qui ne fonctionnent pas :
|
||||
* http://foulab.org/fr/rss/Foulab_News : ne passe pas la validation W3C (novembre 2014)
|
||||
* http://eu.battle.net/hearthstone/fr/feed/news : ne passe pas la validation W3C (novembre 2014)
|
||||
* http://webseriesmag.blogs.liberation.fr/we/atom.xml : ne fonctionne pas chez l'utilisateur mais passe l'ensemble des validations ci-dessus (novembre 2014)
|
||||
|
||||
## Comment changer un mot de passe oublié ?
|
||||
|
||||
Depuis la version [1.10.0](https://github.com/FreshRSS/FreshRSS/releases/tag/1.10.0), l'administrateur peut modifier le mot de passe d'un utilisateur depuis l'interface. Cette interface est disponible dans le menu ```Administration → Gestion des utilisateurs```.
|
||||
Il suffit de sélectionner l'utilisateur, de saisir un mot de passe et de valider.
|
||||
|
||||
Depuis la version [1.8.0](https://github.com/FreshRSS/FreshRSS/releases/tag/1.8.0), l'administrateur peut modifier le mot de passe d'un utilisateur depuis un terminal. Il est bon de noter que celui-ci doit avoir un accès à PHP en ligne de commande. Pour cela, il suffit d'ouvrir son terminal et de saisir la commande suivante :
|
||||
```sh
|
||||
./cli/update_user.php --user <username> --password <password>
|
||||
```
|
||||
Pour plus d'information à ce sujet, il existe la [documentation dédiée](../../cli/README.md).
|
||||
|
||||
@@ -106,7 +106,8 @@ class Minz_Request {
|
||||
$https = self::isHttps();
|
||||
|
||||
if (!empty($_SERVER['HTTP_HOST'])) {
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
//Might contain a port number, and mind IPv6 addresses
|
||||
$host = parse_url('http://' . $_SERVER['HTTP_HOST'], PHP_URL_HOST);
|
||||
} elseif (!empty($_SERVER['SERVER_NAME'])) {
|
||||
$host = $_SERVER['SERVER_NAME'];
|
||||
} else {
|
||||
|
||||
@@ -445,6 +445,9 @@ function unreadCount() { //http://blog.martindoms.com/2009/10/16/using-the-googl
|
||||
}
|
||||
|
||||
function entriesToArray($entries) {
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
$arrayFeedCategoryNames = $feedDAO->arrayFeedCategoryNames();
|
||||
|
||||
$items = array();
|
||||
foreach ($entries as $entry) {
|
||||
$f_id = $entry->feed();
|
||||
@@ -494,9 +497,6 @@ function streamContents($path, $include_target, $start_time, $count, $order, $ex
|
||||
//http://blog.martindoms.com/2009/10/16/using-the-google-reader-api-part-2/#feed
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
|
||||
$feedDAO = FreshRSS_Factory::createFeedDao();
|
||||
$arrayFeedCategoryNames = $feedDAO->arrayFeedCategoryNames();
|
||||
|
||||
switch ($path) {
|
||||
case 'reading-list':
|
||||
$type = 'A';
|
||||
|
||||
Reference in New Issue
Block a user