2012-05-03 19:58:16 +02:00
< ? php
/**
* Filemanager - document merge
*
* @ link http :// www . egroupware . org
* @ author Nathan Gray
* @ package filemanager
* @ copyright 2012 Nathan Gray
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
2016-05-05 09:20:07 +02:00
use EGroupware\Api ;
use EGroupware\Api\Link ;
use EGroupware\Api\Vfs ;
2012-05-03 19:58:16 +02:00
/**
* Filemanager - document merge object
* Only merges information about the files , not the files themselves
*/
2016-05-05 09:20:07 +02:00
class filemanager_merge extends Api\Storage\Merge
2012-05-03 19:58:16 +02:00
{
/**
* Functions that can be called via menuaction
*
* @ var array
*/
var $public_functions = array (
'show_replacements' => true ,
2021-06-23 19:31:47 +02:00
'merge_entries' => true
2012-05-03 19:58:16 +02:00
);
/**
* Fields that are numeric , for special numeric handling
*/
protected $numeric_fields = array (
);
2012-07-30 19:48:56 +02:00
/**
* Fields that are dates or timestamps
*/
public $date_fields = array (
'mtime' , 'ctime'
);
2012-05-03 19:58:16 +02:00
/**
* Business object to pull records from
*/
protected $bo = null ;
2012-05-07 17:53:28 +02:00
/**
* Current directory - affects how files are named
*/
protected $dir = '' ;
2012-05-03 19:58:16 +02:00
/**
* Constructor
*
*/
2012-05-07 17:53:28 +02:00
function __construct ( $_dir = '' )
2012-05-03 19:58:16 +02:00
{
parent :: __construct ();
2014-11-19 13:20:59 +01:00
2012-05-07 17:53:28 +02:00
if ( $_dir )
{
$this -> dir = $_dir ;
}
2014-11-19 13:20:59 +01:00
2016-05-05 09:20:07 +02:00
// switch off handling of html formated content, if html is not used
$this -> parse_html_styles = Api\Storage\Customfields :: use_html ( 'filemanager' );
2012-05-03 19:58:16 +02:00
}
/**
* Get replacements
*
* @ param int $id id of entry
* @ param string & $content = null content to create some replacements only if they are use
* @ return array | boolean
*/
protected function get_replacements ( $id , & $content = null )
{
if ( ! ( $replacements = $this -> filemanager_replacements ( $id , '' , $content )))
{
return false ;
}
return $replacements ;
}
/**
* Get filemanager replacements
*
* @ param int $id id ( vfs path ) of entry
* @ param string $prefix = '' prefix like eg . 'erole'
* @ return array | boolean
*/
public function filemanager_replacements ( $id , $prefix = '' , & $content = null )
{
$info = array ();
2016-05-05 09:20:07 +02:00
$file = Vfs :: lstat ( $id , true );
2012-05-03 19:58:16 +02:00
2016-05-05 09:20:07 +02:00
$file [ 'mtime' ] = Api\DateTime :: to ( $file [ 'mtime' ]);
$file [ 'ctime' ] = Api\DateTime :: to ( $file [ 'ctime' ]);
2012-05-03 19:58:16 +02:00
2016-05-05 09:20:07 +02:00
$file [ 'name' ] = Vfs :: basename ( $id );
2016-07-02 12:28:58 +02:00
$file [ 'dir' ] = ( $dir = Vfs :: dirname ( $id )) ? Vfs :: decodePath ( $dir ) : '' ;
2012-06-05 16:50:22 +02:00
$dirlist = explode ( '/' , $file [ 'dir' ]);
$file [ 'folder' ] = array_pop ( $dirlist );
$file [ 'folder_file' ] = $file [ 'folder' ] . '/' . $file [ 'name' ];
2012-05-03 19:58:16 +02:00
$file [ 'path' ] = $id ;
2012-05-07 17:53:28 +02:00
$file [ 'rel_path' ] = str_replace ( $this -> dir . '/' , '' , $id );
2016-05-05 09:20:07 +02:00
$file [ 'hsize' ] = Vfs :: hsize ( $file [ 'size' ]);
$file [ 'mime' ] = Vfs :: mime_content_type ( $id );
2012-05-03 19:58:16 +02:00
$file [ 'gid' ] *= - 1 ; // our widgets use negative gid's
2016-05-05 09:20:07 +02:00
if (( $props = Vfs :: propfind ( $id )))
2012-05-03 19:58:16 +02:00
{
2014-11-19 13:20:59 +01:00
foreach ( $props as $prop )
{
$file [ $prop [ 'name' ]] = $prop [ 'val' ];
}
2012-05-03 19:58:16 +02:00
}
2016-05-05 09:20:07 +02:00
if (( $file [ 'is_link' ] = Vfs :: is_link ( $id )))
2012-05-03 19:58:16 +02:00
{
2016-05-05 09:20:07 +02:00
$file [ 'symlink' ] = Vfs :: readlink ( $id );
2012-05-03 19:58:16 +02:00
}
2012-05-07 17:53:28 +02:00
// Custom fields
2012-05-03 19:58:16 +02:00
if ( $content && strpos ( $content , '#' ) !== 0 )
{
2012-05-07 17:53:28 +02:00
// Expand link-to custom fields
2014-11-19 13:20:59 +01:00
$this -> cf_link_to_expand ( $file , $content , $info );
2016-05-05 09:20:07 +02:00
foreach ( Api\Storage\Customfields :: get ( 'filemanager' ) as $name => $field )
2012-05-07 17:53:28 +02:00
{
// Set any missing custom fields, or the marker will stay
if ( ! $file [ '#' . $name ])
{
$file [ '#' . $name ] = '' ;
continue ;
}
2016-05-05 09:20:07 +02:00
// Format date cfs per user Api\Preferences
2012-05-07 17:53:28 +02:00
if ( $field [ 'type' ] == 'date' || $field [ 'type' ] == 'date-time' )
{
2012-07-30 19:48:56 +02:00
$this -> date_fields [] = '#' . $name ;
2016-05-05 09:20:07 +02:00
$file [ '#' . $name ] = Api\DateTime :: to ( $file [ '#' . $name ], $field [ 'type' ] == 'date' ? true : '' );
2012-05-07 17:53:28 +02:00
}
}
2012-05-03 19:58:16 +02:00
}
2012-06-18 17:02:52 +02:00
// If in apps folder, try for app-specific placeholders
if ( $dirlist [ 1 ] == 'apps' && count ( $dirlist ) > 1 )
{
2012-06-25 19:54:43 +02:00
// Try this first - a normal path /apps/appname/id/file
2012-06-26 17:24:20 +02:00
list ( $app , $app_id ) = explode ( '/' , substr ( $file [ 'path' ], strpos ( $file [ 'path' ], 'apps/' ) + 5 ));
2012-06-25 19:54:43 +02:00
// Symlink?
2012-06-26 17:24:20 +02:00
if ( ! $app || ! ( int ) $app_id || ! array_key_exists ( $app , $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ])) {
2012-06-25 19:54:43 +02:00
// Try resolving just app + ID - /apps/App Name/Record Title/file
2016-05-05 09:20:07 +02:00
$resolved = Vfs :: resolve_url_symlinks ( implode ( '/' , array_slice ( explode ( '/' , $file [ 'dir' ]), 0 , 4 )));
2012-06-26 17:24:20 +02:00
list ( $app , $app_id ) = explode ( '/' , substr ( $resolved , strpos ( $resolved , 'apps/' ) + 5 ));
2012-06-25 19:54:43 +02:00
2012-06-26 17:24:20 +02:00
if ( ! $app || ! ( int ) $app_id || ! array_key_exists ( $app , $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ])) {
2012-06-25 19:54:43 +02:00
// Get rid of any virtual folders (eg: All$) and symlinks
2016-05-05 09:20:07 +02:00
$resolved = Vfs :: resolve_url_symlinks ( $file [ 'path' ]);
2012-06-26 17:24:20 +02:00
list ( $app , $app_id ) = explode ( '/' , substr ( $resolved , strpos ( $resolved , 'apps/' ) + 5 ));
2012-06-25 19:54:43 +02:00
}
}
2012-06-26 17:24:20 +02:00
if ( $app && $app_id )
2012-06-25 19:54:43 +02:00
{
2012-06-18 17:02:52 +02:00
if ( $app && $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ $app ])
{
$app_merge = null ;
try
{
$classname = $app . '_merge' ;
if ( class_exists ( $classname ))
{
$app_merge = new $classname ();
if ( $app_merge && method_exists ( $app_merge , 'get_replacements' ))
{
2012-06-26 17:24:20 +02:00
$app_placeholders = $app_merge -> get_replacements ( $app_id , $content );
2012-06-18 17:02:52 +02:00
}
}
}
// Silently discard & continue
2014-11-19 13:20:59 +01:00
catch ( Exception $e ) {
unset ( $e ); // not used
}
2012-06-18 17:02:52 +02:00
}
}
}
2016-05-05 09:20:07 +02:00
$link = Link :: mime_open ( $file [ 'url' ], $file [ 'mime' ]);
2012-05-08 17:10:43 +02:00
if ( is_array ( $link ))
{
// Directories have their internal protocol in path here
if ( $link [ 'path' ] && strpos ( $link [ 'path' ], '://' ) !== false ) $link [ 'path' ] = $file [ 'path' ];
2016-05-05 09:20:07 +02:00
$link = Api\Session :: link ( '/index.php' , $link );
2012-05-08 17:10:43 +02:00
}
else
{
// Regular files
2016-05-05 09:20:07 +02:00
$link = Api\Session :: link ( $link );
2012-05-08 17:10:43 +02:00
}
// Prepend site, if missing
2018-03-21 12:40:59 +01:00
if ( $link [ 0 ] == '/' ) $link = Api\Framework :: getUrl ( $link );
2016-05-05 09:20:07 +02:00
$file [ 'link' ] = Api\Html :: a_href ( Api\Html :: htmlspecialchars ( $file [ 'name' ]), $link );
2018-07-24 22:53:38 +02:00
$file [ 'webdav_url' ] = Api\Session :: link ( Vfs :: download_url ( $file [ 'url' ]));
2012-05-07 17:53:28 +02:00
$file [ 'url' ] = $link ;
2012-05-03 19:58:16 +02:00
// Add markers
foreach ( $file as $key => & $value )
{
if ( ! $value ) $value = '' ;
$info [ '$$' . ( $prefix ? $prefix . '/' : '' ) . $key . '$$' ] = $value ;
}
2012-06-18 17:02:52 +02:00
if ( $app_placeholders )
{
$info = array_merge ( $app_placeholders , $info );
}
2012-05-03 19:58:16 +02:00
return $info ;
}
2019-05-07 23:06:19 +02:00
/**
* Create a share for an entry
*
* @ param string $app
* @ param string $id
* @ param string $path
* @ param type $content
* @ return type
*/
protected function create_share ( $app , $id , & $content )
{
// Check if some other process created the share (with custom options)
// and put it in the session cache for us
$path = $id ;
$session = \EGroupware\Api\Cache :: getSession ( Api\Sharing :: class , $path );
if ( $session && $session [ 'share_path' ] == $path )
{
return $session ;
}
2019-07-16 21:44:20 +02:00
else if (( $session = \EGroupware\Api\Cache :: getSession ( Api\Sharing :: class , " $app :: $id " )) &&
substr ( $session [ 'share_path' ], - strlen ( $path )) === $path )
{
return $session ;
}
2019-05-07 23:06:19 +02:00
// Need to create the share here.
// No way to know here if it should be writable, or who it's going to
$mode = /* ? ? Sharing::WRITABLE :*/ Api\Sharing :: READONLY ;
$recipients = array ();
$extra = array ();
2020-03-25 03:34:04 +01:00
return \EGroupware\Api\Vfs\Sharing :: create ( '' , $path , $mode , NULL , $recipients , $extra );
2019-05-07 23:06:19 +02:00
}
2012-05-03 19:58:16 +02:00
/**
2016-05-05 09:20:07 +02:00
* Generate table with replacements for the Api\Preferences
2012-05-03 19:58:16 +02:00
*
*/
public function show_replacements ()
{
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'app_header' ] = lang ( 'filemanager' ) . ' - ' . lang ( 'Replacements for inserting entries into documents' );
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'nonavbar' ] = false ;
2016-05-14 21:26:36 +02:00
echo $GLOBALS [ 'egw' ] -> framework -> header ();
2012-05-03 19:58:16 +02:00
echo " <table width='90%' align='center'> \n " ;
echo '<tr><td colspan="4"><h3>' . lang ( 'Filemanager fields:' ) . " </h3></td></tr> " ;
$n = 0 ;
$fields = array (
'name' => 'name' ,
2012-05-07 17:53:28 +02:00
'path' => 'Absolute path' ,
'rel_path' => 'Path relative to current directory' ,
2012-06-05 16:50:22 +02:00
'folder' => 'Containing folder' ,
'folder_file' => 'Containing folder and file name' ,
2012-05-03 19:58:16 +02:00
'url' => 'url' ,
2018-07-24 22:53:38 +02:00
'webdav_url' => 'External path using webdav' ,
2012-05-07 17:53:28 +02:00
'link' => 'Clickable link to file' ,
2012-05-03 19:58:16 +02:00
'comment' => 'comment' ,
'mtime' => 'modified' ,
'ctime' => 'created' ,
'mime' => 'Type' ,
'hsize' => 'Size' ,
'size' => 'Size (in bytes)' ,
);
foreach ( $fields as $name => $label )
{
if ( ! ( $n & 1 )) echo '<tr>' ;
echo '<td>{{' . $name . '}}</td><td>' . lang ( $label ) . '</td>' ;
if ( $n & 1 ) echo " </tr> \n " ;
$n ++ ;
}
echo '<tr><td colspan="4"><h3>' . lang ( 'Custom fields' ) . " :</h3></td></tr> " ;
2016-05-05 09:20:07 +02:00
foreach ( Api\Storage\Customfields :: get ( 'filemanager' ) as $name => $field )
2012-05-03 19:58:16 +02:00
{
echo '<tr><td>{{#' . $name . '}}</td><td colspan="3">' . $field [ 'label' ] . " </td></tr> \n " ;
}
2012-06-18 17:02:52 +02:00
echo '<tr><td colspan="4"><h3>' . lang ( 'Application fields' ) . " :</h3></td></tr> " ;
echo '<tr><td colspan="4">' . lang ( 'For files linked to an application entry (inside /apps/appname/id/) the placeholders for that application are also available. See the specific application for a list of available placeholders.' ) . '</td></tr>' ;
2012-05-03 19:58:16 +02:00
echo '<tr><td colspan="4"><h3>' . lang ( 'General fields:' ) . " </h3></td></tr> " ;
foreach ( array (
'date' => lang ( 'Date' ),
'user/n_fn' => lang ( 'Name of current user, all other contact fields are valid too' ),
'user/account_lid' => lang ( 'Username' ),
'pagerepeat' => lang ( 'For serial letter use this tag. Put the content, you want to repeat between two Tags.' ),
'label' => lang ( 'Use this tag for addresslabels. Put the content, you want to repeat, between two tags.' ),
'labelplacement' => lang ( 'Tag to mark positions for address labels' ),
'IF fieldname' => lang ( 'Example {{IF n_prefix~Mr~Hello Mr.~Hello Ms.}} - search the field "n_prefix", for "Mr", if found, write Hello Mr., else write Hello Ms.' ),
'NELF' => lang ( 'Example {{NELF role}} - if field role is not empty, you will get a new line with the value of field role' ),
2017-02-10 10:41:43 +01:00
'NENVLF' => lang ( 'Example {{NENVLF role}} - if field role is not empty, set a LF without any value of the field' ),
2012-05-03 19:58:16 +02:00
'LETTERPREFIX' => lang ( 'Example {{LETTERPREFIX}} - Gives a letter prefix without double spaces, if the title is empty for example' ),
'LETTERPREFIXCUSTOM' => lang ( 'Example {{LETTERPREFIXCUSTOM n_prefix title n_family}} - Example: Mr Dr. James Miller' ),
) as $name => $label )
{
echo '<tr><td>{{' . $name . '}}</td><td colspan="3">' . $label . " </td></tr> \n " ;
}
echo " </table> \n " ;
2016-05-14 21:26:36 +02:00
echo $GLOBALS [ 'egw' ] -> framework -> footer ();
2012-05-03 19:58:16 +02:00
}
}