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
2014-07-11 14:03:59 +00:00
* @ license http :// opensource . org / licenses / MIT see COPYING file
2013-08-04 18:58:31 +00:00
*/
2014-04-02 17:55:19 +00:00
2014-07-11 14:03:59 +00:00
final class Tools
2013-08-04 18:58:31 +00:00
{
2014-07-11 14:03:59 +00:00
/**
* Initialize PHP environment
*/
2013-08-04 18:58:31 +00:00
public static function initPhp ()
{
define ( 'START_TIME' , microtime ( true ));
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' );
}
2014-07-11 14:03:59 +00:00
/**
* Get wallabag instance URL
*
* @ return string
*/
2013-08-04 18:58:31 +00:00
public static function getPocheUrl ()
{
$https = ( ! empty ( $_SERVER [ 'HTTPS' ])
&& ( strtolower ( $_SERVER [ 'HTTPS' ]) == 'on' ))
|| ( isset ( $_SERVER [ " SERVER_PORT " ])
2013-10-07 10:30:40 +00:00
&& $_SERVER [ " SERVER_PORT " ] == '443' ) // HTTPS detection.
2014-04-02 17:55:19 +00:00
|| ( isset ( $_SERVER [ " SERVER_PORT " ]) //Custom HTTPS port detection
2014-02-03 11:46:09 +00:00
&& $_SERVER [ " SERVER_PORT " ] == SSL_PORT )
|| ( isset ( $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ])
&& $_SERVER [ 'HTTP_X_FORWARDED_PROTO' ] == 'https' );
2013-10-07 10:30:40 +00:00
2013-08-04 18:58:31 +00:00
$serverport = ( ! isset ( $_SERVER [ " SERVER_PORT " ])
|| $_SERVER [ " SERVER_PORT " ] == '80'
|| ( $https && $_SERVER [ " SERVER_PORT " ] == '443' )
2013-10-07 10:47:13 +00:00
|| ( $https && $_SERVER [ " SERVER_PORT " ] == SSL_PORT ) //Custom HTTPS port detection
2013-08-04 18:58:31 +00:00
? '' : ':' . $_SERVER [ " SERVER_PORT " ]);
$scriptname = str_replace ( '/index.php' , '/' , $_SERVER [ " SCRIPT_NAME " ]);
2013-11-05 09:13:55 +00:00
if ( ! isset ( $_SERVER [ " HTTP_HOST " ])) {
2013-08-04 18:58:31 +00:00
return $scriptname ;
}
2014-04-07 13:44:05 +00:00
$host = ( isset ( $_SERVER [ 'HTTP_X_FORWARDED_HOST' ]) ? $_SERVER [ 'HTTP_X_FORWARDED_HOST' ] : ( isset ( $_SERVER [ 'HTTP_HOST' ]) ? $_SERVER [ 'HTTP_HOST' ] : $_SERVER [ 'SERVER_NAME' ]));
2014-05-29 16:32:55 +00:00
if ( strpos ( $host , ':' ) !== false ) {
$serverport = '' ;
}
2014-06-02 15:00:09 +00:00
2013-08-04 18:58:31 +00:00
return 'http' . ( $https ? 's' : '' ) . '://'
2014-04-07 13:44:05 +00:00
. $host . $serverport . $scriptname ;
2013-08-04 18:58:31 +00:00
}
2014-07-11 14:03:59 +00:00
/**
* Redirects to a URL
*
* @ param string $url
*/
2013-08-04 18:58:31 +00:00
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 ;
}
}
2014-07-11 14:03:59 +00:00
2013-08-07 12:24:07 +00:00
self :: logm ( 'redirect to ' . $url );
2013-08-04 18:58:31 +00:00
header ( 'Location: ' . $url );
exit ();
}
2014-07-11 14:03:59 +00:00
/**
* Returns name of the template file to display
*
* @ param $view
* @ return string
*/
2013-08-04 18:58:31 +00:00
public static function getTplFile ( $view )
{
2013-12-06 13:07:00 +00:00
$views = array (
'install' , 'import' , 'export' , 'config' , 'tags' ,
2014-02-20 17:28:39 +00:00
'edit-tags' , 'view' , 'login' , 'error'
2013-12-06 13:07:00 +00:00
);
2014-07-11 14:03:59 +00:00
return ( in_array ( $view , $views ) ? $view . '.twig' : 'home.twig' );
2013-08-04 18:58:31 +00:00
}
2014-07-11 14:03:59 +00:00
/**
* Download a file ( typically , for downloading pictures on web server )
*
* @ param $url
* @ return bool | mixed | string
*/
2013-08-04 18:58:31 +00:00
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 );
2013-11-13 14:17:34 +00:00
if ( ! ini_get ( 'open_basedir' ) && ! ini_get ( 'safe_mode' )) {
curl_setopt ( $curl , CURLOPT_FOLLOWLOCATION , true );
}
2013-08-04 18:58:31 +00:00
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
2014-04-02 17:55:19 +00:00
$data = @ file_get_contents ( $url , false , $context , - 1 , 4000000 );
2013-08-04 18:58:31 +00:00
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' ;
2013-08-08 19:13:37 +00:00
if ( empty ( $encoding [ 1 ])) $encoding [ 1 ] = 'utf-8' ;
2013-08-04 18:58:31 +00:00
} 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 ;
}
}
2014-07-11 14:03:59 +00:00
/**
* Headers for JSON export
*
* @ param $data
*/
2013-08-04 18:58:31 +00:00
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 ();
}
2014-07-11 14:03:59 +00:00
/**
* Create new line in log file
*
* @ param $message
*/
2013-08-04 18:58:31 +00:00
public static function logm ( $message )
{
2014-02-28 20:49:38 +00:00
if ( DEBUG_POCHE && php_sapi_name () != 'cli' ) {
2013-08-04 18:58:31 +00:00
$t = strval ( date ( 'Y/m/d_H:i:s' )) . ' - ' . $_SERVER [ " REMOTE_ADDR " ] . ' - ' . strval ( $message ) . " \n " ;
2013-08-05 19:56:32 +00:00
file_put_contents ( CACHE . '/log.txt' , $t , FILE_APPEND );
2013-08-07 12:24:07 +00:00
error_log ( 'DEBUG POCHE : ' . $message );
2013-08-04 18:58:31 +00:00
}
}
2014-07-11 14:03:59 +00:00
/**
* Encode a URL by using a salt
*
* @ param $string
* @ return string
*/
2014-04-02 17:55:19 +00:00
public static function encodeString ( $string )
2013-08-04 18:58:31 +00:00
{
return sha1 ( $string . SALT );
}
2013-08-04 20:35:08 +00:00
2014-07-11 14:03:59 +00:00
/**
* Cleans a variable
*
* @ param $var
* @ param string $default
* @ return string
*/
2013-08-05 08:32:15 +00:00
public static function checkVar ( $var , $default = '' )
2013-08-04 20:35:08 +00:00
{
2014-07-11 14:03:59 +00:00
return (( isset ( $_REQUEST [ " $var " ])) ? htmlentities ( $_REQUEST [ " $var " ]) : $default );
2013-08-04 20:35:08 +00:00
}
2013-08-05 13:54:37 +00:00
2014-07-11 14:03:59 +00:00
/**
* Returns the domain name for a URL
*
* @ param $url
* @ return string
*/
2014-07-10 11:17:04 +00:00
public static function getDomain ( $url )
{
return parse_url ( $url , PHP_URL_HOST );
}
2014-07-11 14:03:59 +00:00
/**
* For a given text , we calculate reading time for an article
*
* @ param $text
* @ return float
*/
public static function getReadingTime ( $text )
{
return floor ( str_word_count ( strip_tags ( $text )) / 200 );
2013-08-26 20:25:03 +00:00
}
2013-12-12 08:42:19 +00:00
2014-07-11 14:03:59 +00:00
/**
* Returns the correct header for a status code
*
* @ param $status_code
*/
private static function _status ( $status_code )
2013-12-12 08:42:19 +00:00
{
if ( strpos ( php_sapi_name (), 'apache' ) !== false ) {
header ( 'HTTP/1.0 ' . $status_code );
}
else {
header ( 'Status: ' . $status_code );
}
}
2014-07-11 14:03:59 +00:00
/**
* Download the sqlite database
*/
public static function downloadDb ()
{
2013-12-12 08:42:19 +00:00
header ( 'Content-Disposition: attachment; filename="poche.sqlite.gz"' );
2014-07-11 14:03:59 +00:00
self :: _status ( 200 );
2013-12-12 08:42:19 +00:00
header ( 'Content-Transfer-Encoding: binary' );
header ( 'Content-Type: application/octet-stream' );
echo gzencode ( file_get_contents ( STORAGE_SQLITE ));
exit ;
}
2014-02-28 20:49:38 +00:00
2014-07-11 14:03:59 +00:00
/**
* Get the content for a given URL ( by a call to FullTextFeed )
*
* @ param Url $url
* @ return mixed
*/
2014-02-28 20:49:38 +00:00
public static function getPageContent ( Url $url )
{
// Saving and clearing context
$REAL = array ();
foreach ( $GLOBALS as $key => $value ) {
if ( $key != 'GLOBALS' && $key != '_SESSION' && $key != 'HTTP_SESSION_VARS' ) {
2014-07-11 14:03:59 +00:00
$GLOBALS [ $key ] = array ();
$REAL [ $key ] = $value ;
2014-02-28 20:49:38 +00:00
}
}
// Saving and clearing session
2014-07-11 14:03:59 +00:00
if ( isset ( $_SESSION )) {
2014-03-07 10:54:08 +00:00
$REAL_SESSION = array ();
foreach ( $_SESSION as $key => $value ) {
$REAL_SESSION [ $key ] = $value ;
unset ( $_SESSION [ $key ]);
}
2014-02-28 20:49:38 +00:00
}
// Running code in different context
$scope = function () {
extract ( func_get_arg ( 1 ) );
$_GET = $_REQUEST = array (
2014-07-11 14:03:59 +00:00
" url " => $url -> getUrl (),
" max " => 5 ,
" links " => " preserve " ,
" exc " => " " ,
" format " => " json " ,
" submit " => " Create Feed "
2014-02-28 20:49:38 +00:00
);
ob_start ();
require func_get_arg ( 0 );
2014-03-07 10:54:08 +00:00
$json = ob_get_contents ();
ob_end_clean ();
2014-02-28 20:49:38 +00:00
return $json ;
};
2014-07-11 14:03:59 +00:00
$json = $scope ( " inc/3rdparty/makefulltextfeed.php " , array ( " url " => $url ));
2014-02-28 20:49:38 +00:00
// Clearing and restoring context
2014-07-11 14:03:59 +00:00
foreach ( $GLOBALS as $key => $value ) {
if ( $key != " GLOBALS " && $key != " _SESSION " ) {
2014-02-28 20:49:38 +00:00
unset ( $GLOBALS [ $key ]);
}
}
2014-07-11 14:03:59 +00:00
foreach ( $REAL as $key => $value ) {
2014-02-28 20:49:38 +00:00
$GLOBALS [ $key ] = $value ;
}
2014-07-11 14:03:59 +00:00
2014-02-28 20:49:38 +00:00
// Clearing and restoring session
2014-07-11 14:03:59 +00:00
if ( isset ( $REAL_SESSION )) {
foreach ( $_SESSION as $key => $value ) {
2014-03-07 10:54:08 +00:00
unset ( $_SESSION [ $key ]);
}
2014-07-11 14:03:59 +00:00
foreach ( $REAL_SESSION as $key => $value ) {
2014-03-07 10:54:08 +00:00
$_SESSION [ $key ] = $value ;
}
2014-02-28 20:49:38 +00:00
}
2014-03-07 10:54:08 +00:00
2014-02-28 20:49:38 +00:00
return json_decode ( $json , true );
}
2014-03-10 14:28:47 +00:00
/**
* Returns whether we handle an AJAX ( XMLHttpRequest ) request .
2014-07-11 14:03:59 +00:00
*
2014-03-10 14:28:47 +00:00
* @ return boolean whether we handle an AJAX ( XMLHttpRequest ) request .
*/
public static function isAjaxRequest ()
{
2014-07-11 14:03:59 +00:00
return isset ( $_SERVER [ 'HTTP_X_REQUESTED_WITH' ]) && $_SERVER [ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest' ;
2014-03-10 14:28:47 +00:00
}
2014-07-12 17:01:11 +00:00
/*
* Empty cache folder
*/
public static 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' );
Tools :: redirect ();
}
public static function generateToken ()
{
if ( ini_get ( 'open_basedir' ) === '' ) {
if ( strtoupper ( substr ( PHP_OS , 0 , 3 )) === 'WIN' ) {
// 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 );
}
}
else {
$token = substr ( base64_encode ( uniqid ( mt_rand (), true )), 0 , 20 );
}
return str_replace ( '+' , '' , $token );
}
2013-10-07 10:30:40 +00:00
}