<?php

/**
 * This file is part of an ADDON for use with LEPTON Core.
 * This ADDON is released under the GNU GPL.
 * Additional license terms can be seen in the info.php of this module.
 *
 * @module          Droplets
 * @author          LEPTON Project
 * @copyright       2010-2022 LEPTON Project
 * @link            https://lepton-cms.org
 * @license         http://www.gnu.org/licenses/gpl.html
 * @license_terms   please see info.php of this module
 *
 */

// include class.secure.php to protect this file and the whole CMS!
if(!defined("SEC_FILE")){define("SEC_FILE",'/framework/class.secure.php' );}
if (defined('LEPTON_PATH')) {	
	include LEPTON_PATH.SEC_FILE;
} else {
	$oneback = "../";
	$root = $oneback;
	$level = 1;
	while (($level < 10) && (!file_exists($root.SEC_FILE))) {
		$root .= $oneback;
		$level += 1;
	}
	if (file_exists($root.SEC_FILE)) { 
		include $root.SEC_FILE;   
	} else {
		trigger_error(sprintf("[ <b>%s</b> ] Can't include class.secure.php!", $_SERVER['SCRIPT_NAME']), E_USER_ERROR);
	}
}
// end include class.secure.php

/**
 * this function may be called by modules to handle a droplet upload
 **/
