2008-08-27 13:17:00 +02:00
< ? php
/**
2016-05-05 09:20:07 +02:00
* EGroupware - Hooks for admin , preferences and sidebox - menus
2008-08-27 13:17:00 +02:00
*
* @ link http :// www . egroupware . org
* @ author Ralf Becker < RalfBecker - AT - outdoor - training . de >
* @ package filemanager
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
*/
2016-05-05 09:20:07 +02:00
use EGroupware\Api ;
use EGroupware\Api\Framework ;
use EGroupware\Api\Egw ;
2022-10-25 17:48:52 +02:00
use EGroupware\Api\Json\Push ;
2016-05-05 09:20:07 +02:00
use EGroupware\Api\Vfs ;
2008-08-27 13:17:00 +02:00
/**
* Class containing admin , preferences and sidebox - menus ( used as hooks )
*/
class filemanager_hooks
{
static $appname = 'filemanager' ;
2008-10-05 19:07:36 +02:00
2008-09-04 08:44:48 +02:00
/**
* Data for Filemanagers sidebox menu
*
* @ param array $args
*/
2008-08-27 13:17:00 +02:00
static function sidebox_menu ( $args )
{
2013-12-02 21:13:17 +01:00
// Magic etemplate2 favorites menu (from nextmatch widget)
2016-05-05 09:20:07 +02:00
display_sidebox ( self :: $appname , lang ( 'Favorites' ), Framework\Favorites :: list_favorites ( self :: $appname ));
2014-02-12 22:51:25 +01:00
2008-08-27 13:17:00 +02:00
$location = is_array ( $args ) ? $args [ 'location' ] : $args ;
2008-09-04 08:44:48 +02:00
$rootpath = '/' ;
$basepath = '/home' ;
2008-08-27 13:17:00 +02:00
$homepath = '/home/' . $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ];
//echo "<p>admin_prefs_sidebox_hooks::all_hooks(".print_r($args,True).") appname='$appname', location='$location'</p>\n";
$file_prefs = & $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ self :: $appname ];
if ( $location == 'sidebox_menu' )
{
$title = $GLOBALS [ 'egw_info' ][ 'apps' ][ self :: $appname ][ 'title' ] . ' ' . lang ( 'Menu' );
2010-10-15 21:42:38 +02:00
$file = array ();
2018-11-27 15:22:50 +01:00
// add "file a file" (upload) dialog
$file [] = array (
'text' => 'File a file' ,
'link' => " javascript:app.filemanager.fileafile() " ,
'app' => 'api' ,
'icon' => 'upload' ,
'disableIfNoEPL' => true
);
2010-10-15 21:42:38 +02:00
// add selection for available views, if we have more then one
if ( count ( filemanager_ui :: init_views ()) > 1 )
{
2016-05-05 09:20:07 +02:00
$index_url = Egw :: link ( '/index.php' , array ( 'menuaction' => 'filemanager.filemanager_ui.index' ), false );
2010-10-15 21:42:38 +02:00
$file [] = array (
2016-05-05 09:20:07 +02:00
'text' => Api\Html :: select ( 'filemanager_view' , filemanager_ui :: get_view (), filemanager_ui :: $views , false ,
2010-10-15 21:42:38 +02:00
' onchange="' . " egw_appWindow('filemanager').location=' $index_url &view='+this.value; " .
'" style="width: 100%;"' ),
'no_lang' => True ,
'link' => False
);
}
2010-11-30 15:29:06 +01:00
if ( $file_prefs [ 'showhome' ] != 'no' )
{
2016-05-05 09:20:07 +02:00
$file [ 'Your home directory' ] = Egw :: link ( '/index.php' , array ( 'menuaction' => self :: $appname . '.filemanager_ui.index' , 'path' => $homepath , 'ajax' => 'true' ));
2010-11-30 15:29:06 +01:00
}
if ( $file_prefs [ 'showusers' ] != 'no' )
{
2016-05-05 09:20:07 +02:00
$file [ 'Users and groups' ] = Egw :: link ( '/index.php' , array ( 'menuaction' => self :: $appname . '.filemanager_ui.index' , 'path' => $basepath , 'ajax' => 'true' ));
2010-11-30 15:29:06 +01:00
}
2008-09-04 08:44:48 +02:00
if ( ! empty ( $file_prefs [ 'showbase' ]) && $file_prefs [ 'showbase' ] == 'yes' )
{
2016-05-05 09:20:07 +02:00
$file [ 'Basedirectory' ] = Egw :: link ( '/index.php' , array ( 'menuaction' => self :: $appname . '.filemanager_ui.index' , 'path' => $rootpath , 'ajax' => 'true' ));
2008-09-04 08:44:48 +02:00
}
2016-04-25 12:58:05 +02:00
if ( ! empty ( $file_prefs [ 'startfolder' ]))
2008-09-04 08:44:48 +02:00
{
2016-05-05 09:20:07 +02:00
$file [ 'Startfolder' ] = Egw :: link ( '/index.php' , array ( 'menuaction' => self :: $appname . '.filemanager_ui.index' , 'path' => $file_prefs [ 'startfolder' ], 'ajax' => 'true' ));
2008-08-27 13:17:00 +02:00
}
2016-05-05 09:20:07 +02:00
$file [ 'Shared files' ] = Egw :: link ( '/index.php' , 'menuaction=filemanager.filemanager_shares.index&ajax=true' );
2021-04-20 00:02:41 +02:00
$file [] = [ 'text' => '--' ];
$file [ 'Placeholders' ] = Egw :: link ( '/index.php' , 'menuaction=filemanager.filemanager_merge.show_replacements' );
2008-08-27 13:17:00 +02:00
display_sidebox ( self :: $appname , $title , $file );
}
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ]) self :: admin ( self :: $appname );
}
/**
* Entries for filemanagers ' s admin menu
2009-05-29 12:48:19 +02:00
*
* @ param string | array $location = 'admin' hook name or params
2008-08-27 13:17:00 +02:00
*/
static function admin ( $location = 'admin' )
{
2010-05-15 22:42:46 +02:00
if ( is_array ( $location )) $location = $location [ 'location' ];
2014-06-12 17:39:17 +02:00
$file = Array (
2016-05-05 09:20:07 +02:00
//'Site Configuration' => Egw::link('/index.php','menuaction=admin.admin_config.index&appname='.self::$appname.'&ajax=true'),
2017-01-17 18:24:56 +01:00
'Custom fields' => Egw :: link ( '/index.php' , 'menuaction=admin.admin_customfields.index&appname=' . self :: $appname . '&ajax=true' ),
2016-05-05 09:20:07 +02:00
'Check virtual filesystem' => Egw :: link ( '/index.php' , 'menuaction=filemanager.filemanager_admin.fsck' ),
2021-12-30 13:37:58 +01:00
'Recalculate quota' => Egw :: link ( '/index.php' , 'menuaction=filemanager.filemanager_admin.quotaRecalc' ),
2021-09-13 16:31:46 +02:00
'VFS mounts and versioning' => Egw :: link ( '/index.php' , 'menuaction=filemanager.filemanager_admin.index&ajax=true' ),
2014-06-12 17:39:17 +02:00
);
2008-10-06 19:43:42 +02:00
if ( $location == 'admin' )
{
2008-08-27 13:17:00 +02:00
display_section ( self :: $appname , $file );
2008-10-06 19:43:42 +02:00
}
else
{
2008-08-27 13:17:00 +02:00
display_sidebox ( self :: $appname , lang ( 'Admin' ), $file );
}
}
2008-10-05 19:07:36 +02:00
2009-05-29 12:48:19 +02:00
/**
* Settings for preferences
*
* @ return array with settings
*/
2008-08-27 13:17:00 +02:00
static function settings ()
{
$yes_no = array (
2009-10-19 19:04:11 +02:00
'no' => lang ( 'No' ),
2008-08-28 13:09:09 +02:00
'yes' => lang ( 'Yes' )
2008-08-27 13:17:00 +02:00
);
2008-10-05 19:07:36 +02:00
2009-05-29 12:48:19 +02:00
$settings = array (
2016-08-12 16:29:55 +02:00
'sections.1' => array (
'type' => 'section' ,
'title' => lang ( 'General settings' ),
'no_lang' => true ,
'xmlrpc' => False ,
'admin' => False
),
2008-08-27 13:17:00 +02:00
'startfolder' => array (
'type' => 'input' ,
'name' => 'startfolder' ,
2008-10-06 19:43:42 +02:00
'size' => 60 ,
2010-05-21 09:22:10 +02:00
'label' => 'Enter the complete VFS path to specify your desired start folder.' ,
'help' => 'The default start folder is your personal Folder. The default is used, if you leave this empty, the path does not exist or you lack the neccessary access permissions.' ,
2008-08-27 13:17:00 +02:00
'xmlrpc' => True ,
2009-10-19 19:04:11 +02:00
'admin' => False ,
2008-08-27 13:17:00 +02:00
),
);
2010-11-30 15:29:06 +01:00
$settings += array (
'showbase' => array (
'type' => 'select' ,
'name' => 'showbase' ,
'values' => $yes_no ,
'label' => 'Show link to filemanagers basedirectory (/) in side box menu?' ,
'help' => 'Default behavior is NO. The link will not be shown, but you are still able to navigate to this location, or configure this paricular location as startfolder or folderlink.' ,
'xmlrpc' => True ,
'admin' => False ,
'default' => 'no' ,
),
'showhome' => array (
'type' => 'select' ,
'name' => 'showhome' ,
'values' => $yes_no ,
'label' => lang ( 'Show link "%1" in side box menu?' , lang ( 'Your home directory' )),
'xmlrpc' => True ,
'admin' => False ,
'forced' => 'yes' ,
),
'showusers' => array (
2021-09-30 20:01:37 +02:00
'type' => 'select' ,
'name' => 'showusers' ,
'values' => $yes_no ,
'label' => lang ( 'Show link "%1" in side box menu?' , lang ( 'Users and groups' )),
'xmlrpc' => True ,
'admin' => False ,
'forced' => 'yes' ,
2010-11-30 15:29:06 +01:00
),
);
2012-05-11 10:35:32 +02:00
2021-10-07 18:22:45 +02:00
$merge = new filemanager_merge ();
$settings += $merge -> merge_preferences ();
2012-05-03 19:58:16 +02:00
2018-02-06 18:00:36 +01:00
$editorLink = self :: getEditorLink ();
2020-05-19 19:28:51 +02:00
$mimes = array ( '0' => lang ( 'None' ));
2018-02-15 18:00:04 +01:00
2021-10-07 18:22:45 +02:00
foreach (( array ) $editorLink [ 'mime' ] as $mime => $value )
2019-03-06 13:12:52 +01:00
{
2021-10-07 18:22:45 +02:00
$mimes [ $mime ] = lang ( '%1 file' , strtoupper ( $value [ 'ext' ])) . ' (' . $mime . ')' ;
2019-03-05 21:17:45 +01:00
2021-10-07 18:22:45 +02:00
if ( ! empty ( $value [ 'extra_extensions' ]))
2018-02-15 18:00:04 +01:00
{
2021-10-07 18:22:45 +02:00
$mimes [ $mime ] .= ', ' . strtoupper ( implode ( ', ' , $value [ 'extra_extensions' ]));
2018-02-15 18:00:04 +01:00
}
2018-02-08 10:56:19 +01:00
}
2019-03-05 21:17:45 +01:00
2018-08-24 11:43:34 +02:00
$merge_open_handler = array ( 'download' => lang ( 'download' ), 'collabora' => 'Collabora' );
$document_doubleclick_action = array (
'collabora' => lang ( 'open documents with Collabora, if permissions are given' ),
'download' => lang ( 'download documents' ),
'collabeditor' => lang ( 'open odt documents with CollabEditor' )
);
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'collabora' ])
{
unset ( $document_doubleclick_action [ 'collabora' ], $merge_open_handler [ 'collabora' ]);
}
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'collabeditor' ]) unset ( $document_doubleclick_action [ 'collabeditor' ]);
2018-02-15 18:00:04 +01:00
asort ( $mimes );
2021-05-03 18:12:11 +02:00
2016-08-12 16:29:55 +02:00
$settings += array (
'sections.2' => array (
'type' => 'section' ,
2021-05-03 18:12:11 +02:00
'title' => lang ( 'Collabora Online' ),
2016-08-12 16:29:55 +02:00
'no_lang' => true ,
'xmlrpc' => False ,
'admin' => False
),
2018-02-06 18:00:36 +01:00
'collab_excluded_mimes' => array (
'type' => 'taglist' ,
2018-02-07 13:15:29 +01:00
'label' => lang ( 'Excludes selected mime types' ),
'help' => lang ( 'Excludes selected mime types from being opened by editor' ),
2018-02-06 18:00:36 +01:00
'name' => 'collab_excluded_mimes' ,
2018-07-17 14:52:30 +02:00
'values' => $mimes ,
2020-04-06 15:26:04 +02:00
'default' => 'application/pdf' ,
2018-07-16 13:34:20 +02:00
'attributes' => array (
'autocompelete_url' => ' ' ,
'autocomplete_params' => ' ' ,
'select_options' => $mimes
)
2018-02-06 18:00:36 +01:00
),
2018-02-07 13:15:29 +01:00
'merge_open_handler' => array (
'type' => 'select' ,
'label' => lang ( 'Merge print open handler' ),
2018-02-07 15:18:43 +01:00
'help' => lang ( 'Defines how to open a merge print document' ),
2018-02-07 13:15:29 +01:00
'name' => 'merge_open_handler' ,
2018-08-24 11:43:34 +02:00
'values' => $merge_open_handler ,
2019-07-09 16:11:35 +02:00
'default' => file_exists ( EGW_SERVER_ROOT . '/collabora' ) ? 'collabora' : 'download' ,
2018-08-03 11:08:00 +02:00
),
'document_doubleclick_action' => array (
'type' => 'select' ,
'label' => lang ( 'Default action on double-click' ),
2018-08-10 09:50:27 +02:00
'help' => lang ( 'Defines how to handle double click action on a document file. Images are always opened in the expose-view and emails with email application. All other mime-types are handled by the browser itself.' ),
2018-08-03 11:08:00 +02:00
'name' => 'document_doubleclick_action' ,
2018-08-24 11:43:34 +02:00
'values' => $document_doubleclick_action ,
2019-07-09 16:11:35 +02:00
'default' => file_exists ( EGW_SERVER_ROOT . '/collabora' ) ? 'collabora' : 'download' ,
2018-02-07 13:15:29 +01:00
)
2016-08-12 16:29:55 +02:00
);
2021-04-29 23:20:00 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'collabora' ])
{
$settings += array (
'ui_mode' => array (
'type' => 'select' ,
'label' => lang ( 'UI mode' ),
'name' => 'ui_mode' ,
2021-05-06 18:43:57 +02:00
'values' => [ 'classic' => lang ( 'classic' ), 'notebookbar' => lang ( 'notebookbar' )],
2021-04-29 23:20:00 +02:00
'default' => 'notebookbar'
)
);
}
2009-05-29 12:48:19 +02:00
return $settings ;
2008-08-27 13:17:00 +02:00
}
2012-02-29 15:55:25 +01:00
2012-03-21 11:28:48 +01:00
/**
* Register filemanager as handler for directories
*
2016-05-05 09:20:07 +02:00
* @ return array see Api\Link class
2012-03-21 11:28:48 +01:00
*/
static function search_link ()
{
return array (
2012-07-09 23:23:21 +02:00
'edit' => array (
'menuaction' => 'filemanager.filemanager_ui.file' ,
),
'edit_id' => 'path' ,
'edit_popup' => '495x425' ,
2012-03-21 11:28:48 +01:00
'mime' => array (
2016-05-05 09:20:07 +02:00
Vfs :: DIR_MIME_TYPE => array (
2012-03-21 11:28:48 +01:00
'menuaction' => 'filemanager.filemanager_ui.index' ,
2015-08-26 19:08:37 +02:00
'ajax' => 'true' ,
2012-03-21 11:28:48 +01:00
'mime_id' => 'path' ,
2015-08-26 19:08:37 +02:00
'mime_target' => 'filemanager' ,
// Prevent url from changing to webdav
'mime_url' => ''
2012-03-21 11:28:48 +01:00
),
),
2017-10-05 15:20:14 +02:00
'additional' => array (
'filemanager-editor' => self :: getEditorLink ()
),
2012-07-04 19:00:03 +02:00
'merge' => true ,
2014-10-21 15:51:37 +02:00
'entry' => 'File' ,
'entries' => 'Files' ,
2016-11-07 13:48:24 +01:00
'view_popup' => '980x750'
2012-03-21 11:28:48 +01:00
);
}
2017-10-05 15:20:14 +02:00
/**
* Gets registered links for VFS file editor
*
2019-07-09 16:11:35 +02:00
* @ return array | null links
2017-10-05 15:20:14 +02:00
*/
static function getEditorLink ()
{
2019-09-18 19:54:08 +02:00
foreach ( Api\Hooks :: process ( 'filemanager-editor-link' , 'collabora' ) as $app => $link )
2017-10-05 15:20:14 +02:00
{
2022-10-25 17:48:52 +02:00
if ( $link && ! empty ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ $app ]) &&
2019-07-09 16:11:35 +02:00
( empty ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'filemanager' ][ 'document_doubleclick_action' ]) ||
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'filemanager' ][ 'document_doubleclick_action' ] == $app ))
2017-11-03 16:35:34 +01:00
{
2019-07-09 16:11:35 +02:00
break ;
2017-11-03 16:35:34 +01:00
}
2017-10-05 15:20:14 +02:00
}
return $link ;
}
2022-10-25 17:48:52 +02:00
/**
* Hooks called by vfs , implemented to be able to notify subscribed users about changed files
*
* No need to care for rename or unlink / rmdir as subscriptions are store as properties of the file / directory !
*
* @ param array $data
* @ param string $data [ location ] 'vfs_read' , 'vfs_added' , 'vfs_modified' , 'vfs_unlink' , 'vfs_rename' , 'vfs_mkdir' , 'vfs_rmdir'
* @ param string $data [ path ] vfs path
* @ param string $data [ url ] backend url
* @ param string $data [ mode ] mode of fopen for location = vfs_file_modified
* @ param string $data [ to | from | to_url | from_url ] for location = vfs_file_rename
* @ param string $data [ stat ] only for vfs_ ( unlink | rmdir ), as hook get ' s called after successful unlink / rmdir call
*/
public static function vfs_hooks ( array $data )
{
$path = $data [ 'path' ];
if ( ! $path && $data [ 'to' ])
{
$path = $data [ 'to' ];
}
// ignore / do NOT notify about temporary files or lockfiles created by office programms
if ( preg_match ( '/(^~\$|^\.~lock\.|\.tmp$)/' , Vfs :: basename ( $path )))
{
return ;
}
$stat = isset ( $data [ 'stat' ]) ? $data [ 'stat' ] : Vfs :: stat ( $path );
// we ignore notifications about zero size files, created by some WebDAV clients prior to every real update!
if ( $stat [ 'size' ] || Vfs :: is_dir ( $path ))
{
self :: push ( $data , $stat );
}
}
/**
* Push change information to clients
*
* @ param array $data
* @ return void
* @ throws Api\Json\Exception
*/
protected static function push ( array $data , array $stat )
{
2022-11-01 16:07:55 +01:00
$path = $data [ 'to' ] ? ? $data [ 'from' ] ? ? $data [ 'path' ];
if ( $path && $data [ 'url' ] && $path != $data [ 'url' ] &&
( $path_dir = Vfs :: parse_url ( $path , PHP_URL_PATH )) !== ( $url_dir = Vfs :: parse_url ( $data [ 'url' ], PHP_URL_PATH )))
{
// Looks like some path remapping going on, probably a share
// Try to notify the url path too
$remap = [];
foreach ([ 'from' , 'to' , 'path' ] as $map_path )
{
if ( $data [ $map_path ])
{
$remap [ $map_path ] = str_replace ( $path_dir , $url_dir , Vfs :: parse_url ( $data [ $map_path ], PHP_URL_PATH ));
}
}
static :: push ( $remap + $data , $stat );
}
2022-10-25 17:48:52 +02:00
// Who do we want to broadcast to
$account_id = [];
2022-11-01 16:07:55 +01:00
if ( str_starts_with ( $data [ 'from' ], '/home/' ) || str_starts_with ( $data [ 'to' ], '/home/' ) || str_starts_with ( $path , '/home/' ))
2022-10-25 17:48:52 +02:00
{
// In home, send to just owner and group members
if ( $stat [ 'uid' ])
{
$account_id [] = $stat [ 'uid' ];
}
if ( $stat [ 'gid' ])
{
$account_id += $GLOBALS [ 'egw' ] -> accounts -> members ( '-' . $stat [ 'gid' ], true );
}
}
else
{
// Send to everyone
$account_id = Push :: ALL ;
}
// Send along some ACL info - a list of account_ids that should have read access
$acl = [];
if ( $stat [ 'uid' ])
{
$acl [] = $stat [ 'uid' ];
}
if ( $stat [ 'gid' ])
{
$acl [] = - $stat [ 'gid' ];
}
2022-11-01 16:07:55 +01:00
foreach ([ 'to' , 'from' , 'path' ] as $field )
2022-10-25 17:48:52 +02:00
{
2022-11-01 16:07:55 +01:00
$eacl = Vfs :: get_eacl ( $data [ $field ]);
2022-10-25 17:48:52 +02:00
if ( $eacl )
{
$acl = array_merge ( $acl , array_column ( $eacl , 'owner' ));
}
}
$acl = array_unique ( $acl );
$type = '' ;
$push = new Push ( $account_id );
switch ( $data [ 'location' ])
{
case 'vfs_rename' :
// Extra push to remove the old, since path = ID
$push -> apply ( " egw.push " ,
[[
'app' => 'filemanager' ,
'id' => $data [ 'from' ],
'type' => 'delete' ,
'acl' => $acl ,
'account_id' => $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]
]]
);
// fall through
case 'vfs_added' :
case 'vfs_mkdir' :
$type = 'add' ;
break ;
case 'vfs_modified' :
$type = 'update' ;
break ;
case 'vfs_unlink' :
case 'vfs_rmdir' :
$type = 'delete' ;
break ;
}
$push -> apply ( " egw.push " ,
[[
'app' => 'filemanager' ,
2022-11-01 16:07:55 +01:00
'id' => $data [ 'to' ] ? ? $path ,
2022-10-25 17:48:52 +02:00
'type' => $type ,
'acl' => $acl ,
'account_id' => $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]
]]
);
}
2008-08-27 13:17:00 +02:00
}