Compare commits

...

114 Commits

Author SHA1 Message Date
6a9e4bfc90 version number 2013-08-11 21:04:04 +02:00
15493df62d fixed #114 : minimum & maximum scale removed 2013-08-11 19:42:52 +02:00
82051a6a6a fixed #128: back to home after mark a link as read is fixed 2013-08-11 19:10:48 +02:00
5bf30b0060 layout 2013-08-10 22:17:00 +02:00
baea9b6de5 new logo 2013-08-10 21:39:11 +02:00
fa0483b361 closed #120: top link 2013-08-10 12:21:36 +02:00
b58e261db9 bug in downloading pictures : article content wasn't updated anymore 2013-08-09 23:30:20 +02:00
d8d1542e52 typo 2013-08-09 22:15:40 +02:00
56ab22d02c only display latest dev version if DEBUG is on 2013-08-09 13:05:35 +02:00
6c15854448 Closed #111 : test of install folder moved before 2013-08-09 11:47:37 +02:00
d91787589b fix #113 - reading time 2013-08-09 08:25:16 +02:00
3d8bded89e debug false 2013-08-08 21:28:37 +02:00
5f9bff0f71 some urls weren't well parsed 2013-08-08 21:13:37 +02:00
301e4c5acb installation 2013-08-08 18:41:40 +02:00
572e758bf2 empty phpunit file 2013-08-08 14:07:43 +02:00
64f8970215 travis img 2013-08-08 13:50:53 +02:00
a3436d4cba travis 2013-08-08 13:49:57 +02:00
07ee09f49a comments 2013-08-08 12:33:02 +02:00
25b5caeed1 ignore doc output 2013-08-08 09:57:18 +02:00
313f4ca785 ignore doc output 2013-08-08 09:55:04 +02:00
ed06f04077 test if /install exists 2013-08-08 09:11:12 +02:00
7aa8ccc47d preparing travis 2013-08-08 07:16:07 +02:00
04b55e97de populate user_config 2013-08-07 21:16:12 +02:00
76e9ca2acf good version of poche.sqlite 2013-08-07 21:00:06 +02:00
77dea8a234 1.0 beta1 2013-08-07 20:05:14 +02:00
01c0e050ad Merge pull request #104 from inthepoche/twig
Twig version on dev branch
2013-08-07 10:41:26 -07:00
339d510fda installation instructions 2013-08-07 19:33:56 +02:00
6e5f8db8bb installation instructions 2013-08-07 19:33:13 +02:00
145f50402e installation instructions 2013-08-07 19:31:11 +02:00
1d517de67b installation instructions 2013-08-07 19:23:00 +02:00
c7ec97ce98 cache to FALSE 2013-08-07 19:14:48 +02:00
b916bcfccc fixes for 1.0-beta 2013-08-07 19:14:28 +02:00
580d60b941 file to update from 0.x to 1.x \o/ 2013-08-07 15:46:17 +02:00
68857cea8c setup of storage 2013-08-07 14:38:58 +02:00
bc1ee8524e postgres 2013-08-07 14:24:07 +02:00
8d3275bee4 multi user 2013-08-06 15:51:48 +02:00
7ce7ec4c94 prepare to multi users 2013-08-06 14:18:03 +02:00
17a9cb9608 minify bookmarklet js 2013-08-06 11:00:42 +02:00
f6df40db46 default sorting 2013-08-05 23:11:10 +02:00
6fb3a2a185 move xsrf test 2013-08-05 22:50:00 +02:00
d28a7ca30f remove js 2013-08-05 21:59:21 +02:00
6a361945ea new design, pagination & more 2013-08-05 21:56:32 +02:00
55821e04c1 share email +twitter / class messages 2013-08-05 15:54:37 +02:00
b161295d0b remove xsrf check 2013-08-05 12:53:56 +02:00
4d0e254491 link to download poche when update available 2013-08-05 12:39:24 +02:00
3252078501 close #69: in the config page, you are notified of the release of a new version 2013-08-05 12:34:16 +02:00
21e0af98eb information about db/poche.sqlite 2013-08-05 10:34:57 +02:00
7f959169b7 copy of poche.sqlite 2013-08-05 10:32:15 +02:00
e4ed594d82 rm poche.sqlite 2013-08-05 10:29:49 +02:00
a12832488d update poche.sqlite 2013-08-05 10:03:59 +02:00
a62788c61e #100: welcome to you, instapaper users 2013-08-05 09:43:33 +02:00
3208d538a7 mysql support 2013-08-05 08:54:42 +02:00
2a1791a4b1 view of an article 2013-08-04 22:51:12 +02:00
63c35580c7 twig implementation 2013-08-04 22:35:08 +02:00
c765c3679f import in poche and not in an external file 2013-08-04 21:42:46 +02:00
eb1af59219 refactoring 2013-08-04 20:58:31 +02:00
3ba5f81b7b twig implementation 2013-08-04 18:07:41 +02:00
07b9821e24 composer 2013-08-04 18:03:30 +02:00
15771f4452 gitignore 2013-08-04 18:02:29 +02:00
3dcab1a782 rm composer.phar 2013-08-04 17:51:33 +02:00
46b77928f7 rm vendor 2013-08-04 17:50:34 +02:00
68abd9c71b gitignore vendor 2013-08-04 17:44:17 +02:00
d51ecb6ea8 ignore vendor 2013-08-04 17:35:02 +02:00
7d2eb7a7b9 composer 2013-08-03 20:47:17 +02:00
4f5b44bd3b twig implementation 2013-08-03 19:26:54 +02:00
2b840e0cfb twig implementation 2013-08-03 08:57:35 +02:00
8cbb2a8802 twig implementation 2013-08-03 08:25:11 +02:00
c67e13e04b new tpl files 2013-08-03 08:24:42 +02:00
afe60d614b remove file 2013-08-03 08:05:02 +02:00
161395d709 mv pochetool pochetools 2013-08-02 23:04:24 +02:00
5ffe5cf541 rename pocheTool -> pocheTools 2013-08-02 23:00:57 +02:00
8069e235fd move Twig in 3rdparty 2013-08-02 22:43:56 +02:00
45161a6402 delete some files 2013-08-02 22:41:21 +02:00
a4565e88ed add Twig & refactor poche 2013-08-02 22:40:51 +02:00
f6c9baab3e rename myTool -> pocheTool and delete some stuff 2013-08-02 21:40:29 +02:00
da2c5d6fc3 display URL at home poche 2013-08-02 13:51:22 +02:00
408f3df28e URL is now encoded 2013-08-02 11:48:57 +02:00
2ee436eaa1 poche / pocket / bolsillo / Tasche & more 2013-08-02 10:39:03 +02:00
02ea9f0769 first test for readability import 2013-08-01 18:34:50 +02:00
99dd7d3877 testing icon in bookmarklet, thanks to @GeekShadow in #94 2013-08-01 11:00:27 +02:00
4d8bcc0c6b set demo mode to false 2013-07-31 19:58:14 +02:00
538cdfa883 fix #70: if demo mode, fields are filled 2013-07-31 19:37:14 +02:00
70b5d24f72 fix #80: add a link in the footer to report a wrong display 2013-07-31 19:21:49 +02:00
3db95a85de update external libs 2013-07-31 19:09:06 +02:00
95a7596cb4 fix #92: add a link to the top 2013-07-31 19:03:02 +02:00
6d37de5f82 typo in readme 2013-07-31 11:50:38 +02:00
66ce09ba03 google groups link 2013-07-31 11:45:10 +02:00
6499b26ae8 demo mode (you can't update password in demo mode 2013-06-01 08:29:37 +02:00
da368cc84f update password in config screen 2013-06-01 08:23:37 +02:00
aa8c9f2a32 Installation mode 2013-05-31 22:55:52 +02:00
baa8617364 update JSLikeHTMLElement 2013-04-24 08:27:55 +02:00
494e21b4da add tidy call to clean html output 2013-04-23 16:03:52 +02:00
0ace6cab0b Fix #47 - update Readability class (thx to http://code.fivefilters.org/php-readability/) 2013-04-23 15:57:23 +02:00
c1c9f252f7 display flash message in article view 2013-04-23 15:37:03 +02:00
2987031bc3 Fixed #73 - Can't Poch url with special caracter 2013-04-23 15:25:12 +02:00
3e7188185d Merge branch 'memiks-gestion_erreur_readability' into dev 2013-04-23 15:19:33 +02:00
8d5aab49c1 lien corrigé dans le README 2013-04-23 15:18:22 +02:00
cdcc8d2533 Remove debug on Readability output 2013-04-23 08:09:54 -05:00
ae9571694f Correction erreur sur le Self 2013-04-23 07:29:16 -05:00
4ddbd26787 Ajout du global msg et gestion du retour dans Readability 2013-04-23 07:22:19 -05:00
8444bb0600 Merge branch 'master' of github.com:inthepoche/poche 2013-04-23 09:40:35 +02:00
29c6fd4607 messages d'erreur si pas possible d'ajouter ou de supprimer un lien 2013-04-23 09:38:57 +02:00
37f2773aa5 Merge pull request #74 from inthepoche/dev
v0.2.1
2013-04-22 23:34:55 -07:00
e682978e5b Revert "Update style.css"
This reverts commit 176d733a44.
2013-04-23 08:30:48 +02:00
69ca1455d1 v0.2.1 2013-04-23 08:08:42 +02:00
88958248fa message de bienvenue 2013-04-23 08:07:47 +02:00
2761de0184 Merge pull request #72 from Silvus/dev
Style de l'écran de connexion
2013-04-22 23:04:18 -07:00
d2beefd27c Petit correctif des couleurs de la classe "bouton" au hover 2013-04-22 23:10:35 +02:00
8af1077265 Le logo poche renvoie vers l'accueil 2013-04-22 23:02:04 +02:00
9acfade829 Reprise du style de l'écran de connexion 2013-04-22 22:58:07 +02:00
d3607de929 Update style.css
coquille pour l'affichage des liens sur la page view
2013-04-22 20:27:23 +03:00
176d733a44 Update style.css
coquille pour l'affichage des liens sur la page view
2013-04-22 19:57:40 +03:00
e858ac2776 login & password dans le readme 2013-04-22 08:32:30 +02:00
37c6ed4e7a Merge pull request #67 from inthepoche/dev
tag 0.2
2013-04-21 10:53:22 -07:00
103 changed files with 4804 additions and 4073 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
vendor
composer.phar
db/poche.sqlite
output
phpdoc*

15
.travis.yml Normal file
View File

@ -0,0 +1,15 @@
language: php
php:
- 5.4
branches:
only:
- dev
before_script:
- composer install
notifications:
email:
- nicolas.loeuillet@gmail.com

12
CREDITS
View File

@ -1,16 +1,14 @@
poche is based on :
* ReadItYourself http://www.memiks.fr/readityourself/
* PHP Readability http://www.keyvan.net/2010/08/php-readability/
* PHP Readability https://bitbucket.org/fivefilters/php-readability
* Encoding https://github.com/neitanod/forceutf8
* logo by Brightmix http://www.iconfinder.com/icondetails/43256/128/jeans_monotone_pocket_icon
* icons http://icomoon.io
* PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
* Twig http://twig.sensiolabs.org
* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
* Pagination https://github.com/daveismyname/pagination
poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License
Contributors :
Nicolas Lœuillet aka nico_somb
Tom.C. aka tmos
PeaceCopathe
Gregoire_M
Contributors : https://github.com/inthepoche/poche/graphs/contributors

53
INSTALL.md Normal file
View File

@ -0,0 +1,53 @@
# Installing poche
Get the [latest version](https://github.com/inthepoche/poche/archive/1.0-beta1.zip) of poche on github. Unzip it and upload it on your server.
your datas can be stored on sqlite, postgres or mysql databases.
Edit /inc/poche/config.inc.php :
```php
define ('STORAGE','sqlite'); # postgres, mysql, sqlite
define ('STORAGE_SERVER', 'localhost'); # leave blank for sqlite
define ('STORAGE_DB', 'poche'); # only for postgres & mysql
define ('STORAGE_SQLITE', './db/poche.sqlite');
define ('STORAGE_USER', 'user'); # leave blank for sqlite
define ('STORAGE_PASSWORD', 'pass'); # leave blank for sqlite
```
poche must have write access on assets, cache and db directories.
[PHP cURL](http://www.php.net/manual/en/book.curl.php) & [tidy_parse_string](http://www.php.net/manual/en/tidy.parsestring.php) are recommended.
## twig
poche now uses twig for templating. You have to install twig.
Install composer in your project :
```bash
curl -s http://getcomposer.org/installer | php
```
Install via composer :
```bash
php composer.phar install
```
If you don't want to install twig by yourself, you can download [this file](http://static.inthepoche.com/files/poche-1.0-latest-with-twig.zip).
## storage in sqlite
You have to install [sqlite for php](http://www.php.net/manual/en/book.sqlite.php) on your server.
Copy /install/poche.sqlite in /db
## storage in mysql
Execute /install/mysql.sql file in your database.
## storage in postgres
Execute /install/postgres.sql file in your database.
## upgrading from poche <= 0.3
With poche <= 0.3, all your datas were stored in a sqlite file. The structure of this file changed.
You have to execute http://yourpoche/install/update_sqlite_from_0_to_1.php before using this new version.
## installing poche
you can go on your poche http://yourpoche. You have to fill the fields and that's all !

View File

@ -1,31 +1,19 @@
# poche
Abandon Pocket, Instapaper and other Readability service : adopt poche. It is the same, but it is open source.
Abandon Pocket, Instapaper and other Readability service : adopt poche. It is the same, but it is open source. Moreover, you can migrate from Pocket & Readability.
![poche](http://inthepoche.com/img/logo.png)
The website of poche is [inthepoche.com](http://inthepoche.com).
To get news from poche, [follow us on twitter](http://twitter.com/getpoche) or [read the poche blog](http://inthepoche.com/blog).
To test poche, a demo website is online : [demo.inthepoche.com](http://demo.inthepoche.com) (login poche, password poche).
To get news from poche, [follow us on twitter](http://twitter.com/getpoche) or [read the poche blog](http://inthepoche.com/blog). A Google Group is also available : [poche-users](https://groups.google.com/forum/#!forum/poche-users).
[![flattr](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/1265480/poche-a-read-it-later-open-source-system)
## Usage
You can easily add a "poched" page with the bookmarklet.
## Installation
poche save the entire content of a poched links : text and pictures are stored on your server.
You can :
* read a page in a comfortable reading view
* archive a link
* put a link in favorite
* delete a link
## Requirements & installation
You have to install [sqlite for php](http://www.php.net/manual/en/book.sqlite.php) on your server.
Get the [latest version](https://github.com/nicosomb/poche) of poche on github. Unzip it and upload it on your server. poche must have write access on assets, cache and db directories.
That's all, **poche works** !
Read the INSTALL.md file.
## Security
You **have** to protect your db/poche.sqlite file. Modify the virtual host of your website to add this condition :
@ -44,12 +32,14 @@ location ~ /(db) {
}
```
## Import from Pocket
## Usage
See the documentation on our website : [inthepoche.com](http://inthepoche.com).
If you want to import your Pocket datas, [export them here](https://getpocket.com/export). Put the HTML file in your poche directory, execute import.php file locally by following instructions. Be careful, the script can take a very long time.
## Travis
[![Build Status](https://api.travis-ci.org/inthepoche/poche.png?branch=dev)](http://travis-ci.org/#!/inthepoche/poche)
## License
Copyright © 2010-2013 Nicolas Lœuillet <nicolas@loeuillet.org>
Copyright © 2010-2013 Nicolas Lœuillet <nicolas.loeuillet@gmail.com>
This work is free. You can redistribute it and/or modify it under the
terms of the Do What The Fuck You Want To Public License, Version 2,
as published by Sam Hocevar. See the COPYING file for more details.
as published by Sam Hocevar. See the COPYING file for more details.

11
TODO.md Normal file
View File

@ -0,0 +1,11 @@
# TODO
pouvoir annuler la suppression
conventions codage ? phing ? vérifier error_log qui trainent
phpDocumentor
minifier css
revoir tous les css
barre fixe d'admin sur la page d'un billet ?
revoir export (export vers pocket &cie ? )
raccourcis clavier
date d'ajout d'un lien

7
composer.json Normal file
View File

@ -0,0 +1,7 @@
{
"require": {
"twig/twig": "1.*",
"twig/extensions": "1.0.*",
"umpirsky/twig-gettext-extractor": "1.1.*"
}
}

744
composer.lock generated Normal file
View File

@ -0,0 +1,744 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "1c8badb14d91f4f3ef1cfae23252a2c4",
"packages": [
{
"name": "symfony/event-dispatcher",
"version": "v2.3.2",
"target-dir": "Symfony/Component/EventDispatcher",
"source": {
"type": "git",
"url": "https://github.com/symfony/EventDispatcher.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/dependency-injection": "~2.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\EventDispatcher\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com",
"time": "2013-05-13 14:36:40"
},
{
"name": "symfony/filesystem",
"version": "v2.3.2",
"target-dir": "Symfony/Component/Filesystem",
"source": {
"type": "git",
"url": "https://github.com/symfony/Filesystem.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Filesystem/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Filesystem\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Filesystem Component",
"homepage": "http://symfony.com",
"time": "2013-06-04 15:02:05"
},
{
"name": "symfony/form",
"version": "v2.3.2",
"target-dir": "Symfony/Component/Form",
"source": {
"type": "git",
"url": "https://github.com/symfony/Form.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Form/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/event-dispatcher": "~2.1",
"symfony/intl": "~2.3",
"symfony/options-resolver": "~2.1",
"symfony/property-access": "~2.2"
},
"require-dev": {
"symfony/http-foundation": "~2.2",
"symfony/validator": "~2.2"
},
"suggest": {
"symfony/http-foundation": "",
"symfony/validator": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Form\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Form Component",
"homepage": "http://symfony.com",
"time": "2013-07-01 12:24:43"
},
{
"name": "symfony/icu",
"version": "v1.0.0",
"target-dir": "Symfony/Component/Icu",
"source": {
"type": "git",
"url": "https://github.com/symfony/Icu.git",
"reference": "v1.0.0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Icu/zipball/v1.0.0",
"reference": "v1.0.0",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/intl": ">=2.3,<3.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Symfony\\Component\\Icu\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
}
],
"description": "Contains an excerpt of the ICU data and classes to load it.",
"homepage": "http://symfony.com",
"keywords": [
"icu",
"intl"
],
"time": "2013-06-03 18:32:07"
},
{
"name": "symfony/intl",
"version": "v2.3.2",
"target-dir": "Symfony/Component/Intl",
"source": {
"type": "git",
"url": "https://github.com/symfony/Intl.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Intl/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/icu": "~1.0-RC"
},
"require-dev": {
"symfony/filesystem": ">=2.1"
},
"suggest": {
"ext-intl": "to use the component with locales other than \"en\""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Intl\\": ""
},
"classmap": [
"Symfony/Component/Intl/Resources/stubs"
],
"files": [
"Symfony/Component/Intl/Resources/stubs/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Igor Wiedler",
"email": "igor@wiedler.ch",
"homepage": "http://wiedler.ch/igor/"
},
{
"name": "Bernhard Schussek",
"email": "bschussek@gmail.com"
},
{
"name": "Eriksen Costa",
"email": "eriksen.costa@infranology.com.br"
}
],
"description": "A PHP replacement layer for the C intl extension that includes additional data from the ICU library.",
"homepage": "http://symfony.com",
"keywords": [
"i18n",
"icu",
"internationalization",
"intl",
"l10n",
"localization"
],
"time": "2013-07-08 13:00:35"
},
{
"name": "symfony/options-resolver",
"version": "v2.3.2",
"target-dir": "Symfony/Component/OptionsResolver",
"source": {
"type": "git",
"url": "https://github.com/symfony/OptionsResolver.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/OptionsResolver/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\OptionsResolver\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony OptionsResolver Component",
"homepage": "http://symfony.com",
"keywords": [
"config",
"configuration",
"options"
],
"time": "2013-04-11 06:50:46"
},
{
"name": "symfony/property-access",
"version": "v2.3.2",
"target-dir": "Symfony/Component/PropertyAccess",
"source": {
"type": "git",
"url": "https://github.com/symfony/PropertyAccess.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/PropertyAccess/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\PropertyAccess\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony PropertyAccess Component",
"homepage": "http://symfony.com",
"keywords": [
"access",
"array",
"extraction",
"index",
"injection",
"object",
"property",
"property path",
"reflection"
],
"time": "2013-07-01 12:24:43"
},
{
"name": "symfony/routing",
"version": "v2.3.2",
"target-dir": "Symfony/Component/Routing",
"source": {
"type": "git",
"url": "https://github.com/symfony/Routing.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Routing/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"doctrine/common": "~2.2",
"psr/log": "~1.0",
"symfony/config": "~2.2",
"symfony/yaml": "~2.0"
},
"suggest": {
"doctrine/common": "",
"symfony/config": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Routing\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Routing Component",
"homepage": "http://symfony.com",
"time": "2013-06-23 08:16:02"
},
{
"name": "symfony/translation",
"version": "v2.3.2",
"target-dir": "Symfony/Component/Translation",
"source": {
"type": "git",
"url": "https://github.com/symfony/Translation.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Translation/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/config": "~2.0",
"symfony/yaml": "~2.2"
},
"suggest": {
"symfony/config": "",
"symfony/yaml": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Component\\Translation\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Translation Component",
"homepage": "http://symfony.com",
"time": "2013-05-13 14:36:40"
},
{
"name": "symfony/twig-bridge",
"version": "v2.3.2",
"target-dir": "Symfony/Bridge/Twig",
"source": {
"type": "git",
"url": "https://github.com/symfony/TwigBridge.git",
"reference": "v2.3.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/TwigBridge/zipball/v2.3.2",
"reference": "v2.3.2",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"twig/twig": "~1.11"
},
"require-dev": {
"symfony/form": "2.2.*",
"symfony/http-kernel": "~2.2",
"symfony/routing": "~2.2",
"symfony/security": "~2.0",
"symfony/templating": "~2.1",
"symfony/translation": "~2.2",
"symfony/yaml": "~2.0"
},
"suggest": {
"symfony/form": "",
"symfony/http-kernel": "",
"symfony/routing": "",
"symfony/security": "",
"symfony/templating": "",
"symfony/translation": "",
"symfony/yaml": ""
},
"type": "symfony-bridge",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-0": {
"Symfony\\Bridge\\Twig\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Twig Bridge",
"homepage": "http://symfony.com",
"time": "2013-05-16 10:19:58"
},
{
"name": "twig/extensions",
"version": "v1.0.0",
"source": {
"type": "git",
"url": "https://github.com/fabpot/Twig-extensions.git",
"reference": "v1.0.0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fabpot/Twig-extensions/zipball/v1.0.0",
"reference": "v1.0.0",
"shasum": ""
},
"require": {
"twig/twig": "1.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Twig_Extensions_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Common additional features for Twig that do not directly belong in core",
"homepage": "https://github.com/fabpot/Twig-extensions",
"keywords": [
"debug",
"i18n",
"text"
],
"time": "2013-02-28 14:21:30"
},
{
"name": "twig/twig",
"version": "v1.13.2",
"source": {
"type": "git",
"url": "https://github.com/fabpot/Twig.git",
"reference": "v1.13.2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.13.2",
"reference": "v1.13.2",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.13-dev"
}
},
"autoload": {
"psr-0": {
"Twig_": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "http://twig.sensiolabs.org",
"keywords": [
"templating"
],
"time": "2013-08-03 15:35:31"
},
{
"name": "umpirsky/twig-gettext-extractor",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/umpirsky/Twig-Gettext-Extractor.git",
"reference": "1.1.3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/umpirsky/Twig-Gettext-Extractor/zipball/1.1.3",
"reference": "1.1.3",
"shasum": ""
},
"require": {
"php": ">=5.3.3",
"symfony/filesystem": ">=2.0,<3.0",
"symfony/form": ">=2.0,<3.0",
"symfony/routing": ">=2.0,<3.0",
"symfony/translation": ">=2.0,<3.0",
"symfony/twig-bridge": ">=2.0,<3.0",
"twig/extensions": "1.0.*",
"twig/twig": ">=1.2.0,<2.0-dev"
},
"require-dev": {
"symfony/config": "2.1.*"
},
"bin": [
"twig-gettext-extractor"
],
"type": "application",
"autoload": {
"psr-0": {
"Twig\\Gettext": "."
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Саша Стаменковић",
"email": "umpirsky@gmail.com",
"homepage": "http://umpirsky.com"
}
],
"description": "The Twig Gettext Extractor is Poedit friendly tool which extracts translations from twig templates.",
"time": "2013-02-14 16:41:48"
}
],
"packages-dev": [
],
"aliases": [
],
"minimum-stability": "stable",
"stability-flags": [
],
"platform": [
],
"platform-dev": [
]
}

View File

@ -1,90 +0,0 @@
/*** GENERAL ***/
body {
color: #fff;
background-color: #0d0d0d;
}
a, a:hover, a:visited {
color: #fff;
}
#main ul#links li a.current {
background-color: #000;
color: #fff;
}
#links a:hover, .backhome a:hover{
background-color: #fff;
color: #000;
}
input[type=submit].delete {
background : url('../img/dark/remove.png') no-repeat center center;
color : transparent;
}
#main .entrie {
color: #fff;
background-color: #000;
border: 1px solid #fff;
}
#main .entrie h2 a:hover {
color: #29B1E3;
}
a.fav span {
background: url('../img/dark/star-on.png') no-repeat;
}
a.fav span:hover {
background: url('../img/dark/star-off.png') no-repeat;
}
a.fav-off span {
background: url('../img/dark/star-off.png') no-repeat;
}
a.fav-off span:hover {
background: url('../img/dark/star-on.png') no-repeat;
}
a.archive span {
background: url('../img/dark/checkmark-on.png') no-repeat;
}
a.archive span:hover {
background: url('../img/dark/checkmark-off.png') no-repeat;
}
a.archive-off span {
background: url('../img/dark/checkmark-off.png') no-repeat;
}
a.archive-off span:hover {
background: url('../img/dark/checkmark-on.png') no-repeat;
}
/*** ***/
/*** ARTICLE PAGE ***/
body.article {
color: #fff;
background-color: #0d0d0d;
}
#article header {
border-bottom: 1px solid #222222;
}
#article article {
border-bottom: 1px solid #222222;
}
.vieworiginal a {
color: #888888;
}
.entrie {
background-color: #fff;
}

View File

@ -1,90 +0,0 @@
/*** GENERAL ***/
body {
color: #222222;
background-color: #F1F1F1;
}
a, a:hover, a:visited {
color: #000;
}
#main ul#links li a.current {
background-color: #000;
color: #fff;
}
#links a:hover, .backhome a:hover{
background-color: #040707;
color: #F1F1F1;
}
input[type=submit].delete {
background : url('../img/light/remove.png') no-repeat center center;
color : transparent;
}
#main .entrie {
color: #2e2e2e;
background-color: #ffffff;
border: 1px solid #000;
}
#main .entrie h2 a:hover {
color: #F5BE00;
}
a.fav span {
background: url('../img/light/star-on.png') no-repeat;
}
a.fav span:hover {
background: url('../img/light/star-off.png') no-repeat;
}
a.fav-off span {
background: url('../img/light/star-off.png') no-repeat;
}
a.fav-off span:hover {
background: url('../img/light/star-on.png') no-repeat;
}
a.archive span {
background: url('../img/light/checkmark-on.png') no-repeat;
}
a.archive span:hover {
background: url('../img/light/checkmark-off.png') no-repeat;
}
a.archive-off span {
background: url('../img/light/checkmark-off.png') no-repeat;
}
a.archive-off span:hover {
background: url('../img/light/checkmark-on.png') no-repeat;
}
/*** ***/
/*** ARTICLE PAGE ***/
body.article {
color: #222222;
background-color: #F1F1F1;
}
#article header {
border-bottom: 1px solid #222222;
}
#article article {
border-bottom: 1px solid #222222;
}
.vieworiginal a {
color: #888888;
}
.entrie {
background-color: #fff;
}

View File

@ -1,217 +0,0 @@
/*** GENERAL ***/
body {
font: 20px/1.3em Palatino,Georgia,serif;
margin: 10px;
}
header {
text-align: center;
}
#main ul#links {
padding: 0;
list-style-type: none;
text-align: center;
}
#main ul#links li {
display: inline;
}
#main ul#links li a.current {
-webkit-border-radius: 2px;
border-radius: 2px;
}
#main ul#sort {
padding: 0;
list-style-type: none;
text-align: center;
}
#main ul#sort li {
display: inline;
font-size: 0.9em;
}
#main ul#sort img:hover {
cursor: pointer;
}
#main, #article {
margin: 0 auto;
}
#links a, .backhome a{
text-decoration: none;
padding: 5px 10px;
}
#links a:hover, .backhome a:hover{
-webkit-border-radius: 2px;
border-radius: 2px;
}
footer {
text-align: right;
}
/*** ***/
/*** LOGIN FORM ***/
ul#login li {
list-style-type: none;
}
/*** ***/
/*** LINKS DISPLAY ***/
#main a.tool {
text-decoration: none;
cursor: pointer;
}
input[type=submit].delete {
width : 16px;
height :16px;
border : none;
cursor: pointer;
font-size : 0;
}
#main #content {
margin-top: 20px;
}
#main .entrie {
padding: 15px;
min-height: 8em;
border: 1px solid;
}
#main .entrie h2 a {
text-decoration: none;
}
.tools {
text-align: right;
}
.tools ul {
padding: 0; margin: 0;
list-style-type: none;
}
.tools ul li {
line-height: 20px;
}
.tools a.tool {
cursor: pointer;
}
#article .tools {
position: relative;
display: inline;
top: 0px;
right: 0px;
width: 100%;
text-align: left;
}
#article.tools ul li{
display: inline;
}
#main .entrie .tools a.tool span, #article .tools a.tool span {
display: inline-block;
width: 16px;
height: 16px;
}
/*** ***/
/*** ARTICLE PAGE ***/
body.article {
font: 20px/1.3em Palatino,Georgia,serif;
}
#article header {
text-align: left;
}
#article header a {
text-decoration: none;
}
.vieworiginal a {
text-decoration: none;
}
.backhome {
display: inline;
}
/*** ***/
#main
{
max-width: 60em; /* 960 px */
margin: 0 auto;
}
#content
{
width: 103.125%; /* 990px */
overflow: hidden;
margin-left: -1.562%; /* 15px */
margin-bottom: -1.875em; /* 30px */
}
.entrie
{
width: 30.303%; /* 300px */
background-color: #fff;
float: left;
margin: 0 1.515% 1.875em; /* 15px 30px */
}
@media only screen and ( max-width: 40em ) /* 640px */
{
.entrie
{
width: 46.876%; /* 305px */
margin-bottom: 0.938em; /* 15px */
}
}
@media only screen and ( max-width: 20em ) /* 320px */
{
#content
{
width: 100%;
margin-left: 0;
}
.entrie
{
width: 100%;
margin-left: 0;
margin-right: 0;
}
}
/*** ***/
/*** MESSAGES ***/
.messages { width: 100%; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; }
.messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; }
/*.messages:hover a.closeMessage { visibility:visible; }*/
.messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; }
.messages.error { border: 1px solid #C42608; color: #c00 !important; background: #FFF0EF; }
.messages.error p { background: url(../img/messages/cross.png ) no-repeat 0px 50%; color:#c00 !important; }
.messages.success {background: #E0FBCC; border: 1px solid #6DC70C; }
.messages.success p { background: url(../img/messages/tick.png) no-repeat 0px 50%; color: #2B6301 !important; }
.messages.warning { background: #FFFCD3; border: 1px solid #EBCD41; color: #000; }
.messages.warning p { background: url(../img/messages/warning.png ) no-repeat 0px 50%; color: #5F4E01; }
.messages.information, .messages.info { background: #DFEBFB; border: 1px solid #82AEE7; }
.messages.information p, .messages.info p { background: url(../img/messages/help.png ) no-repeat 0px 50%; color: #064393; }
.messages.information a { text-decoration: underline; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 911 B

View File

@ -1,50 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
set_time_limit(0);
include dirname(__FILE__).'/inc/config.php';
include dirname(__FILE__).'/inc/simple_html_dom.php';
if (!isset($_GET['start'])) {
echo 'Please execute the import script locally, it can take a very long time. <br /><a href="import.php?start">Bye bye Pocket, let\'s go !</a>';
}
else {
$html = new simple_html_dom();
$html->load_file('ril_export.html');
$read = 0;
$errors = array();
foreach($html->find('ul') as $ul)
{
foreach($ul->find('li') as $li)
{
$a = $li->find('a');
$url = $a[0]->href;
action_to_do('add', $url);
if ($read == '1') {
$last_id = $db->getHandle()->lastInsertId();
$sql_update = "UPDATE entries SET is_read=~is_read WHERE id=?";
$params_update = array($last_id);
$query_update = $db->getHandle()->prepare($sql_update);
$query_update->execute($params_update);
}
}
# Pocket génère un fichier HTML avec deux <ul>
# Le premier concerne les éléments non lus
# Le second concerne les éléments archivés
$read = 1;
}
echo 'Import from Pocket completed. <a href="index.php">Welcome to #poche !</a>';
logm('import from pocket completed');
}

View File

@ -106,5 +106,4 @@ class JSLikeHTMLElement extends DOMElement
{
return '['.$this->tagName.']';
}
}
?>
}

1138
inc/3rdparty/Readability.php vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -93,7 +93,7 @@ class Session
// Force logout
public static function logout()
{
unset($_SESSION['uid'],$_SESSION['info'],$_SESSION['expires_on'],$_SESSION['tokens']);
unset($_SESSION['uid'],$_SESSION['info'],$_SESSION['expires_on'],$_SESSION['tokens'], $_SESSION['login'], $_SESSION['pass'], $_SESSION['poche_user']);
}
// Make sure user is logged in.

460
inc/class.messages.php → inc/3rdparty/class.messages.php vendored Normal file → Executable file
View File

@ -1,231 +1,231 @@
<?php
//--------------------------------------------------------------------------------------------------
// Session-Based Flash Messages v1.0
// Copyright 2012 Mike Everhart (http://mikeeverhart.net)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//------------------------------------------------------------------------------
// Description:
//------------------------------------------------------------------------------
//
// Stores messages in Session data to be easily retrieved later on.
// This class includes four different types of messages:
// - Success
// - Error
// - Warning
// - Information
//
// See README for basic usage instructions, or see samples/index.php for more advanced samples
//
//--------------------------------------------------------------------------------------------------
// Changelog
//--------------------------------------------------------------------------------------------------
//
// 2011-05-15 - v1.0 - Initial Version
//
//--------------------------------------------------------------------------------------------------
class Messages {
//-----------------------------------------------------------------------------------------------
// Class Variables
//-----------------------------------------------------------------------------------------------
var $msgId;
var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );
var $msgClass = 'messages';
var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'></a>\n%s</div>\n";
var $msgBefore = '<p>';
var $msgAfter = "</p>\n";
/**
* Constructor
* @author Mike Everhart
*/
public function __construct() {
// Generate a unique ID for this user and session
$this->msgId = md5(uniqid());
// Create the session array if it doesnt already exist
if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
}
/**
* Add a message to the queue
*
* @author Mike Everhart
*
* @param string $type The type of message to add
* @param string $message The message
* @param string $redirect_to (optional) If set, the user will be redirected to this URL
* @return bool
*
*/
public function add($type, $message, $redirect_to=null) {
if( !isset($_SESSION['flash_messages']) ) return false;
if( !isset($type) || !isset($message[0]) ) return false;
// Replace any shorthand codes with their full version
if( strlen(trim($type)) == 1 ) {
$type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );
// Backwards compatibility...
} elseif( $type == 'information' ) {
$type = 'info';
}
// Make sure it's a valid message type
if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
// If the session array doesn't exist, create it
if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
$_SESSION['flash_messages'][$type][] = $message;
if( !is_null($redirect_to) ) {
header("Location: $redirect_to");
exit();
}
return true;
}
//-----------------------------------------------------------------------------------------------
// display()
// print queued messages to the screen
//-----------------------------------------------------------------------------------------------
/**
* Display the queued messages
*
* @author Mike Everhart
*
* @param string $type Which messages to display
* @param bool $print True = print the messages on the screen
* @return mixed
*
*/
public function display($type='all', $print=true) {
$messages = '';
$data = '';
if( !isset($_SESSION['flash_messages']) ) return false;
if( $type == 'g' || $type == 'growl' ) {
$this->displayGrowlMessages();
return true;
}
// Print a certain type of message?
if( in_array($type, $this->msgTypes) ) {
foreach( $_SESSION['flash_messages'][$type] as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
// Clear the viewed messages
$this->clear($type);
// Print ALL queued messages
} elseif( $type == 'all' ) {
foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
$messages = '';
foreach( $msgArray as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
}
// Clear ALL of the messages
$this->clear();
// Invalid Message Type?
} else {
return false;
}
// Print everything to the screen or return the data
if( $print ) {
echo $data;
} else {
return $data;
}
}
/**
* Check to see if there are any queued error messages
*
* @author Mike Everhart
*
* @return bool true = There ARE error messages
* false = There are NOT any error messages
*
*/
public function hasErrors() {
return empty($_SESSION['flash_messages']['error']) ? false : true;
}
/**
* Check to see if there are any ($type) messages queued
*
* @author Mike Everhart
*
* @param string $type The type of messages to check for
* @return bool
*
*/
public function hasMessages($type=null) {
if( !is_null($type) ) {
if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type];
} else {
foreach( $this->msgTypes as $type ) {
if( !empty($_SESSION['flash_messages']) ) return true;
}
}
return false;
}
/**
* Clear messages from the session data
*
* @author Mike Everhart
*
* @param string $type The type of messages to clear
* @return bool
*
*/
public function clear($type='all') {
if( $type == 'all' ) {
unset($_SESSION['flash_messages']);
} else {
unset($_SESSION['flash_messages'][$type]);
}
return true;
}
public function __toString() { return $this->hasMessages(); }
public function __destruct() {
//$this->clear();
}
} // end class
<?php
//--------------------------------------------------------------------------------------------------
// Session-Based Flash Messages v1.0
// Copyright 2012 Mike Everhart (http://mikeeverhart.net)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//------------------------------------------------------------------------------
// Description:
//------------------------------------------------------------------------------
//
// Stores messages in Session data to be easily retrieved later on.
// This class includes four different types of messages:
// - Success
// - Error
// - Warning
// - Information
//
// See README for basic usage instructions, or see samples/index.php for more advanced samples
//
//--------------------------------------------------------------------------------------------------
// Changelog
//--------------------------------------------------------------------------------------------------
//
// 2011-05-15 - v1.0 - Initial Version
//
//--------------------------------------------------------------------------------------------------
class Messages {
//-----------------------------------------------------------------------------------------------
// Class Variables
//-----------------------------------------------------------------------------------------------
var $msgId;
var $msgTypes = array( 'help', 'info', 'warning', 'success', 'error' );
var $msgClass = 'messages';
var $msgWrapper = "<div class='%s %s'><a href='#' class='closeMessage'>X</a>\n%s</div>\n";
var $msgBefore = '<p>';
var $msgAfter = "</p>\n";
/**
* Constructor
* @author Mike Everhart
*/
public function __construct() {
// Generate a unique ID for this user and session
$this->msgId = md5(uniqid());
// Create the session array if it doesnt already exist
if( !array_key_exists('flash_messages', $_SESSION) ) $_SESSION['flash_messages'] = array();
}
/**
* Add a message to the queue
*
* @author Mike Everhart
*
* @param string $type The type of message to add
* @param string $message The message
* @param string $redirect_to (optional) If set, the user will be redirected to this URL
* @return bool
*
*/
public function add($type, $message, $redirect_to=null) {
if( !isset($_SESSION['flash_messages']) ) return false;
if( !isset($type) || !isset($message[0]) ) return false;
// Replace any shorthand codes with their full version
if( strlen(trim($type)) == 1 ) {
$type = str_replace( array('h', 'i', 'w', 'e', 's'), array('help', 'info', 'warning', 'error', 'success'), $type );
// Backwards compatibility...
} elseif( $type == 'information' ) {
$type = 'info';
}
// Make sure it's a valid message type
if( !in_array($type, $this->msgTypes) ) die('"' . strip_tags($type) . '" is not a valid message type!' );
// If the session array doesn't exist, create it
if( !array_key_exists( $type, $_SESSION['flash_messages'] ) ) $_SESSION['flash_messages'][$type] = array();
$_SESSION['flash_messages'][$type][] = $message;
if( !is_null($redirect_to) ) {
header("Location: $redirect_to");
exit();
}
return true;
}
//-----------------------------------------------------------------------------------------------
// display()
// print queued messages to the screen
//-----------------------------------------------------------------------------------------------
/**
* Display the queued messages
*
* @author Mike Everhart
*
* @param string $type Which messages to display
* @param bool $print True = print the messages on the screen
* @return mixed
*
*/
public function display($type='all', $print=true) {
$messages = '';
$data = '';
if( !isset($_SESSION['flash_messages']) ) return false;
if( $type == 'g' || $type == 'growl' ) {
$this->displayGrowlMessages();
return true;
}
// Print a certain type of message?
if( in_array($type, $this->msgTypes) ) {
foreach( $_SESSION['flash_messages'][$type] as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
// Clear the viewed messages
$this->clear($type);
// Print ALL queued messages
} elseif( $type == 'all' ) {
foreach( $_SESSION['flash_messages'] as $type => $msgArray ) {
$messages = '';
foreach( $msgArray as $msg ) {
$messages .= $this->msgBefore . $msg . $this->msgAfter;
}
$data .= sprintf($this->msgWrapper, $this->msgClass, $type, $messages);
}
// Clear ALL of the messages
$this->clear();
// Invalid Message Type?
} else {
return false;
}
// Print everything to the screen or return the data
if( $print ) {
echo $data;
} else {
return $data;
}
}
/**
* Check to see if there are any queued error messages
*
* @author Mike Everhart
*
* @return bool true = There ARE error messages
* false = There are NOT any error messages
*
*/
public function hasErrors() {
return empty($_SESSION['flash_messages']['error']) ? false : true;
}
/**
* Check to see if there are any ($type) messages queued
*
* @author Mike Everhart
*
* @param string $type The type of messages to check for
* @return bool
*
*/
public function hasMessages($type=null) {
if( !is_null($type) ) {
if( !empty($_SESSION['flash_messages'][$type]) ) return $_SESSION['flash_messages'][$type];
} else {
foreach( $this->msgTypes as $type ) {
if( !empty($_SESSION['flash_messages']) ) return true;
}
}
return false;
}
/**
* Clear messages from the session data
*
* @author Mike Everhart
*
* @param string $type The type of messages to clear
* @return bool
*
*/
public function clear($type='all') {
if( $type == 'all' ) {
unset($_SESSION['flash_messages']);
} else {
unset($_SESSION['flash_messages'][$type]);
}
return true;
}
public function __toString() { return $this->hasMessages(); }
public function __destruct() {
//$this->clear();
}
} // end class
?>

202
inc/3rdparty/paginator.php vendored Normal file
View File

@ -0,0 +1,202 @@
<?php
/*
* PHP Pagination Class
*
* @author David Carr - dave@daveismyname.com - http://www.daveismyname.com
* @version 1.0
* @date October 20, 2013
*/
class Paginator{
/**
* set the number of items per page.
*
* @var numeric
*/
private $_perPage;
/**
* set get parameter for fetching the page number
*
* @var string
*/
private $_instance;
/**
* sets the page number.
*
* @var numeric
*/
private $_page;
/**
* set the limit for the data source
*
* @var string
*/
private $_limit;
/**
* set the total number of records/items.
*
* @var numeric
*/
private $_totalRows = 0;
/**
* __construct
*
* pass values when class is istantiated
*
* @param numeric $_perPage sets the number of iteems per page
* @param numeric $_instance sets the instance for the GET parameter
*/
public function __construct($perPage,$instance){
$this->_instance = $instance;
$this->_perPage = $perPage;
$this->set_instance();
}
/**
* get_start
*
* creates the starting point for limiting the dataset
* @return numeric
*/
private function get_start(){
return ($this->_page * $this->_perPage) - $this->_perPage;
}
/**
* set_instance
*
* sets the instance parameter, if numeric value is 0 then set to 1
*
* @var numeric
*/
private function set_instance(){
$this->_page = (int) (!isset($_GET[$this->_instance]) ? 1 : $_GET[$this->_instance]);
$this->_page = ($this->_page == 0 ? 1 : $this->_page);
}
/**
* set_total
*
* collect a numberic value and assigns it to the totalRows
*
* @var numeric
*/
public function set_total($_totalRows){
$this->_totalRows = $_totalRows;
}
/**
* get_limit
*
* returns the limit for the data source, calling the get_start method and passing in the number of items perp page
*
* @return string
*/
public function get_limit(){
if (STORAGE == 'postgres') {
return "LIMIT ".$this->_perPage." OFFSET ".$this->get_start();
} else {
return "LIMIT ".$this->get_start().",".$this->_perPage;
}
}
/**
* page_links
*
* create the html links for navigating through the dataset
*
* @var sting $path optionally set the path for the link
* @var sting $ext optionally pass in extra parameters to the GET
* @return string returns the html menu
*/
public function page_links($path='?',$ext=null)
{
$adjacents = "2";
$prev = $this->_page - 1;
$next = $this->_page + 1;
$lastpage = ceil($this->_totalRows/$this->_perPage);
$lpm1 = $lastpage - 1;
$pagination = "";
if($lastpage > 1)
{
$pagination .= "<div class='pagination'>";
if ($this->_page > 1)
$pagination.= "<a href='".$path."$this->_instance=$prev"."$ext'>« previous</a>";
else
$pagination.= "<span class='disabled'>« previous</span>";
if ($lastpage < 7 + ($adjacents * 2))
{
for ($counter = 1; $counter <= $lastpage; $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
}
elseif($lastpage > 5 + ($adjacents * 2))
{
if($this->_page < 1 + ($adjacents * 2))
{
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
$pagination.= "...";
$pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
$pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
}
elseif($lastpage - ($adjacents * 2) > $this->_page && $this->_page > ($adjacents * 2))
{
$pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
$pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
$pagination.= "...";
for ($counter = $this->_page - $adjacents; $counter <= $this->_page + $adjacents; $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
$pagination.= "..";
$pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
$pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
}
else
{
$pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
$pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
$pagination.= "..";
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
}
}
if ($this->_page < $counter - 1)
$pagination.= "<a href='".$path."$this->_instance=$next"."$ext'>next »</a>";
else
$pagination.= "<span class='disabled'>next »</span>";
$pagination.= "</div>\n";
}
return $pagination;
}
}

View File

@ -1,265 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class MyTool
{
public static function initPhp()
{
define('START_TIME', microtime(true));
if (phpversion() < 5) {
die("Argh you don't have PHP 5 !");
}
error_reporting(E_ALL);
function stripslashesDeep($value) {
return is_array($value)
? array_map('stripslashesDeep', $value)
: stripslashes($value);
}
if (get_magic_quotes_gpc()) {
$_POST = array_map('stripslashesDeep', $_POST);
$_GET = array_map('stripslashesDeep', $_GET);
$_COOKIE = array_map('stripslashesDeep', $_COOKIE);
}
ob_start();
register_shutdown_function('ob_end_flush');
}
public static function isUrl($url)
{
// http://neo22s.com/check-if-url-exists-and-is-online-php/
$pattern='|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i';
return preg_match($pattern, $url);
}
public static function isEmail($email)
{
$pattern = "/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2, 4}$/i";
return (preg_match($pattern, $email));
}
public static function formatBBCode($text)
{
$replace = array(
'/\[m\](.+?)\[\/m\]/is'
=> '/* moderate */',
'/\[b\](.+?)\[\/b\]/is'
=> '<strong>$1</strong>',
'/\[i\](.+?)\[\/i\]/is'
=> '<em>$1</em>',
'/\[s\](.+?)\[\/s\]/is'
=> '<del>$1</del>',
'/\[u\](.+?)\[\/u\]/is'
=> '<span style="text-decoration: underline;">$1</span>',
'/\[url\](.+?)\[\/url]/is'
=> '<a href="$1">$1</a>',
'/\[url=(\w+:\/\/[^\]]+)\](.+?)\[\/url]/is'
=> '<a href="$1">$2</a>',
'/\[quote\](.+?)\[\/quote\]/is'
=> '<blockquote>$1</blockquote>',
'/\[code\](.+?)\[\/code\]/is'
=> '<code>$1</code>',
'/\[([^[]+)\|([^[]+)\]/is'
=> '<a href="$2">$1</a>'
);
$text = preg_replace(
array_keys($replace),
array_values($replace),
$text
);
return $text;
}
public static function formatText($text)
{
$text = preg_replace_callback(
'/<code_html>(.*?)<\/code_html>/is',
create_function(
'$matches',
'return htmlspecialchars($matches[1]);'
),
$text
);
$text = preg_replace_callback(
'/<code_php>(.*?)<\/code_php>/is',
create_function(
'$matches',
'return highlight_string("<?php $matches[1] ?>", true);'
),
$text
);
$text = preg_replace('/<br \/>/is', '', $text);
$text = preg_replace(
'#(^|\s)([a-z]+://([^\s\w/]?[\w/])*)(\s|$)#im',
'\\1<a href="\\2">\\2</a>\\4',
$text
);
$text = preg_replace(
'#(^|\s)wp:?([a-z]{2}|):([\w]+)#im',
'\\1<a href="http://\\2.wikipedia.org/wiki/\\3">\\3</a>',
$text
);
$text = str_replace(
'http://.wikipedia.org/wiki/',
'http://www.wikipedia.org/wiki/',
$text
);
$text = str_replace('\wp:', 'wp:', $text);
$text = str_replace('\http:', 'http:', $text);
$text = MyTool::formatBBCode($text);
$text = nl2br($text);
return $text;
}
public static function getUrl()
{
$https = (!empty($_SERVER['HTTPS'])
&& (strtolower($_SERVER['HTTPS']) == 'on'))
|| (isset($_SERVER["SERVER_PORT"])
&& $_SERVER["SERVER_PORT"] == '443'); // HTTPS detection.
$serverport = (!isset($_SERVER["SERVER_PORT"])
|| $_SERVER["SERVER_PORT"] == '80'
|| ($https && $_SERVER["SERVER_PORT"] == '443')
? ''
: ':' . $_SERVER["SERVER_PORT"]);
$scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]);
if (!isset($_SERVER["SERVER_NAME"])) {
return $scriptname;
}
return 'http' . ($https ? 's' : '') . '://'
. $_SERVER["SERVER_NAME"] . $serverport . $scriptname;
}
public static function rrmdir($dir)
{
if (is_dir($dir) && ($d = @opendir($dir))) {
while (($file = @readdir($d)) !== false) {
if ( $file == '.' || $file == '..' ) {
continue;
} else {
unlink($dir . '/' . $file);
}
}
}
}
public static function humanBytes($bytes)
{
$siPrefix = array( 'bytes', 'KB', 'MB', 'GB', 'TB', 'EB', 'ZB', 'YB' );
$base = 1024;
$class = min((int) log($bytes, $base), count($siPrefix) - 1);
$val = sprintf('%1.2f', $bytes / pow($base, $class));
return $val . ' ' . $siPrefix[$class];
}
public static function returnBytes($val)
{
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last)
{
case 'g': $val *= 1024;
case 'm': $val *= 1024;
case 'k': $val *= 1024;
}
return $val;
}
public static function getMaxFileSize()
{
$sizePostMax = MyTool::returnBytes(ini_get('post_max_size'));
$sizeUploadMax = MyTool::returnBytes(ini_get('upload_max_filesize'));
// Return the smaller of two:
return min($sizePostMax, $sizeUploadMax);
}
public static function smallHash($text)
{
$t = rtrim(base64_encode(hash('crc32', $text, true)), '=');
// Get rid of characters which need encoding in URLs.
$t = str_replace('+', '-', $t);
$t = str_replace('/', '_', $t);
$t = str_replace('=', '@', $t);
return $t;
}
public static function renderJson($data)
{
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json; charset=UTF-8');
echo json_encode($data);
exit();
}
public static function grabToLocal($url, $file, $force = false)
{
if ((!file_exists($file) || $force) && in_array('curl', get_loaded_extensions())){
$ch = curl_init ($url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
$raw = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200) {
$fp = fopen($file, 'x');
fwrite($fp, $raw);
fclose($fp);
}
curl_close ($ch);
}
}
public static function redirect($rurl = '')
{
if ($rurl === '') {
// if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_HOST),$_SERVER['SERVER_NAME'])==0)
$rurl = (empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER']);
if (isset($_POST['returnurl'])) {
$rurl = $_POST['returnurl'];
}
}
// prevent loop
if (empty($rurl) || parse_url($rurl, PHP_URL_QUERY) === $_SERVER['QUERY_STRING']) {
$rurl = MyTool::getUrl();
}
if (substr($rurl, 0, 1) !== '?') {
$ref = MyTool::getUrl();
if (substr($rurl, 0, strlen($ref)) !== $ref) {
$rurl = $ref;
}
}
header('Location: '.$rurl);
exit();
}
public static function silence_errors($num, $str)
{
// No-op
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,45 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <nicolas@loeuillet.org>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
define ('POCHE_VERSION', '0.2');
if (!is_dir('db/')) {
@mkdir('db/',0705);
}
define ('ABS_PATH', 'assets/');
define ('CONVERT_LINKS_FOOTNOTES', TRUE);
define ('DOWNLOAD_PICTURES', TRUE);
$storage_type = 'sqlite'; # sqlite or file
include 'functions.php';
require_once 'Readability.php';
require_once 'Encoding.php';
require_once 'rain.tpl.class.php';
require_once 'MyTool.class.php';
require_once 'Session.class.php';
require_once 'store/store.class.php';
require_once 'store/sqlite.class.php';
require_once 'store/file.class.php';
require_once 'class.messages.php';
Session::init();
$store = new $storage_type();
$msg = new Messages();
# initialisation de RainTPL
raintpl::$tpl_dir = './tpl/';
raintpl::$cache_dir = './cache/';
raintpl::$base_url = get_poche_url();
raintpl::configure('path_replace', false);
raintpl::configure('debug', false);
$tpl = new raintpl();
$tpl->assign('msg', $msg);

View File

@ -1,354 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
/**
* Permet de générer l'URL de poche pour le bookmarklet
*/
function get_poche_url()
{
$protocol = "http";
if(isset($_SERVER['HTTPS'])) {
if($_SERVER['HTTPS'] != "off" && $_SERVER['HTTPS'] != "") {
$protocol = "https";
}
}
return $protocol . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
// function define to retrieve url content
function get_external_file($url)
{
$timeout = 15;
// spoofing FireFox 18.0
$useragent="Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0";
if (in_array ('curl', get_loaded_extensions())) {
// Fetch feed from URL
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
// FeedBurner requires a proper USER-AGENT...
curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate");
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
$data = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$httpcodeOK = isset($httpcode) and ($httpcode == 200 or $httpcode == 301);
curl_close($curl);
} else {
// create http context and add timeout and user-agent
$context = stream_context_create(array('http'=>array('timeout' => $timeout,'header'=> "User-Agent: ".$useragent,/*spoot Mozilla Firefox*/'follow_location' => true)));
// only download page lesser than 4MB
$data = @file_get_contents($url, false, $context, -1, 4000000); // We download at most 4 MB from source.
if(isset($http_response_header) and isset($http_response_header[0])) {
$httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== FALSE) or (strpos($http_response_header[0], '301 Moved Permanently') !== FALSE));
}
}
// if response is not empty and response is OK
if (isset($data) and isset($httpcodeOK) and $httpcodeOK ) {
// take charset of page and get it
preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
// if meta tag is found
if (!empty($meta[0])) {
// retrieve encoding in $enc
preg_match('#charset="?(.*)"#si', $meta[0], $enc);
// if charset is found set it otherwise, set it to utf-8
$html_charset = (!empty($enc[1])) ? strtolower($enc[1]) : 'utf-8';
} else {
$html_charset = 'utf-8';
$enc[1] = '';
}
// replace charset of url to charset of page
$data = str_replace('charset='.$enc[1], 'charset='.$html_charset, $data);
return $data;
}
else {
return FALSE;
}
}
/**
* Préparation de l'URL avec récupération du contenu avant insertion en base
*/
function prepare_url($url)
{
$parametres = array();
$url = html_entity_decode(trim($url));
// We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...)
// from shaarli, by sebsauvage
$i=strpos($url,'&utm_source='); if ($i!==false) $url=substr($url,0,$i);
$i=strpos($url,'?utm_source='); if ($i!==false) $url=substr($url,0,$i);
$i=strpos($url,'#xtor=RSS-'); if ($i!==false) $url=substr($url,0,$i);
$title = $url;
if (!preg_match('!^https?://!i', $url))
$url = 'http://' . $url;
$html = Encoding::toUTF8(get_external_file($url,15));
if (isset($html) and strlen($html) > 0)
{
$r = new Readability($html, $url);
$r->convertLinksToFootnotes = CONVERT_LINKS_FOOTNOTES;
if($r->init())
{
$content = $r->articleContent->innerHTML;
$parametres['title'] = $r->articleTitle->innerHTML;
$parametres['content'] = $content;
return $parametres;
}
}
$msg->add('e', 'error during url preparation');
logm('error during url preparation');
return FALSE;
}
/**
* On modifie les URLS des images dans le corps de l'article
*/
function filtre_picture($content, $url, $id)
{
$matches = array();
preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
foreach($matches as $i => $link)
{
$link[1] = trim($link[1]);
if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1]) )
{
$absolute_path = get_absolute_link($link[2],$url);
$filename = basename(parse_url($absolute_path, PHP_URL_PATH));
$directory = create_assets_directory($id);
$fullpath = $directory . '/' . $filename;
download_pictures($absolute_path, $fullpath);
$content = str_replace($matches[$i][2], $fullpath, $content);
}
}
return $content;
}
/**
* Retourne le lien absolu
*/
function get_absolute_link($relative_link, $url)
{
/* return if already absolute URL */
if (parse_url($relative_link, PHP_URL_SCHEME) != '') return $relative_link;
/* queries and anchors */
if ($relative_link[0]=='#' || $relative_link[0]=='?') return $url . $relative_link;
/* parse base URL and convert to local variables:
$scheme, $host, $path */
extract(parse_url($url));
/* remove non-directory element from path */
$path = preg_replace('#/[^/]*$#', '', $path);
/* destroy path if relative url points to root */
if ($relative_link[0] == '/') $path = '';
/* dirty absolute URL */
$abs = $host . $path . '/' . $relative_link;
/* replace '//' or '/./' or '/foo/../' with '/' */
$re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
/* absolute URL is ready! */
return $scheme.'://'.$abs;
}
/**
* Téléchargement des images
*/
function download_pictures($absolute_path, $fullpath)
{
$rawdata = get_external_file($absolute_path);
if(file_exists($fullpath)) {
unlink($fullpath);
}
$fp = fopen($fullpath, 'x');
fwrite($fp, $rawdata);
fclose($fp);
}
/**
* Crée un répertoire de médias pour l'article
*/
function create_assets_directory($id)
{
$assets_path = ABS_PATH;
if(!is_dir($assets_path)) {
mkdir($assets_path, 0705);
}
$article_directory = $assets_path . $id;
if(!is_dir($article_directory)) {
mkdir($article_directory, 0705);
}
return $article_directory;
}
/**
* Suppression du répertoire d'images
*/
function remove_directory($directory)
{
if(is_dir($directory)) {
$files = array_diff(scandir($directory), array('.','..'));
foreach ($files as $file) {
(is_dir("$directory/$file")) ? remove_directory("$directory/$file") : unlink("$directory/$file");
}
return rmdir($directory);
}
}
function display_view($view, $id = 0, $full_head = 'yes')
{
global $tpl, $store, $msg;
switch ($view)
{
case 'export':
$entries = $store->retrieveAll();
$tpl->assign('export', myTool::renderJson($entries));
$tpl->draw('export');
logm('export view');
break;
case 'config':
$tpl->assign('load_all_js', 0);
$tpl->draw('head');
$tpl->draw('home');
$tpl->draw('config');
$tpl->draw('js');
$tpl->draw('footer');
logm('config view');
break;
case 'view':
$entry = $store->retrieveOneById($id);
if ($entry != NULL) {
$tpl->assign('id', $entry['id']);
$tpl->assign('url', $entry['url']);
$tpl->assign('title', $entry['title']);
$tpl->assign('content', $entry['content']);
$tpl->assign('is_fav', $entry['is_fav']);
$tpl->assign('is_read', $entry['is_read']);
$tpl->assign('load_all_js', 0);
$tpl->draw('view');
}
else {
logm('error in view call : entry is NULL');
}
logm('view link #' . $id);
break;
default: # home view
$entries = $store->getEntriesByView($view);
$tpl->assign('entries', $entries);
if ($full_head == 'yes') {
$tpl->assign('load_all_js', 1);
$tpl->draw('head');
$tpl->draw('home');
}
$tpl->draw('entries');
if ($full_head == 'yes') {
$tpl->draw('js');
$tpl->draw('footer');
}
break;
}
}
/**
* Appel d'une action (mark as fav, archive, delete)
*/
function action_to_do($action, $url, $id = 0)
{
global $store, $msg;
switch ($action)
{
case 'add':
if ($url == '')
continue;
if (MyTool::isUrl($url)) {
if($parametres_url = prepare_url($url)) {
$store->add($url, $parametres_url['title'], $parametres_url['content']);
$last_id = $store->getLastId();
if (DOWNLOAD_PICTURES) {
$content = filtre_picture($parametres_url['content'], $url, $last_id);
}
$msg->add('s', 'the link has been added successfully');
}
}
else {
$msg->add('e', 'the link has been added successfully');
logm($url . ' is not a valid url');
}
logm('add link ' . $url);
break;
case 'delete':
remove_directory(ABS_PATH . $id);
$store->deleteById($id);
$msg->add('s', 'the link has been deleted successfully');
logm('delete link #' . $id);
break;
case 'toggle_fav' :
$store->favoriteById($id);
$msg->add('s', 'the favorite toggle has been done successfully');
logm('mark as favorite link #' . $id);
break;
case 'toggle_archive' :
$store->archiveById($id);
$msg->add('s', 'the archive toggle has been done successfully');
logm('archive link #' . $id);
break;
default:
break;
}
}
function logm($message)
{
$t = strval(date('Y/m/d_H:i:s')).' - '.$_SERVER["REMOTE_ADDR"].' - '.strval($message)."\n";
file_put_contents('./log.txt',$t,FILE_APPEND);
}

View File

@ -0,0 +1,223 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class Database {
var $handle;
function __construct()
{
switch (STORAGE) {
case 'sqlite':
$db_path = 'sqlite:' . STORAGE_SQLITE;
$this->handle = new PDO($db_path);
break;
case 'mysql':
$db_path = 'mysql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
$this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
break;
case 'postgres':
$db_path = 'pgsql:host=' . STORAGE_SERVER . ';dbname=' . STORAGE_DB;
$this->handle = new PDO($db_path, STORAGE_USER, STORAGE_PASSWORD);
break;
}
$this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Tools::logm('storage type ' . STORAGE);
}
private function getHandle() {
return $this->handle;
}
public function isInstalled() {
$sql = "SELECT username FROM users";
$query = $this->executeQuery($sql, array());
$hasAdmin = count($query->fetchAll());
if ($hasAdmin == 0)
return FALSE;
return TRUE;
}
public function install($login, $password) {
$sql = 'INSERT INTO users ( username, password, name, email) VALUES (?, ?, ?, ?)';
$params = array($login, $password, $login, ' ');
$query = $this->executeQuery($sql, $params);
$sequence = '';
if (STORAGE == 'postgres') {
$sequence = 'users_id_seq';
}
$id_user = intval($this->getLastId($sequence));
$sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
$params = array($id_user, 'pager', '10');
$query = $this->executeQuery($sql, $params);
$sql = 'INSERT INTO users_config ( user_id, name, value ) VALUES (?, ?, ?)';
$params = array($id_user, 'language', 'en_EN.UTF8');
$query = $this->executeQuery($sql, $params);
return TRUE;
}
private function getConfigUser($id) {
$sql = "SELECT * FROM users_config WHERE user_id = ?";
$query = $this->executeQuery($sql, array($id));
$result = $query->fetchAll();
$user_config = array();
foreach ($result as $key => $value) {
$user_config[$value['name']] = $value['value'];
}
return $user_config;
}
public function login($username, $password) {
$sql = "SELECT * FROM users WHERE username=? AND password=?";
$query = $this->executeQuery($sql, array($username, $password));
$login = $query->fetchAll();
$user = array();
if (isset($login[0])) {
$user['id'] = $login[0]['id'];
$user['username'] = $login[0]['username'];
$user['password'] = $login[0]['password'];
$user['name'] = $login[0]['name'];
$user['email'] = $login[0]['email'];
$user['config'] = $this->getConfigUser($login[0]['id']);
}
return $user;
}
public function updatePassword($id, $password)
{
$sql_update = "UPDATE users SET password=? WHERE id=?";
$params_update = array($password, $id);
$query = $this->executeQuery($sql_update, $params_update);
}
private function executeQuery($sql, $params) {
try
{
$query = $this->getHandle()->prepare($sql);
$query->execute($params);
return $query;
}
catch (Exception $e)
{
Tools::logm('execute query error : '.$e->getMessage());
return FALSE;
}
}
public function retrieveAll($user_id) {
$sql = "SELECT * FROM entries WHERE user_id=? ORDER BY id";
$query = $this->executeQuery($sql, array($user_id));
$entries = $query->fetchAll();
return $entries;
}
public function retrieveOneById($id, $user_id) {
$entry = NULL;
$sql = "SELECT * FROM entries WHERE id=? AND user_id=?";
$params = array(intval($id), $user_id);
$query = $this->executeQuery($sql, $params);
$entry = $query->fetchAll();
return $entry[0];
}
public function getEntriesByView($view, $user_id, $limit = '') {
switch ($_SESSION['sort'])
{
case 'ia':
$order = 'ORDER BY id';
break;
case 'id':
$order = 'ORDER BY id DESC';
break;
case 'ta':
$order = 'ORDER BY lower(title)';
break;
case 'td':
$order = 'ORDER BY lower(title) DESC';
break;
default:
$order = 'ORDER BY id';
break;
}
switch ($view)
{
case 'archive':
$sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? " . $order;
$params = array($user_id, 1);
break;
case 'fav' :
$sql = "SELECT * FROM entries WHERE user_id=? AND is_fav=? " . $order;
$params = array($user_id, 1);
break;
default:
$sql = "SELECT * FROM entries WHERE user_id=? AND is_read=? " . $order;
$params = array($user_id, 0);
break;
}
$sql .= ' ' . $limit;
$query = $this->executeQuery($sql, $params);
$entries = $query->fetchAll();
return $entries;
}
public function updateContent($id, $content, $user_id) {
$sql_action = 'UPDATE entries SET content = ? WHERE id=? AND user_id=?';
$params_action = array($content, $id, $user_id);
$query = $this->executeQuery($sql_action, $params_action);
return $query;
}
public function add($url, $title, $content, $user_id) {
$sql_action = 'INSERT INTO entries ( url, title, content, user_id ) VALUES (?, ?, ?, ?)';
$params_action = array($url, $title, $content, $user_id);
$query = $this->executeQuery($sql_action, $params_action);
return $query;
}
public function deleteById($id, $user_id) {
$sql_action = "DELETE FROM entries WHERE id=? AND user_id=?";
$params_action = array($id, $user_id);
$query = $this->executeQuery($sql_action, $params_action);
return $query;
}
public function favoriteById($id, $user_id) {
$sql_action = "UPDATE entries SET is_fav=NOT is_fav WHERE id=? AND user_id=?";
$params_action = array($id, $user_id);
$query = $this->executeQuery($sql_action, $params_action);
}
public function archiveById($id, $user_id) {
$sql_action = "UPDATE entries SET is_read=NOT is_read WHERE id=? AND user_id=?";
$params_action = array($id, $user_id);
$query = $this->executeQuery($sql_action, $params_action);
}
public function getLastId($column = '') {
return $this->getHandle()->lastInsertId($column);
}
}

491
inc/poche/Poche.class.php Normal file
View File

@ -0,0 +1,491 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class Poche
{
public $user;
public $store;
public $tpl;
public $messages;
public $pagination;
function __construct()
{
if (file_exists('./install') && !DEBUG_POCHE) {
Tools::logm('folder /install exists');
die('To install your poche with sqlite, copy /install/poche.sqlite in /db and delete the folder /install. you have to delete the /install folder before using poche.');
}
$this->store = new Database();
$this->init();
$this->messages = new Messages();
# installation
if(!$this->store->isInstalled())
{
$this->install();
}
}
private function init()
{
Tools::initPhp();
Session::init();
if (isset($_SESSION['poche_user']) && $_SESSION['poche_user'] != array()) {
$this->user = $_SESSION['poche_user'];
}
else {
# fake user, just for install & login screens
$this->user = new User();
$this->user->setConfig($this->getDefaultConfig());
}
# l10n
$language = $this->user->getConfigValue('language');
putenv('LC_ALL=' . $language);
setlocale(LC_ALL, $language);
bindtextdomain($language, LOCALE);
textdomain($language);
# template engine
$loader = new Twig_Loader_Filesystem(TPL);
if (DEBUG_POCHE) {
$twig_params = array();
}
else {
$twig_params = array('cache' => CACHE);
}
$this->tpl = new Twig_Environment($loader, $twig_params);
$this->tpl->addExtension(new Twig_Extensions_Extension_I18n());
# filter to display domain name of an url
$filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
$this->tpl->addFilter($filter);
# filter for reading time
$filter = new Twig_SimpleFilter('getReadingTime', 'Tools::getReadingTime');
$this->tpl->addFilter($filter);
# Pagination
$this->pagination = new Paginator($this->user->getConfigValue('pager'), 'p');
}
private function install()
{
Tools::logm('poche still not installed');
echo $this->tpl->render('install.twig', array(
'token' => Session::getToken()
));
if (isset($_GET['install'])) {
if (($_POST['password'] == $_POST['password_repeat'])
&& $_POST['password'] != "" && $_POST['login'] != "") {
# let's rock, install poche baby !
$this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']));
Session::logout();
Tools::logm('poche is now installed');
Tools::redirect();
}
else {
Tools::logm('error during installation');
Tools::redirect();
}
}
exit();
}
public function getDefaultConfig()
{
return array(
'pager' => PAGINATION,
'language' => LANG,
);
}
/**
* Call action (mark as fav, archive, delete, etc.)
*/
public function action($action, Url $url, $id = 0, $import = FALSE)
{
switch ($action)
{
case 'add':
if($parametres_url = $url->fetchContent()) {
if ($this->store->add($url->getUrl(), $parametres_url['title'], $parametres_url['content'], $this->user->getId())) {
Tools::logm('add link ' . $url->getUrl());
$sequence = '';
if (STORAGE == 'postgres') {
$sequence = 'entries_id_seq';
}
$last_id = $this->store->getLastId($sequence);
if (DOWNLOAD_PICTURES) {
$content = filtre_picture($parametres_url['content'], $url->getUrl(), $last_id);
Tools::logm('updating content article');
$this->store->updateContent($last_id, $content, $this->user->getId());
}
if (!$import) {
$this->messages->add('s', _('the link has been added successfully'));
}
}
else {
if (!$import) {
$this->messages->add('e', _('error during insertion : the link wasn\'t added'));
Tools::logm('error during insertion : the link wasn\'t added ' . $url->getUrl());
}
}
}
else {
if (!$import) {
$this->messages->add('e', _('error during fetching content : the link wasn\'t added'));
Tools::logm('error during content fetch ' . $url->getUrl());
}
}
if (!$import) {
Tools::redirect();
}
break;
case 'delete':
$msg = 'delete link #' . $id;
if ($this->store->deleteById($id, $this->user->getId())) {
if (DOWNLOAD_PICTURES) {
remove_directory(ABS_PATH . $id);
}
$this->messages->add('s', _('the link has been deleted successfully'));
}
else {
$this->messages->add('e', _('the link wasn\'t deleted'));
$msg = 'error : can\'t delete link #' . $id;
}
Tools::logm($msg);
Tools::redirect('?');
break;
case 'toggle_fav' :
$this->store->favoriteById($id, $this->user->getId());
Tools::logm('mark as favorite link #' . $id);
if (!$import) {
Tools::redirect();
}
break;
case 'toggle_archive' :
$this->store->archiveById($id, $this->user->getId());
Tools::logm('archive link #' . $id);
if (!$import) {
Tools::redirect();
}
break;
default:
break;
}
}
function displayView($view, $id = 0)
{
$tpl_vars = array();
switch ($view)
{
case 'config':
$dev = $this->getPocheVersion('dev');
$prod = $this->getPocheVersion('prod');
$compare_dev = version_compare(POCHE_VERSION, $dev);
$compare_prod = version_compare(POCHE_VERSION, $prod);
$tpl_vars = array(
'dev' => $dev,
'prod' => $prod,
'compare_dev' => $compare_dev,
'compare_prod' => $compare_prod,
);
Tools::logm('config view');
break;
case 'view':
$entry = $this->store->retrieveOneById($id, $this->user->getId());
if ($entry != NULL) {
Tools::logm('view link #' . $id);
$content = $entry['content'];
if (function_exists('tidy_parse_string')) {
$tidy = tidy_parse_string($content, array('indent'=>true, 'show-body-only' => true), 'UTF8');
$tidy->cleanRepair();
$content = $tidy->value;
}
$tpl_vars = array(
'entry' => $entry,
'content' => $content,
);
}
else {
Tools::logm('error in view call : entry is null');
}
break;
default: # home view
$entries = $this->store->getEntriesByView($view, $this->user->getId());
$this->pagination->set_total(count($entries));
$page_links = $this->pagination->page_links('?view=' . $view . '&sort=' . $_SESSION['sort'] . '&');
$datas = $this->store->getEntriesByView($view, $this->user->getId(), $this->pagination->get_limit());
$tpl_vars = array(
'entries' => $datas,
'page_links' => $page_links,
);
Tools::logm('display ' . $view . ' view');
break;
}
return $tpl_vars;
}
/**
* update the password of the current user.
* if MODE_DEMO is TRUE, the password can't be updated.
* @todo add the return value
* @todo set the new password in function header like this updatePassword($newPassword)
* @return boolean
*/
public function updatePassword()
{
if (MODE_DEMO) {
$this->messages->add('i', _('in demo mode, you can\'t update your password'));
Tools::logm('in demo mode, you can\'t do this');
Tools::redirect('?view=config');
}
else {
if (isset($_POST['password']) && isset($_POST['password_repeat'])) {
if ($_POST['password'] == $_POST['password_repeat'] && $_POST['password'] != "") {
$this->messages->add('s', _('your password has been updated'));
$this->store->updatePassword($this->user->getId(), Tools::encodeString($_POST['password'] . $this->user->getUsername()));
Session::logout();
Tools::logm('password updated');
Tools::redirect();
}
else {
$this->messages->add('e', _('the two fields have to be filled & the password must be the same in the two fields'));
Tools::redirect('?view=config');
}
}
}
}
/**
* checks if login & password are correct and save the user in session.
* it redirects the user to the $referer link
* @param string $referer the url to redirect after login
* @todo add the return value
* @return boolean
*/
public function login($referer)
{
if (!empty($_POST['login']) && !empty($_POST['password'])) {
$user = $this->store->login($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']));
if ($user != array()) {
# Save login into Session
Session::login($user['username'], $user['password'], $_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']), array('poche_user' => new User($user)));
$this->messages->add('s', _('welcome to your poche'));
if (!empty($_POST['longlastingsession'])) {
$_SESSION['longlastingsession'] = 31536000;
$_SESSION['expires_on'] = time() + $_SESSION['longlastingsession'];
session_set_cookie_params($_SESSION['longlastingsession']);
} else {
session_set_cookie_params(0);
}
session_regenerate_id(true);
Tools::logm('login successful');
Tools::redirect($referer);
}
$this->messages->add('e', _('login failed: bad login or password'));
Tools::logm('login failed');
Tools::redirect();
} else {
$this->messages->add('e', _('login failed: you have to fill all fields'));
Tools::logm('login failed');
Tools::redirect();
}
}
/**
* log out the poche user. It cleans the session.
* @todo add the return value
* @return boolean
*/
public function logout()
{
$this->user = array();
Session::logout();
$this->messages->add('s', _('see you soon!'));
Tools::logm('logout');
Tools::redirect();
}
/**
* import from Instapaper. poche needs a ./instapaper-export.html file
* @todo add the return value
* @return boolean
*/
private function importFromInstapaper()
{
# TODO gestion des articles favs
$html = new simple_html_dom();
$html->load_file('./instapaper-export.html');
Tools::logm('starting import from instapaper');
$read = 0;
$errors = array();
foreach($html->find('ol') as $ul)
{
foreach($ul->find('li') as $li)
{
$a = $li->find('a');
$url = new Url(base64_encode($a[0]->href));
$this->action('add', $url, 0, TRUE);
if ($read == '1') {
$sequence = '';
if (STORAGE == 'postgres') {
$sequence = 'entries_id_seq';
}
$last_id = $this->store->getLastId($sequence);
$this->action('toggle_archive', $url, $last_id, TRUE);
}
}
# the second <ol> is for read links
$read = 1;
}
$this->messages->add('s', _('import from instapaper completed'));
Tools::logm('import from instapaper completed');
Tools::redirect();
}
/**
* import from Pocket. poche needs a ./ril_export.html file
* @todo add the return value
* @return boolean
*/
private function importFromPocket()
{
# TODO gestion des articles favs
$html = new simple_html_dom();
$html->load_file('./ril_export.html');
Tools::logm('starting import from pocket');
$read = 0;
$errors = array();
foreach($html->find('ul') as $ul)
{
foreach($ul->find('li') as $li)
{
$a = $li->find('a');
$url = new Url(base64_encode($a[0]->href));
$this->action('add', $url, 0, TRUE);
if ($read == '1') {
$sequence = '';
if (STORAGE == 'postgres') {
$sequence = 'entries_id_seq';
}
$last_id = $this->store->getLastId($sequence);
$this->action('toggle_archive', $url, $last_id, TRUE);
}
}
# the second <ul> is for read links
$read = 1;
}
$this->messages->add('s', _('import from pocket completed'));
Tools::logm('import from pocket completed');
Tools::redirect();
}
/**
* import from Readability. poche needs a ./readability file
* @todo add the return value
* @return boolean
*/
private function importFromReadability()
{
# TODO gestion des articles lus / favs
$str_data = file_get_contents("./readability");
$data = json_decode($str_data,true);
Tools::logm('starting import from Readability');
foreach ($data as $key => $value) {
$url = '';
foreach ($value as $attr => $attr_value) {
if ($attr == 'article__url') {
$url = new Url(base64_encode($attr_value));
}
$sequence = '';
if (STORAGE == 'postgres') {
$sequence = 'entries_id_seq';
}
// if ($attr_value == 'favorite' && $attr_value == 'true') {
// $last_id = $this->store->getLastId($sequence);
// $this->store->favoriteById($last_id);
// $this->action('toogle_fav', $url, $last_id, TRUE);
// }
if ($attr_value == 'archive' && $attr_value == 'true') {
$last_id = $this->store->getLastId($sequence);
$this->action('toggle_archive', $url, $last_id, TRUE);
}
}
if ($url->isCorrect())
$this->action('add', $url, 0, TRUE);
}
$this->messages->add('s', _('import from Readability completed'));
Tools::logm('import from Readability completed');
Tools::redirect();
}
/**
* import datas into your poche
* @param string $from name of the service to import : pocket, instapaper or readability
* @todo add the return value
* @return boolean
*/
public function import($from)
{
if ($from == 'pocket') {
return $this->importFromPocket();
}
else if ($from == 'readability') {
return $this->importFromReadability();
}
else if ($from == 'instapaper') {
return $this->importFromInstapaper();
}
}
/**
* export poche entries in json
* @return json all poche entries
*/
public function export()
{
$entries = $this->store->retrieveAll($this->user->getId());
echo $this->tpl->render('export.twig', array(
'export' => Tools::renderJson($entries),
));
Tools::logm('export view');
}
/**
* Checks online the latest version of poche and cache it
* @param string $which 'prod' or 'dev'
* @return string latest $which version
*/
private function getPocheVersion($which = 'prod')
{
$cache_file = CACHE . '/' . $which;
# checks if the cached version file exists
if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 86400 ))) {
$version = file_get_contents($cache_file);
} else {
$version = file_get_contents('http://static.inthepoche.com/versions/' . $which);
file_put_contents($cache_file, $version, LOCK_EX);
}
return $version;
}
}

236
inc/poche/Tools.class.php Normal file
View File

@ -0,0 +1,236 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class Tools
{
public static function initPhp()
{
define('START_TIME', microtime(true));
if (phpversion() < 5) {
die(_('Oops, it seems you don\'t have PHP 5.'));
}
error_reporting(E_ALL);
function stripslashesDeep($value) {
return is_array($value)
? array_map('stripslashesDeep', $value)
: stripslashes($value);
}
if (get_magic_quotes_gpc()) {
$_POST = array_map('stripslashesDeep', $_POST);
$_GET = array_map('stripslashesDeep', $_GET);
$_COOKIE = array_map('stripslashesDeep', $_COOKIE);
}
ob_start();
register_shutdown_function('ob_end_flush');
}
public static function getPocheUrl()
{
$https = (!empty($_SERVER['HTTPS'])
&& (strtolower($_SERVER['HTTPS']) == 'on'))
|| (isset($_SERVER["SERVER_PORT"])
&& $_SERVER["SERVER_PORT"] == '443'); // HTTPS detection.
$serverport = (!isset($_SERVER["SERVER_PORT"])
|| $_SERVER["SERVER_PORT"] == '80'
|| ($https && $_SERVER["SERVER_PORT"] == '443')
? '' : ':' . $_SERVER["SERVER_PORT"]);
$scriptname = str_replace('/index.php', '/', $_SERVER["SCRIPT_NAME"]);
if (!isset($_SERVER["SERVER_NAME"])) {
return $scriptname;
}
return 'http' . ($https ? 's' : '') . '://'
. $_SERVER["SERVER_NAME"] . $serverport . $scriptname;
}
public static function redirect($url = '')
{
if ($url === '') {
$url = (empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER']);
if (isset($_POST['returnurl'])) {
$url = $_POST['returnurl'];
}
}
# prevent loop
if (empty($url) || parse_url($url, PHP_URL_QUERY) === $_SERVER['QUERY_STRING']) {
$url = Tools::getPocheUrl();
}
if (substr($url, 0, 1) !== '?') {
$ref = Tools::getPocheUrl();
if (substr($url, 0, strlen($ref)) !== $ref) {
$url = $ref;
}
}
self::logm('redirect to ' . $url);
header('Location: '.$url);
exit();
}
public static function getTplFile($view)
{
$tpl_file = 'home.twig';
switch ($view)
{
case 'install':
$tpl_file = 'install.twig';
break;
case 'import';
$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;
default:
break;
}
return $tpl_file;
}
public static function getFile($url)
{
$timeout = 15;
$useragent = "Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0";
if (in_array ('curl', get_loaded_extensions())) {
# Fetch feed from URL
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
# for ssl, do not verified certificate
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE );
# FeedBurner requires a proper USER-AGENT...
curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate");
curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
$data = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$httpcodeOK = isset($httpcode) and ($httpcode == 200 or $httpcode == 301);
curl_close($curl);
} else {
# create http context and add timeout and user-agent
$context = stream_context_create(
array(
'http' => array(
'timeout' => $timeout,
'header' => "User-Agent: " . $useragent,
'follow_location' => true
),
'ssl' => array(
'verify_peer' => false,
'allow_self_signed' => true
)
)
);
# only download page lesser than 4MB
$data = @file_get_contents($url, false, $context, -1, 4000000);
if (isset($http_response_header) and isset($http_response_header[0])) {
$httpcodeOK = isset($http_response_header) and isset($http_response_header[0]) and ((strpos($http_response_header[0], '200 OK') !== FALSE) or (strpos($http_response_header[0], '301 Moved Permanently') !== FALSE));
}
}
# if response is not empty and response is OK
if (isset($data) and isset($httpcodeOK) and $httpcodeOK) {
# take charset of page and get it
preg_match('#<meta .*charset=.*>#Usi', $data, $meta);
# if meta tag is found
if (!empty($meta[0])) {
preg_match('#charset="?(.*)"#si', $meta[0], $encoding);
# if charset is found set it otherwise, set it to utf-8
$html_charset = (!empty($encoding[1])) ? strtolower($encoding[1]) : 'utf-8';
if (empty($encoding[1])) $encoding[1] = 'utf-8';
} else {
$html_charset = 'utf-8';
$encoding[1] = '';
}
# replace charset of url to charset of page
$data = str_replace('charset=' . $encoding[1], 'charset=' . $html_charset, $data);
return $data;
}
else {
return FALSE;
}
}
public static function renderJson($data)
{
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json; charset=UTF-8');
echo json_encode($data);
exit();
}
public static function logm($message)
{
if (DEBUG_POCHE) {
$t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n";
file_put_contents(CACHE . '/log.txt', $t, FILE_APPEND);
error_log('DEBUG POCHE : ' . $message);
}
}
public static function encodeString($string)
{
return sha1($string . SALT);
}
public static function checkVar($var, $default = '')
{
return ((isset ($_REQUEST["$var"])) ? htmlentities($_REQUEST["$var"]) : $default);
}
public static function getDomain($url)
{
$pieces = parse_url($url);
$domain = isset($pieces['host']) ? $pieces['host'] : '';
if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
return $regs['domain'];
}
return FALSE;
}
public static function getReadingTime($text) {
$word = str_word_count(strip_tags($text));
$minutes = floor($word / 200);
$seconds = floor($word % 200 / (200 / 60));
$time = array('minutes' => $minutes, 'seconds' => $seconds);
return $minutes;
}
}

94
inc/poche/Url.class.php Normal file
View File

@ -0,0 +1,94 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class Url
{
public $url;
function __construct($url)
{
$this->url = base64_decode($url);
}
public function getUrl() {
return $this->url;
}
public function setUrl($url) {
$this->url = $url;
}
public function isCorrect()
{
$pattern = '|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i';
return preg_match($pattern, $this->url);
}
public function clean()
{
$url = html_entity_decode(trim($this->url));
$stuff = strpos($url,'&utm_source=');
if ($stuff !== FALSE)
$url = substr($url, 0, $stuff);
$stuff = strpos($url,'?utm_source=');
if ($stuff !== FALSE)
$url = substr($url, 0, $stuff);
$stuff = strpos($url,'#xtor=RSS-');
if ($stuff !== FALSE)
$url = substr($url, 0, $stuff);
$this->url = $url;
}
public function fetchContent()
{
if ($this->isCorrect()) {
$this->clean();
$html = Encoding::toUTF8(Tools::getFile($this->getUrl()));
# if Tools::getFile() if not able to retrieve HTTPS content, try the same URL with HTTP protocol
if (!preg_match('!^https?://!i', $this->getUrl()) && (!isset($html) || strlen($html) <= 0)) {
$this->setUrl('http://' . $this->getUrl());
$html = Encoding::toUTF8(Tools::getFile($this->getUrl()));
}
if (function_exists('tidy_parse_string')) {
$tidy = tidy_parse_string($html, array(), 'UTF8');
$tidy->cleanRepair();
$html = $tidy->value;
}
$parameters = array();
if (isset($html) and strlen($html) > 0)
{
$readability = new Readability($html, $this->getUrl());
$readability->convertLinksToFootnotes = CONVERT_LINKS_FOOTNOTES;
$readability->revertForcedParagraphElements = REVERT_FORCED_PARAGRAPH_ELEMENTS;
if($readability->init())
{
$content = $readability->articleContent->innerHTML;
$parameters['title'] = $readability->articleTitle->innerHTML;
$parameters['content'] = $content;
return $parameters;
}
}
}
else {
#$msg->add('e', _('error during url preparation : the link is not valid'));
Tools::logm($this->getUrl() . ' is not a valid url');
}
return FALSE;
}
}

50
inc/poche/User.class.php Normal file
View File

@ -0,0 +1,50 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class User
{
public $id;
public $username;
public $name;
public $password;
public $email;
public $config;
function __construct($user = array())
{
if ($user != array()) {
$this->id = $user['id'];
$this->username = $user['username'];
$this->name = $user['name'];
$this->password = $user['password'];
$this->email = $user['email'];
$this->config = $user['config'];
}
}
public function getId()
{
return $this->id;
}
public function getUsername()
{
return $this->username;
}
public function setConfig($config)
{
$this->config = $config;
}
public function getConfigValue($name) {
return (isset($this->config[$name])) ? $this->config[$name] : FALSE;
}
}

61
inc/poche/config.inc.php Normal file
View File

@ -0,0 +1,61 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <nicolas@loeuillet.org>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
# storage
define ('STORAGE','sqlite'); # postgres, mysql, sqlite
define ('STORAGE_SERVER', 'localhost'); # leave blank for sqlite
define ('STORAGE_DB', 'poche'); # only for postgres & mysql
define ('STORAGE_SQLITE', './db/poche.sqlite');
define ('STORAGE_USER', 'postgres'); # leave blank for sqlite
define ('STORAGE_PASSWORD', 'postgres'); # leave blank for sqlite
define ('POCHE_VERSION', '1.0-beta2');
define ('MODE_DEMO', FALSE);
define ('DEBUG_POCHE', FALSE);
define ('CONVERT_LINKS_FOOTNOTES', FALSE);
define ('REVERT_FORCED_PARAGRAPH_ELEMENTS', FALSE);
define ('DOWNLOAD_PICTURES', FALSE);
define ('SHARE_TWITTER', TRUE);
define ('SHARE_MAIL', TRUE);
define ('SALT', '464v54gLLw928uz4zUBqkRJeiPY68zCX');
define ('ABS_PATH', 'assets/');
define ('TPL', './tpl');
define ('LOCALE', './locale');
define ('CACHE', './cache');
define ('LANG', 'en_EN.UTF8');
define ('PAGINATION', '10');
define ('THEME', 'light');
# /!\ Be careful if you change the lines below /!\
require_once './inc/poche/User.class.php';
require_once './inc/poche/Tools.class.php';
require_once './inc/poche/Url.class.php';
require_once './inc/3rdparty/class.messages.php';
require_once './inc/poche/Poche.class.php';
require_once './inc/3rdparty/Readability.php';
require_once './inc/3rdparty/Encoding.php';
require_once './inc/poche/Database.class.php';
require_once './vendor/autoload.php';
require_once './inc/3rdparty/simple_html_dom.php';
require_once './inc/3rdparty/paginator.php';
require_once './inc/3rdparty/Session.class.php';
if (DOWNLOAD_PICTURES) {
require_once './inc/poche/pochePictures.php';
}
$poche = new Poche();
#XSRF protection with token
// if (!empty($_POST)) {
// if (!Session::isToken($_POST['token'])) {
// die(_('Wrong token'));
// }
// unset($_SESSION['tokens']);
// }

110
inc/poche/pochePictures.php Normal file
View File

@ -0,0 +1,110 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
/**
* On modifie les URLS des images dans le corps de l'article
*/
function filtre_picture($content, $url, $id)
{
$matches = array();
preg_match_all('#<\s*(img)[^>]+src="([^"]*)"[^>]*>#Si', $content, $matches, PREG_SET_ORDER);
foreach($matches as $i => $link) {
$link[1] = trim($link[1]);
if (!preg_match('#^(([a-z]+://)|(\#))#', $link[1])) {
$absolute_path = get_absolute_link($link[2],$url);
$filename = basename(parse_url($absolute_path, PHP_URL_PATH));
$directory = create_assets_directory($id);
$fullpath = $directory . '/' . $filename;
download_pictures($absolute_path, $fullpath);
$content = str_replace($matches[$i][2], $fullpath, $content);
}
}
return $content;
}
/**
* Retourne le lien absolu
*/
function get_absolute_link($relative_link, $url) {
/* return if already absolute URL */
if (parse_url($relative_link, PHP_URL_SCHEME) != '') return $relative_link;
/* queries and anchors */
if ($relative_link[0]=='#' || $relative_link[0]=='?') return $url . $relative_link;
/* parse base URL and convert to local variables:
$scheme, $host, $path */
extract(parse_url($url));
/* remove non-directory element from path */
$path = preg_replace('#/[^/]*$#', '', $path);
/* destroy path if relative url points to root */
if ($relative_link[0] == '/') $path = '';
/* dirty absolute URL */
$abs = $host . $path . '/' . $relative_link;
/* replace '//' or '/./' or '/foo/../' with '/' */
$re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
/* absolute URL is ready! */
return $scheme.'://'.$abs;
}
/**
* Téléchargement des images
*/
function download_pictures($absolute_path, $fullpath)
{
$rawdata = Tools::getFile($absolute_path);
if(file_exists($fullpath)) {
unlink($fullpath);
}
$fp = fopen($fullpath, 'x');
fwrite($fp, $rawdata);
fclose($fp);
}
/**
* Crée un répertoire de médias pour l'article
*/
function create_assets_directory($id)
{
$assets_path = ABS_PATH;
if(!is_dir($assets_path)) {
mkdir($assets_path, 0705);
}
$article_directory = $assets_path . $id;
if(!is_dir($article_directory)) {
mkdir($article_directory, 0705);
}
return $article_directory;
}
/**
* Suppression du répertoire d'images
*/
function remove_directory($directory)
{
if(is_dir($directory)) {
$files = array_diff(scandir($directory), array('.','..'));
foreach ($files as $file) {
(is_dir("$directory/$file")) ? remove_directory("$directory/$file") : unlink("$directory/$file");
}
return rmdir($directory);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class File extends Store {
function __construct() {
}
public function add() {
}
public function retrieveOneById($id) {
}
public function retrieveOneByURL($url) {
}
public function deleteById($id) {
}
public function favoriteById($id) {
}
public function archiveById($id) {
}
public function getEntriesByView($view) {
}
public function getLastId() {
}
public function updateContentById($id) {
}
}

View File

@ -1,144 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class Sqlite extends Store {
public static $db_path = 'sqlite:./db/poche.sqlite';
var $handle;
function __construct() {
parent::__construct();
$this->handle = new PDO(self::$db_path);
$this->handle->exec('CREATE TABLE IF NOT EXISTS "entries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE , "title" VARCHAR, "url" VARCHAR UNIQUE , "is_read" INTEGER DEFAULT 0, "is_fav" INTEGER DEFAULT 0, "content" BLOB)');
$this->handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
private function getHandle() {
return $this->handle;
}
private function executeQuery($sql, $params) {
try
{
$query = $this->getHandle()->prepare($sql);
$query->execute($params);
return $query;
}
catch (Exception $e)
{
logm('execute query error : '.$e->getMessage());
}
}
public function retrieveAll() {
$sql = "SELECT * FROM entries ORDER BY id";
$query = $this->executeQuery($sql, array());
$entries = $query->fetchAll();
return $entries;
}
public function retrieveOneById($id) {
parent::__construct();
$entry = NULL;
$sql = "SELECT * FROM entries WHERE id=?";
$params = array(intval($id));
$query = $this->executeQuery($sql, $params);
$entry = $query->fetchAll();
return $entry[0];
}
public function getEntriesByView($view) {
parent::__construct();
switch ($_SESSION['sort'])
{
case 'ia':
$order = 'ORDER BY id';
break;
case 'id':
$order = 'ORDER BY id DESC';
break;
case 'ta':
$order = 'ORDER BY lower(title)';
break;
case 'td':
$order = 'ORDER BY lower(title) DESC';
break;
default:
$order = 'ORDER BY id';
break;
}
switch ($view)
{
case 'archive':
$sql = "SELECT * FROM entries WHERE is_read=? " . $order;
$params = array(-1);
break;
case 'fav' :
$sql = "SELECT * FROM entries WHERE is_fav=? " . $order;
$params = array(-1);
break;
default:
$sql = "SELECT * FROM entries WHERE is_read=? " . $order;
$params = array(0);
break;
}
$query = $this->executeQuery($sql, $params);
$entries = $query->fetchAll();
return $entries;
}
public function add($url, $title, $content) {
parent::__construct();
$sql_action = 'INSERT INTO entries ( url, title, content ) VALUES (?, ?, ?)';
$params_action = array($url, $title, $content);
$query = $this->executeQuery($sql_action, $params_action);
}
public function deleteById($id) {
parent::__construct();
$sql_action = "DELETE FROM entries WHERE id=?";
$params_action = array($id);
$query = $this->executeQuery($sql_action, $params_action);
}
public function favoriteById($id) {
parent::__construct();
$sql_action = "UPDATE entries SET is_fav=~is_fav WHERE id=?";
$params_action = array($id);
$query = $this->executeQuery($sql_action, $params_action);
}
public function archiveById($id) {
parent::__construct();
$sql_action = "UPDATE entries SET is_read=~is_read WHERE id=?";
$params_action = array($id);
$query = $this->executeQuery($sql_action, $params_action);
}
public function getLastId() {
parent::__construct();
return $this->getHandle()->lastInsertId();
}
public function updateContentById($id) {
parent::__construct();
$sql_update = "UPDATE entries SET content=? WHERE id=?";
$params_update = array($content, $id);
$query = $this->executeQuery($sql_update, $params_update);
}
}

View File

@ -1,55 +0,0 @@
<?php
/**
* poche, a read it later open source system
*
* @category poche
* @author Nicolas Lœuillet <support@inthepoche.com>
* @copyright 2013
* @license http://www.wtfpl.net/ see COPYING file
*/
class Store {
function __construct() {
}
public function add() {
}
public function retrieveAll() {
}
public function retrieveOneById($id) {
}
public function retrieveOneByURL($url) {
}
public function deleteById($id) {
}
public function favoriteById($id) {
}
public function archiveById($id) {
}
public function getEntriesByView($view) {
}
public function getLastId() {
}
public function updateContentById($id) {
}
}

View File

@ -8,66 +8,57 @@
* @license http://www.wtfpl.net/ see COPYING file
*/
include dirname(__FILE__).'/inc/config.php';
include dirname(__FILE__).'/inc/poche/config.inc.php';
myTool::initPhp();
# XSRF protection with token
if (!empty($_POST)) {
if (!Session::isToken($_POST['token'])) {
die('Wrong token.');
}
unset($_SESSION['tokens']);
}
$ref = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
# Parse GET & REFERER vars
$referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER'];
$view = Tools::checkVar('view', 'home');
$action = Tools::checkVar('action');
$id = Tools::checkVar('id');
$_SESSION['sort'] = Tools::checkVar('sort', 'id');
$url = new Url((isset ($_GET['url'])) ? $_GET['url'] : '');
# poche actions
if (isset($_GET['login'])) {
// Login
if (!empty($_POST['login']) && !empty($_POST['password'])) {
if (Session::login('poche', 'poche', $_POST['login'], $_POST['password'])) {
logm('login successful');
if (!empty($_POST['longlastingsession'])) {
$_SESSION['longlastingsession'] = 31536000;
$_SESSION['expires_on'] = time() + $_SESSION['longlastingsession'];
session_set_cookie_params($_SESSION['longlastingsession']);
} else {
session_set_cookie_params(0); // when browser closes
}
session_regenerate_id(true);
MyTool::redirect($ref);
}
logm('login failed');
die("Login failed !");
} else {
logm('login failed');
}
# hello you
$poche->login($referer);
}
elseif (isset($_GET['logout'])) {
logm('logout');
Session::logout();
MyTool::redirect();
# see you soon !
$poche->logout();
}
elseif (isset($_GET['config'])) {
# Update password
$poche->updatePassword();
}
elseif (isset($_GET['import'])) {
$import = $poche->import($_GET['from']);
}
elseif (isset($_GET['export'])) {
$poche->export();
}
# Traitement des paramètres et déclenchement des actions
$view = (isset ($_REQUEST['view'])) ? htmlentities($_REQUEST['view']) : 'index';
$full_head = (isset ($_REQUEST['full_head'])) ? htmlentities($_REQUEST['full_head']) : 'yes';
$action = (isset ($_REQUEST['action'])) ? htmlentities($_REQUEST['action']) : '';
$_SESSION['sort'] = (isset ($_REQUEST['sort'])) ? htmlentities($_REQUEST['sort']) : 'id';
$id = (isset ($_REQUEST['id'])) ? htmlspecialchars($_REQUEST['id']) : '';
$url = (isset ($_GET['url'])) ? $_GET['url'] : '';
$tpl->assign('isLogged', Session::isLogged());
$tpl->assign('referer', $ref);
$tpl->assign('view', $view);
$tpl->assign('poche_url', myTool::getUrl());
$tpl->assign('title', 'poche, a read it later open source system');
# vars to send to templates
$tpl_vars = array(
'referer' => $referer,
'view' => $view,
'poche_url' => Tools::getPocheUrl(),
'title' => _('poche, a read it later open source system'),
'token' => Session::getToken(),
);
if (Session::isLogged()) {
action_to_do($action, $url, $id);
display_view($view, $id, $full_head);
$poche->action($action, $url, $id);
$tpl_file = Tools::getTplFile($view);
$tpl_vars = array_merge($tpl_vars, $poche->displayView($view, $id));
}
else {
$tpl->draw('login');
$tpl_file = 'login.twig';
}
# because messages can be added in $poche->action(), we have to add this entry now (we can add it before)
$messages = $poche->messages->display('all', FALSE);
$tpl_vars = array_merge($tpl_vars, array('messages' => $messages));
# display poche
echo $poche->tpl->render($tpl_file, $tpl_vars);

34
install/mysql.sql Normal file
View File

@ -0,0 +1,34 @@
CREATE TABLE IF NOT EXISTS `config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `entries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`url` varchar(255) NOT NULL,
`is_read` tinyint(1) NOT NULL,
`is_fav` tinyint(1) NOT NULL,
`content` blob NOT NULL,
`user_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`name` int(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `users_config` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

30
install/postgres.sql Normal file
View File

@ -0,0 +1,30 @@
CREATE TABLE config (
id bigserial primary key,
name varchar(255) NOT NULL,
value varchar(255) NOT NULL
);
CREATE TABLE entries (
id bigserial primary key,
title varchar(255) NOT NULL,
url varchar(255) NOT NULL,
is_read boolean DEFAULT false,
is_fav boolean DEFAULT false,
content TEXT,
user_id integer NOT NULL
);
CREATE TABLE users (
id bigserial primary key,
username varchar(255) NOT NULL,
password varchar(255) NOT NULL,
name varchar(255) NOT NULL,
email varchar(255) NOT NULL
);
CREATE TABLE users_config (
id bigserial primary key,
user_id integer NOT NULL,
name varchar(255) NOT NULL,
value varchar(255) NOT NULL
);

View File

@ -0,0 +1,72 @@
<?php
# import script to upgrade from poche 0.3
$db_path = 'sqlite:../db/poche.sqlite';
$handle = new PDO($db_path);
$handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
# Requêtes à exécuter pour mettre à jour poche.sqlite en 1.x
# ajout d'un champ user_id sur la table entries
$sql = 'ALTER TABLE entries RENAME TO tempEntries;';
$query = $handle->prepare($sql);
$query->execute();
$sql = 'CREATE TABLE entries (id INTEGER PRIMARY KEY, title TEXT, url TEXT, is_read NUMERIC DEFAULT 0, is_fav NUMERIC DEFAULT 0, content BLOB, user_id NUMERIC);';
$query = $handle->prepare($sql);
$query->execute();
$sql = 'INSERT INTO entries (id, title, url, is_read, is_fav, content) SELECT id, title, url, is_read, is_fav, content FROM tempEntries;';
$query = $handle->prepare($sql);
$query->execute();
# Update tout pour mettre user_id = 1
$sql = 'UPDATE entries SET user_id = 1;';
$query = $handle->prepare($sql);
$query->execute();
# Changement des flags pour les lus / favoris
$sql = 'UPDATE entries SET is_read = 1 WHERE is_read = -1;';
$query = $handle->prepare($sql);
$query->execute();
$sql = 'UPDATE entries SET is_fav = 1 WHERE is_fav = -1;';
$query = $handle->prepare($sql);
$query->execute();
# Création de la table users
$sql = 'CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, password TEXT, name TEXT, email TEXT);';
$query = $handle->prepare($sql);
$query->execute();
$sql = 'INSERT INTO users (username) SELECT value FROM config WHERE name = "login";';
$query = $handle->prepare($sql);
$query->execute();
$sql = "UPDATE users SET password = (SELECT value FROM config WHERE name = 'password')";
$query = $handle->prepare($sql);
$query->execute();
# Création de la table users_config
$sql = 'CREATE TABLE users_config (id INTEGER PRIMARY KEY, user_id NUMERIC, name TEXT, value TEXT);';
$query = $handle->prepare($sql);
$query->execute();
$sql = 'INSERT INTO users_config (user_id, name, value) VALUES (1, "pager", "10");';
$query = $handle->prepare($sql);
$query->execute();
$sql = 'INSERT INTO users_config (user_id, name, value) VALUES (1, "language", "en_EN.UTF8");';
$query = $handle->prepare($sql);
$query->execute();
# Suppression de la table temporaire
$sql = 'DROP TABLE tempEntries;';
$query = $handle->prepare($sql);
$query->execute();
# Vidage de la table de config
$sql = 'DELETE FROM config;';
$query = $handle->prepare($sql);
$query->execute();
echo 'welcome to poche 1.0 !';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,57 +0,0 @@
function toggle_favorite(element, id) {
$(element).toggleClass('fav-off');
$.ajax ({
url: "index.php?action=toggle_fav",
data:{id:id}
});
}
function toggle_archive(element, id, view_article) {
$(element).toggleClass('archive-off');
$.ajax ({
url: "index.php?action=toggle_archive",
data:{id:id}
});
var obj = $('#entry-'+id);
// on vient de la vue de l'article, donc pas de gestion de grille
if (view_article != 1) {
$('#content').masonry('remove',obj);
$('#content').masonry('reloadItems');
$('#content').masonry('reload');
}
}
function sort_links(view, sort) {
$.get('index.php', { view: view, sort: sort, full_head: 'no' }, function(data) {
$('#content').html(data);
});
}
// ---------- Swith light or dark view
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
}
$('#themeswitch').click(function() {
// we want the dark
if ($('body').hasClass('light-style')) {
setActiveStyleSheet('dark-style');
$('body').addClass('dark-style');
$('body').removeClass('light-style');
$('#themeswitch').text('light');
// we want the light
} else if ($('body').hasClass('dark-style')) {
setActiveStyleSheet('light-style');
$('body').addClass('light-style');
$('body').removeClass('dark-style');
$('#themeswitch').text('dark');
}
return false;
});

Binary file not shown.

View File

@ -0,0 +1,376 @@
msgid ""
msgstr ""
"Project-Id-Version: poche\n"
"POT-Creation-Date: 2013-08-06 08:35+0100\n"
"PO-Revision-Date: 2013-08-06 08:35+0100\n"
"Last-Translator: Nicolas Lœuillet <nicolas.loeuillet@gmail.com>\n"
"Language-Team: poche <support@inthepoche.com>\n"
"Language: Français\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.4\n"
"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
"X-Poedit-Basepath: /\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-SearchPath-0: /var/www/poche-i18n\n"
#: /var/www/poche-i18n/index.php:43
msgid "poche, a read it later open source system"
msgstr "poche, a read it later open source system"
#: /var/www/poche-i18n/inc/poche/Poche.class.php:101
msgid "the link has been added successfully"
msgstr "le lien a été ajouté avec succès"
#: /var/www/poche-i18n/inc/poche/Poche.class.php:104
msgid "error during insertion : the link wasn't added"
msgstr "erreur durant l'insertion : le lien n'a pas été ajouté"
#: /var/www/poche-i18n/inc/poche/Poche.class.php:109
msgid "error during fetching content : the link wasn't added"
msgstr "erreur durant la récupération du contenu : le lien n'a pas été ajouté"
#: /var/www/poche-i18n/inc/poche/Poche.class.php:119
msgid "the link has been deleted successfully"
msgstr "le lien a été supprimé avec succès"
#: /var/www/poche-i18n/inc/poche/Poche.class.php:123
msgid "the link wasn't deleted"
msgstr "le lien n'a pas été supprimé"
#: /var/www/poche-i18n/inc/poche/Tools.class.php:18
msgid "Oops, it seems you don't have PHP 5."
msgstr "Oups, il semblerait que PHP 5 ne soit pas installé. "
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:32
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:70
#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:50
msgid "config"
msgstr "config"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:46
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:31
#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:26
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:34
msgid "home"
msgstr "accueil"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:54
#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:34
msgid "favorites"
msgstr "favoris"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:62
#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:42
msgid "archive"
msgstr "archives"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:74
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:76
#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:54
#: /var/www/poche-i18n/cache/76/a4/e7c21f2e0ba29104fc654cd8ba41.php:56
msgid "logout"
msgstr "déconnexion"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:87
msgid "Bookmarklet"
msgstr "Bookmarklet"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:91
msgid ""
"Thanks to the bookmarklet, you will be able to easily add a link to your "
"poche."
msgstr ""
"Grâce au bookmarklet, vous pouvez ajouter facilement un lien dans votre "
"poche."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:93
msgid "Have a look to this documentation:"
msgstr "Jetez un œil à la documentation :"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:97
msgid "Drag & drop this link to your bookmarks bar and have fun with poche."
msgstr ""
"Glissez / déposez ce lien dans votre barre de favoris de votre navigateur et "
"prenez du bon temps avec poche."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:103
msgid "poche it!"
msgstr "poche-le !"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:108
msgid "Updating poche"
msgstr "Mettre à jour poche"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:113
msgid "your version"
msgstr "votre version"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:119
msgid "latest stable version"
msgstr "dernière version stable"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:125
msgid "a more recent stable version is available."
msgstr "une version stable plus récente est disponible."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:128
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:142
msgid "you are up to date."
msgstr "vous êtes à jour."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:133
msgid "latest dev version"
msgstr "dernière version de développement"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:139
msgid "a more recent development version is available."
msgstr "une version de développement plus récente est disponible."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:150
msgid "Change your password"
msgstr "Modifier votre mot de passe"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:157
msgid "New password:"
msgstr "Nouveau mot de passe :"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:161
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:171
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:60
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:68
msgid "Password"
msgstr "Mot de passe"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:167
msgid "Repeat your new password:"
msgstr "Répétez le nouveau mot de passe :"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:177
msgid "Update"
msgstr "Mettre à jour"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:193
msgid "Import"
msgstr "Import"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:197
msgid "Please execute the import script locally, it can take a very long time."
msgstr "Merci d'exécuter l'import en local, cela peut prendre du temps. "
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:201
msgid "More infos in the official doc:"
msgstr "Plus d'infos sur la documentation officielle :"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:206
msgid "import from Pocket"
msgstr "l'import depuis Pocket est terminé."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:210
msgid "import from Readability"
msgstr "l'import depuis Readability est terminé."
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:214
msgid "import from Instapaper"
msgstr "Import depuis Instapaper"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:220
msgid "Export your poche datas"
msgstr "Exporter vos données de poche"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:224
msgid "Click here"
msgstr "Cliquez-ici"
#: /var/www/poche-i18n/cache/c9/b0/845a8dc93165e6c00b6b43068799.php:226
msgid "to export your poche datas."
msgstr "pour exporter vos données de poche."
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:46
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:139
#: /var/www/poche-i18n/cache/30/97/b548692380c89d047a16cec7af79.php:22
msgid "back to home"
msgstr "retour à l'accueil"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:50
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:147
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:119
msgid "toggle mark as read"
msgstr "marquer comme lu"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:60
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:157
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:129
msgid "toggle favorite"
msgstr "favori"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:70
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:167
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:139
msgid "delete"
msgstr "supprimer"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:82
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:179
msgid "tweet"
msgstr "tweeter"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:93
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:190
msgid "email"
msgstr "envoyer par email"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:109
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:125
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:153
msgid "original"
msgstr "original"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:143
msgid "back to top"
msgstr "retour en haut de page"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:198
msgid "this article appears wrong?"
msgstr "cet article s'affiche mal ?"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:200
msgid "create an issue"
msgstr "créer un ticket"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:202
msgid "or"
msgstr "ou"
#: /var/www/poche-i18n/cache/7a/1e/68e6b4aec1301ae024cc85232e7c.php:206
msgid "contact us by mail"
msgstr "contactez-nous par email"
#: /var/www/poche-i18n/cache/88/8a/ee3b7080c13204391c14947a0c2c.php:22
msgid "powered by"
msgstr "propulsé par"
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:31
msgid "installation"
msgstr "installation"
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:42
msgid "install your poche"
msgstr "installez votre poche"
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:47
msgid ""
"poche is still not installed. Please fill the below form to install it. "
"Don't hesitate to <a href='http://inthepoche.com/?pages/Documentation'>read "
"the documentation on poche website</a>."
msgstr ""
"poche n'est pas encore installé. Merci de remplir les champs ci-dessous pour "
"l'installer. N'hésitez pas à <a href='http://inthepoche.com/?pages/"
"Documentation'>lire la documentation sur le site de poche</a>."
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:53
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:55
msgid "Login"
msgstr "Nom d'utilisateur"
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:67
msgid "Repeat your password"
msgstr "Répétez votre mot de passe"
#: /var/www/poche-i18n/cache/d4/28/e0d08991ec2d8a7b133505e7c651.php:74
msgid "Install"
msgstr "Installer"
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:31
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:42
msgid "login to your poche"
msgstr "Se connecter à votre poche"
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:48
msgid "you are in demo mode, some features may be disabled."
msgstr ""
"vous êtes en mode démo, certaines fonctionnalités sont peut-être désactivées."
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:80
msgid "Stay signed in"
msgstr "rester connecté"
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:86
msgid "(Do not check on public computers)"
msgstr "(à ne pas cocher sur un ordinateur public)"
#: /var/www/poche-i18n/cache/ae/26/05eb67771213c16bd8c9aaf2d2c4.php:93
msgid "Sign in"
msgstr ""
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:55
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:57
msgid "by date asc"
msgstr "par date asc"
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:59
msgid "by date"
msgstr "par date"
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:65
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:67
msgid "by date desc"
msgstr "par date desc"
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:75
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:77
msgid "by title asc"
msgstr "par titre asc"
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:79
msgid "by title"
msgstr "par titre"
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:85
#: /var/www/poche-i18n/cache/dd/a8/530129765655dcde0a70a31a78b6.php:87
msgid "by title desc"
msgstr "par titre desc"
#~ msgid "Please choose between Pocket & Readabilty :"
#~ msgstr "Merci de choisir entre Pocket & Readability :"
#~ msgid "Bye bye Pocket, let's go !"
#~ msgstr "Bye bye Pocket, en route !"
#~ msgid "Bye bye Readability, let's go !"
#~ msgstr "Bye bye Readability, en route !"
#~ msgid "Welcome to poche !"
#~ msgstr "Bienvenue dans poche !"
#~ msgid "Error with the import."
#~ msgstr "Erreur durant l'import."
#~ msgid "Wrong token."
#~ msgstr "Mauvais jeton."
#~ msgid "Login failed !"
#~ msgstr "Connexion échouée."
#~ msgid "your password has been updated"
#~ msgstr "Votre mot de passe a été mis à jour. "
#~ msgid "in demo mode, you can't update password"
#~ msgstr "En mode démo, le mot de passe ne peut être modifié."
#~ msgid ""
#~ "your password can't be empty and you have to repeat it in the second field"
#~ msgstr ""
#~ "Votre mot de passe ne peut être vide et vous devez le répéter dans le "
#~ "second champ."
#~ msgid "error during url preparation : the link wasn't added"
#~ msgstr "erreur durant l'insertion : le lien n'a pas été ajouté"
#~ msgid "error during url preparation : the link is not valid"
#~ msgstr "erreur durant la préparation de l'URL : le lien n'est pas valide"
#~ msgid "TEST"
#~ msgstr "NICOLAS"

0
phpunit.xml.dist Normal file
View File

3
tpl/_bookmarklet.twig Normal file
View File

@ -0,0 +1,3 @@
<script type="text/javascript">
top["bookmarklet-url@inthepoche.com"]=""+"<!DOCTYPE html>"+"<html>"+"<head>"+"<title>poche it !</title>"+'<link rel="icon" href="{{poche_url}}tpl/img/favicon.ico" />'+"</head>"+"<body>"+"<script>"+"window.onload=function(){"+"window.setTimeout(function(){"+"history.back();"+"},250);"+"};"+"</scr"+"ipt>"+"</body>"+"</html>"
</script>

4
tpl/_footer.twig Normal file
View File

@ -0,0 +1,4 @@
<footer class="w600p center mt3 smaller txtright">
<p>{% trans "powered by" %} <a href="http://inthepoche.com">poche</a></p>
{% if constant('DEBUG_POCHE') == 1 %}<p><strong>{% trans "debug mode is on so cache is off." %} {% trans "your poche version:" %}{{constant('POCHE_VERSION')}}. {% trans "storage:" %} {{constant('STORAGE')}}</strong></p>{% endif %}
</footer>

11
tpl/_head.twig Normal file
View File

@ -0,0 +1,11 @@
<link rel="shortcut icon" type="image/x-icon" href="./tpl/img/favicon.ico" />
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="./tpl/img/apple-touch-icon-144x144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="./tpl/img/apple-touch-icon-72x72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="./tpl/img/apple-touch-icon-precomposed.png">
<link rel="stylesheet" href="./tpl/css/knacss.css" media="all">
<link rel="stylesheet" href="./tpl/css/style.css" media="all">
<link rel="stylesheet" href="./tpl/css/style-{{ constant('THEME') }}.css" media="all" title="{{ constant('THEME') }} theme">
<link rel="stylesheet" href="./tpl/css/messages.css" media="all">
<link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<script src="./tpl/js/jquery-2.0.3.min.js"></script>
<script type="text/javascript">$(document).ready(function(){$("body").prepend('<a href="#top" class="top_link" title="{% trans "back to top" %}"><img src="./tpl/img/{{ constant("THEME") }}/backtotop.png" alt={% trans "back to top" %}"/></a>');$(".top_link").css({position:"fixed",right:"15px",bottom:"15px",display:"none",padding:"20px",background:"#ccc","-moz-border-radius":"40px","-webkit-border-radius":"40px","border-radius":"40px",opacity:"0.9","z-index":"2000"});$(window).scroll(function(){posScroll=$(document).scrollTop();if(posScroll>=400)$(".top_link").fadeIn(600);else $(".top_link").fadeOut(600)})})</script>

7
tpl/_menu.twig Normal file
View File

@ -0,0 +1,7 @@
<ul id="links">
<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=archive" {% if view == 'archive' %}class="current"{% endif %}>{% trans "archive" %}</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>
</ul>

1
tpl/_messages.twig Normal file
View File

@ -0,0 +1 @@
{{ messages | raw }}

3
tpl/_top.twig Normal file
View File

@ -0,0 +1,3 @@
<header class="w600p center mbm">
<h1><a href="./" title="{% trans "back to home" %}" ><img src="./tpl/img/logo.png" alt="logo poche" /></a></h1>
</header>

View File

@ -1,8 +0,0 @@
<div id="content">
<h2>Bookmarklet</h2>
<p>Thanks to the bookmarklet, you will be able to easily add a link to your poche. If you don't know how use a bookmarklet, <a href="http://support.mozilla.org/en-US/kb/bookmarklets-perform-common-web-page-tasks">have a look here</a>.</p>
<p>Drag & drop this link to your bookmarks bar and have fun with poche.</p>
<p><a style="cursor: move; border: 1px dashed grey; background: white;" title="i am a bookmarklet, use me !" href="javascript:(function(){var%20url%20=%20location.href%20||%20url;window.open('{$poche_url}?action=add&url='%20+%20encodeURIComponent(url),'_self');})();">poche it !</a></p>
<h2>Export</h2>
<p><a href="?view=export" target="_blank">Click here</a> to export your poche datas.</p>
</div>

57
tpl/config.twig Normal file
View File

@ -0,0 +1,57 @@
{% extends "layout.twig" %}
{% block title %}{% trans "config" %}{% endblock %}
{% block menu %}
<ul id="links">
<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=archive" {% if view == 'archive' %}class="current"{% endif %}>{% trans "archive" %}</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>
</ul>
{% endblock %}
{% block content %}
<h2>{% trans "Bookmarklet" %}</h2>
<p>{% trans "Thanks to the bookmarklet, you will be able to easily add a link to your poche." %} {% trans "Have a look to this documentation:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a>.</p>
<p>{% trans "Drag & drop this link to your bookmarks bar and have fun with poche." %}</p>
<p class="txtcenter"><a ondragend="this.click();" style="cursor: move; border: 1px dashed grey; background: white; padding: 5px;" title="i am a bookmarklet, use me !" href="javascript:if(top['bookmarklet-url@inthepoche.com']){top['bookmarklet-url@inthepoche.com'];}else{(function(){var%20url%20=%20location.href%20||%20url;window.open('{{ poche_url }}?action=add&url='%20+%20btoa(url),'_self');})();void(0);}">{% trans "poche it!" %}</a></p>
<h2>{% trans "Updating poche" %}</h2>
<p><ul>
<li>{% trans "your version" %} : <strong>{{ constant('POCHE_VERSION') }}</strong></li>
<li>{% trans "latest stable version" %} : {{ prod }}. {% if compare_prod == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent stable version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>
{% if constant('DEBUG_POCHE') == 1 %}<li>{% trans "latest dev version" %} : {{ dev }}. {% if compare_dev == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent development version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>{% endif %}
</ul>
</p>
<h2>{% trans "Change your password" %}</h2>
<form method="post" action="?config" name="loginform">
<fieldset class="w500p">
<div class="row">
<label class="col w150p" for="password">{% trans "New password:" %}</label>
<input class="col" type="password" id="password" name="password" placeholder="{% trans "Password" %}" tabindex="2">
</div>
<div class="row">
<label class="col w150p" for="password_repeat">{% trans "Repeat your new password:" %}</label>
<input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="{% trans "Password" %}" tabindex="3">
</div>
<div class="row mts txtcenter">
<button class="bouton" type="submit" tabindex="4">{% trans "Update" %}</button>
</div>
</fieldset>
<input type="hidden" name="returnurl" value="{{ referer }}">
<input type="hidden" name="token" value="{{ token }}">
</form>
<h2>{% trans "Import" %}</h2>
<p>{% trans "Please execute the import script locally, it can take a very long time." %}</p>
<p>{% trans "More infos in the official doc:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a></p>
<p><ul>
<li><a href="./?import&from=pocket">{% trans "import from Pocket" %}</a> (you must have a "ril_export.html" file on your server)</li>
<li><a href="./?import&from=readability">{% trans "import from Readability" %}</a> (you must have a "readability" file on your server)</li>
<li><a href="./?import&from=instapaper">{% trans "import from Instapaper" %}</a> (you must have a "instapaper-export.html" file on your server)</li>
</ul></p>
<h2>{% trans "Export your poche datas" %}</h2>
<p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your poche datas." %}</p>
{% endblock %}

13
tpl/css/messages.css Executable file
View File

@ -0,0 +1,13 @@
.messages { width: 400px; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; }
.messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; }
/*.messages:hover a.closeMessage { visibility:visible; }*/
.messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; }
.messages.error { border: 1px solid #C42608; color: #c00 !important; background: #FFF0EF; }
.messages.error p { background: url(../img/messages/cross.png ) no-repeat 0px 50%; color:#c00 !important; }
.messages.success {background: #E0FBCC; border: 1px solid #6DC70C; }
.messages.success p { background: url(../img/messages/tick.png) no-repeat 0px 50%; color: #2B6301 !important; }
.messages.warning { background: #FFFCD3; border: 1px solid #EBCD41; color: #000; }
.messages.warning p { background: url(../img/messages/warning.png ) no-repeat 0px 50%; color: #5F4E01; }
.messages.information, .messages.info { background: #DFEBFB; border: 1px solid #82AEE7; }
.messages.information p, .messages.info p { background: url(../img/messages/help.png ) no-repeat 0px 50%; color: #064393; }
.messages.information a { text-decoration: underline; }

53
tpl/css/style-light.css Normal file
View File

@ -0,0 +1,53 @@
a.back span {
background: url('../img/light/left.png') no-repeat;
}
a.top span {
background: url('../img/light/top.png') no-repeat;
}
a.fav span {
background: url('../img/light/star-on.png') no-repeat;
}
a.fav span:hover {
background: url('../img/light/star-off.png') no-repeat;
}
a.fav-off span {
background: url('../img/light/star-off.png') no-repeat;
}
a.fav-off span:hover {
background: url('../img/light/star-on.png') no-repeat;
}
a.archive span {
background: url('../img/light/checkmark-on.png') no-repeat;
}
a.archive span:hover {
background: url('../img/light/checkmark-off.png') no-repeat;
}
a.archive-off span {
background: url('../img/light/checkmark-off.png') no-repeat;
}
a.archive-off span:hover {
background: url('../img/light/checkmark-on.png') no-repeat;
}
a.twitter span {
background: url('../img/light/twitter.png') no-repeat;
}
a.email span {
background: url('../img/light/envelop.png') no-repeat;
}
a.delete span {
background: url('../img/light/remove.png') no-repeat;
}

243
tpl/css/style.css Normal file
View File

@ -0,0 +1,243 @@
body {
font-size: 16px;
font-family: 'Roboto', sans-serif;
margin: 10px;
}
header {
text-align: center;
}
header h1 {
font-size: 1.3em;
}
.bouton {
border-radius: 2px;
}
#main {
margin: 0 auto;
}
#main ul#links {
padding: 0;
list-style-type: none;
text-align: center;
font-size: 0.9em;
}
#main ul#links li {
display: inline;
}
#main ul#links li a.current {
-webkit-border-radius: 2px;
border-radius: 2px;
}
#main ul#sort {
padding: 0;
list-style-type: none;
text-align: center;
opacity: 0.5;
}
#main ul#sort li {
display: inline;
font-size: 0.9em;
}
#main ul#sort img:hover {
cursor: pointer;
}
#links a{
text-decoration: none;
padding: 5px 10px;
}
#links a:hover{
-webkit-border-radius: 2px;
border-radius: 2px;
}
/*** ***/
/*** LINKS DISPLAY ***/
#main a.tool {
text-decoration: none;
cursor: pointer;
}
#main #content {
margin-top: 20px;
}
#main #content h2 {
font-size: 1.3em;
text-decoration: none;
}
#main #content .entrie {
border-bottom: 1px dashed #222222;
}
#main .entrie ul.tools {
list-style-type: none;
}
#main .entrie ul.tools li {
/*display: inline;*/
}
.tools {
float: right;
text-align: right;
opacity: 0.5;
}
.tools p {
font-size: 0.8em;}
/*
.tools ul {
padding: 0; margin: 0;
list-style-type: none;
}
.tools ul li {
line-height: 20px;
}
.tools a.tool {
cursor: pointer;
}*/
#main .entrie .tools a.tool span, #article .tools a.tool span {
display: inline-block;
width: 16px;
height: 16px;
}
/*** ***/
/*** ARTICLE PAGE ***/
#article {
margin: 0 auto;
}
#article header {
text-align: left;
}
#article header a {
text-decoration: none;
}
.vieworiginal a, .vieworiginal a:hover, .vieworiginal a:visited {
text-decoration: none;
color: #888888;
}
.backhome {
display: inline;
}
#article .tools {
position: relative;
display: inline;
top: 0px;
right: 0px;
width: 100%;
}
#article .tools ul li{
display: inline;
}
/*** GENERAL ***/
body {
color: #000;
}
a, a:hover, a:visited {
color: #000;
}
.bouton {
background-color: #000;
color: #fff;
border: none;
}
.bouton:hover {
background-color: #222222;
color: #F1F1F1;
}
#main ul#links li a.current {
background-color: #000;
color: #fff;
}
#links a:hover{
background-color: #040707;
color: #F1F1F1;
}
/*** ***/
/*** ARTICLE PAGE ***/
#article header, #article article {
border-bottom: 1px solid #222222;
}
/* Pagination */
.pagination {
clear: both;
padding-bottom: 20px;
padding-top: 10px;
text-align: right;
}
.pagination a {
border: 1px solid #D5D5D5;
color: #333;
font-size: 11px;
font-weight: bold;
height: 25px;
padding: 4px 8px;
text-decoration: none;
margin:2px;
}
.pagination a:hover, .pagination a:active {
background:#efefef;
}
.pagination span.current {
background-color: #ccc;
border: 1px solid #D5D5D5;
color: #000;
font-size: 11px;
font-weight: bold;
height: 25px;
padding: 4px 8px;
text-decoration: none;
margin:2px;
}
.pagination span.disabled {
border: 1px solid #EEEEEE;
color: #DDDDDD;
margin:2px;
padding: 4px 8px;
font-size: 11px;
font-weight: bold;
}
footer {
clear: both;
}
.reading-time {
font-size: 0.8em;
}

