2013-08-04 18:58:31 +00:00
< ? php
/**
2014-01-28 09:36:04 +00:00
* wallabag , self hostable application allowing you to not miss any content anymore
2013-08-04 18:58:31 +00:00
*
2014-01-28 09:36:04 +00:00
* @ category wallabag
* @ author Nicolas Lœuillet < nicolas @ loeuillet . org >
2013-08-04 18:58:31 +00:00
* @ copyright 2013
* @ license http :// www . wtfpl . net / see COPYING file
*/
class Poche
{
2013-09-20 08:21:39 +00:00
public static $canRenderTemplates = true ;
public static $configFileAvailable = true ;
2013-08-06 12:18:03 +00:00
public $user ;
2013-08-04 18:58:31 +00:00
public $store ;
public $tpl ;
2013-08-05 13:54:37 +00:00
public $messages ;
2013-08-05 19:56:32 +00:00
public $pagination ;
2013-09-20 08:21:39 +00:00
private $currentTheme = '' ;
2013-10-07 12:26:25 +00:00
private $currentLanguage = '' ;
2013-10-07 11:12:28 +00:00
private $notInstalledMessage = array ();
2013-08-04 18:58:31 +00:00
2014-02-21 14:24:33 +00:00
private $language_names = array (
'cs_CZ.utf8' => 'čeština' ,
'de_DE.utf8' => 'German' ,
'en_EN.utf8' => 'English' ,
'es_ES.utf8' => 'Español' ,
'fa_IR.utf8' => 'فارسی' ,
'fr_FR.utf8' => 'Français' ,
'it_IT.utf8' => 'Italiano' ,
'pl_PL.utf8' => 'Polski' ,
2014-03-16 19:43:46 +00:00
'pt_BR.utf8' => 'Português (Brasil)' ,
2014-02-21 14:24:33 +00:00
'ru_RU.utf8' => 'Pу с с кий' ,
'sl_SI.utf8' => 'Slovenščina' ,
2014-02-26 13:43:49 +00:00
'uk_UA.utf8' => 'Українська' ,
2014-02-21 14:24:33 +00:00
);
2013-09-20 08:21:39 +00:00
public function __construct ()
2013-08-04 18:58:31 +00:00
{
2013-10-07 11:12:28 +00:00
if ( $this -> configFileIsAvailable ()) {
$this -> init ();
2013-09-20 08:21:39 +00:00
}
2013-10-07 11:12:28 +00:00
if ( $this -> themeIsInstalled ()) {
$this -> initTpl ();
2013-09-20 08:21:39 +00:00
}
2013-10-07 11:12:28 +00:00
if ( $this -> systemIsInstalled ()) {
$this -> store = new Database ();
$this -> messages = new Messages ();
# installation
if ( ! $this -> store -> isInstalled ()) {
$this -> install ();
}
2013-12-23 09:35:09 +00:00
$this -> store -> checkTags ();
2013-08-04 18:58:31 +00:00
}
}
2013-09-20 08:21:39 +00:00
private function init ()
{
Tools :: initPhp ();
2013-08-04 18:58:31 +00:00
2013-09-20 08:21:39 +00:00
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 );
# Pagination
$this -> pagination = new Paginator ( $this -> user -> getConfigValue ( 'pager' ), 'p' );
# Set up theme
$themeDirectory = $this -> user -> getConfigValue ( 'theme' );
if ( $themeDirectory === false ) {
$themeDirectory = DEFAULT_THEME ;
}
$this -> currentTheme = $themeDirectory ;
2013-10-07 12:26:25 +00:00
# Set up language
$languageDirectory = $this -> user -> getConfigValue ( 'language' );
if ( $languageDirectory === false ) {
$languageDirectory = DEFAULT_THEME ;
}
$this -> currentLanguage = $languageDirectory ;
2013-09-20 08:21:39 +00:00
}
public function configFileIsAvailable () {
if ( ! self :: $configFileAvailable ) {
2013-10-07 11:12:28 +00:00
$this -> notInstalledMessage [] = 'You have to rename inc/poche/config.inc.php.new to inc/poche/config.inc.php.' ;
2013-09-20 08:21:39 +00:00
return false ;
}
return true ;
}
public function themeIsInstalled () {
2013-10-07 11:12:28 +00:00
$passTheme = TRUE ;
2013-09-20 08:21:39 +00:00
# Twig is an absolute requirement for Poche to function. Abort immediately if the Composer installer hasn't been run yet
if ( ! self :: $canRenderTemplates ) {
2014-02-13 17:57:57 +00:00
$this -> notInstalledMessage [] = 'Twig does not seem to be installed. Please initialize the Composer installation to automatically fetch dependencies. You can also download <a href="http://wllbg.org/vendor">vendor.zip</a> and extract it in your wallabag folder.' ;
2013-10-07 11:12:28 +00:00
$passTheme = FALSE ;
2013-09-20 08:21:39 +00:00
}
2013-10-03 12:23:03 +00:00
if ( ! is_writable ( CACHE )) {
2013-10-07 11:12:28 +00:00
$this -> notInstalledMessage [] = 'You don\'t have write access on cache directory.' ;
2013-10-03 12:23:03 +00:00
self :: $canRenderTemplates = false ;
2013-10-07 11:12:28 +00:00
$passTheme = FALSE ;
2013-10-03 12:23:03 +00:00
}
2013-09-20 08:21:39 +00:00
# Check if the selected theme and its requirements are present
2014-01-28 10:19:06 +00:00
$theme = $this -> getTheme ();
if ( $theme != '' && ! is_dir ( THEME . '/' . $theme )) {
$this -> notInstalledMessage [] = 'The currently selected theme (' . $theme . ') does not seem to be properly installed (Missing directory: ' . THEME . '/' . $theme . ')' ;
2013-09-20 08:21:39 +00:00
self :: $canRenderTemplates = false ;
2013-10-07 11:12:28 +00:00
$passTheme = FALSE ;
2013-09-20 08:21:39 +00:00
}
2014-01-28 10:19:06 +00:00
$themeInfo = $this -> getThemeInfo ( $theme );
if ( isset ( $themeInfo [ 'requirements' ]) && is_array ( $themeInfo [ 'requirements' ])) {
foreach ( $themeInfo [ 'requirements' ] as $requiredTheme ) {
if ( ! is_dir ( THEME . '/' . $requiredTheme )) {
$this -> notInstalledMessage [] = 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')' ;
2013-09-20 08:21:39 +00:00
2014-01-28 10:19:06 +00:00
self :: $canRenderTemplates = false ;
2013-09-20 08:21:39 +00:00
2014-01-28 10:19:06 +00:00
$passTheme = FALSE ;
}
2013-09-20 08:21:39 +00:00
}
}
2013-10-07 11:12:28 +00:00
if ( ! $passTheme ) {
return FALSE ;
}
2013-09-20 08:21:39 +00:00
return true ;
}
2013-08-15 08:54:14 +00:00
/**
* all checks before installation .
2013-09-20 08:21:39 +00:00
* @ todo move HTML to template
2013-08-15 08:54:14 +00:00
* @ return boolean
*/
2013-09-20 08:21:39 +00:00
public function systemIsInstalled ()
2013-08-04 18:58:31 +00:00
{
2013-10-07 11:12:28 +00:00
$msg = TRUE ;
2013-09-20 08:21:39 +00:00
$configSalt = defined ( 'SALT' ) ? constant ( 'SALT' ) : '' ;
if ( empty ( $configSalt )) {
2013-10-07 11:12:28 +00:00
$this -> notInstalledMessage [] = 'You have not yet filled in the SALT value in the config.inc.php file.' ;
$msg = FALSE ;
}
if ( STORAGE == 'sqlite' && ! file_exists ( STORAGE_SQLITE )) {
2013-09-20 08:21:39 +00:00
Tools :: logm ( 'sqlite file doesn\'t exist' );
2013-10-07 11:12:28 +00:00
$this -> notInstalledMessage [] = 'sqlite file doesn\'t exist, you can find it in install folder. Copy it in /db folder.' ;
$msg = FALSE ;
}
if ( is_dir ( ROOT . '/install' ) && ! DEBUG_POCHE ) {
$this -> notInstalledMessage [] = 'you have to delete the /install folder before using poche.' ;
$msg = FALSE ;
}
if ( STORAGE == 'sqlite' && ! is_writable ( STORAGE_SQLITE )) {
2013-08-16 18:19:31 +00:00
Tools :: logm ( 'you don\'t have write access on sqlite file' );
2013-10-07 11:12:28 +00:00
$this -> notInstalledMessage [] = 'You don\'t have write access on sqlite file.' ;
$msg = FALSE ;
2013-08-16 18:19:31 +00:00
}
2013-09-20 08:21:39 +00:00
2013-10-07 11:12:28 +00:00
if ( ! $msg ) {
2013-09-20 08:21:39 +00:00
return false ;
2013-08-06 13:51:48 +00:00
}
2013-08-06 12:18:03 +00:00
2013-09-20 08:21:39 +00:00
return true ;
}
public function getNotInstalledMessage () {
return $this -> notInstalledMessage ;
2013-08-15 08:54:14 +00:00
}
2013-08-04 18:58:31 +00:00
2013-08-15 08:54:14 +00:00
private function initTpl ()
{
2013-09-20 08:21:39 +00:00
$loaderChain = new Twig_Loader_Chain ();
2014-01-28 10:19:06 +00:00
$theme = $this -> getTheme ();
2013-09-20 08:21:39 +00:00
# add the current theme as first to the loader chain so Twig will look there first for overridden template files
try {
2014-01-28 10:19:06 +00:00
$loaderChain -> addLoader ( new Twig_Loader_Filesystem ( THEME . '/' . $theme ));
2013-09-20 08:21:39 +00:00
} catch ( Twig_Error_Loader $e ) {
# @todo isInstalled() should catch this, inject Twig later
2014-01-28 10:19:06 +00:00
die ( 'The currently selected theme (' . $theme . ') does not seem to be properly installed (' . THEME . '/' . $theme . ' is missing)' );
2013-09-20 08:21:39 +00:00
}
# add all required themes to the loader chain
2014-01-28 10:19:06 +00:00
$themeInfo = $this -> getThemeInfo ( $theme );
if ( isset ( $themeInfo [ 'requirements' ]) && is_array ( $themeInfo [ 'requirements' ])) {
foreach ( $themeInfo [ 'requirements' ] as $requiredTheme ) {
try {
$loaderChain -> addLoader ( new Twig_Loader_Filesystem ( THEME . '/' . $requiredTheme ));
} catch ( Twig_Error_Loader $e ) {
# @todo isInstalled() should catch this, inject Twig later
die ( 'The required "' . $requiredTheme . '" theme is missing for the current theme (' . $theme . ')' );
}
2013-09-20 08:21:39 +00:00
}
}
2013-08-07 12:24:07 +00:00
if ( DEBUG_POCHE ) {
2014-01-28 10:19:06 +00:00
$twigParams = array ();
2013-09-20 08:21:39 +00:00
} else {
2014-01-28 10:19:06 +00:00
$twigParams = array ( 'cache' => CACHE );
2013-08-07 12:24:07 +00:00
}
2013-09-20 08:21:39 +00:00
2014-01-28 10:19:06 +00:00
$this -> tpl = new Twig_Environment ( $loaderChain , $twigParams );
2013-08-04 18:58:31 +00:00
$this -> tpl -> addExtension ( new Twig_Extensions_Extension_I18n ());
2013-09-20 08:21:39 +00:00
2013-08-05 13:54:37 +00:00
# filter to display domain name of an url
$filter = new Twig_SimpleFilter ( 'getDomain' , 'Tools::getDomain' );
$this -> tpl -> addFilter ( $filter );
2013-08-04 18:58:31 +00:00
2013-08-09 06:25:16 +00:00
# filter for reading time
$filter = new Twig_SimpleFilter ( 'getReadingTime' , 'Tools::getReadingTime' );
$this -> tpl -> addFilter ( $filter );
2013-08-04 18:58:31 +00:00
}
2014-01-28 10:19:06 +00:00
private function install ()
2013-08-04 18:58:31 +00:00
{
Tools :: logm ( 'poche still not installed' );
echo $this -> tpl -> render ( 'install.twig' , array (
2013-09-20 08:21:39 +00:00
'token' => Session :: getToken (),
'theme' => $this -> getTheme (),
'poche_url' => Tools :: getPocheUrl ()
2013-08-04 18:58:31 +00:00
));
if ( isset ( $_GET [ 'install' ])) {
if (( $_POST [ 'password' ] == $_POST [ 'password_repeat' ])
&& $_POST [ 'password' ] != " " && $_POST [ 'login' ] != " " ) {
# let's rock, install poche baby !
2013-08-16 18:19:31 +00:00
if ( $this -> store -> install ( $_POST [ 'login' ], Tools :: encodeString ( $_POST [ 'password' ] . $_POST [ 'login' ])))
{
Session :: logout ();
Tools :: logm ( 'poche is now installed' );
Tools :: redirect ();
}
2013-08-05 19:56:32 +00:00
}
else {
Tools :: logm ( 'error during installation' );
2013-08-04 18:58:31 +00:00
Tools :: redirect ();
}
}
exit ();
}
2013-09-20 08:21:39 +00:00
public function getTheme () {
return $this -> currentTheme ;
}
2013-10-07 12:26:25 +00:00
2014-01-28 10:19:06 +00:00
/**
* Provides theme information by parsing theme . ini file if present in the theme ' s root directory .
* In all cases , the following data will be returned :
* - name : theme ' s name , or key if the theme is unnamed ,
* - current : boolean informing if the theme is the current user theme .
*
* @ param string $theme Theme key ( directory name )
* @ return array | boolean Theme information , or false if the theme doesn ' t exist .
*/
public function getThemeInfo ( $theme ) {
if ( ! is_dir ( THEME . '/' . $theme )) {
return false ;
}
$themeIniFile = THEME . '/' . $theme . '/theme.ini' ;
$themeInfo = array ();
if ( is_file ( $themeIniFile ) && is_readable ( $themeIniFile )) {
$themeInfo = parse_ini_file ( $themeIniFile );
}
if ( $themeInfo === false ) {
$themeInfo = array ();
}
if ( ! isset ( $themeInfo [ 'name' ])) {
$themeInfo [ 'name' ] = $theme ;
}
$themeInfo [ 'current' ] = ( $theme === $this -> getTheme ());
return $themeInfo ;
2013-10-07 12:26:25 +00:00
}
2013-09-20 08:21:39 +00:00
public function getInstalledThemes () {
$handle = opendir ( THEME );
$themes = array ();
2014-01-28 10:19:06 +00:00
2013-09-20 08:21:39 +00:00
while (( $theme = readdir ( $handle )) !== false ) {
# Themes are stored in a directory, so all directory names are themes
# @todo move theme installation data to database
2014-01-28 10:19:06 +00:00
if ( ! is_dir ( THEME . '/' . $theme ) || in_array ( $theme , array ( '.' , '..' ))) {
2013-09-20 08:21:39 +00:00
continue ;
}
2014-01-28 10:19:06 +00:00
$themes [ $theme ] = $this -> getThemeInfo ( $theme );
2013-09-20 08:21:39 +00:00
}
2014-01-28 10:19:06 +00:00
2014-02-20 12:29:53 +00:00
ksort ( $themes );
2013-09-20 08:21:39 +00:00
return $themes ;
}
2013-08-04 18:58:31 +00:00
2014-01-28 10:19:06 +00:00
public function getLanguage () {
return $this -> currentLanguage ;
}
2013-10-07 12:26:25 +00:00
public function getInstalledLanguages () {
$handle = opendir ( LOCALE );
$languages = array ();
while (( $language = readdir ( $handle )) !== false ) {
# Languages are stored in a directory, so all directory names are languages
# @todo move language installation data to database
2014-02-26 13:43:49 +00:00
if ( ! is_dir ( LOCALE . '/' . $language ) || in_array ( $language , array ( '..' , '.' , 'tools' ))) {
2013-10-07 12:26:25 +00:00
continue ;
}
$current = false ;
if ( $language === $this -> getLanguage ()) {
$current = true ;
}
2014-02-26 13:43:49 +00:00
$languages [] = array ( 'name' => ( isset ( $this -> language_names [ $language ]) ? $this -> language_names [ $language ] : $language ), 'value' => $language , 'current' => $current );
2013-10-07 12:26:25 +00:00
}
return $languages ;
}
2013-08-06 13:51:48 +00:00
public function getDefaultConfig ()
2013-09-20 08:21:39 +00:00
{
2013-08-06 13:51:48 +00:00
return array (
'pager' => PAGINATION ,
'language' => LANG ,
2013-09-20 08:21:39 +00:00
'theme' => DEFAULT_THEME
);
2013-08-06 13:51:48 +00:00
}
2013-08-04 18:58:31 +00:00
/**
* Call action ( mark as fav , archive , delete , etc . )
*/
2014-02-14 12:59:27 +00:00
public function action ( $action , Url $url , $id = 0 , $import = FALSE , $autoclose = FALSE , $tags = null )
2013-08-04 18:58:31 +00:00
{
switch ( $action )
{
case 'add' :
2014-02-28 20:49:38 +00:00
if ( ! $import ) {
$content = Tools :: getPageContent ( $url );
$title = ( $content [ 'rss' ][ 'channel' ][ 'item' ][ 'title' ] != '' ) ? $content [ 'rss' ][ 'channel' ][ 'item' ][ 'title' ] : _ ( 'Untitled' );
$body = $content [ 'rss' ][ 'channel' ][ 'item' ][ 'description' ];
2013-08-25 18:10:23 +00:00
2014-02-28 20:49:38 +00:00
// clean content from prevent xss attack
$config = HTMLPurifier_Config :: createDefault ();
2014-03-07 12:52:52 +00:00
$config -> set ( 'Cache.SerializerPath' , CACHE );
2014-02-28 20:49:38 +00:00
$purifier = new HTMLPurifier ( $config );
$title = $purifier -> purify ( $title );
$body = $purifier -> purify ( $body );
}
else {
$title = '' ;
$body = '' ;
}
2014-02-21 14:44:13 +00:00
2014-02-14 15:27:22 +00:00
//search for possible duplicate if not in import mode
2014-03-14 07:54:44 +00:00
$duplicate = NULL ;
2014-02-14 15:27:22 +00:00
if ( ! $import ) {
$duplicate = $this -> store -> retrieveOneByURL ( $url -> getUrl (), $this -> user -> getId ());
}
2013-12-06 08:45:27 +00:00
if ( $this -> store -> add ( $url -> getUrl (), $title , $body , $this -> user -> getId ())) {
2013-08-25 18:10:23 +00:00
Tools :: logm ( 'add link ' . $url -> getUrl ());
$sequence = '' ;
if ( STORAGE == 'postgres' ) {
$sequence = 'entries_id_seq' ;
2013-08-04 18:58:31 +00:00
}
2013-08-25 18:10:23 +00:00
$last_id = $this -> store -> getLastId ( $sequence );
if ( DOWNLOAD_PICTURES ) {
2013-12-06 08:45:27 +00:00
$content = filtre_picture ( $body , $url -> getUrl (), $last_id );
2013-08-25 18:10:23 +00:00
Tools :: logm ( 'updating content article' );
$this -> store -> updateContent ( $last_id , $content , $this -> user -> getId ());
}
2014-02-14 15:27:22 +00:00
if ( $duplicate != NULL ) {
// duplicate exists, so, older entry needs to be deleted (as new entry should go to the top of list), BUT favorite mark and tags should be preserved
Tools :: logm ( 'link ' . $url -> getUrl () . ' is a duplicate' );
// 1) - preserve tags and favorite, then drop old entry
$this -> store -> reassignTags ( $duplicate [ 'id' ], $last_id );
if ( $duplicate [ 'is_fav' ]) {
$this -> store -> favoriteById ( $last_id , $this -> user -> getId ());
}
if ( $this -> store -> deleteById ( $duplicate [ 'id' ], $this -> user -> getId ())) {
Tools :: logm ( 'previous link ' . $url -> getUrl () . ' entry deleted' );
}
}
2013-08-25 18:10:23 +00:00
if ( ! $import ) {
$this -> messages -> add ( 's' , _ ( 'the link has been added successfully' ));
2013-08-04 18:58:31 +00:00
}
}
else {
2013-08-07 17:14:28 +00:00
if ( ! $import ) {
2013-08-25 18:10:23 +00:00
$this -> messages -> add ( 'e' , _ ( 'error during insertion : the link wasn\'t added' ));
Tools :: logm ( 'error during insertion : the link wasn\'t added ' . $url -> getUrl ());
2013-08-07 17:14:28 +00:00
}
}
2013-08-25 18:10:23 +00:00
2013-08-07 17:14:28 +00:00
if ( ! $import ) {
2013-10-27 06:37:05 +00:00
if ( $autoclose == TRUE ) {
Tools :: redirect ( '?view=home' );
} else {
2013-10-27 06:47:14 +00:00
Tools :: redirect ( '?view=home&closewin=true' );
2013-10-27 06:37:05 +00:00
}
2013-08-04 18:58:31 +00:00
}
break ;
case 'delete' :
2013-08-07 12:24:07 +00:00
$msg = 'delete link #' . $id ;
2013-08-06 13:51:48 +00:00
if ( $this -> store -> deleteById ( $id , $this -> user -> getId ())) {
2013-08-04 18:58:31 +00:00
if ( DOWNLOAD_PICTURES ) {
remove_directory ( ABS_PATH . $id );
}
2013-08-05 19:56:32 +00:00
$this -> messages -> add ( 's' , _ ( 'the link has been deleted successfully' ));
2013-08-04 18:58:31 +00:00
}
else {
2013-08-05 19:56:32 +00:00
$this -> messages -> add ( 'e' , _ ( 'the link wasn\'t deleted' ));
2013-08-07 12:24:07 +00:00
$msg = 'error : can\'t delete link #' . $id ;
2013-08-04 18:58:31 +00:00
}
2013-08-07 12:24:07 +00:00
Tools :: logm ( $msg );
2013-10-25 12:25:37 +00:00
Tools :: redirect ( '?' );
2013-08-04 18:58:31 +00:00
break ;
case 'toggle_fav' :
2013-08-06 13:51:48 +00:00
$this -> store -> favoriteById ( $id , $this -> user -> getId ());
2013-08-04 18:58:31 +00:00
Tools :: logm ( 'mark as favorite link #' . $id );
2013-08-07 17:14:28 +00:00
if ( ! $import ) {
Tools :: redirect ();
}
2013-08-04 18:58:31 +00:00
break ;
case 'toggle_archive' :
2013-08-06 13:51:48 +00:00
$this -> store -> archiveById ( $id , $this -> user -> getId ());
2013-08-04 18:58:31 +00:00
Tools :: logm ( 'archive link #' . $id );
2013-08-07 17:14:28 +00:00
if ( ! $import ) {
Tools :: redirect ();
}
2013-08-04 18:58:31 +00:00
break ;
2014-02-12 20:52:01 +00:00
case 'archive_all' :
$this -> store -> archiveAll ( $this -> user -> getId ());
Tools :: logm ( 'archive all links' );
if ( ! $import ) {
Tools :: redirect ();
}
break ;
2013-12-06 14:07:51 +00:00
case 'add_tag' :
2014-02-14 12:59:27 +00:00
if ( $import ){
$entry_id = $id ;
$tags = explode ( ',' , $tags );
}
else {
$tags = explode ( ',' , $_POST [ 'value' ]);
$entry_id = $_POST [ 'entry_id' ];
}
2014-02-19 12:25:28 +00:00
$entry = $this -> store -> retrieveOneById ( $entry_id , $this -> user -> getId ());
if ( ! $entry ) {
$this -> messages -> add ( 'e' , _ ( 'Article not found!' ));
Tools :: logm ( 'error : article not found' );
Tools :: redirect ();
}
2014-03-10 14:28:47 +00:00
//get all already set tags to preven duplicates
$already_set_tags = array ();
$entry_tags = $this -> store -> retrieveTagsByEntry ( $entry_id );
foreach ( $entry_tags as $tag ) {
$already_set_tags [] = $tag [ 'value' ];
}
2013-12-06 14:07:51 +00:00
foreach ( $tags as $key => $tag_value ) {
$value = trim ( $tag_value );
2014-03-10 14:28:47 +00:00
if ( $value && ! in_array ( $value , $already_set_tags )) {
$tag = $this -> store -> retrieveTagByValue ( $value );
if ( is_null ( $tag )) {
# we create the tag
$tag = $this -> store -> createTag ( $value );
$sequence = '' ;
if ( STORAGE == 'postgres' ) {
$sequence = 'tags_id_seq' ;
}
$tag_id = $this -> store -> getLastId ( $sequence );
}
else {
$tag_id = $tag [ 'id' ];
}
# we assign the tag to the article
$this -> store -> setTagToEntry ( $tag_id , $entry_id );
2013-12-06 14:07:51 +00:00
}
}
2014-02-14 12:59:27 +00:00
if ( ! $import ) {
Tools :: redirect ();
}
2013-12-06 14:07:51 +00:00
break ;
case 'remove_tag' :
$tag_id = $_GET [ 'tag_id' ];
2014-02-19 12:25:28 +00:00
$entry = $this -> store -> retrieveOneById ( $id , $this -> user -> getId ());
if ( ! $entry ) {
$this -> messages -> add ( 'e' , _ ( 'Article not found!' ));
Tools :: logm ( 'error : article not found' );
Tools :: redirect ();
}
2013-12-06 14:07:51 +00:00
$this -> store -> removeTagForEntry ( $id , $tag_id );
Tools :: redirect ();
break ;
2013-08-04 18:58:31 +00:00
default :
break ;
}
}
function displayView ( $view , $id = 0 )
{
$tpl_vars = array ();
switch ( $view )
{
case 'config' :
2014-03-01 18:10:17 +00:00
$dev_infos = $this -> getPocheVersion ( 'dev' );
$dev = trim ( $dev_infos [ 0 ]);
$check_time_dev = date ( 'd-M-Y H:i' , $dev_infos [ 1 ]);
$prod_infos = $this -> getPocheVersion ( 'prod' );
$prod = trim ( $prod_infos [ 0 ]);
$check_time_prod = date ( 'd-M-Y H:i' , $prod_infos [ 1 ]);
2013-10-07 11:19:34 +00:00
$compare_dev = version_compare ( POCHE , $dev );
$compare_prod = version_compare ( POCHE , $prod );
2013-09-20 08:21:39 +00:00
$themes = $this -> getInstalledThemes ();
2013-10-07 12:26:25 +00:00
$languages = $this -> getInstalledLanguages ();
2013-12-03 09:40:27 +00:00
$token = $this -> user -> getConfigValue ( 'token' );
2013-12-23 08:09:10 +00:00
$http_auth = ( isset ( $_SERVER [ 'PHP_AUTH_USER' ]) || isset ( $_SERVER [ 'REMOTE_USER' ])) ? true : false ;
2013-08-05 10:34:16 +00:00
$tpl_vars = array (
2013-09-20 08:21:39 +00:00
'themes' => $themes ,
2013-10-07 12:26:25 +00:00
'languages' => $languages ,
2013-08-05 10:34:16 +00:00
'dev' => $dev ,
'prod' => $prod ,
2014-03-01 18:10:17 +00:00
'check_time_dev' => $check_time_dev ,
'check_time_prod' => $check_time_prod ,
2013-08-05 10:34:16 +00:00
'compare_dev' => $compare_dev ,
'compare_prod' => $compare_prod ,
2013-12-03 09:40:27 +00:00
'token' => $token ,
'user_id' => $this -> user -> getId (),
2013-10-20 14:53:54 +00:00
'http_auth' => $http_auth ,
2013-08-05 10:34:16 +00:00
);
2013-08-04 18:58:31 +00:00
Tools :: logm ( 'config view' );
break ;
2013-12-06 13:03:14 +00:00
case 'edit-tags' :
# tags
2014-02-19 12:25:28 +00:00
$entry = $this -> store -> retrieveOneById ( $id , $this -> user -> getId ());
if ( ! $entry ) {
$this -> messages -> add ( 'e' , _ ( 'Article not found!' ));
Tools :: logm ( 'error : article not found' );
Tools :: redirect ();
}
2013-12-06 13:03:14 +00:00
$tags = $this -> store -> retrieveTagsByEntry ( $id );
$tpl_vars = array (
2013-12-06 14:07:51 +00:00
'entry_id' => $id ,
2013-12-06 13:03:14 +00:00
'tags' => $tags ,
2014-02-20 17:28:39 +00:00
'entry' => $entry ,
2013-12-06 13:22:29 +00:00
);
break ;
2013-12-06 12:15:06 +00:00
case 'tags' :
2013-12-06 13:37:42 +00:00
$token = $this -> user -> getConfigValue ( 'token' );
2014-03-10 14:28:47 +00:00
//if term is set - search tags for this term
$term = Tools :: checkVar ( 'term' );
$tags = $this -> store -> retrieveAllTags ( $this -> user -> getId (), $term );
if ( Tools :: isAjaxRequest ()) {
$result = array ();
foreach ( $tags as $tag ) {
$result [] = $tag [ 'value' ];
}
echo json_encode ( $result );
exit ;
}
2013-12-06 12:15:06 +00:00
$tpl_vars = array (
2013-12-06 13:37:42 +00:00
'token' => $token ,
'user_id' => $this -> user -> getId (),
2013-12-06 12:15:06 +00:00
'tags' => $tags ,
);
break ;
2014-03-22 10:09:18 +00:00
2014-04-02 15:44:47 +00:00
case 'search' :
if ( isset ( $_GET [ 'search' ])){
$search = filter_var ( $_GET [ 'search' ], FILTER_SANITIZE_STRING );
$tpl_vars [ 'entries' ] = $this -> store -> search ( $search , $this -> user -> getId ());
$count = count ( $tpl_vars [ 'entries' ]);
$this -> pagination -> set_total ( $count );
$page_links = str_replace ( array ( 'previous' , 'next' ), array ( _ ( 'previous' ), _ ( 'next' )),
$this -> pagination -> page_links ( '?view=' . $view . '?search=' . $search . '&sort=' . $_SESSION [ 'sort' ] . '&' ));
$tpl_vars [ 'page_links' ] = $page_links ;
$tpl_vars [ 'nb_results' ] = $count ;
$tpl_vars [ 'search_term' ] = $search ;
}
2014-03-22 10:09:18 +00:00
break ;
2013-08-04 18:58:31 +00:00
case 'view' :
2013-08-06 13:51:48 +00:00
$entry = $this -> store -> retrieveOneById ( $id , $this -> user -> getId ());
2013-08-04 18:58:31 +00:00
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 ;
2013-09-20 12:09:26 +00:00
}
2013-09-08 18:54:11 +00:00
2013-09-20 12:09:26 +00:00
# flattr checking
$flattr = new FlattrItem ();
2013-12-06 12:02:38 +00:00
$flattr -> checkItem ( $entry [ 'url' ], $entry [ 'id' ]);
# tags
$tags = $this -> store -> retrieveTagsByEntry ( $entry [ 'id' ]);
2013-09-08 18:54:11 +00:00
2013-09-20 12:09:26 +00:00
$tpl_vars = array (
2013-12-06 12:02:38 +00:00
'entry' => $entry ,
'content' => $content ,
'flattr' => $flattr ,
'tags' => $tags
2013-09-20 12:09:26 +00:00
);
2013-08-04 18:58:31 +00:00
}
else {
2013-08-09 20:15:40 +00:00
Tools :: logm ( 'error in view call : entry is null' );
2013-08-04 18:58:31 +00:00
}
break ;
2014-02-20 17:28:39 +00:00
default : # home, favorites, archive and tag views
2013-08-04 18:58:31 +00:00
$tpl_vars = array (
2013-08-27 14:02:25 +00:00
'entries' => '' ,
'page_links' => '' ,
2013-08-28 17:12:11 +00:00
'nb_results' => '' ,
2014-02-28 11:08:11 +00:00
'listmode' => ( isset ( $_COOKIE [ 'listmode' ]) ? true : false ),
2013-08-04 18:58:31 +00:00
);
2013-10-03 12:46:46 +00:00
2014-02-20 17:28:39 +00:00
//if id is given - we retrive entries by tag: id is tag id
if ( $id ) {
$tpl_vars [ 'tag' ] = $this -> store -> retrieveTag ( $id , $this -> user -> getId ());
$tpl_vars [ 'id' ] = intval ( $id );
}
$count = $this -> store -> getEntriesByViewCount ( $view , $this -> user -> getId (), $id );
if ( $count > 0 ) {
$this -> pagination -> set_total ( $count );
2014-02-07 15:49:27 +00:00
$page_links = str_replace ( array ( 'previous' , 'next' ), array ( _ ( 'previous' ), _ ( 'next' )),
2014-02-20 17:28:39 +00:00
$this -> pagination -> page_links ( '?view=' . $view . '&sort=' . $_SESSION [ 'sort' ] . (( $id ) ? '&id=' . $id : '' ) . '&' ));
$tpl_vars [ 'entries' ] = $this -> store -> getEntriesByView ( $view , $this -> user -> getId (), $this -> pagination -> get_limit (), $id );
2013-08-27 14:02:25 +00:00
$tpl_vars [ 'page_links' ] = $page_links ;
2014-02-20 17:28:39 +00:00
$tpl_vars [ 'nb_results' ] = $count ;
2013-08-27 14:02:25 +00:00
}
2013-08-05 19:56:32 +00:00
Tools :: logm ( 'display ' . $view . ' view' );
2013-08-04 18:58:31 +00:00
break ;
}
return $tpl_vars ;
}
2013-08-04 19:42:46 +00:00
2013-08-08 10:33:02 +00:00
/**
* 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
*/
2013-08-04 19:42:46 +00:00
public function updatePassword ()
{
2013-08-05 13:54:37 +00:00
if ( MODE_DEMO ) {
2013-08-06 13:51:48 +00:00
$this -> messages -> add ( 'i' , _ ( 'in demo mode, you can\'t update your password' ));
2013-08-05 13:54:37 +00:00
Tools :: logm ( 'in demo mode, you can\'t do this' );
2013-08-05 19:56:32 +00:00
Tools :: redirect ( '?view=config' );
2013-08-05 13:54:37 +00:00
}
else {
if ( isset ( $_POST [ 'password' ]) && isset ( $_POST [ 'password_repeat' ])) {
if ( $_POST [ 'password' ] == $_POST [ 'password_repeat' ] && $_POST [ 'password' ] != " " ) {
2013-08-06 13:51:48 +00:00
$this -> messages -> add ( 's' , _ ( 'your password has been updated' ));
$this -> store -> updatePassword ( $this -> user -> getId (), Tools :: encodeString ( $_POST [ 'password' ] . $this -> user -> getUsername ()));
2013-08-04 19:42:46 +00:00
Session :: logout ();
2013-08-06 13:51:48 +00:00
Tools :: logm ( 'password updated' );
2013-08-04 19:42:46 +00:00
Tools :: redirect ();
}
else {
2013-08-06 13:51:48 +00:00
$this -> messages -> add ( 'e' , _ ( 'the two fields have to be filled & the password must be the same in the two fields' ));
2013-08-05 19:56:32 +00:00
Tools :: redirect ( '?view=config' );
2013-08-04 19:42:46 +00:00
}
}
}
}
2013-09-20 08:21:39 +00:00
public function updateTheme ()
{
# no data
if ( empty ( $_POST [ 'theme' ])) {
}
# we are not going to change it to the current theme...
if ( $_POST [ 'theme' ] == $this -> getTheme ()) {
$this -> messages -> add ( 'w' , _ ( 'still using the "' . $this -> getTheme () . '" theme!' ));
Tools :: redirect ( '?view=config' );
}
$themes = $this -> getInstalledThemes ();
$actualTheme = false ;
2014-01-28 10:19:06 +00:00
foreach ( array_keys ( $themes ) as $theme ) {
if ( $theme == $_POST [ 'theme' ]) {
2013-09-20 08:21:39 +00:00
$actualTheme = true ;
break ;
}
}
if ( ! $actualTheme ) {
$this -> messages -> add ( 'e' , _ ( 'that theme does not seem to be installed' ));
Tools :: redirect ( '?view=config' );
}
$this -> store -> updateUserConfig ( $this -> user -> getId (), 'theme' , $_POST [ 'theme' ]);
$this -> messages -> add ( 's' , _ ( 'you have changed your theme preferences' ));
$currentConfig = $_SESSION [ 'poche_user' ] -> config ;
$currentConfig [ 'theme' ] = $_POST [ 'theme' ];
$_SESSION [ 'poche_user' ] -> setConfig ( $currentConfig );
2014-02-27 12:24:29 +00:00
$this -> emptyCache ();
2013-09-20 08:21:39 +00:00
Tools :: redirect ( '?view=config' );
}
2013-08-04 19:42:46 +00:00
2013-10-07 12:26:25 +00:00
public function updateLanguage ()
{
# no data
if ( empty ( $_POST [ 'language' ])) {
}
# we are not going to change it to the current language...
if ( $_POST [ 'language' ] == $this -> getLanguage ()) {
$this -> messages -> add ( 'w' , _ ( 'still using the "' . $this -> getLanguage () . '" language!' ));
Tools :: redirect ( '?view=config' );
}
$languages = $this -> getInstalledLanguages ();
$actualLanguage = false ;
foreach ( $languages as $language ) {
2014-02-21 14:24:33 +00:00
if ( $language [ 'value' ] == $_POST [ 'language' ]) {
2013-10-07 12:26:25 +00:00
$actualLanguage = true ;
break ;
}
}
if ( ! $actualLanguage ) {
$this -> messages -> add ( 'e' , _ ( 'that language does not seem to be installed' ));
Tools :: redirect ( '?view=config' );
}
$this -> store -> updateUserConfig ( $this -> user -> getId (), 'language' , $_POST [ 'language' ]);
$this -> messages -> add ( 's' , _ ( 'you have changed your language preferences' ));
$currentConfig = $_SESSION [ 'poche_user' ] -> config ;
$currentConfig [ 'language' ] = $_POST [ 'language' ];
$_SESSION [ 'poche_user' ] -> setConfig ( $currentConfig );
2014-02-27 12:26:07 +00:00
$this -> emptyCache ();
2013-10-07 12:26:25 +00:00
Tools :: redirect ( '?view=config' );
2014-03-22 10:09:18 +00:00
}
2013-10-20 14:53:54 +00:00
/**
* get credentials from differents sources
* it redirects the user to the $referer link
* @ return array
*/
2013-12-23 08:09:10 +00:00
private function credentials () {
if ( isset ( $_SERVER [ 'PHP_AUTH_USER' ])) {
2014-01-30 14:35:31 +00:00
return array ( $_SERVER [ 'PHP_AUTH_USER' ], 'php_auth' , true );
2013-12-23 08:09:10 +00:00
}
if ( ! empty ( $_POST [ 'login' ]) && ! empty ( $_POST [ 'password' ])) {
2014-01-30 14:35:31 +00:00
return array ( $_POST [ 'login' ], $_POST [ 'password' ], false );
2013-12-23 08:09:10 +00:00
}
if ( isset ( $_SERVER [ 'REMOTE_USER' ])) {
2014-01-30 14:35:31 +00:00
return array ( $_SERVER [ 'REMOTE_USER' ], 'http_auth' , true );
2013-12-23 08:09:10 +00:00
}
2013-12-23 09:35:09 +00:00
2014-01-30 14:35:31 +00:00
return array ( false , false , false );
}
2013-10-20 14:53:54 +00:00
2013-08-08 10:33:02 +00:00
/**
* 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
*/
2013-08-04 19:42:46 +00:00
public function login ( $referer )
{
2014-01-30 14:35:31 +00:00
list ( $login , $password , $isauthenticated ) = $this -> credentials ();
2013-10-20 14:53:54 +00:00
if ( $login === false || $password === false ) {
$this -> messages -> add ( 'e' , _ ( 'login failed: you have to fill all fields' ));
Tools :: logm ( 'login failed' );
Tools :: redirect ();
}
if ( ! empty ( $login ) && ! empty ( $password )) {
2014-01-30 14:35:31 +00:00
$user = $this -> store -> login ( $login , Tools :: encodeString ( $password . $login ), $isauthenticated );
2013-08-06 12:18:03 +00:00
if ( $user != array ()) {
# Save login into Session
2014-01-30 14:35:31 +00:00
$longlastingsession = isset ( $_POST [ 'longlastingsession' ]);
$passwordTest = ( $isauthenticated ) ? $user [ 'password' ] : Tools :: encodeString ( $password . $login );
Session :: login ( $user [ 'username' ], $user [ 'password' ], $login , $passwordTest , $longlastingsession , array ( 'poche_user' => new User ( $user )));
2014-02-12 19:04:47 +00:00
$this -> messages -> add ( 's' , _ ( 'welcome to your wallabag' ));
2013-08-06 13:51:48 +00:00
Tools :: logm ( 'login successful' );
2013-08-04 19:42:46 +00:00
Tools :: redirect ( $referer );
}
2013-08-06 13:51:48 +00:00
$this -> messages -> add ( 'e' , _ ( 'login failed: bad login or password' ));
2013-08-04 19:42:46 +00:00
Tools :: logm ( 'login failed' );
Tools :: redirect ();
}
}
2013-08-08 10:33:02 +00:00
/**
* log out the poche user . It cleans the session .
* @ todo add the return value
* @ return boolean
*/
2013-08-04 19:42:46 +00:00
public function logout ()
{
2013-08-06 12:18:03 +00:00
$this -> user = array ();
2013-08-04 19:42:46 +00:00
Session :: logout ();
2013-08-07 17:14:28 +00:00
Tools :: logm ( 'logout' );
2013-08-04 19:42:46 +00:00
Tools :: redirect ();
}
2013-08-08 10:33:02 +00:00
/**
* import from Instapaper . poche needs a ./ instapaper - export . html file
* @ todo add the return value
2013-08-24 13:59:51 +00:00
* @ param string $targetFile the file used for importing
2013-08-08 10:33:02 +00:00
* @ return boolean
*/
2013-08-24 13:59:51 +00:00
private function importFromInstapaper ( $targetFile )
2013-08-04 19:42:46 +00:00
{
2013-08-05 08:32:15 +00:00
# TODO gestion des articles favs
2013-08-05 07:43:33 +00:00
$html = new simple_html_dom ();
2013-08-24 13:59:51 +00:00
$html -> load_file ( $targetFile );
2013-08-07 17:14:28 +00:00
Tools :: logm ( 'starting import from instapaper' );
2013-08-05 07:43:33 +00:00
$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 ));
2013-08-07 17:14:28 +00:00
$this -> action ( 'add' , $url , 0 , TRUE );
2013-08-05 07:43:33 +00:00
if ( $read == '1' ) {
2013-08-07 17:14:28 +00:00
$sequence = '' ;
if ( STORAGE == 'postgres' ) {
$sequence = 'entries_id_seq' ;
}
$last_id = $this -> store -> getLastId ( $sequence );
$this -> action ( 'toggle_archive' , $url , $last_id , TRUE );
2013-08-05 07:43:33 +00:00
}
}
2013-08-05 08:32:15 +00:00
# the second <ol> is for read links
2013-08-05 07:43:33 +00:00
$read = 1 ;
}
2014-03-14 07:54:44 +00:00
$unlink = unlink ( $targetFile );
2014-02-28 20:49:38 +00:00
$this -> messages -> add ( 's' , _ ( 'import from instapaper completed. You have to execute the cron to fetch content.' ));
2013-08-04 20:35:08 +00:00
Tools :: logm ( 'import from instapaper completed' );
Tools :: redirect ();
}
2013-08-04 19:42:46 +00:00
2013-08-08 10:33:02 +00:00
/**
* import from Pocket . poche needs a ./ ril_export . html file
* @ todo add the return value
2013-08-24 13:59:51 +00:00
* @ param string $targetFile the file used for importing
2013-08-08 10:33:02 +00:00
* @ return boolean
*/
2013-08-24 13:59:51 +00:00
private function importFromPocket ( $targetFile )
2013-08-04 20:35:08 +00:00
{
2013-08-05 08:32:15 +00:00
# TODO gestion des articles favs
2013-08-04 20:35:08 +00:00
$html = new simple_html_dom ();
2013-08-24 13:59:51 +00:00
$html -> load_file ( $targetFile );
2013-08-07 17:14:28 +00:00
Tools :: logm ( 'starting import from pocket' );
2013-08-04 20:35:08 +00:00
$read = 0 ;
$errors = array ();
foreach ( $html -> find ( 'ul' ) as $ul )
{
foreach ( $ul -> find ( 'li' ) as $li )
2013-08-04 19:42:46 +00:00
{
2013-08-04 20:35:08 +00:00
$a = $li -> find ( 'a' );
$url = new Url ( base64_encode ( $a [ 0 ] -> href ));
2013-08-07 17:14:28 +00:00
$this -> action ( 'add' , $url , 0 , TRUE );
2014-02-14 12:59:27 +00:00
$sequence = '' ;
if ( STORAGE == 'postgres' ) {
$sequence = 'entries_id_seq' ;
}
$last_id = $this -> store -> getLastId ( $sequence );
2013-08-04 20:35:08 +00:00
if ( $read == '1' ) {
2013-08-07 17:14:28 +00:00
$this -> action ( 'toggle_archive' , $url , $last_id , TRUE );
2013-08-04 19:42:46 +00:00
}
2014-02-14 12:59:27 +00:00
$tags = $a [ 0 ] -> tags ;
if ( ! empty ( $tags )) {
$this -> action ( 'add_tag' , $url , $last_id , true , false , $tags );
}
2013-08-04 19:42:46 +00:00
}
2013-08-05 08:32:15 +00:00
# the second <ul> is for read links
2013-08-04 20:35:08 +00:00
$read = 1 ;
2013-08-04 19:42:46 +00:00
}
2014-03-14 07:54:44 +00:00
$unlink = unlink ( $targetFile );
2014-02-28 20:49:38 +00:00
$this -> messages -> add ( 's' , _ ( 'import from pocket completed. You have to execute the cron to fetch content.' ));
2013-08-04 20:35:08 +00:00
Tools :: logm ( 'import from pocket completed' );
Tools :: redirect ();
}
2013-08-04 19:42:46 +00:00
2013-08-08 10:33:02 +00:00
/**
* import from Readability . poche needs a ./ readability file
* @ todo add the return value
2013-08-24 13:59:51 +00:00
* @ param string $targetFile the file used for importing
2013-08-08 10:33:02 +00:00
* @ return boolean
*/
2013-08-24 13:59:51 +00:00
private function importFromReadability ( $targetFile )
2013-08-04 20:35:08 +00:00
{
2013-08-05 08:32:15 +00:00
# TODO gestion des articles lus / favs
2013-08-24 13:59:51 +00:00
$str_data = file_get_contents ( $targetFile );
2013-08-04 20:35:08 +00:00
$data = json_decode ( $str_data , true );
2013-08-07 17:14:28 +00:00
Tools :: logm ( 'starting import from Readability' );
2013-08-15 09:29:28 +00:00
$count = 0 ;
2013-08-04 20:35:08 +00:00
foreach ( $data as $key => $value ) {
2013-08-15 09:29:28 +00:00
$url = NULL ;
$favorite = FALSE ;
$archive = FALSE ;
2014-01-03 14:18:13 +00:00
foreach ( $value as $item ) {
foreach ( $item as $attr => $value ) {
if ( $attr == 'article__url' ) {
$url = new Url ( base64_encode ( $value ));
2013-08-15 09:29:28 +00:00
}
2014-01-03 14:18:13 +00:00
$sequence = '' ;
if ( STORAGE == 'postgres' ) {
$sequence = 'entries_id_seq' ;
}
if ( $value == 'true' ) {
if ( $attr == 'favorite' ) {
$favorite = TRUE ;
}
if ( $attr == 'archive' ) {
$archive = TRUE ;
}
2013-08-15 09:29:28 +00:00
}
}
2014-01-03 14:18:13 +00:00
# we can add the url
if ( ! is_null ( $url ) && $url -> isCorrect ()) {
$this -> action ( 'add' , $url , 0 , TRUE );
$count ++ ;
if ( $favorite ) {
$last_id = $this -> store -> getLastId ( $sequence );
$this -> action ( 'toggle_fav' , $url , $last_id , TRUE );
}
if ( $archive ) {
$last_id = $this -> store -> getLastId ( $sequence );
$this -> action ( 'toggle_archive' , $url , $last_id , TRUE );
}
2013-08-07 17:14:28 +00:00
}
2013-08-04 19:42:46 +00:00
}
}
2014-03-14 07:54:44 +00:00
unlink ( $targetFile );
2014-02-28 20:49:38 +00:00
$this -> messages -> add ( 's' , _ ( 'import from Readability completed. You have to execute the cron to fetch content.' ));
2013-08-04 20:35:08 +00:00
Tools :: logm ( 'import from Readability completed' );
Tools :: redirect ();
2013-08-04 19:42:46 +00:00
}
2014-01-07 19:21:43 +00:00
/**
* import from Poche exported file
* @ param string $targetFile the file used for importing
* @ return boolean
*/
private function importFromPoche ( $targetFile )
{
$str_data = file_get_contents ( $targetFile );
$data = json_decode ( $str_data , true );
Tools :: logm ( 'starting import from Poche' );
$sequence = '' ;
if ( STORAGE == 'postgres' ) {
$sequence = 'entries_id_seq' ;
}
$count = 0 ;
foreach ( $data as $value ) {
$url = new Url ( base64_encode ( $value [ 'url' ]));
$favorite = ( $value [ 'is_fav' ] == - 1 );
$archive = ( $value [ 'is_read' ] == - 1 );
# we can add the url
if ( ! is_null ( $url ) && $url -> isCorrect ()) {
$this -> action ( 'add' , $url , 0 , TRUE );
$count ++ ;
if ( $favorite ) {
$last_id = $this -> store -> getLastId ( $sequence );
$this -> action ( 'toggle_fav' , $url , $last_id , TRUE );
}
if ( $archive ) {
$last_id = $this -> store -> getLastId ( $sequence );
$this -> action ( 'toggle_archive' , $url , $last_id , TRUE );
}
}
}
2014-03-14 07:54:44 +00:00
unlink ( $targetFile );
2014-02-28 20:49:38 +00:00
$this -> messages -> add ( 's' , _ ( 'import from Poche completed. You have to execute the cron to fetch content.' ));
2014-01-07 19:21:43 +00:00
Tools :: logm ( 'import from Poche completed' );
Tools :: redirect ();
}
2013-08-08 10:33:02 +00:00
/**
* 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
*/
2013-08-04 20:35:08 +00:00
public function import ( $from )
2013-08-04 19:42:46 +00:00
{
2013-08-24 13:59:51 +00:00
$providers = array (
'pocket' => 'importFromPocket' ,
'readability' => 'importFromReadability' ,
2014-01-07 19:21:43 +00:00
'instapaper' => 'importFromInstapaper' ,
'poche' => 'importFromPoche' ,
2013-08-24 13:59:51 +00:00
);
if ( ! isset ( $providers [ $from ])) {
$this -> messages -> add ( 'e' , _ ( 'Unknown import provider.' ));
Tools :: redirect ();
2013-08-04 20:35:08 +00:00
}
2013-08-24 13:59:51 +00:00
2014-02-28 19:36:32 +00:00
$targetFile = CACHE . '/' . constant ( strtoupper ( $from ) . '_FILE' );
2013-08-24 13:59:51 +00:00
if ( ! file_exists ( $targetFile )) {
$this -> messages -> add ( 'e' , _ ( 'Could not find required "' . $targetFile . '" import file.' ));
Tools :: redirect ();
2013-08-04 20:35:08 +00:00
}
2013-08-24 13:59:51 +00:00
$this -> $providers [ $from ]( $targetFile );
2013-08-04 20:35:08 +00:00
}
2013-08-04 19:42:46 +00:00
2014-02-28 19:36:32 +00:00
public function uploadFile () {
if ( isset ( $_FILES [ 'file' ]))
{
$dir = CACHE . '/' ;
$file = basename ( $_FILES [ 'file' ][ 'name' ]);
if ( move_uploaded_file ( $_FILES [ 'file' ][ 'tmp_name' ], $dir . $file )) {
$this -> messages -> add ( 's' , _ ( 'File uploaded. You can now execute import.' ));
}
else {
$this -> messages -> add ( 'e' , _ ( 'Error while importing file. Do you have access to upload it?' ));
}
}
Tools :: redirect ( '?view=config' );
}
2013-08-08 10:33:02 +00:00
/**
* export poche entries in json
* @ return json all poche entries
*/
2013-08-04 20:35:08 +00:00
public function export ()
{
2014-03-28 15:53:06 +00:00
$filename = " wallabag-export- " . $this -> user -> getId () . " - " . date ( " Y-m-d " ) . " .json " ;
header ( 'Content-Disposition: attachment; filename=' . $filename );
2013-08-06 13:51:48 +00:00
$entries = $this -> store -> retrieveAll ( $this -> user -> getId ());
2013-08-04 20:35:08 +00:00
echo $this -> tpl -> render ( 'export.twig' , array (
'export' => Tools :: renderJson ( $entries ),
));
Tools :: logm ( 'export view' );
2013-08-04 19:42:46 +00:00
}
2013-08-05 10:34:16 +00:00
2013-08-08 10:33:02 +00:00
/**
2013-08-08 11:49:57 +00:00
* Checks online the latest version of poche and cache it
2013-08-08 10:33:02 +00:00
* @ param string $which 'prod' or 'dev'
* @ return string latest $which version
*/
2013-08-05 10:34:16 +00:00
private function getPocheVersion ( $which = 'prod' )
{
$cache_file = CACHE . '/' . $which ;
2014-03-01 18:10:17 +00:00
$check_time = time ();
2013-08-08 11:49:57 +00:00
# checks if the cached version file exists
2013-08-05 10:34:16 +00:00
if ( file_exists ( $cache_file ) && ( filemtime ( $cache_file ) > ( time () - 86400 ))) {
$version = file_get_contents ( $cache_file );
2014-03-01 18:10:17 +00:00
$check_time = filemtime ( $cache_file );
2013-08-05 10:34:16 +00:00
} else {
2014-01-28 09:49:57 +00:00
$version = file_get_contents ( 'http://static.wallabag.org/versions/' . $which );
2013-08-05 10:34:16 +00:00
file_put_contents ( $cache_file , $version , LOCK_EX );
}
2014-03-01 18:10:17 +00:00
return array ( $version , $check_time );
2013-08-05 10:34:16 +00:00
}
2013-12-03 09:40:27 +00:00
public function generateToken ()
{
if ( ini_get ( 'open_basedir' ) === '' ) {
2014-03-26 16:19:57 +00:00
if ( strtoupper ( substr ( PHP_OS , 0 , 3 )) === 'WIN' ) {
echo 'This is a server using Windows!' ;
// alternative to /dev/urandom for Windows
$token = substr ( base64_encode ( uniqid ( mt_rand (), true )), 0 , 20 );
} else {
$token = substr ( base64_encode ( file_get_contents ( '/dev/urandom' , false , null , 0 , 20 )), 0 , 15 );
}
2013-12-03 09:40:27 +00:00
}
else {
$token = substr ( base64_encode ( uniqid ( mt_rand (), true )), 0 , 20 );
}
2014-02-12 18:58:49 +00:00
$token = str_replace ( '+' , '' , $token );
2013-12-03 09:40:27 +00:00
$this -> store -> updateUserConfig ( $this -> user -> getId (), 'token' , $token );
$currentConfig = $_SESSION [ 'poche_user' ] -> config ;
$currentConfig [ 'token' ] = $token ;
$_SESSION [ 'poche_user' ] -> setConfig ( $currentConfig );
2014-02-23 08:56:21 +00:00
Tools :: redirect ();
2013-12-03 09:40:27 +00:00
}
2013-12-06 13:37:42 +00:00
public function generateFeeds ( $token , $user_id , $tag_id , $type = 'home' )
2013-12-03 09:40:27 +00:00
{
2013-12-06 13:37:42 +00:00
$allowed_types = array ( 'home' , 'fav' , 'archive' , 'tag' );
2013-12-03 09:40:27 +00:00
$config = $this -> store -> getConfigUser ( $user_id );
2014-03-10 07:10:03 +00:00
if ( $config == null ) {
die ( _ ( 'User with this id (' . $user_id . ') does not exist.' ));
}
2013-12-03 09:40:27 +00:00
if ( ! in_array ( $type , $allowed_types ) ||
$token != $config [ 'token' ]) {
die ( _ ( 'Uh, there is a problem while generating feeds.' ));
}
// Check the token
2013-12-06 09:14:59 +00:00
$feed = new FeedWriter ( RSS2 );
2014-02-13 07:57:44 +00:00
$feed -> setTitle ( 'wallabag — ' . $type . ' feed' );
2013-12-03 09:40:27 +00:00
$feed -> setLink ( Tools :: getPocheUrl ());
2014-03-01 12:09:37 +00:00
$feed -> setChannelElement ( 'pubDate' , date ( DATE_RSS , time ()));
$feed -> setChannelElement ( 'generator' , 'wallabag' );
$feed -> setDescription ( 'wallabag ' . $type . ' elements' );
2013-12-03 09:40:27 +00:00
2013-12-06 13:37:42 +00:00
if ( $type == 'tag' ) {
2014-02-19 12:25:28 +00:00
$entries = $this -> store -> retrieveEntriesByTag ( $tag_id , $user_id );
2013-12-06 13:37:42 +00:00
}
else {
$entries = $this -> store -> getEntriesByView ( $type , $user_id );
}
2013-12-03 09:40:27 +00:00
if ( count ( $entries ) > 0 ) {
foreach ( $entries as $entry ) {
$newItem = $feed -> createNewItem ();
2014-01-03 09:15:05 +00:00
$newItem -> setTitle ( $entry [ 'title' ]);
2014-03-14 08:35:48 +00:00
$newItem -> setLink ( $entry [ 'url' ]);
2013-12-03 09:40:27 +00:00
$newItem -> setDate ( time ());
$newItem -> setDescription ( $entry [ 'content' ]);
$feed -> addItem ( $newItem );
}
}
$feed -> genarateFeed ();
exit ;
}
2014-02-14 14:11:57 +00:00
public function emptyCache () {
$files = new RecursiveIteratorIterator (
new RecursiveDirectoryIterator ( CACHE , RecursiveDirectoryIterator :: SKIP_DOTS ),
RecursiveIteratorIterator :: CHILD_FIRST
);
foreach ( $files as $fileinfo ) {
$todo = ( $fileinfo -> isDir () ? 'rmdir' : 'unlink' );
$todo ( $fileinfo -> getRealPath ());
}
Tools :: logm ( 'empty cache' );
$this -> messages -> add ( 's' , _ ( 'Cache deleted.' ));
Tools :: redirect ();
}
2013-10-20 14:53:54 +00:00
}