Check if the file type is .zip. * --> Extract it to a temp folder. * --> Check for the .info file. If not exists throw error * --> Extract the information from the .info file. * --> Check for the plugin name already exists or not. * --> if Plugin Name exists it compare the version of .info and version of plugin stored in db. * --> if same throw error and if different it checks for UpdateInfo field in .info file. * --> if UpdateInfo not found throw error. * --> if UpdateInfo found add the update to the ryzom_ams_lib.updates table. * --> if it's not an update and plugin with same name already exists throw error. * --> if plugin with same name not present provide option to install plugin * * @author Shubham Meena, mentored by Matthew Lagoe * */ /** * This function is used in installing plugins or adding updates * for previously installed plugins. * */ function install_plugin() { $result = array(); // if logged in if ( WebUsers :: isLoggedIn() ) { // path of temporary folder for storing files $temp_path = "../../ams_lib/temp"; // create a temp directory if not exist // temp folder where we first store all uploaded plugins before install if ( !file_exists( "$temp_path" ) ) { mkdir( $temp_path ); } // checking the server if file is uploaded or not if ( ( isset( $_FILES["file"] ) ) && ( $_FILES["file"]["size"] > 0 ) ) { $fileName = $_FILES["file"]["name"]; //the files name takes from the HTML form $fileTmpLoc = $_FILES["file"]["tmp_name"]; //file in the PHP tmp folder $dir = trim( $_FILES["file"]["name"], ".zip" ); $target_path = "../../ams_lib/plugins/$dir"; //path in which the zip extraction is to be done $destination = "../../ams_lib/plugins/"; // scanning plugin folder if plugin with same name is already exists or not $x = checkForUpdate( $dir, $destination, $fileTmpLoc, $temp_path ); if ( $x == '1' ) { echo "update found"; throw new SystemExit(); } else if ( $x == '2' ) { echo "Plugin already exists with same name ."; throw new SystemExit(); } else if ( $x == '3' ) { echo "Update info is not present in the update"; throw new SystemExit(); } // checking for the command to install plugin is given or not if ( !isset( $_POST['install_plugin'] ) ) { if ( ( $_FILES["file"]["type"] == 'application/zip' ) ) { if ( move_uploaded_file( $fileTmpLoc, $temp_path . "/" . $fileName ) ) { echo "$fileName upload is complete.
" . "
"; throw new SystemExit(); } else { echo "Error in uploading file."; throw new SystemExit(); } } else { echo "Please select a file with .zip extension to upload."; throw new SystemExit(); } } else { // calling function to unzip archives if ( zipExtraction( $temp_path . "/" . $fileName , $destination ) ) { if ( file_exists( $target_path . "/.info" ) ) { $result = readPluginFile( ".info", $target_path ); // sending all info to the database $install_result = array(); $install_result['FileName'] = $target_path; $install_result['Name'] = $result['PluginName']; $install_result['Type'] = $result['Type']; if ( Ticket_User :: isMod( unserialize( $_SESSION['ticket_user'] ) ) ) { $install_result['Permission'] = 'admin'; } else { $install_result['Permission'] = 'user'; } $install_result['Info'] = json_encode( $result ); // connection with the database $dbr = new DBLayer( "lib" ); $dbr -> insert( "plugins", $install_result ); // if everything is successfull redirecting to the plugin template header("Cache-Control: max-age=1"); header( "Location: index.php?page=plugins&result=1" ); throw new SystemExit(); } else { // file .info not exists rmdir( $target_path ); header("Cache-Control: max-age=1"); header( "Location: index.php?page=install_plugin&result=2" ); throw new SystemExit(); } } else { // extraction failed header("Cache-Control: max-age=1"); header( "Location: index.php?page=install_plugin&result=0" ); throw new SystemExit(); } } } else { echo "Please Browse for a file before clicking the upload button"; throw new SystemExit(); } } } /** * function to unzip the zipped files * * @param $target_path path to the target zipped file * @param $destination path to the destination * @return boolean */ function zipExtraction( $target_path, $destination ) { $zip = new ZipArchive(); $x = $zip -> open( $target_path ); if ( $x === true ) { if ( $zip -> extractTo( $destination ) ) { $zip -> close(); return true; } else { $zip -> close(); return false; } } } /** * function to read text files and extract * the information into an array * * ----------------------------------------------------------- * format: * ----------------------------------------------------------- * PluginName = Name of the plugin * Version = version of the plugin * Type = type of the plugin * TemplatePath = path to the template * Description = Description of the plugin ,it's functionality * ----------------------------------------------------------- * * reads only files with name .info * * @param $fileName file to read * @param $target_path path to the folder containing .info file * @return array containing above information in array(value => key) */ function readPluginFile( $fileName, $target_path ) { $file_handle = fopen( $target_path . "/" . $fileName, "r" ); $result = array(); while ( !feof( $file_handle ) ) { $line_of_text = fgets( $file_handle ); $parts = array_map( 'trim', explode( '=', $line_of_text, 2 ) ); @$result[$parts[0]] = $parts[1]; } fclose( $file_handle ); return $result; } /** * function to check for updates or * if the same plugin already exists * also, if the update founds ,check for the UpdateInfo in the .info file. * Update is saved in the temp directory with pluginName_version.zip * * @param $fileName file which is uploaded in .zip extension * @param $findPath where we have to look for the installed plugins * @param $tempFile path for the temporary file * @param $tempPath path where we have to store the update * @return 2 if plugin already exists and update not found * @return 3 if update info tag not found in .info file */ function checkForUpdate( $fileName, $findPath, $tempFile, $tempPath ) { // check for plugin if exists $file = scandir( $findPath ); foreach( $file as $key => $value ) { if ( strcmp( $value, $fileName ) == 0 ) { if ( !file_exists( $tempPath . "/test" ) ) { mkdir( $tempPath . "/test" ); } // extracting the update if ( zipExtraction( $tempFile, $tempPath . "/test/" ) ) { $result = readPluginFile( ".info", $tempPath . "/test/" . $fileName ); // check for the version for the plugin $db = new DBLayer( "lib" ); $sth = $db -> select( "plugins", array( 'Name' => $result['PluginName'] ), "Name = :Name" ); $info = $sth -> fetch(); $info['Info'] = json_decode( $info['Info'] ); // the two versions from main plugin and the updated part $new_version = explode( '.', $result['Version'] ); $pre_version = explode( '.', $info['Info'] -> Version ); // For all plugins we have used semantic versioning // Format: X.Y.Z ,X->Major, Y->Minor, Z->Patch // change in the X Y & Z values refer the type of change in the plugin. // for initial development only Minor an Patch MUST be 0. // if there is bug fix then there MUST be an increment in the Z value. // if there is change in the functionality or addition of new functionality // then there MUST be an increment in the Y value. // When there is increment in the X value , Y and Z MUST be 0. // comparing if there is some change if ( !array_diff( $new_version , $pre_version ) ) { // removing the uploaded file Plugincache :: rrmdir( $tempPath . "/test/" . $fileName ); return '2'; //plugin already exists } else { // check for update info if exists if ( !array_key_exists( 'UpdateInfo', $result ) ) { return '3'; //update info tag not found } else { // check if update already exists if ( pluginUpdateExists( $info['Id'], $tempPath . "/" . trim( $fileName, ".zip" ) . "_" . $result['Version'] . ".zip" ) ) { echo "Update already exists"; throw new SystemExit(); } else { // removing the preivous update $dbr = new DBLayer( "lib" ); $dbr -> delete( "updates", array( 'id' => $info['Id'] ), "PluginId=:id" ); // storing update in the temp directory // format of update save if ( move_uploaded_file( $tempFile, $tempPath . "/" . trim( $fileName, ".zip" ) . "_" . $result['Version'] . ".zip" ) ) { // setting update information in the database $update['PluginId'] = $info['Id']; $update['UpdatePath'] = $tempPath . "/" . trim( $fileName, ".zip" ) . "_" . $result['Version'] . ".zip"; $update['UpdateInfo'] = json_encode( $result ); $dbr -> insert( "updates", $update ); header("Cache-Control: max-age=1"); header( "Location: index.php?page=plugins&result=7" ); throw new SystemExit(); } } } } } } } } /** * Function to check for the update of a plugin already exists * * @param $pluginId id of the plugin for which update is available * @param $updatePath path of the new update * @return boolean True if update already exists else False * */ function PluginUpdateExists( $pluginId, $updatePath ) { $db = new DBLayer( 'lib' ); $sth = $db -> selectWithParameter( "UpdatePath", "updates", array( 'pluginid' => $pluginId ), "PluginId=:pluginid" ); $row = $sth -> fetch(); if ( $updatePath == $row['UpdatePath'] ) { return true; } else { rmdir( $row['UpdatePath'] ); return false; } }