View File

@ -1,18 +0,0 @@
<div id="content">
{loop="entries"}
<div id="entry-{$value.id}" class="entrie mb2">
<span class="content">
<h2 class="h6-like">
<a href="index.php?&view=view&id={$value.id}">{$value.title}</a>
</h2>
<div class="tools">
<ul>
<li><a title="toggle mark as read" class="tool archive {if="$value.is_read == '0'"}archive-off{/if}" onclick="toggle_archive(this, {$value.id})"><span></span></a></li>
<li><a title="toggle favorite" class="tool fav {if="$value.is_fav == '0'"}fav-off{/if}" onclick="toggle_favorite(this, {$value.id})"><span></span></a></li>
<li><form method="post" onsubmit="return confirm('Are you sure?')" style="display: inline;"><input type="hidden" name="token" id="token" value="<?php echo Session::getToken(); ?>" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="view" name="view" value="{$view}" /><input type="hidden" id="id" name="id" value="{$value.id}" /><input type="submit" class="delete" title="toggle delete" /></form></li>
</ul>
</div>
</span>
</div>
{/loop}
</div>

View File

@ -1 +0,0 @@
export {$export}

1
tpl/export.twig Normal file
View File

@ -0,0 +1 @@
{{ export }}

View File

@ -1,7 +0,0 @@
</div>
<footer class="mr2 mt3 smaller">
<p>powered by <a href="http://inthepoche.com">poche</a><br />follow us on <a href="https://twitter.com/getpoche" title="follow us on twitter">twitter</a></p>
</footer>
</body>
</html>