function droplets_upload( $input ) {

    global $database, $MOD_DROPLETS;
    
    // Set temp vars
    $temp_dir   = LEPTON_PATH.'/temp/';
    $temp_file  = $temp_dir . filter_var( $_FILES[$input]['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $temp_unzip = LEPTON_PATH.'/temp/unzip/';

    // Try to upload the file to the temp dir
    if( ! move_uploaded_file( filter_var( $_FILES[$input]['tmp_name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS), $temp_file ) )
    {
   	    return array( 'error', $MOD_DROPLETS['Upload failed'] );
    }

    $result = droplet_install( $temp_file, $temp_unzip );

    // Delete the temp zip file
    if( file_exists( $temp_file) )
    {
        unlink( $temp_file );
    }
    rm_full_dir($temp_unzip);

    // show errors
    if ( isset( $result['errors'] ) && is_array( $result['errors'] ) && count( $result['errors'] ) > 0 ) {
        return array( 'error', $result['errors'], NULL );
    }
    
    // return success
    return array( 'success', $result['count'] );
    
}   // end function droplets_upload()


/**
 * this function may be called by modules to install a droplet 
 **/
function droplet_install( $temp_file, $temp_unzip ) {

    global $admin, $database;

	$errors  = array();
    $count   = 0;
	$imports = array();
	
	$zip = lib_lepton::getToolInstance("pclzip", $temp_file);
	
	$zip->extract(PCLZIP_OPT_PATH, $temp_unzip);
    
    // now, open all *.php files and search for the header;
    // an exported droplet starts with "//:"
    if ( (is_dir($temp_unzip)) && ($dh = opendir($temp_unzip) ) )
    {
        while ( false !== ( $file = readdir($dh) ) )
        {
            if ( ( $file[0] != "." ) && ( preg_match( '/^(.*)\.php$/i', $file, $name_match ) ) )
            {
                // Name of the Droplet = Filename
                $name  = $name_match[1];
                // Slurp file contents
                $lines = file( $temp_unzip.'/'.$file );
                // First line: Description
                if ( preg_match( '#^//\:(.*)$#', $lines[0], $match ) ) {
                    $description = $match[1];
                }
                // Second line: Usage instructions
                if ( preg_match( '#^//\:(.*)$#', $lines[1], $match ) ) {
                    $usage       = addslashes( $match[1] );
                }
                // Remaining: Droplet code
                $code = implode( '', array_slice( $lines, 2 ) );
                // replace 'evil' chars in code
                $tags = array('<?php', '?>' , '<?');
                $code = addslashes(str_replace($tags, '', $code));
                // Already in the DB?
                $stmt  = 'INSERT';
                $id    = NULL;
                $found = $database->get_one("SELECT * FROM ".TABLE_PREFIX."mod_droplets WHERE name='$name'");
                if ( $found && $found > 0 )
                {
                    $stmt = 'REPLACE';
                    $id   = $found;
                }
                // execute
                $database->simple_query("$stmt INTO ".TABLE_PREFIX."mod_droplets VALUES(" . ( $id!==NULL ? "'".$id."'" : 'NULL' ). ",'$name','$code','$description','".time()."','".(isset( $_SESSION[ 'USER_ID' ] ) ? $_SESSION[ 'USER_ID' ] : '1')."',1,0,0,0,'$usage')");
                if( ! $database->is_error() )
                {
                    $count++;
                    $imports[$name] = 1;
                }
                else
                {
                    $errors[$name] = $database->get_error();
                }
                // try to remove the temp file
                unlink( $temp_unzip.'/'.$file);
            
            }
        }
        closedir($dh);
    }
    
    return array( 'count' => $count, 'errors' => $errors, 'imported'=> $imports );
    
}   // end function droplet_install()

/**
 *  Get a list of all droplets and show them
 *
 **/
function list_droplets( $info = NULL )
{
    global $admin;

    // check for global read perms
    $groups = $admin->get_groups_id();
    
    $database = LEPTON_database::getInstance();
	
    $oDroplets = droplets::getInstance();
	
	$backups = $oDroplets->backups;
	$MOD_DROPLETS = $oDroplets->language;

    $rows = array();
    
    // L* 4.5
    $aAllDroplets = [];
    $result  = $database->execute_query(
        "SELECT t1.id, name, code, description, active, comments, view_perm, edit_perm 
            FROM
                " . TABLE_PREFIX . "mod_droplets 
                    AS t1 LEFT OUTER JOIN 
                " . TABLE_PREFIX . "mod_droplets_permissions 
                    AS t2 ON t1.id = t2.id 
            ORDER BY name 
            ASC",
        true,
        $aAllDroplets,
        true
    );

    if(true === $result)
    {
        foreach($aAllDroplets as &$droplet)
        {
            // the current user needs global edit permissions, or specific edit permissions to see this droplet
            if ( !is_allowed( 'modify_droplets', $groups ) && ( $droplet[ 'edit_perm' ] ) )
            {
                // get edit groups for this droplet
                if ( ($admin->get_user_id() != 1) && (!is_in_array( $droplet[ 'edit_perm' ], $groups )) )
                {
                    continue;
                }
                else
                {
                    $droplet[ 'user_can_modify_this' ] = true;
                }
            }
            $comments = str_replace( array(
                "\r\n",
                "\n",
                "\r"
            ), '<br />', $droplet[ 'comments' ] );
            
            if ( !strpos( $comments, "[[" ) )
            {
                $comments = '<span class="usage">' . $MOD_DROPLETS[ 'Use' ] . ": [[" . $droplet[ 'name' ] . "]]</span><br />" . $comments;
            }
            $comments = str_replace( array(
                "[[",
                "]]"
            ), array(
                '<b>[[',
                ']]</b>'
            ), $comments );
            $droplet[ 'valid_code' ] = check_syntax( $droplet[ 'code' ] );
            $droplet[ 'comments' ] = $comments;
            // droplet included in search?
	        $droplet['is_in_search'] = true;

			$droplet['delete_message'] = sprintf( $MOD_DROPLETS['Are you sure'], $droplet[ 'name' ] );

            array_push( $rows, $droplet );
        }
    }

    echo lib_twig_box::getInstance()->render( 
    	'@droplets/modify.lte', 
    	array(
			'rows'       => $rows,
			'num_rows'	=> count($rows),
			'info'       => $info,
			'backups'    => ( ( count( $backups ) && is_allowed( 'Manage_backups', $groups ) ) ? 1 : NULL ),
			'can_export' => ( is_allowed( 'Export_droplets', $groups ) ? 1 : NULL ),
			'can_import' => ( is_allowed( 'Import_droplets', $groups ) ? 1 : NULL ),
			'can_delete' => ( is_allowed( 'Delete_droplets', $groups ) ? 1 : NULL ),
			'can_modify' => ( is_allowed( 'Modify_droplets', $groups ) ? 1 : NULL ),
			'can_perms'  => ( is_allowed( 'Manage_perms', $groups ) ? 1 : NULL ),

			'can_add'    => ( is_allowed( 'Add_droplets', $groups ) ? 1 : NULL ),
			// Aldus 2021-10-28 - fix
			'IMGURL'    => LEPTON_URL . '/modules/droplets/css/images',
    		'DOCURL'    => LEPTON_URL . '/modules/droplets/docs/readme.php?url='.LEPTON_URL.'/modules/droplets/docs',
    		'action'    => ADMIN_URL . '/admintools/tool.php?tool=droplets',
    		'MOD_DROPLETS'   => droplets::getInstance()->language // ! attention
        )
    );

}

/**
 *
 **/
function manage_backups()
{
    global $admin;
    //, $parser, $database, $settings, $MOD_DROPLETS;

    $MOD_DROPLETS = droplets::getInstance()->language;
    $groups = $admin->get_groups_id();
    if ( !is_allowed( 'Manage_backups', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }

    $rows = array();
    $info = NULL;

    $sRecover = (isset($_REQUEST[ 'recover' ]) )
        ? filter_var( $_REQUEST[ 'recover' ], FILTER_SANITIZE_STRING )
        : ""
        ;

    // recover
    if ( file_exists( dirname( __FILE__ ) . '/export/' . $sRecover ) )
    {
        $temp_unzip = LEPTON_PATH . '/temp/unzip/';
        $result     = droplet_install( dirname( __FILE__ ) . '/export/' .$sRecover, $temp_unzip );
        $info       = str_replace("{{count}}", $result[ 'count' ], $MOD_DROPLETS[ 'Successfully imported Droplet(s)'] );
    }

    $sDelbackup = (isset( $_REQUEST[ 'delbackup' ]))
        ? filter_var( $_REQUEST[ 'delbackup' ], FILTER_SANITIZE_STRING )
        : ""
        ;

    // delete single backup
    if (($sDelbackup != "") && (file_exists( dirname( __FILE__ ) . '/export/' . $sDelbackup )))
    {
        unlink( dirname( __FILE__ ) . '/export/' . $sDelbackup );
		$info = str_replace("{{file}}", $sDelbackup, $MOD_DROPLETS[ 'Backup file deleted:']);
    }

    // delete a list of backups
    // get all marked droplets
    $marked = ( (isset( $_POST[ 'markeddroplet' ])) && (is_array($_POST[ 'markeddroplet' ] )) )
        ? (array) $_POST[ 'markeddroplet' ]
        : array()
        ;

    if ( !empty( $marked ) )
    {
        $deleted = array();
        foreach ( $marked as $file )
        {
            $sTempFile = dirname( __FILE__ ) . '/export/' . $file ;
            if ( file_exists( $sTempFile ) )
            {
                unlink( $sTempFile );
				$deleted[] = str_replace("{{file}}", basename( $sTempFile ) , $MOD_DROPLETS[ 'Backup file deleted:'] );
            }
        }
        if ( count( $deleted ) )
        {
            $info = implode( '<br />', $deleted );
        }
    }

	LEPTON_handle::register( "file_list" );
    $backups = file_list( dirname( __FILE__ ) . '/export' , array('index.php'), false , "zip" );

    if ( count( $backups ) > 0 )
    {
        require_once(LEPTON_PATH.'/modules/lib_lepton/pclzip/pclzip.lib.php');
        
        // sort by name
        // sort( $backups );
        foreach ( $backups as $file )
        {
            // stat
            $stat   = stat( $file );
            
            // get zip contents
			
            $oZip = new PclZip( $file );            
            $count  = $oZip->listContent();

            $rows[] = array(
                'name' => basename( $file ),
                'size' => $stat[ 'size' ],
                'date' => date( DATE_FORMAT." - ".TIME_FORMAT , $stat[ 'ctime' ] ),
                'files' => count( $count ),
                'listfiles' => "- ".implode( ",<br />- ", array_map( function( $cnt ) { return $cnt["filename"]; } , $count ) ) ,
                'download' =>  LEPTON_URL . '/modules/droplets/export/' . basename( $file )
            );
        }
    }

    echo lib_twig_box::getInstance()->render(
    	'@droplets/backups.lte',
    	array(
        	'rows' => $rows,
        	'info' => $info,
        	'backups' => ( count( $backups ) ? 1 : NULL ),
        	'num_rows' => count( $rows ),
			// Aldus 2021-10-28 - fix
			'IMGURL'    => LEPTON_URL . '/modules/droplets/css/images',
    		'DOCURL'    => LEPTON_URL . '/modules/droplets/docs/readme.php?url='.LEPTON_URL.'/modules/droplets/docs',
    		'action'    => ADMIN_URL . '/admintools/tool.php?tool=droplets',
    		'MOD_DROPLETS'   => droplets::getInstance()->language // ! attention
    	)
    );

} // end function manage_backups()

/**
 *
 **/
function manage_perms()
{
    global $admin;
    
    $oDroplets = droplets::getInstance();
    
    $MOD_DROPLETS = $oDroplets->language;
    $settings = $oDroplets->settings;
    $database = LEPTON_database::getInstance();
    
    $info   = NULL;
    $groups = array();
    $rows   = array();

    $this_user_groups = $admin->get_groups_id();
    if ( !is_allowed( 'Manage_perms', $this_user_groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }

    // get available groups
    $aAllGroups = array();
    $database->execute_query(
        "SELECT `group_id`, `name` FROM `" . TABLE_PREFIX . "groups` ORDER BY `name`",
        true,
        $aAllGroups,
        true
    );
    
    foreach($aAllGroups as $row)
    {
        $groups[ $row[ 'group_id' ] ] = $row[ 'name' ];
    }

    if ( isset( $_REQUEST[ 'save' ] ) || isset( $_REQUEST[ 'save_and_back' ] ) )
    {
        foreach ( $settings as $key => $value )
        {
            if ( isset( $_REQUEST[ $key ] ) )
            {
				$database->build_and_execute( 
					'UPDATE', 
					TABLE_PREFIX.'mod_droplets_settings', 
					['value' => implode( '|', $_REQUEST[ $key ] ) ], 
					'attribute = "'.$key.'"'
				);
            }
        }
        // reload settings
        $oDroplets->getSettings();
        $settings = $oDroplets->settings;
        
        $info     = $MOD_DROPLETS[ 'Permissions saved' ];
        if ( isset( $_REQUEST[ 'save_and_back' ] ) )
        {
            list_droplets( $info );
            return  true;
        }
    }

    foreach ( $settings as $key => $value )
    {
        $line = array();
        foreach ( $groups as $id => $name )
        {
            $line[] = '<span class="perm_item"><input type="checkbox" name="'.$key.'[]" id="'.$key.'_'.$id.'" value="'.$id .'"'. ( (is_in_array( $value, $id ) || ($id==1) ) ? ' checked="checked"' : NULL ) .' /><label for="'.$key.'_'.$id.'">'. $name.'</label></div>' . "\n";
        }
        $rows[] = array(
            'groups' => implode( '', $line ),
            'name' => $MOD_DROPLETS[ $key ]
        );
    }

    // sort rows by permission name (=text)
	sort($rows);
	
    echo lib_twig_box::getInstance()->render(
    	'@droplets/permissions.lte',
    	array(
            'rows' => $rows,
            'info' => $info,
            'num_rows' => count($rows),         
   			// Aldus 2021-10-28 - fix
			'IMGURL'    => LEPTON_URL . '/modules/droplets/css/images',
    		'DOCURL'    => LEPTON_URL . '/modules/droplets/docs/readme.php?url='.LEPTON_URL.'/modules/droplets/docs',
    		'action'    => ADMIN_URL . '/admintools/tool.php?tool=droplets',
    		'MOD_DROPLETS'   => droplets::getInstance()->language // ! attention
        )
    );

} // end function manage_perms()

/**
 *	Exporting marked droplets int a zip archive
 *	
 **/
function export_droplets()
{
    global $admin, $database; //$parser, $MOD_DROPLETS;

    $database = LEPTON_database::getInstance();
    $MOD_DROPLETS = droplets::getInstance()->language;
    
    $groups = $admin->get_groups_id();
    if ( !is_allowed( 'Export_droplets', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }

    $info = array();

    // get all marked droplets
    $marked = isset( $_POST[ 'markeddroplet' ] ) ? $_POST[ 'markeddroplet' ] : array();

    if ( isset( $marked ) && !is_array( $marked ) )
    {
        $marked = array(
             $marked
        );
    }

    if ( !count( $marked ) )
    {
        return $MOD_DROPLETS[ 'Please mark some droplets to export' ];
    }

    $temp_dir = LEPTON_PATH . '/temp/droplets/';

    // make the temporary working directory
    if(!file_exists($temp_dir))
    {
    	mkdir( $temp_dir );
	}
	
	$all_marked_droplets = array();
	$database->execute_query(
		"SELECT * FROM `".TABLE_PREFIX."mod_droplets` WHERE id IN (".implode(",", $marked).")",
		true,
		$all_marked_droplets,
		true
	);
	
	foreach ( $all_marked_droplets as $droplet )
	{
		$name    = $droplet[ "name" ];
		$info[]  = 'Droplet: ' . $name . '.php<br />';
		$sFile   = $temp_dir . $name . '.php';
		$fh      = fopen( $sFile, 'w' );
		fwrite( $fh, '//:' . $droplet[ 'description' ] . "\n" );
		fwrite( $fh, '//:' . str_replace( "\n", " ", $droplet[ 'comments' ] ) . "\n" );
		fwrite( $fh, $droplet[ 'code' ] );
		fclose( $fh );
	}

    $filename = 'droplets';

    // if there's only a single droplet to export, name the zip-file after this droplet
    if ( count( $marked ) === 1 )
    {
        $filename = 'droplet_' . $name;
    }

    // add current date to filename
    $filename .= '_' . date( 'Y-m-d' );

    // while there's an existing file, add a number to the filename
    if ( file_exists( LEPTON_PATH . '/modules/droplets/export/' . $filename . '.zip' ) )
    {
        $n = 1;
        while ( file_exists( LEPTON_PATH . '/modules/droplets/export/' . $filename . '_' . $n . '.zip' ) )
        {
            $n++;
        }
        $filename .= '_' . $n;
    }

    $temp_file = LEPTON_PATH . '/temp/' . $filename . '.zip';

    // create zip
    $zip = lib_lepton::getToolInstance("pclzip", $temp_file);

	LEPTON_handle::register( "file_list" );
	$all_files_for_archive = file_list( substr($temp_dir, 0, -1), array("index.php"), false, "php");

    if (count($all_files_for_archive) == 0)
    {
    	  echo "Packaging error: ", $zip->getStatusString(), "<br />";
    	  die("Error : ".$zip->errorInfo(true) );
    }
    else {
    
    	foreach( $all_files_for_archive as $temp_filename)
    	{
    	    $zip->add( $temp_filename, PCLZIP_OPT_REMOVE_PATH, $temp_dir  );
    	}
    
        // create the export folder if it doesn't exist
        if ( ! file_exists( LEPTON_PATH.'/modules/droplets/export' ) )
        {
            mkdir(LEPTON_PATH.'/modules/droplets/export');
        }
        
        if ( ! copy( $temp_file, LEPTON_PATH.'/modules/droplets/export/'.$filename.'.zip' ) )
        {
            echo '<div class="drfail">Unable to move the exported ZIP-File!</div>';
            $download = LEPTON_URL.'/temp/'.$filename.'.zip';
        }
        else {
            unlink( $temp_file );
            $download = LEPTON_URL.'/modules/droplets/export/'.$filename.'.zip';
        }
		echo '<div class="drok">Backup created - <a href="'.$download.'">Download</a></div>';
    }
    rm_full_dir($temp_dir);

    return $MOD_DROPLETS[ 'Backup created' ] . '<br /><br />' . implode( "\n", $info ) . '<br /><br /><a href="' . $download . '">Download</a>';

} // end function export_droplets()

/**
 *  Import a droplet from a given zip archiv
 **/
function import_droplets()
{
    global $admin;

    $MOD_DROPLETS = droplets::getInstance()->language;
    
    $groups = $admin->get_groups_id();
    if ( !is_allowed( 'Import_droplets', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }

    $problem = NULL;

    if ( count( $_FILES ) )
    {
        list( $result, $data ) = droplets_upload( 'file' );
        $info = NULL;
        if ( is_array( $data ) )
        {
            $isIndexed = array_values( $data ) === $data;
            if ( $isIndexed )
            {
                $info .= implode( '<br />', $data );
            }
            else
            {
                foreach ( $data as $key => $value )
                {
                    $info .= $key . ' -> ' . $value . "<br />";
                }
            }
        }
        if ( $result == 'error' )
        {
            $problem = $MOD_DROPLETS[ 'An error occurred when trying to import the Droplet(s)' ] . '<br /><br />' . $info;
        }
        else
        {
            if(!is_array($data))
            {
                $data = [ $data ];
            }
			List_droplets( str_replace("{{count}}", count($data), $MOD_DROPLETS[ 'Successfully imported Droplet(s)'] ));
            return;
        }
    }

    echo lib_twig_box::getInstance()->render(
    	'@droplets/import.lte',
    	array(
        	 'problem' => $problem,        	 
 			// Aldus 2021-10-28 - fix
			'IMGURL'    => LEPTON_URL . '/modules/droplets/css/images',
    		'DOCURL'    => LEPTON_URL . '/modules/droplets/docs/readme.php?url='.LEPTON_URL.'/modules/droplets/docs',
    		'action'    => ADMIN_URL . '/admintools/tool.php?tool=droplets',
    		'MOD_DROPLETS'   => droplets::getInstance()->language // ! attention
    	)
    );

} // end function import_droplets()

/**
 *  @return bool    True if success, otherwise false;
 **/
function delete_droplets()
{
    global $admin, $database; //$parser, $MOD_DROPLETS;

    $groups = $admin->get_groups_id();
    if ( !is_allowed( 'Delete_droplets', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }

    $errors = array();

    // get all marked droplets
    $marked = isset( $_POST[ 'markeddroplet' ] ) ? $_POST[ 'markeddroplet' ] : array();

    if ( isset( $marked ) && !is_array( $marked ) )
    {
        $marked = array(
             $marked
        );
    }

    if ( !count( $marked ) )
    {
        list_droplets( $MOD_DROPLETS[ 'Please mark some droplets to delete' ] );
        return false; // should never be reached
    }

    foreach ( $marked as $id )
    {
        // get the name; needed to delete data file  ?? is not needed in further code????
        $database->simple_query( "DELETE FROM ".TABLE_PREFIX."mod_droplets WHERE id = ".$id );
        if ( $database->is_error() )
        {
            $errors[] = sprintf($MOD_DROPLETS[ 'Unable to delete droplet: {{id}}'], array(
                 'id' => $id
            ) );
        }
    }

    list_droplets( implode( "<br />", $errors ) );
    return true;

} // end function delete_droplets()

/**
 * copy a droplet
 **/
function copy_droplet( $id )
{
    global $admin;
    
    $database = LEPTON_database::getInstance();
    $MOD_DROPLETS = droplets::getInstance()->language;

    $groups = $admin->get_groups_id();
    if ( !is_allowed( 'Modify_droplets', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }

    $data = array();
    $database->execute_query(
        "SELECT * FROM `" . TABLE_PREFIX . "mod_droplets` WHERE `id` = ".$id,
        true,
        $data,
        false
    );
    
    $new_name = $data[ 'name' ] . "_copy";
    $i        = 1;

    // look for doubles
    // do ... while ()
    do {
        $found = [];
        $database->execute_query(
            "SELECT * FROM `" . TABLE_PREFIX . "mod_droplets` WHERE `name`='".$new_name."'",
            true,
            $found,
            false
        );
        
        if(0 === count($found))
        {
            break;
        } else {
            $new_name = $data[ 'name' ] . "_copy" . $i++;
        }
         
    } while ( count($found) > 0 );

 	unset($data['id']);
 	$data['name'] = $new_name;
 	$data['modified_by'] = $admin->get_user_id();
 	$data['modified_when']	= time();
 	
 	$database->build_and_execute(
 		"insert",
 		 TABLE_PREFIX . "mod_droplets",
 		 $data
 	);

    if ( !$database->is_error() )
    {
        $new_id = $database->get_db_handle()->lastInsertId();
        return edit_droplet( $new_id );
    }
    else
    {
        echo "ERROR: ", $database->get_error();
    }
}

/**
 * edit a droplet
 **/
function edit_droplet( $id )
{
    global $admin;

    $groups = $admin->get_groups_id();

    $database = LEPTON_database::getInstance();
    $MOD_DROPLETS = droplets::getInstance()->language;
    
    if ( $id == 'new' && !is_allowed( 'Add_droplets', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ]." [1]");
    }
    else
    {
        if ( !is_allowed( 'Modify_droplets', $groups ) )
        {
            $admin->print_error( $MOD_DROPLETS[ "You dont have the permission to do this" ]." [2]" );
        }
    }

    $problem  = NULL;
    $info     = NULL;
    $problems = array();

    if ( isset( $_POST[ 'cancel' ] ) )
    {
        list_droplets();
        return true;
    }

	$data = array();
    if ( $id != 'new' )
    {
		$database->execute_query(
            "SELECT * FROM ".TABLE_PREFIX."mod_droplets WHERE id = ".$id,
            true,
            $data,
            false
        );
    }
    else
    {
        $data = array(
            'name' => '',
            'active' => 1,
            'description' => '',
            'code' => '',
            'comments' => ''
        );
    }

    if ( isset( $_POST[ 'save' ] ) || isset( $_POST[ 'save_and_back' ] ) )
    {
        // check the code before saving
        if ( !check_syntax( $admin->get_post( 'code' ) ) )
        {
            $problem      = $MOD_DROPLETS['Please check the syntax!'];
            $data         = $_POST;
        }
        else
        {
            // syntax okay, check fields and save
            if ( $admin->get_post( 'name' ) == '' )
            {
                $problems[] = $MOD_DROPLETS['Please enter a name!'];
            }
            if ( $admin->get_post( 'code' ) == '' )
            {
                $problems[] = $MOD_DROPLETS['You have entered no code!'];
            }

            if ( !count( $problems ) )
            {
                $continue      = true;
                $title         = addslashes( $admin->get_post( 'name' ) );
                $active        = $admin->get_post( 'active' );
                $show_wysiwyg  = $admin->get_post( 'show_wysiwyg' );
                $description   = addslashes( $admin->get_post( 'description' ) );
                $tags          = array(
                    '<?php',
                    '?>',
                    '<?'
                );
                $content       = str_replace( $tags, '', $admin->get_post( 'code' ) );
                $comments      = addslashes( $admin->get_post( 'comments' ) );
                $modified_when = time();
                $modified_by   = $admin->get_user_id();
                if ( $id == 'new' )
                {
                    // check for doubles
					$double = array();
					$database->execute_query(
						"SELECT * FROM `".TABLE_PREFIX."mod_droplets` WHERE `name` = '".$title."'",
						true,
						$double,
						false
					);

                    if ( count($double) > 0 )
                    {
                        $problem  = $MOD_DROPLETS['There is already a droplet with the same name!'];
                        $continue = false;
                        $data     = $_POST;
                        $data['code'] = stripslashes( $_POST[ 'code' ] );
                    }
                    else
                    {
						// Generate query for a new insert
						$fields = array(
							'name'	=> $title,
							'code'	=> $content,
							'description'	=> stripslashes( $description ),  // we are using pdo here!
							'modified_when'	=> $modified_when,
							'modified_by'	=> $modified_by,
							'active'		=> $active,
							'admin_edit'	=> 1,
							'admin_view'	=> 1,
							'show_wysiwyg'	=> (!isset($show_wysiwyg) ? 0 : $show_wysiwyg),
							'comments'		=> stripslashes( $comments )  // we are using pdo here!
						);
						
						$database->build_and_execute(
							'insert',
							TABLE_PREFIX . "mod_droplets",
							$fields
						);
						
					    if ( $database->is_error() )
					    {
					        echo "ERROR: ", $database->get_error();
					    }
                        
                    }
                }
                else
                {
                    // Update row
                    $fields = array(
                    	'name'	=> $title,
                    	'active'	=> $active,
                    	'show_wysiwyg'	=> (!isset($show_wysiwyg) ? 0 : $show_wysiwyg),
                    	'description'	=> $description,
                    	'modified_when'	=> $modified_when,
						'modified_by'	=> $modified_by,
                    	'code'	=> $content,
                    	'comments'	=> stripslashes( $comments )  // we are using pdo here!
                    );
                    $database->build_and_execute(
                    	"update",
                    	TABLE_PREFIX . "mod_droplets",
                    	$fields,
                    	"`id`= ".$id 
                    );
                    	
                    // reload Droplet data
					$data = array();
					$database->execute_query(
						"SELECT * FROM ".TABLE_PREFIX."mod_droplets WHERE id = ".$id,
						true,
						$data,
						false
					);
                }
                if ( $continue )
                {
                    // Check if there is a db error
                    if ( $database->is_error() )
                    {
                        $problem = $database->get_error();
                    }
                    else
                    {
                        if ( $id == 'new' || isset( $_POST[ 'save_and_back' ] ) )
                        {
                            list_droplets( $MOD_DROPLETS['The Droplet was saved'] );
                            return true; // should never be reached
                        }
                        else
                        {
                            $info = $MOD_DROPLETS['The Droplet was saved'];
                        }
                    }
                }
            }
            else
            {
                $problem = implode( "<br />", $problems );
            }
        }
    }

    echo lib_twig_box::getInstance()->render
	(
    	'@droplets/edit.lte',
    	array
		(
            'problem' => $problem,
            'info' => $info,
            'data' => $data,
            'id'   => $id,
            'name' => $data[ 'name' ],
    		'register_area' => edit_area::registerEditArea('code'),  		
			// Aldus 2021-10-28 - fix
			'IMGURL'    => LEPTON_URL . '/modules/droplets/css/images',
    		'DOCURL'    => LEPTON_URL . '/modules/droplets/docs/readme.php?url='.LEPTON_URL.'/modules/droplets/docs',
    		'action'    => ADMIN_URL . '/admintools/tool.php?tool=droplets',
    		'MOD_DROPLETS'   => droplets::getInstance()->language // ! attention
		) 
	);
} // end function edit_droplet()

/**
 *      Edit the permissions for a given droplet by id
 **/
function edit_droplet_perms( $id )
{
    global $admin;
    
    $database = LEPTON_database::getInstance();
    $MOD_DROPLETS = droplets::getInstance()->language;
    
    // look if user can set permissions
    $this_user_groups = $admin->get_groups_id();
    
    if ( !is_allowed( 'Manage_perms', $this_user_groups ) )
    {
        $admin->print_error( $MOD_DROPLETS["You don't have the permission to do this"] );
    }

    $info = NULL;

    // get available groups
    $aAllGroups = array();
    $database->execute_query(
        "SELECT `group_id`, `name` FROM `" . TABLE_PREFIX . "groups` ORDER BY `name`",
        true,
        $aAllGroups,
        true
    );
    
    foreach( $aAllGroups as $row )
    {
        $groups[ $row[ 'group_id' ] ] = $row[ 'name' ];
    }
    
    // save perms
    if ( isset( $_REQUEST[ 'save' ] ) || isset( $_REQUEST[ 'save_and_back' ] ) )
    {
        $edit = (
			isset($_REQUEST['edit_perm'])
				? ( is_array($_REQUEST['edit_perm']) ? implode('|',$_REQUEST['edit_perm']) : $_REQUEST['edit_perm'] )
				: "1"   // admin!
				);
        $view = (
				isset($_REQUEST['view_perm'])
				? ( is_array($_REQUEST['view_perm']) ? implode('|',$_REQUEST['view_perm']) : $_REQUEST['view_perm'] )
				: "1"   // admin!
				);
		
        $test = $database->get_one("SELECT `id` FROM `".TABLE_PREFIX."mod_droplets_permissions` WHERE `id`=".$id);

        $job = ($test === NULL)
            ? 'insert'
            : 'update'
            ;
        
        $fields = array(
            'edit_perm' => $edit,
            'view_perm' => $view,
            'id'        => $id      // to avoid errors within MYSQL-STRICT as 'id' doesn't have a default value
        );
        
        $success = $database->build_and_execute(
            $job,
            TABLE_PREFIX."mod_droplets_permissions",
            $fields,
            "`id`=".$id
        );
        if(false === $success)
        {
            echo LEPTON_tools::display( $database->get_error(), 'pre', 'ui message red' );
        }
        
        $info = $MOD_DROPLETS['The Droplet was saved'];
        if ( isset( $_REQUEST[ 'save_and_back' ] ) )
        {
            list_droplets( $info );
            return true;
        }
    }

    // get droplet data
    $data  = array();
    $database->execute_query(
        "SELECT * FROM " . TABLE_PREFIX . "mod_droplets AS t1 LEFT OUTER JOIN ".TABLE_PREFIX."mod_droplets_permissions AS t2 ON t1.id=t2.id WHERE t1.id = '$id'",
        true,
        $data,
        false
    );

    foreach ( array(
        'edit_perm',
        'view_perm'
    ) as $key )
    {
        $allowed_groups = ( isset( $data[ $key ] ) ? explode( '|', $data[ $key ] ) : array ());
        $line           = array();
        foreach ( $groups as $gid => $name )
        {
            $line[] = '<input type="checkbox" name="' . $key . '[]" id="' . $key . '_' . $gid . '" value="' . $gid . '"' . ( ( is_in_array( $allowed_groups, $gid ) || !count( $allowed_groups ) ) ? ' checked="checked"' : NULL ) . '>' . '<label for="' . $key . '_' . $gid . '">' . $name . '</label>' . "\n";
        }
        $rows[] = array(
            'groups' => implode( '', $line ),
            'name' => $MOD_DROPLETS[ $key ]
        );
    }

    echo lib_twig_box::getInstance()->render(
    	'@droplets/droplet_permissions.lte',
    	array(
    	    'rows' => $rows,
    	    'info' => $info,
    	    'id'   => $id,
    	    'num_rows' => count($rows), 	    
   			// Aldus 2021-10-28 - fix
			'IMGURL'    => LEPTON_URL . '/modules/droplets/css/images',
    		'DOCURL'    => LEPTON_URL . '/modules/droplets/docs/readme.php?url='.LEPTON_URL.'/modules/droplets/docs',
    		'action'    => ADMIN_URL . '/admintools/tool.php?tool=droplets',
    		'MOD_DROPLETS'   => droplets::getInstance()->language // ! attention
    	)
    );
}

/**
 *	Aldus: switch between active/inactive
 **/
function toggle_active( $id )
{
    global $admin, $MOD_DROPLETS;

    $database = LEPTON_database::getInstance();
    
    $groups = $admin->get_groups_id();
    if ( !is_allowed( 'Modify_droplets', $groups ) )
    {
        $admin->print_error( $MOD_DROPLETS[ "You don't have the permission to do this" ] );
    }
    
    $state = $database->get_one( "SELECT `active` FROM " . TABLE_PREFIX . "mod_droplets WHERE id = '$id'" );

    $new = ( $state == 1 ) ? 0 : 1;

    $database->simple_query( "UPDATE `" . TABLE_PREFIX . "mod_droplets` SET `active`='".$new."' WHERE `id` = ".$id);

}

/**
 * checks if any item of $allowed is in $current
 * Aldus:: m.f.i obsolete!
 **/
function is_in_array( $allowed, $current )
{
    if ( !is_array( $allowed ) )
    {
        if ( substr_count( $allowed, '|' ) )
        {
            $allowed = explode( '|', $allowed );
        }
        else
        {
            $allowed = array(
                 $allowed
            );
        }
    }
    if ( !is_array( $current ) )
    {
        if ( substr_count( $current, '|' ) )
        {
            $current = explode( '|', $current );
        }
        else
        {
            $current = array(
                 $current
            );
        }
    }
    foreach ( $allowed as $gid )
    {
        if ( in_array( $gid, $current ) )
        {
            return true;
        }
    }
    return false;
} // end function is_in_array()

/**
 *  Test permission agains the settings.
 *
 *  @param string   sAtrributeName   A valid name of the an existing "attribute" inside the droplet_settings table.
 *  @param integer  iGroupsID        A Valid group id OR an array with ids!
 *
 *  @return bool
 */
function is_allowed( $sAtrributeName, $iGroupsID )
{
    $settings = droplets::getInstance()->settings;
    
    if ( !array_key_exists( $sAtrributeName, $settings ) )
    {
        // The requestest attributename does not exist inside the table - so we return false
        return false;
    }
    else
    {
        // Is iGroupsID a single value or an array? 
        // Make sure that we have an array here!
        if(!is_array( $iGroupsID))
        {
            $iGroupsID = array( $iGroupsID );
        }
        
        $value = $settings[ $sAtrributeName ];
        
        // Make sure that the value of the entry is an array.
        if ( !is_array( $value ) )
        {
            $value = array( $value );
        }
        
        // Test all groups_ids agains the settings ids.
        foreach( $iGroupsID as $iTempID )
        {
            if( true === in_array( $iTempID, $value ) )
            {
                return true;
            }
        }
        // None match!
        return false;
    }
}

/**
 * check the syntax of given code
 **/
function check_syntax( $code )
{
   return eval( 'return true;' . $code );
}
