0) $this->chunk_size = max(UPDRAFTPLUS_UPLOAD_CHUNKSIZE, 5000000); } /** * Upload a single file * * @param String $file - the basename of the file to upload * @param String $local_path - the full path of the file * * @return Boolean - success status. Failures can also be thrown as exceptions. */ public function do_upload($file, $local_path) { global $updraftplus; $opts = $this->options; $storage = $this->get_storage(); if (is_wp_error($storage)) throw new Exception($storage->get_error_message()); if (!is_object($storage)) throw new Exception("Backblaze service error (got a ".gettype($storage).")"); $backup_path = empty($opts['backup_path']) ? '' : trailingslashit($opts['backup_path']); $remote_path = $backup_path.$file; $file_hash = md5($file); $this->_uploaded_size = $this->jobdata_get('total_bytes_sent_'.$file_hash, 0); if (!file_exists($local_path) || !is_readable($local_path)) throw new Exception("Could not read file: $local_path"); $bucket_name = $opts['bucket_name']; // Create bucket if bucket doesn't exists if (!isset($this->is_upload_bucket_exist) && $this->is_valid_bucket_name($bucket_name)) { $buckets = $this->get_bucket_names_array(); if (!in_array($bucket_name, $buckets)) { $new_bucket_created = $storage->createPrivateBucket($bucket_name); if ($new_bucket_created) { $this->is_upload_bucket_exist = true; $this->log("bucket was not found, but a new private bucket has now been created: ".$bucket_name); } else { $this->log("bucket was not found, and creation of a new private bucket failed: ".$bucket_name); } } else { $this->is_upload_bucket_exist = true; } } if (1 === ($ret = $updraftplus->chunked_upload($this, $file, "backblaze://".trailingslashit($bucket_name).$backup_path.$file, 'Backblaze', $this->chunk_size, $this->_uploaded_size))) { $result = $storage->upload(array( 'BucketName' => $opts['bucket_name'], 'FileName' => $remote_path, 'Body' => file_get_contents($local_path), )); if (is_object($result) && is_callable(array($result, 'getSize')) && $result->getSize() > 1) { $ret = true; } else { $ret = false; $this->log("all-in-one upload fail: ".serialize($result)); } } return $ret; } /** * N.B. If we ever use varying-size chunks, we must be careful as to what we do with $chunk_index * * @param String $file - Basename for the file being uploaded * @param Resource|String $fp - Data to send, or a file handle to read upload data from * @param Integer $chunk_index - Index of chunked upload * @param Integer $upload_size - Size of the upload, in bytes (this and the next are only used if a resource was given for $fp) * @param Integer $upload_start - How many bytes into the file the upload process has got * @param Integer $upload_end - How many bytes into the file we will be after this chunk is uploaded (not currently used) * @param Integer $total_file_size - Total file size (not currently used) * * @return Boolean|WP_Error */ public function chunked_upload($file, $fp, $chunk_index, $upload_size = 0, $upload_start = 0, $upload_end = 0, $total_file_size = 0) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Filter use // Already done? This is not checked if we are sent data directly, as that implies forcing. if (is_resource($fp) && $upload_start < $this->_uploaded_size) return 1; $storage = $this->get_storage(); if (is_wp_error($storage)) return $storage; if (!is_object($storage)) return new WP_Error('no_backblaze_service', "Backblaze service error (got a ".gettype($storage).")"); $file_hash = md5($file); $upload_state = $this->jobdata_get('upload_state_'.$file_hash, array()); // An upload URL is valid for 24 hours. But, we'll only use them for 1 hour, in case something else happens to invalidate it (we don't want to wait a whole day before getting a new one). if (!empty($upload_state['saved_at']) && $upload_state['saved_at'] < time() - 3600) $upload_state = array(); $large_file_id = empty($upload_state['large_file_id']) ? false : $upload_state['large_file_id']; $upload_url = empty($upload_state['upload_url']) ? false : $upload_state['upload_url']; $auth_token = empty($upload_state['auth_token']) ? false : $upload_state['auth_token']; $need_new_state = ($large_file_id && $upload_url && $auth_token) ? false : true; $opts = $this->options; $backup_path = empty($opts['backup_path']) ? '' : trailingslashit($opts['backup_path']); $remote_path = $backup_path.$file; if (!$large_file_id) { $this->log("initiating multi-part upload"); try { $response = $storage->uploadLargeStart(array( 'FileName' => $remote_path, 'BucketName' => $opts['bucket_name'], )); if (empty($response['fileId'])) { $this->log('Unexpected response to uploadLargeStart: '.serialize($response)); return false; } } catch (Exception $e) { $this->log('Unexpected chunk uploading exception ('.get_class($e).'): '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')'); return false; } $large_file_id = $response['fileId']; } $this->_large_file_id = $large_file_id; if (!$upload_url || !$auth_token) { try { $this->log("requesting multi-part file upload url (id $large_file_id)"); $response = $storage->uploadLargeUrl(array( 'FileId' => $large_file_id, )); if (empty($response['authorizationToken']) || empty($response['uploadUrl'])) { $this->log('Unexpected response to uploadLargeUrl: '.serialize($response)); return false; } } catch (Exception $e) { $this->log('Unexpected error when getting upload URL ('.get_class($e).'): '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')'); return false; } $auth_token = $response['authorizationToken']; $upload_url = $response['uploadUrl']; } if ($need_new_state) { $this->jobdata_set('upload_state_'.$file_hash, array( 'large_file_id' => $large_file_id, 'upload_url' => $upload_url, 'auth_token' => $auth_token, // N.B. An upload URL is valid for 24 hours 'saved_at' => time() )); } if (is_resource($fp)) { if (false === ($data = fread($fp, $upload_size))) { $this->log(__('Error: unexpected file read fail', 'updraftplus'), 'error'); $this->log("File read fail (fread() returned false)"); return false; } } elseif (is_string($fp)) { $data = $fp; } else { return new WP_Error('backblaze_chunk_data_error', __('Error:', 'updraftplus')." backblaze::chunked_upload() received invalid input"); } $sha1_of_parts = $this->jobdata_get('sha1_of_parts_'.$file_hash, array()); $sha1_of_parts[$chunk_index - 1] = sha1($data); try { $response = $storage->uploadLargePart(array( 'AuthorizationToken' => $auth_token, 'FilePartNo' => $chunk_index, 'UploadUrl' => $upload_url, 'Body' => $data, )); if (!is_array($response) || !isset($response['partNumber'])) { $this->log("Unexpected response to uploadLargePart: ".serialize($response)); return false; } } catch (Exception $e) { if ($e->getCode() >= 500 && $e->getCode() <= 599) { $this->jobdata_set('upload_state_'.$file_hash, array( 'large_file_id' => $large_file_id, 'upload_url' => '', 'auth_token' => '', )); } return new WP_Error('backblaze_chunk_upload_error', __('Error:', 'updraftplus')." {$e->getCode()}, Message: {$e->getMessage()}"); } $this->_sha1_of_parts = $sha1_of_parts; $this->jobdata_set('sha1_of_parts_'.$file_hash, $sha1_of_parts); $this->jobdata_set('total_bytes_sent_'.$file_hash, $upload_end + 1); return true; } /** * Called when all chunks have been uploaded, to allow any required finishing actions to be carried out * * @param String $file - the basename of the file being uploaded * * @return Integer|Boolean - success or failure state of any finishing actions */ public function chunked_upload_finish($file) { $file_hash = md5($file); $storage = $this->get_storage(); // This happens if chunked_upload_finish is called without chunked_upload having been called if (empty($this->_large_file_id)) { $upload_state = $this->jobdata_get('upload_state_'.$file_hash, array()); // An upload URL is valid for 24 hours. But, we'll only use them for 1 hour, in case something else happens to invalidate it (we don't want to wait a whole day before getting a new one). if (!empty($upload_state['saved_at']) && $upload_state['saved_at'] < time() - 3600) $upload_state = array(); $this->_large_file_id = empty($upload_state['large_file_id']) ? false : $upload_state['large_file_id']; $this->_sha1_of_parts = $this->jobdata_get('sha1_of_parts_'.$file_hash, array()); } try { $response = $storage->uploadLargeFinish(array( 'FileId' => $this->_large_file_id, 'FilePartSha1Array' => $this->_sha1_of_parts, )); } catch (Exception $e) { global $updraftplus; if (preg_match('/No active upload for: .*/', $e->getMessage())) { $this->log("upload: b2_finish_large_file has already been called ('".$e->getMessage()."')"); return 1; } elseif (preg_match('/Part number (\d+) has not been uploaded/i', $e->getMessage(), $matches)) { $missing_chunk_index = $matches[1]; $this->log("Exception in uploadLargeFinish(); will retry part $missing_chunk_index: {$e->getCode()}, Message: {$e->getMessage()} (line: {$e->getLine()}, file: {$e->getFile()})"); $updraft_dir = $updraftplus->backups_dir_location(); // If more than this are needed, they will happen on the next resumption static $retries = 12; if (false === ($data = file_get_contents($updraft_dir.'/'.$file, false, null, ($missing_chunk_index - 1 ) * $this->chunk_size, $this->chunk_size))) { $retry_part = new WP_Error('file_read_failed', "Could not read: $file"); } elseif ($retries > 0) { $retries--; $retry_part = $this->chunked_upload($file, $data, $missing_chunk_index); // Missing part was uploaded; try the whole again if (true === $retry_part) { return $this->chunked_upload_finish($file); } // N.B. chunked_upload() does its own logging when returning false } if (is_wp_error($retry_part)) { $this->log("Failed ".$retry_part->get_error_code().": ".$retry_part->get_error_message()); } } else { $this->log("Exception in uploadLargeFinish(): {$e->getCode()}, Message: {$e->getMessage()} (line: {$e->getLine()}, file: {$e->getFile()})"); } return false; } global $updraftplus; $this->log('upload: success (b2_finish_large_file called successfully; chunks='.count($this->_sha1_of_parts).', file ID returned='.$response->getId().', size='.$response->getSize().')'); // Clean-up $this->jobdata_delete('upload_state_'.$file_hash); $this->jobdata_delete('sha1_of_parts_'.$file_hash); // (int)1 means 'we already logged', as opposed to (boolean)true which does not return 1; } /** * Perform a download of the requested file * * @param String $file - the file (basename) to download * @param String $fullpath - the full path to download it too * @param Integer $start_offset - byte marker to begin at (starting from 0) * * @return Boolean|Integer - success/failure, or a byte counter of how much has been downloaded. Exceptions can also be thrown for errors. */ public function do_download($file, $fullpath) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Filter use global $updraftplus; $remote_files = $this->do_listfiles($file); if (is_wp_error($remote_files)) { throw new Exception('Download error ('.$remote_files->get_error_code().'): '.$remote_files->get_error_message()); } foreach ($remote_files as $file_info) { if ($file_info['name'] == $file) { return $updraftplus->chunked_download($file, $this, $file_info['size'], true, null, 2*1048576); } } $this->log("$file: file not found in listing of remote directory"); return false; } /** * Callback used by by chunked downloading API * * @param String $file - the file (basename) to be downloaded * @param Array $headers - supplied headers * @return String - the data downloaded */ public function chunked_download($file, $headers) { // $curl_options = array(); // if (is_array($headers) && !empty($headers['Range']) && preg_match('/bytes=(.*)$/', $headers['Range'], $matches)) { // $curl_options[CURLOPT_RANGE] = $matches[1]; $opts = $this->options; $storage = $this->get_storage(); $backup_path = empty($opts['backup_path']) ? '' : trailingslashit($opts['backup_path']); $options = array( 'BucketName' => $opts['bucket_name'], 'FileName' => $backup_path.$file, ); if (!empty($headers)) $options['headers'] = $headers; $remote_file = $storage->download($options); return is_string($remote_file) ? $remote_file : false; } /** * Acts as a WordPress options filter * * @param Array $settings - pre-filtered settings * * @return Array filtered settings */ public function options_filter($settings) { if (is_array($settings) && !empty($settings['version']) && !empty($settings['settings'])) { foreach ($settings['settings'] as $instance_id => $instance_settings) { if (!empty($instance_settings['backup_path'])) { $settings['settings'][$instance_id]['backup_path'] = trim($instance_settings['backup_path'], "/ \t\n\r\0\x0B"); } } } return $settings; } /** * Delete an indicated file from remote storage * * @param Array $files - the files (basename) to delete * * @return Boolean|Array - success/failure status of the delete operation. Throwing exception is also permitted. */ public function do_delete($files) { $opts = $this->options; $storage = $this->get_storage(); $backup_path = empty($opts['backup_path']) ? '' : trailingslashit($opts['backup_path']); try { if (count($files) > 1) { $multipleFiles = array(); foreach ($files as $file) { $multipleFiles[] = array( 'FileName' => $backup_path.$file, 'BucketName' => $opts['bucket_name'] ); } $result = $storage->deleteMultipleFiles($multipleFiles, $opts['bucket_name'], $backup_path); } else { $fileName = $files[0]; $result = $storage->deleteFile(array( 'FileName' => $backup_path.$fileName, 'BucketName' => $opts['bucket_name'], )); } } catch (UpdraftPlus_Backblaze_NotFoundException $e) { // This exception should only be possible on the single file delete path $this->log("$fileName: file not found (so likely already deleted)"); return true; } return $result; } /** * This method is used to get a list of backup files for the remote storage option * * @param String $match - a string to match when looking for files * * @return Array|WP_Error - returns an array of files (arrays with keys 'name' (basename) and (optional) 'size' (');">

ASSOCIATION APTE

ASSOCIATION APTE

APTE est une association qui facilite l’accès à la culture des personnes avec autisme par la pratique instrumentale (piano).

La dotation de la Fondation Initiative Autisme a permis :

  • La prise en charge d’une partie des coûts des cours de piano dispensés aux jeunes élèves de l’association
  • La réalisation de formations DOLCE (méthode adaptée au public avec autisme) pour des professeurs de musique
  • La contribution à la création de représentations qui ont permis à de jeunes élèves avec autisme de se produire sur scène face à un public
  • Une participation au développement de centres APTE en régions 
 Retour