View File

@ -1,22 +0,0 @@
<!DOCTYPE html>
<!--[if lte IE 6]> <html class="no-js ie6 ie67 ie678" lang="en"> <![endif]-->
<!--[if lte IE 7]> <html class="no-js ie7 ie67 ie678" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 ie678" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<html>
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=10">
<title>{$title}</title>
<link rel="shortcut icon" type="image/x-icon" href="./img/favicon.ico" />
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="./img/apple-touch-icon-144x144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="./img/apple-touch-icon-72x72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="./img/apple-touch-icon-precomposed.png">
<link rel="stylesheet" href="./css/knacss.css" media="all">
<link rel="stylesheet" href="./css/style.css" media="all">
<!-- Light Theme -->
<link rel="stylesheet" href="./css/style-light.css" media="all" title="light-style">
<!-- Dark Theme -->
<link rel="alternate stylesheet" href="./css/style-dark.css" media="all" title="dark-style">
</head>

View File

@ -1,19 +0,0 @@
<body class="light-style">
<header>
<h1><img src="./img/logo.png" alt="logo poche" />poche</h1>
</header>
<div id="main">
<ul id="links">
<li><a href="index.php" {if="$view == 'index'"}class="current"{/if}>home</a></li>
<li><a href="?view=fav" {if="$view == 'fav'"}class="current"{/if}>favorites</a></li>
<li><a href="?view=archive" {if="$view == 'archive'"}class="current"{/if}>archive</a></li>
<li><a href="?view=config" {if="$view == 'config'"}class="current"{/if}>config</a></li>
<li><a href="?logout" title="Logout">logout</a></li>
</ul>
{if condition="isset($entries)"}
<ul id="sort">
<li><img src="img/up.png" onclick="sort_links('{$view}', 'ia');" title="by date asc" /> by date <img src="img/down.png" onclick="sort_links('{$view}', 'id');" title="by date desc" /></li>
<li><img src="img/up.png" onclick="sort_links('{$view}', 'ta');" title="by title asc" /> by title <img src="img/down.png" onclick="sort_links('{$view}', 'td');" title="by title desc" /></li>
</ul>
{/if}
{include="messages"}

