2011-07-27 21:07:28 +04:00
< ? php
/**
* Class for utility functions
*
*/
2011-07-29 23:36:03 +04:00
class OC_Util {
2011-07-27 21:07:28 +04:00
public static $scripts = array ();
public static $styles = array ();
public static $headers = array ();
2012-02-06 02:49:22 +04:00
private static $rootMounted = false ;
2011-07-27 21:07:28 +04:00
private static $fsSetup = false ;
2012-05-14 19:57:43 +04:00
public static $core_styles = array ();
2012-05-15 01:15:53 +04:00
public static $core_scripts = array ();
2011-07-27 21:07:28 +04:00
// Can be set up
2012-06-19 19:38:04 +04:00
public static function setupFS ( $user = '' ){ // configure the initial filesystem based on the configuration
2011-07-27 21:07:28 +04:00
if ( self :: $fsSetup ){ //setting up the filesystem twice can only lead to trouble
return false ;
}
2012-06-20 00:50:28 +04:00
$CONFIG_DATADIRECTORY = OC_Config :: getValue ( " datadirectory " , OC :: $SERVERROOT . " /data " );
2012-02-06 00:45:41 +04:00
//first set up the local "root" storage
2012-02-06 02:49:22 +04:00
if ( ! self :: $rootMounted ){
2012-06-20 00:50:28 +04:00
OC_Filesystem :: mount ( 'OC_Filestorage_Local' , array ( 'datadir' => $CONFIG_DATADIRECTORY ), '/' );
2012-02-06 02:49:22 +04:00
self :: $rootMounted = true ;
}
2012-06-20 10:57:21 +04:00
// If we are not forced to load a specific user we load the one that is logged in
if ( $user == " " && OC_User :: isLoggedIn ()){
$user = OC_User :: getUser ();
}
2011-07-27 21:07:28 +04:00
if ( $user != " " ){ //if we aren't logged in, there is no use to set up the filesystem
2012-06-19 19:38:04 +04:00
$user_dir = '/' . $user . '/files' ;
$userdirectory = $CONFIG_DATADIRECTORY . $user_dir ;
2012-06-20 00:50:28 +04:00
if ( ! is_dir ( $userdirectory )){
mkdir ( $userdirectory , 0755 , true );
2011-07-27 21:07:28 +04:00
}
//jail the user into his "home" directory
2012-06-19 19:38:04 +04:00
OC_Filesystem :: init ( $user_dir );
2011-08-15 22:37:50 +04:00
$quotaProxy = new OC_FileProxy_Quota ();
OC_FileProxy :: register ( $quotaProxy );
2011-07-27 21:07:28 +04:00
self :: $fsSetup = true ;
2012-06-11 00:34:21 +04:00
// Load personal mount config
2012-06-20 00:50:28 +04:00
if ( is_file ( $CONFIG_DATADIRECTORY . '/' . $user . '/mount.php' )) {
$mountConfig = include ( $CONFIG_DATADIRECTORY . '/' . $user . '/mount.php' );
2012-06-11 00:34:21 +04:00
if ( isset ( $mountConfig [ 'user' ][ $user ])) {
foreach ( $mountConfig [ 'user' ][ $user ] as $mountPoint => $options ) {
OC_Filesystem :: mount ( $options [ 'class' ], $options [ 'options' ], $mountPoint );
}
}
}
2012-06-19 19:38:04 +04:00
OC_Hook :: emit ( 'OC_Filesystem' , 'setup' , array ( 'user' => $user , 'user_dir' => $user_dir ));
2011-07-27 21:07:28 +04:00
}
}
public static function tearDownFS (){
2011-07-29 23:36:03 +04:00
OC_Filesystem :: tearDown ();
2011-07-27 21:07:28 +04:00
self :: $fsSetup = false ;
}
/**
* get the current installed version of ownCloud
* @ return array
*/
public static function getVersion (){
2012-06-09 18:04:47 +04:00
return array ( 4 , 80 , 1 );
2011-09-28 15:52:26 +04:00
}
/**
* get the current installed version string of ownCloud
* @ return string
*/
public static function getVersionString (){
2012-05-19 20:21:33 +04:00
return '5 pre alpha' ;
2011-07-27 21:07:28 +04:00
}
2012-04-01 13:20:12 +04:00
/**
* get the current installed edition of ownCloud . There is the community edition that just returns an empty string and the enterprise edition that returns " Enterprise " .
* @ return string
*/
public static function getEditionString (){
return '' ;
}
2011-07-27 21:07:28 +04:00
/**
* add a javascript file
*
2012-05-01 23:07:08 +04:00
* @ param appid $application
* @ param filename $file
2011-07-27 21:07:28 +04:00
*/
public static function addScript ( $application , $file = null ){
if ( is_null ( $file )){
$file = $application ;
$application = " " ;
}
if ( ! empty ( $application )){
self :: $scripts [] = " $application /js/ $file " ;
} else {
self :: $scripts [] = " js/ $file " ;
}
}
/**
* add a css file
*
2012-05-01 23:07:08 +04:00
* @ param appid $application
* @ param filename $file
2011-07-27 21:07:28 +04:00
*/
public static function addStyle ( $application , $file = null ){
if ( is_null ( $file )){
$file = $application ;
$application = " " ;
}
if ( ! empty ( $application )){
self :: $styles [] = " $application /css/ $file " ;
} else {
self :: $styles [] = " css/ $file " ;
}
}
/**
* @ brief Add a custom element to the header
* @ param string tag tag name of the element
2012-02-08 01:33:01 +04:00
* @ param array $attributes array of attributes for the element
2011-07-27 21:07:28 +04:00
* @ param string $text the text content for the element
*/
public static function addHeader ( $tag , $attributes , $text = '' ){
self :: $headers [] = array ( 'tag' => $tag , 'attributes' => $attributes , 'text' => $text );
}
2012-04-16 14:21:12 +04:00
/**
* formats a timestamp in the " right " way
*
* @ param int timestamp $timestamp
* @ param bool dateOnly option to ommit time from the result
*/
public static function formatDate ( $timestamp , $dateOnly = false ){
if ( isset ( $_SESSION [ 'timezone' ])){ //adjust to clients timezone if we know it
$systemTimeZone = intval ( date ( 'O' ));
$systemTimeZone = ( round ( $systemTimeZone / 100 , 0 ) * 60 ) + ( $systemTimeZone % 100 );
$clientTimeZone = $_SESSION [ 'timezone' ] * 60 ;
$offset = $clientTimeZone - $systemTimeZone ;
$timestamp = $timestamp + $offset * 60 ;
}
$timeformat = $dateOnly ? 'F j, Y' : 'F j, Y, H:i' ;
return date ( $timeformat , $timestamp );
}
2011-07-27 21:07:28 +04:00
/**
* Shows a pagenavi widget where you can jump to different pages .
*
* @ param int $pagecount
* @ param int $page
* @ param string $url
2011-07-29 23:36:03 +04:00
* @ return OC_Template
2011-07-27 21:07:28 +04:00
*/
public static function getPageNavi ( $pagecount , $page , $url ) {
$pagelinkcount = 8 ;
if ( $pagecount > 1 ) {
$pagestart = $page - $pagelinkcount ;
if ( $pagestart < 0 ) $pagestart = 0 ;
$pagestop = $page + $pagelinkcount ;
if ( $pagestop > $pagecount ) $pagestop = $pagecount ;
2011-07-29 23:36:03 +04:00
$tmpl = new OC_Template ( '' , 'part.pagenavi' , '' );
2011-07-27 21:07:28 +04:00
$tmpl -> assign ( 'page' , $page );
$tmpl -> assign ( 'pagecount' , $pagecount );
$tmpl -> assign ( 'pagestart' , $pagestart );
$tmpl -> assign ( 'pagestop' , $pagestop );
$tmpl -> assign ( 'url' , $url );
return $tmpl ;
}
}
/**
* check if the current server configuration is suitable for ownCloud
* @ return array arrays with error messages and hints
*/
public static function checkServer (){
$errors = array ();
//check for database drivers
2012-01-03 15:37:33 +04:00
if ( ! ( is_callable ( 'sqlite_open' ) or class_exists ( 'SQLite3' )) and ! is_callable ( 'mysql_connect' ) and ! is_callable ( 'pg_connect' )){
2011-12-30 23:38:56 +04:00
$errors [] = array ( 'error' => 'No database drivers (sqlite, mysql, or postgresql) installed.<br/>' , 'hint' => '' ); //TODO: sane hint
2011-07-27 21:07:28 +04:00
}
2011-07-29 23:36:03 +04:00
$CONFIG_DBTYPE = OC_Config :: getValue ( " dbtype " , " sqlite " );
$CONFIG_DBNAME = OC_Config :: getValue ( " dbname " , " owncloud " );
2011-07-27 21:07:28 +04:00
//common hint for all file permissons error messages
2011-10-22 21:39:05 +04:00
$permissionsHint = " Permissions can usually be fixed by giving the webserver write access to the ownCloud directory " ;
2011-07-27 21:07:28 +04:00
2012-06-20 00:12:05 +04:00
// Check if config folder is writable.
if ( ! is_writable ( OC :: $SERVERROOT . " /config/ " )) {
$errors [] = array ( 'error' => " Can't write into config directory 'config' " , 'hint' => " You can usually fix this by giving the webserver user write access to the config directory in owncloud " );
}
// Check if apps folder is writable.
if ( OC_Config :: getValue ( 'writable_appsdir' , true ) && ! is_writable ( OC :: $SERVERROOT . " /apps/ " )) {
$errors [] = array ( 'error' => " Can't write into apps directory 'apps' " , 'hint' => " You can usually fix this by giving the webserver user write access to the config directory in owncloud " );
}
2012-06-20 00:50:28 +04:00
$CONFIG_DATADIRECTORY = OC_Config :: getValue ( " datadirectory " , OC :: $SERVERROOT . " /data " );
2011-07-27 21:07:28 +04:00
//check for correct file permissions
if ( ! stristr ( PHP_OS , 'WIN' )){
2011-09-28 13:44:46 +04:00
$permissionsModHint = " Please change the permissions to 0770 so that the directory cannot be listed by other users. " ;
2012-06-20 00:50:28 +04:00
$prems = substr ( decoct ( @ fileperms ( $CONFIG_DATADIRECTORY )), - 3 );
2011-07-27 21:07:28 +04:00
if ( substr ( $prems , - 1 ) != '0' ){
2012-06-20 00:50:28 +04:00
OC_Helper :: chmodr ( $CONFIG_DATADIRECTORY , 0770 );
2011-07-27 21:07:28 +04:00
clearstatcache ();
2012-06-20 00:50:28 +04:00
$prems = substr ( decoct ( @ fileperms ( $CONFIG_DATADIRECTORY )), - 3 );
2011-07-27 21:07:28 +04:00
if ( substr ( $prems , 2 , 1 ) != '0' ){
2012-06-20 00:50:28 +04:00
$errors [] = array ( 'error' => 'Data directory (' . $CONFIG_DATADIRECTORY . ') is readable for other users<br/>' , 'hint' => $permissionsModHint );
2011-07-27 21:07:28 +04:00
}
}
2011-07-29 23:36:03 +04:00
if ( OC_Config :: getValue ( " enablebackup " , false )){
2012-06-20 00:12:05 +04:00
$CONFIG_BACKUPDIRECTORY = OC_Config :: getValue ( " backupdirectory " , OC :: $SERVERROOT . " /backup " );
2011-08-07 01:19:00 +04:00
$prems = substr ( decoct ( @ fileperms ( $CONFIG_BACKUPDIRECTORY )), - 3 );
2011-07-27 21:07:28 +04:00
if ( substr ( $prems , - 1 ) != '0' ){
2011-07-29 23:36:03 +04:00
OC_Helper :: chmodr ( $CONFIG_BACKUPDIRECTORY , 0770 );
2011-07-27 21:07:28 +04:00
clearstatcache ();
2011-08-07 01:19:00 +04:00
$prems = substr ( decoct ( @ fileperms ( $CONFIG_BACKUPDIRECTORY )), - 3 );
2011-07-27 21:07:28 +04:00
if ( substr ( $prems , 2 , 1 ) != '0' ){
2011-09-28 13:44:46 +04:00
$errors [] = array ( 'error' => 'Data directory (' . $CONFIG_BACKUPDIRECTORY . ') is readable for other users<br/>' , 'hint' => $permissionsModHint );
2011-07-27 21:07:28 +04:00
}
}
}
} else {
2011-09-18 22:57:05 +04:00
//TODO: permissions checks for windows hosts
2011-07-27 21:07:28 +04:00
}
2012-06-20 00:12:05 +04:00
// Create root dir.
2012-06-20 00:50:28 +04:00
if ( ! is_dir ( $CONFIG_DATADIRECTORY )){
$success =@ mkdir ( $CONFIG_DATADIRECTORY );
2012-06-20 00:12:05 +04:00
if ( ! $success ) {
2012-06-20 00:50:28 +04:00
$errors [] = array ( 'error' => " Can't create data directory ( " . $CONFIG_DATADIRECTORY . " ) " , 'hint' => " You can usually fix this by giving the webserver write access to the ownCloud directory ' " . OC :: $SERVERROOT . " ' (in a terminal, use the command 'chown -R www-data:www-data /path/to/your/owncloud/install/data' " );
2012-06-20 00:12:05 +04:00
}
2012-06-20 00:50:28 +04:00
} else if ( ! is_writable ( $CONFIG_DATADIRECTORY )){
$errors [] = array ( 'error' => 'Data directory (' . $CONFIG_DATADIRECTORY . ') not writable by ownCloud<br/>' , 'hint' => $permissionsHint );
2011-07-27 21:07:28 +04:00
}
2011-09-27 21:08:38 +04:00
// check if all required php modules are present
if ( ! class_exists ( 'ZipArchive' )){
2011-09-29 17:53:58 +04:00
$errors [] = array ( 'error' => 'PHP module zip not installed.<br/>' , 'hint' => 'Please ask your server administrator to install the module.' );
2011-09-27 21:08:38 +04:00
}
if ( ! function_exists ( 'mb_detect_encoding' )){
$errors [] = array ( 'error' => 'PHP module mb multibyte not installed.<br/>' , 'hint' => 'Please ask your server administrator to install the module.' );
}
2011-09-28 13:47:29 +04:00
if ( ! function_exists ( 'ctype_digit' )){
$errors [] = array ( 'error' => 'PHP module ctype is not installed.<br/>' , 'hint' => 'Please ask your server administrator to install the module.' );
}
2012-04-17 21:06:45 +04:00
if ( ! function_exists ( 'json_encode' )){
$errors [] = array ( 'error' => 'PHP module JSON is not installed.<br/>' , 'hint' => 'Please ask your server administrator to install the module.' );
}
2012-04-17 21:09:41 +04:00
if ( ! function_exists ( 'imagepng' )){
$errors [] = array ( 'error' => 'PHP module GD is not installed.<br/>' , 'hint' => 'Please ask your server administrator to install the module.' );
}
2012-04-30 15:28:31 +04:00
if ( floatval ( phpversion ()) < 5.3 ){
$errors [] = array ( 'error' => 'PHP 5.3 is required.<br/>' , 'hint' => 'Please ask your server administrator to update PHP to version 5.3 or higher. PHP 5.2 is no longer supported by ownCloud and the PHP community.' );
}
2012-06-01 22:00:33 +04:00
if ( ! defined ( 'PDO::ATTR_DRIVER_NAME' )){
$errors [] = array ( 'error' => 'PHP PDO module is not installed.<br/>' , 'hint' => 'Please ask your server administrator to install the module.' );
}
2011-07-27 21:07:28 +04:00
return $errors ;
}
2011-09-18 23:31:56 +04:00
2011-09-26 00:47:29 +04:00
public static function displayLoginPage ( $parameters = array ()){
if ( isset ( $_COOKIE [ " username " ])){
$parameters [ " username " ] = $_COOKIE [ " username " ];
2011-10-01 01:48:20 +04:00
} else {
$parameters [ " username " ] = '' ;
2011-09-26 00:47:29 +04:00
}
2012-04-27 01:17:46 +04:00
$sectoken = rand ( 1000000 , 9999999 );
$_SESSION [ 'sectoken' ] = $sectoken ;
$parameters [ " sectoken " ] = $sectoken ;
2011-09-26 00:47:29 +04:00
OC_Template :: printGuestPage ( " " , " login " , $parameters );
}
2011-09-28 13:44:46 +04:00
2011-10-01 01:05:10 +04:00
/**
2012-02-21 23:05:02 +04:00
* Check if the app is enabled , redirects to home if not
2011-10-01 01:05:10 +04:00
*/
public static function checkAppEnabled ( $app ){
if ( ! OC_App :: isEnabled ( $app )){
2012-02-16 22:45:00 +04:00
header ( 'Location: ' . OC_Helper :: linkToAbsolute ( '' , 'index.php' ));
2011-10-01 01:05:10 +04:00
exit ();
}
}
2011-09-18 23:31:56 +04:00
/**
2012-02-21 23:05:02 +04:00
* Check if the user is logged in , redirects to home if not . With
* redirect URL parameter to the request URI .
2011-09-18 23:31:56 +04:00
*/
public static function checkLoggedIn (){
// Check if we are a user
if ( ! OC_User :: isLoggedIn ()){
2012-02-21 23:05:02 +04:00
header ( 'Location: ' . OC_Helper :: linkToAbsolute ( '' , 'index.php' ) . '?redirect_url=' . urlencode ( $_SERVER [ " REQUEST_URI " ]));
2011-09-18 23:31:56 +04:00
exit ();
}
}
/**
* Check if the user is a admin , redirects to home if not
*/
public static function checkAdminUser (){
// Check if we are a user
self :: checkLoggedIn ();
if ( ! OC_Group :: inGroup ( OC_User :: getUser (), 'admin' )){
2012-02-16 22:45:00 +04:00
header ( 'Location: ' . OC_Helper :: linkToAbsolute ( '' , 'index.php' ));
2011-09-18 23:31:56 +04:00
exit ();
}
}
/**
* Redirect to the user default page
*/
public static function redirectToDefaultPage (){
2012-06-11 17:21:37 +04:00
OC_Log :: write ( 'core' , 'redirectToDefaultPage' , OC_Log :: DEBUG );
if ( isset ( $_REQUEST [ 'redirect_url' ]) && ( substr ( $_REQUEST [ 'redirect_url' ], 0 , strlen ( OC :: $WEBROOT )) == OC :: $WEBROOT || $_REQUEST [ 'redirect_url' ][ 0 ] == '/' )) {
2012-05-19 00:56:15 +04:00
header ( 'Location: ' . $_REQUEST [ 'redirect_url' ]);
2012-06-20 19:10:17 +04:00
}
else if ( isset ( OC :: $REQUESTEDAPP ) && ! empty ( OC :: $REQUESTEDAPP )) {
header ( 'Location: ' . OC :: $WEBROOT . '/?app=' . OC :: $REQUESTEDAPP );
}
else {
2012-04-18 10:20:51 +04:00
header ( 'Location: ' . OC :: $WEBROOT . '/' . OC_Appconfig :: getValue ( 'core' , 'defaultpage' , '?app=files' ));
2011-10-04 21:27:57 +04:00
}
2011-09-18 23:31:56 +04:00
exit ();
}
2012-06-05 21:32:48 +04:00
/**
* get an id unqiue for this instance
* @ return string
*/
public static function getInstanceId (){
$id = OC_Config :: getValue ( 'instanceid' , null );
if ( is_null ( $id )){
$id = uniqid ();
OC_Config :: setValue ( 'instanceid' , $id );
}
return $id ;
}
2012-06-09 17:05:14 +04:00
/**
2012-06-13 19:33:19 +04:00
* @ brief Register an get / post call . This is important to prevent CSRF attacks
2012-06-09 17:05:14 +04:00
* Todo : Write howto
2012-06-13 19:33:19 +04:00
* @ return $token Generated token .
2012-06-09 17:05:14 +04:00
*/
public static function callRegister (){
2012-06-11 14:13:08 +04:00
//mamimum time before token exires
$maxtime = ( 60 * 60 ); // 1 hour
2012-06-09 17:05:14 +04:00
// generate a random token.
$token = mt_rand ( 1000 , 9000 ) . mt_rand ( 1000 , 9000 ) . mt_rand ( 1000 , 9000 );
// store the token together with a timestamp in the session.
$_SESSION [ 'requesttoken-' . $token ] = time ();
2012-06-11 14:13:08 +04:00
// cleanup old tokens garbage collector
2012-06-19 19:20:19 +04:00
// only run every 20th time so we don't waste cpu cycles
2012-06-11 14:13:08 +04:00
if ( rand ( 0 , 20 ) == 0 ) {
foreach ( $_SESSION as $key => $value ) {
// search all tokens in the session
if ( substr ( $key , 0 , 12 ) == 'requesttoken' ) {
if ( $value + $maxtime < time ()){
// remove outdated tokens
unset ( $_SESSION [ $key ]);
}
}
}
}
2012-06-09 17:05:14 +04:00
// return the token
return ( $token );
}
/**
2012-06-13 19:33:19 +04:00
* @ brief Check an ajax get / post call if the request token is valid .
* @ return boolean False if request token is not set or is invalid .
2012-06-09 17:05:14 +04:00
*/
2012-06-13 19:33:19 +04:00
public static function isCallRegistered (){
2012-06-09 17:05:14 +04:00
//mamimum time before token exires
$maxtime = ( 60 * 60 ); // 1 hour
if ( isset ( $_GET [ 'requesttoken' ])) {
$token = $_GET [ 'requesttoken' ];
} elseif ( isset ( $_POST [ 'requesttoken' ])){
$token = $_POST [ 'requesttoken' ];
2012-06-13 19:33:19 +04:00
} elseif ( isset ( $_SERVER [ 'HTTP_REQUESTTOKEN' ])){
$token = $_SERVER [ 'HTTP_REQUESTTOKEN' ];
2012-06-09 17:05:14 +04:00
} else {
2012-06-13 19:33:19 +04:00
//no token found.
return false ;
2012-06-09 17:05:14 +04:00
}
if ( isset ( $_SESSION [ 'requesttoken-' . $token ])) {
$timestamp = $_SESSION [ 'requesttoken-' . $token ];
2012-06-13 19:27:49 +04:00
if ( $timestamp + $maxtime < time ()){
2012-06-13 19:33:19 +04:00
return false ;
2012-06-09 17:05:14 +04:00
} else {
//token valid
2012-06-13 19:33:19 +04:00
return true ;
2012-06-09 17:05:14 +04:00
}
} else {
2012-06-13 19:33:19 +04:00
return false ;
2012-06-09 17:05:14 +04:00
}
}
2012-06-13 19:33:19 +04:00
/**
* @ brief Check an ajax get / post call if the request token is valid . exit if not .
* Todo : Write howto
*/
public static function callCheck (){
if ( ! OC_Util :: isCallRegistered ()) {
exit ;
}
}
2012-06-19 19:20:19 +04:00
2012-06-21 16:07:04 +04:00
/**
* @ brief Public function to sanitize HTML
*
2012-06-19 19:20:19 +04:00
* This function is used to sanitize HTML and should be applied on any string or array of strings before displaying it on a web page .
*
* @ param string or array of strings
2012-06-21 16:07:04 +04:00
* @ return array with sanitized strings or a single sinitized string , depends on the input parameter .
2012-06-19 19:20:19 +04:00
*/
2012-06-21 16:07:04 +04:00
public static function sanitizeHTML ( & $value ){
if ( is_array ( $value ) || is_object ( $value )) array_walk_recursive ( $value , 'OC_Util::sanitizeHTML' );
else $value = htmlentities ( $value , ENT_QUOTES , 'UTF-8' ); //Specify encoding for PHP<5.4
2012-06-19 19:20:19 +04:00
return $value ;
}
2012-06-21 16:07:04 +04:00
/**
* Check if the htaccess file is working buy creating a test file in the data directory and trying to access via http
*/
public static function ishtaccessworking () {
// testdata
$filename = '/htaccesstest.txt' ;
$testcontent = 'testcontent' ;
// creating a test file
$testfile = OC_Config :: getValue ( " datadirectory " , OC :: $SERVERROOT . " /data " ) . '/' . $filename ;
$fp = @ fopen ( $testfile , 'w' );
@ fwrite ( $fp , $testcontent );
@ fclose ( $fp );
// accessing the file via http
$url = OC_Helper :: serverProtocol () . '://' . OC_Helper :: serverHost () . OC :: $WEBROOT . '/data' . $filename ;
$fp = @ fopen ( $url , 'r' );
$content =@ fread ( $fp , 2048 );
@ fclose ( $fp );
// cleanup
@ unlink ( $testfile );
// does it work ?
if ( $content == $testcontent ) {
return ( false );
} else {
return ( true );
}
}
2011-07-27 21:07:28 +04:00
}