30
tpl/home.twig Normal file
View File

@ -0,0 +1,30 @@
{% extends "layout.twig" %}
{% block title %}{% trans "home" %}{% endblock %}
{% block menu %}
{% include '_menu.twig' %}
{% endblock %}
{% block precontent %}
<ul id="sort">
<li><a href="./?sort=ia&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/top.png" alt="{% trans "by date asc" %}" title="{% trans "by date asc" %}" /></a> {% trans "by date" %} <a href="./?sort=id&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/down.png" alt="{% trans "by date desc" %}" title="{% trans "by date desc" %}" /></a></li>
<li><a href="./?sort=ta&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/top.png" alt="{% trans "by title asc" %}" title="{% trans "by title asc" %}" /></a> {% trans "by title" %} <a href="./?sort=td&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/down.png" alt="{% trans "by title desc" %}" title="{% trans "by title desc" %}" /></a></li>
</ul>
{% endblock %}
{% block content %}
{{ page_links | raw }}
{% 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|e }}</a></h2>
<ul class="tools">
<li>
<a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
<li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
<li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
<li class="reading-time">{{ entry.content| getReadingTime }} min</li>
</li>
</ul>
<p>{{ entry.content|striptags|slice(0, 300) }}...</p>
<p class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></p>
</div>
{% endfor %}
{{ page_links | raw }}
{% endblock %}

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

BIN
tpl/img/light/backtotop.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

View File

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

View File

Before

Width:  |  Height:  |  Size: 216 B

After

Width:  |  Height:  |  Size: 216 B

BIN
tpl/img/light/envelop.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

BIN
tpl/img/light/left.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

View File

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 252 B

View File

Before

Width:  |  Height:  |  Size: 314 B

After

Width:  |  Height:  |  Size: 314 B

View File

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 281 B

0
img/up.png → tpl/img/light/top.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

BIN
tpl/img/light/twitter.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

BIN
tpl/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 662 B

After

Width:  |  Height:  |  Size: 662 B

View File

Before

Width:  |  Height:  |  Size: 655 B

After

Width:  |  Height:  |  Size: 655 B

View File

Before

Width:  |  Height:  |  Size: 786 B

After

Width:  |  Height:  |  Size: 786 B

View File

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

View File

Before

Width:  |  Height:  |  Size: 666 B

After

Width:  |  Height:  |  Size: 666 B

28
tpl/install.twig Normal file
View File

@ -0,0 +1,28 @@
{% extends "layout.twig" %}
{% block title %}{% trans "installation" %}{% endblock %}
{% block content %}
<form method="post" action="?install" name="loginform">
<fieldset class="w500p center">
<h2 class="mbs txtcenter">{% trans "install your poche" %}</h2>
<p>
{% trans "poche is still not installed. Please fill the below form to install it. Don't hesitate to <a href='http://inthepoche.com/?pages/Documentation'>read the documentation on poche website</a>." %}
</p>
<div class="row">
<label class="col w150p" for="login">{% trans "Login" %}</label>
<input class="col" type="text" id="login" name="login" placeholder="Login" tabindex="1" autofocus />
</div>
<div class="row">
<label class="col w150p" for="password">{% trans "Password" %}</label>
<input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2">
</div>
<div class="row">
<label class="col w150p" for="password_repeat">{% trans "Repeat your password" %}</label>
<input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="Password" tabindex="3">
</div>
<div class="row mts txtcenter">
<button class="bouton" type="submit" tabindex="4">{% trans "Install" %}</button>
</div>
</fieldset>
<input type="hidden" name="token" value="{{ token }}">
</form>
{% endblock %}

View File

@ -1,22 +0,0 @@
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/poche.js"></script>
{if="$load_all_js == '1'"}
<script type="text/javascript" src="js/jquery.masonry.min.js"></script>
<script type="text/javascript">
$( window ).load( function()
{
var columns = 3,
setColumns = function() { columns = $( window ).width() > 640 ? 3 : $( window ).width() > 320 ? 2 : 1; };
setColumns();
$( window ).resize( setColumns );
$( '#content' ).masonry(
{
itemSelector: '.entrie',
columnWidth: function( containerWidth ) { return containerWidth / columns; }
});
});
</script>
{/if}

6
tpl/js/jquery-2.0.3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

29
tpl/layout.twig Normal file
View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<!--[if lte IE 6]> <html class="no-js ie6 ie67 ie678" lang="en"> <![endif]-->
<!--[if lte IE 7]> <html class="no-js ie7 ie67 ie678" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 ie678" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<html>
<head>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=10">
<title>{% block title %}{% endblock %} - poche</title>
{% include '_head.twig' %}
{% include '_bookmarklet.twig' %}
</head>
<body>
{% include '_top.twig' %}
<div id="main">
{% block menu %}{% endblock %}
{% block precontent %}{% endblock %}
{% block messages %}
{% include '_messages.twig' %}
{% endblock %}
<div id="content" class="w600p center">
{% block content %}{% endblock %}
</div>
</div>
{% include '_footer.twig' %}
</body>
</html>

View File

@ -1,31 +0,0 @@
{include="head"}
<body class="light-style">
<header>
<h1><img src="./img/logo.png" alt="logo poche" />poche</h1>
</header>
<div id="main">
<form method="post" action="?login" name="loginform">
<fieldset>
<h2>login to your poche</h2>
<ul id="login">
<li>
<label for="login">Login</label> <input type="text" id="login" name="login" placeholder="Login" tabindex="1">
</li>
<li>
<label for="password">Password</label> <input type="password" id="password" name="password" placeholder="Password" tabindex="2">
</li>
<li>
<label><input type="checkbox" name="longlastingsession" tabindex="3">&nbsp;Stay signed in (Do not check on public computers)</label>
</li>
<li>
<button type="submit" tabindex="4">Sign in</button>
</li>
</ul>
</fieldset>
<input type="hidden" name="returnurl" value="<?php echo htmlspecialchars($referer);?>">
<input type="hidden" name="token" value="<?php echo Session::getToken(); ?>">
</form>
<script type="text/javascript">
window.onload = document.loginform.login.focus();
</script>
{include="footer"}

32
tpl/login.twig Normal file
View File

@ -0,0 +1,32 @@
{% extends "layout.twig" %}
{% block title %}{% trans "login to your poche" %}{% endblock %}
{% block content %}
<form method="post" action="?login" name="loginform">
<fieldset class="w500p center">
<h2 class="mbs txtcenter">{% trans "login to your poche" %}</h2>
{% if constant('MODE_DEMO') == 1 %}<p>{% trans "you are in demo mode, some features may be disabled." %}</p>{% endif %}
<div class="row">
<label class="col w150p" for="login">{% trans "Login" %}</label>
<input class="col" type="text" id="login" name="login" placeholder="Login" tabindex="1" autofocus {% if constant('MODE_DEMO') == 1 %}value="poche"{% endif %} />
</div>
<div class="row">
<label class="col w150p" for="password">{% trans "Password" %}</label>
<input class="col" type="password" id="password" name="password" placeholder="Password" tabindex="2" {% if constant('MODE_DEMO') == 1 %}value="poche"{% endif %} />
</div>
<div class="row">
<label class="col w150p" for="longlastingsession">{% trans "Stay signed in" %}</label>
<div class="col">
<input type="checkbox" id="longlastingsession" name="longlastingsession" tabindex="3">
<small class="inbl">{% trans "(Do not check on public computers)" %}</small>
</div>
</div>
<div class="row mts txtcenter">
<button class="bouton" type="submit" tabindex="4">{% trans "Login" %}</button>
</div>
</fieldset>
<input type="hidden" name="returnurl" value="{{ referer }}">
<input type="hidden" name="token" value="{{ token }}">
</form>
{% endblock %}

Some files were not shown because too many files have changed in this diff Show More