%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br/plugins/glpiinventory/inc/ |
Current File : //var/www/projetos/suporte.iigd.com.br/plugins/glpiinventory/inc/deployfile.class.php |
<?php /** * --------------------------------------------------------------------- * GLPI Inventory Plugin * Copyright (C) 2021 Teclib' and contributors. * * http://glpi-project.org * * based on FusionInventory for GLPI * Copyright (C) 2010-2021 by the FusionInventory Development Team. * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI Inventory Plugin. * * GLPI Inventory Plugin is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GLPI Inventory Plugin is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with GLPI Inventory Plugin. If not, see <https://www.gnu.org/licenses/>. * --------------------------------------------------------------------- */ if (!defined('GLPI_ROOT')) { die("Sorry. You can't access directly to this file"); } /** * Manage the files to deploy. */ class PluginGlpiinventoryDeployFile extends PluginGlpiinventoryDeployPackageItem { public $shortname = 'files'; public $json_name = 'associatedFiles'; /** * The right name for this class * * @var string */ public static $rightname = 'plugin_glpiinventory_package'; const REGISTRY_NO_DB_ENTRY = 0x1; const REGISTRY_NO_MANIFEST = 0x2; /** * Get the 2 types to add files * * @return array */ public function getTypes() { $types = [ 'Computer' => __("Upload from computer", 'glpiinventory') ]; if (GLPI_INSTALL_MODE !== 'CLOUD') { $types['Server'] = __("Upload from server", 'glpiinventory'); } return $types; } /** * Display list of files * * @global array $CFG_GLPI * @param PluginGlpiinventoryDeployPackage $package PluginGlpiinventoryDeployPackage instance * @param array $data array converted of 'json' field in DB where stored actions * @param string $rand unique element id used to identify/update an element */ public function displayList(PluginGlpiinventoryDeployPackage $package, $data, $rand) { global $CFG_GLPI; $package_id = $package->getID(); $canedit = $package->canUpdateContent(); // compute short shas to find the corresponding entries in database $short_shas = []; foreach ($data['jobs']['associatedFiles'] as $sha512) { $short_shas[] = substr($sha512, 0, 6); } // find corresponding file entries $files = $this->find(['shortsha512' => $short_shas]); // do a quick mapping between database id and short shas $files_mapping = []; foreach ($files as $file) { $files_mapping[$file['shortsha512']] = $file['id']; } echo "<table class='tab_cadrehov package_item_list' id='table_files_$rand'>"; $i = 0; foreach ($data['jobs']['associatedFiles'] as $sha512) { $short_sha = substr($sha512, 0, 6); $file_id = 0; $fileregistry_error = 0; // check if the files is registered in database if (!array_key_exists($short_sha, $files_mapping)) { $fileregistry_error |= self::REGISTRY_NO_DB_ENTRY; } if (!$this->checkPresenceManifest($sha512)) { $fileregistry_error |= self::REGISTRY_NO_MANIFEST; } // get database entries if (!$fileregistry_error) { $file_id = $files_mapping[$short_sha]; $file_name = $files[$file_id]['name']; $file_size = $files[$file_id]['filesize']; //mimetype icon if (isset($files[$file_id]['mimetype'])) { $file_mimetype = str_replace('/', '__', $files[$file_id]['mimetype']); } else { $file_mimetype = null; } } else { // get file's name from what has been saved in json $file_name = $data['associatedFiles'][$sha512]['name']; $file_size = null; $file_mimetype = null; } $file_uncompress = $data['associatedFiles'][$sha512]['uncompress']; $file_p2p = $data['associatedFiles'][$sha512]['p2p']; $file_p2p_retention_duration = $data['associatedFiles'][$sha512]['p2p-retention-duration']; // start new line $pics_path = Plugin::getWebDir('glpiinventory') . "/pics/"; echo Search::showNewLine(Search::HTML_OUTPUT, ($i % 2)); if ($canedit) { echo "<td class='control'>"; Html::showCheckbox(['name' => 'file_entries[' . $i . ']', 'value' => 0]); echo "</td>"; } echo "<td class='filename'>"; if ( !empty($file_mimetype) && file_exists($pics_path . "extensions/$file_mimetype.png") ) { echo "<img src='" . $pics_path . "extensions/$file_mimetype.png' />"; } else { echo "<img src='" . $pics_path . "extensions/documents.png' />"; } //filename echo " "; if ($canedit) { echo "<a class='edit' onclick=\"edit_subtype('file', $package_id, $rand ,this)\">"; } echo $file_name; if ($canedit) { echo "</a>"; } //p2p icon if ( isset($file_p2p) && $file_p2p != 0 ) { echo "<a title='" . __('p2p', 'glpiinventory') . ", " . __("retention", 'glpiinventory') . " : " . $file_p2p_retention_duration . " " . __("Minute(s)", 'glpiinventory') . "' class='more'>"; echo "<img src='" . $pics_path . "p2p.png' />"; echo "<sup>" . $file_p2p_retention_duration . "</sup>"; echo "</a>"; } //uncompress icon if ( isset($file_uncompress) && $file_uncompress != 0 ) { echo "<a title='" . __('uncompress', 'glpiinventory') . "' class='more'><img src='" . $pics_path . "uncompress.png' /></a>"; } //download file if (!$fileregistry_error) { $path = Plugin::getWebDir('glpiinventory') . "/front/deployfile_download.php?deployfile_id=" . $file_id; echo "<a href='" . $path . "' title='" . __('Download', 'glpiinventory') . "' class='download' data-bs-toggle='tooltip' target='_blank' ><i class='ti ti-download'></a>"; } //sha fingerprint $sha_status = "good"; if ($fileregistry_error != 0) { $sha_status = "bad"; } echo "<div class='fingerprint'>"; echo "<div class='fingerprint_" . $sha_status . "'>" . $sha512; if ($fileregistry_error & self::REGISTRY_NO_DB_ENTRY) { echo "<div class='fingerprint_badmsg'>" . __("This file is not correctly registered in database.") . "<br/>" . __("You can fix it by uploading or selecting the good one."); echo "</div>"; } if ($fileregistry_error & self::REGISTRY_NO_MANIFEST) { echo "<div class='fingerprint_badmsg'>" . __("This file doesn't have any manifest file associated.") . "<br/>" . __("You must upload the file."); echo "</div>"; } echo "</div>"; echo "</div>"; //filesize if (!$fileregistry_error) { echo "<div class='size'>"; echo __('Size') . ": " . $this->processFilesize($file_size); echo "</div>"; } echo "</td>"; if ($canedit) { echo "<td class='rowhandler control' title='" . __('drag', 'glpiinventory') . "'><div class='drag row'></div></td>"; } $i++; } if ($canedit) { echo "<tr><th>"; echo Html::getCheckAllAsCheckbox("filesList$rand", mt_rand()); echo "</th><th colspan='3' class='mark'></th></tr>"; } echo "</table>"; if ($canedit) { echo " <img src='" . $CFG_GLPI["root_doc"] . "/pics/arrow-left.png' alt=''>"; echo "<input type='submit' name='delete' value=\"" . __('Delete', 'glpiinventory') . "\" class='submit'>"; } } /** * Display different fields relative the file selected * * @global array $CFG_GLPI * @param array $config * @param array $request_data * @param string $rand unique element id used to identify/update an element * @param string $mode mode in use (create, edit...) * @return void */ public function displayAjaxValues($config, $request_data, $rand, $mode) { $fi_path = Plugin::getWebDir('glpiinventory'); $pfDeployPackage = new PluginGlpiinventoryDeployPackage(); if (isset($request_data['packages_id'])) { $pfDeployPackage->getFromDB($request_data['packages_id']); } else { $pfDeployPackage->getEmpty(); } $p2p = 0; $p2p_retention_duration = 0; $uncompress = 0; if ($mode === self::CREATE) { $source = $request_data['value']; /** * No need to continue if there is no selected source */ if ($source === '0') { return; } } else { $p2p = $config['data']['p2p']; $p2p_retention_duration = $config['data']['p2p-retention-duration']; $uncompress = $config['data']['uncompress']; } echo "<table class='package_item'>"; /* * Display file upload input only in 'create' mode */ echo "<tr>"; echo "<th>" . __("File", 'glpiinventory') . "</th>"; echo "<td>"; if ($mode === self::CREATE) { switch ($request_data['value']) { case "Computer": echo "<input type='file' name='file' value='" . __("filename", 'glpiinventory') . "' />"; echo " <i>" . $this->getMaxUploadSize() . "</i>"; break; case "Server": echo "<input type='text' name='filename' id='server_filename$rand'" . " style='width:500px;float:left' />"; echo "<input type='button' class='submit' value='" . __("Choose", 'glpiinventory') . "' onclick='fileModal$rand.show();' />"; Ajax::createModalWindow( "fileModal$rand", $fi_path . "/ajax/deployfilemodal.php", ['title' => __('Select the file on server', 'glpiinventory'), 'extraparams' => [ 'rand' => $rand ]] ); break; } } else { /* * Display only name in 'edit' mode */ echo $config['data']['name']; } echo "</td>"; echo "</tr>"; echo "<tr>"; echo "<th>" . __("Uncompress", 'glpiinventory') . "<img style='float:right' " . "src='" . $fi_path . "/pics/uncompress.png' /></th>"; echo "<td>"; Html::showCheckbox(['name' => 'uncompress', 'checked' => $uncompress]); echo "</td>"; echo "</tr>"; echo "<tr>"; echo "<th>" . __("P2P", 'glpiinventory') . "<img style='float:right' src='" . $fi_path . "/pics/p2p.png' /></th>"; echo "<td>"; Html::showCheckbox(['name' => 'p2p', 'checked' => $p2p]); echo "</td>"; echo "</tr>"; echo "<tr>"; echo "<th>" . __("retention", 'glpiinventory') . " - " . __("Minute(s)", 'glpiinventory') . "</th>"; echo "<td>"; echo "<input type='number' name='p2p-retention-duration' value='$p2p_retention_duration' />"; echo "</td>"; echo "</tr>"; $this->addOrSaveButton($pfDeployPackage, $mode); echo "</table>"; } /** * Show files / directory on server. * This is used when get a file on the server * * @global array $CFG_GLPI * @param string $rand unique element id used to identify/update an element */ public static function showServerFileTree($rand) { echo "<script type='text/javascript'>"; echo "Ext.Ajax.defaultHeaders = {'X-Glpi-Csrf-Token' : getAjaxCsrfToken()};"; echo "var Tree_Category_Loader$rand = new Ext.tree.TreeLoader({ dataUrl:'" . Plugin::getWebDir('glpiinventory') . "/ajax/serverfilestreesons.php' });"; echo "var Tree_Category$rand = new Ext.tree.TreePanel({ collapsible : false, animCollapse : false, border : false, id : 'tree_projectcategory$rand', el : 'tree_projectcategory$rand', autoScroll : true, animate : false, enableDD : true, containerScroll : true, height : 320, width : 670, loader : Tree_Category_Loader$rand, rootVisible : false, listeners: { click: function(node, event) { if (node.leaf == true) { console.log('server_filename$rand'); Ext.get('server_filename$rand').dom.value = node.id; fileModal$rand.hide(); } } } });"; // SET the root node. echo "var Tree_Category_Root$rand = new Ext.tree.AsyncTreeNode({ text : '', draggable : false, id : '-1' // this IS the id of the startnode }); Tree_Category$rand.setRootNode(Tree_Category_Root$rand);"; // Render the tree. echo "Tree_Category$rand.render(); Tree_Category_Root$rand.expand();"; echo "</script>"; echo '<div class="alert alert-info d-flex" role="alert">'; echo '<i class="fas fa-exclamation-circle fa-2x me-2"></i>'; echo '<p>' . sprintf(__('Files need to be uploaded to %s folder to be displayed here', 'glpiinventory'), '<mark>/files/_plugins/glpiinventory/upload/</mark>') . '</p>'; echo '</div>'; echo "<div id='tree_projectcategory$rand' ></div>"; echo "</div>"; } /** * Get files / directories on server * * @param string $node */ public static function getServerFileTree($node) { $nodes = []; $pfConfig = new PluginGlpiinventoryConfig(); $dir = $pfConfig->getValue('server_upload_path'); $security_problem = false; if ($node != "-1") { if (strstr($node, "..")) { $security_problem = true; } $matches = []; preg_match("/^(" . str_replace("/", "\/", $dir) . ")(.*)$/", $node, $matches); if (count($matches) != 3) { $security_problem = true; } } if (!$security_problem) { // leaf node if ($node != -1) { $dir = $node; } if (($handle = opendir($dir))) { $folders = $files = []; //list files in dir selected //we store folders and files separately to sort them alphabetically separately while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { $filepath = $dir . "/" . $entry; if (is_dir($filepath)) { $folders[$filepath] = $entry; } else { $files[$filepath] = $entry; } } } //sort folders and files (and maintain index association) asort($folders); asort($files); //add folders in json foreach ($folders as $filepath => $entry) { $path['text'] = $entry; $path['id'] = $filepath; $path['draggable'] = false; $path['leaf'] = false; $path['cls'] = 'folder'; $nodes[] = $path; } //add files in json foreach ($files as $filepath => $entry) { $path['text'] = $entry; $path['id'] = $filepath; $path['draggable'] = false; $path['leaf'] = true; $path['cls'] = 'file'; $nodes[] = $path; } closedir($handle); } } print json_encode($nodes); } /** * Add a new item in files of the package * * @param array $params list of fields with value of the file */ public function add_item($params) { switch ($params['filestype']) { case 'Server': return $this->uploadFileFromServer($params); break; default: return $this->uploadFileFromComputer($params); } return false; } /** * Remove an item * * @param array $params * @return boolean */ public function remove_item($params) { if (!isset($params['file_entries'])) { return false; } $shasToRemove = []; //get current order json $data = json_decode($this->getJson($params['packages_id']), true); $files = $data['jobs']['associatedFiles']; //remove selected checks foreach ($params['file_entries'] as $index => $checked) { if ($checked >= "1" || $checked == "on") { //get sha512 $sha512 = $data['jobs']['associatedFiles'][$index]; //remove file unset($files[$index]); unset($data['associatedFiles'][$sha512]); $shasToRemove[] = $sha512; } } $data['jobs']['associatedFiles'] = array_values($files); //update order $this->updateOrderJson($params['packages_id'], $data); //remove files in repo foreach ($shasToRemove as $sha512) { $this->removeFileInRepo($sha512); } return true; } /** * Save the item in files * * @param array $params list of fields with value of the file */ public function save_item($params) { //get current order json $data = json_decode($this->getJson($params['id']), true); //get sha512 $sha512 = $data['jobs'][$this->json_name][$params['index']]; //get file in json $file = $data[$this->json_name][$sha512]; //remove value in json unset($data[$this->json_name][$sha512]); //update values $file['p2p'] = isset($params['p2p']) ? $params['p2p'] : 0; $file['p2p-retention-duration'] = $params['p2p-retention-duration']; $file['uncompress'] = isset($params['uncompress']) ? $params['uncompress'] : 0; //add modified entry $data[$this->json_name][$sha512] = $file; //update order $this->updateOrderJson($params['id'], $data); } /** * Upload file from user computer * * @param array $params * @return boolean */ public function uploadFileFromComputer($params) { if (isset($params["id"])) { //file uploaded? if ( isset($_FILES['file']['tmp_name']) && !empty($_FILES['file']['tmp_name']) ) { $file_tmp_name = $_FILES['file']['tmp_name']; } if ( isset($_FILES['file']['name']) && !empty($_FILES['file']['name']) ) { $filename = $_FILES['file']['name']; } //file upload errors if (isset($_FILES['file']['error'])) { $error = true; $msg = __("Upload error", 'glpiinventory'); switch ($_FILES['file']['error']) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $msg = __("Transfer error: the file size is too big", 'glpiinventory'); break; case UPLOAD_ERR_PARTIAL: $msg = __("The uploaded file was only partially uploaded", 'glpiinventory'); break; case UPLOAD_ERR_NO_FILE: $msg = __("No file was uploaded", 'glpiinventory'); break; case UPLOAD_ERR_NO_TMP_DIR: $msg = __("Missing a temporary folder", 'glpiinventory'); break; case UPLOAD_ERR_CANT_WRITE: $msg = __("Failed to write file to disk", 'glpiinventory'); break; case UPLOAD_ERR_EXTENSION: $msg = __("PHP extension stopped the file upload", 'glpiinventory'); break; case UPLOAD_ERR_OK: //no error, continue $error = false; } if ($error) { Session::addMessageAfterRedirect($msg); return false; } } //prepare file data for insertion in repo $data = [ 'id' => $params['id'], 'file_tmp_name' => $file_tmp_name ?? '', 'mime_type' => $_FILES['file']['type'], 'filesize' => $_FILES['file']['size'], 'filename' => $filename ?? '', 'p2p' => isset($params['p2p']) ? $params['p2p'] : 0, 'uncompress' => isset($params['uncompress']) ? $params['uncompress'] : 0, 'p2p-retention-duration' => (is_numeric($params['p2p-retention-duration']) ? $params['p2p-retention-duration'] : 0) ]; //Add file in repo if (isset($filename) && $this->addFileInRepo($data)) { Session::addMessageAfterRedirect(__('File saved!', 'glpiinventory')); return true; } else { Session::addMessageAfterRedirect(__('Failed to copy file', 'glpiinventory')); return false; } } Session::addMessageAfterRedirect(__('File missing', 'glpiinventory')); return false; } /** * Upload file from temp folder in server * * @param array $params * @return boolean */ public function uploadFileFromServer($params) { if (preg_match('/\.\./', $params['filename'])) { die; } if (isset($params["id"])) { $file_path = $params['filename']; $filename = basename($file_path); $mime_type = ''; if ( function_exists('finfo_open') && ($finfo = finfo_open(FILEINFO_MIME)) ) { $mime_type = finfo_file($finfo, $file_path); finfo_close($finfo); } elseif (function_exists('mime_content_type')) { $mime_type = mime_content_type($file_path); } $filesize = filesize($file_path); //prepare file data for insertion in repo $data = [ 'file_tmp_name' => $file_path, 'mime_type' => $mime_type, 'filesize' => $filesize, 'filename' => $filename, 'p2p' => isset($params['p2p']) ? $params['p2p'] : 0, 'uncompress' => isset($params['uncompress']) ? $params['uncompress'] : 0, 'p2p-retention-duration' => ( isset($params['p2p-retention-duration']) && is_numeric($params['p2p-retention-duration']) ? $params['p2p-retention-duration'] : 0 ), 'id' => $params['id'] ]; //Add file in repo if ($filename && $this->addFileInRepo($data)) { Session::addMessageAfterRedirect(__('File saved!', 'glpiinventory')); return true; } else { Session::addMessageAfterRedirect(__('Failed to copy file', 'glpiinventory')); return false; } } Session::addMessageAfterRedirect(__('File missing', 'glpiinventory')); return false; } /** * Get directories based on sha512 * * @param string $sha512 * @return string the directories based on sha512 */ public function getDirBySha512($sha512) { $first = substr($sha512, 0, 1); $second = substr($sha512, 0, 2); return "$first/$second"; } /** * Create a configuration request data * * @since 9.2 */ public function getItemConfig(PluginGlpiinventoryDeployPackage $package, $request_data) { $element = $package->getSubElement($this->json_name, $request_data['index']); $config = []; if ($element) { $config = [ 'hash' => $element, 'data' => $package->getAssociatedFile($element), ]; } return $config; } /** * Move uploaded file part in right/final directory * * @param string $filePath path of the file + filename * @param boolean $skip_creation * @return string */ public function registerFilepart($filePath, $skip_creation = false) { $sha512 = hash_file('sha512', $filePath); if (!$skip_creation) { $dir = PLUGIN_GLPI_INVENTORY_REPOSITORY_DIR . $this->getDirBySha512($sha512); if (!file_exists($dir)) { mkdir($dir, 0777, true); } copy($filePath, $dir . '/' . $sha512); } return $sha512; } /** * Add file in the repository * * @param array $params * @return boolean */ public function addFileInRepo($params) { $filename = addslashes($params['filename']); $file_tmp_name = $params['file_tmp_name']; $maxPartSize = 1024 * 1024; $tmpFilepart = tempnam(GLPI_PLUGIN_DOC_DIR . "/glpiinventory/", "filestore"); $sha512 = hash_file('sha512', $file_tmp_name); $short_sha512 = substr($sha512, 0, 6); $file_present_in_repo = false; if ($this->checkPresenceFile($sha512)) { $file_present_in_repo = true; } $file_present_in_db = (!empty($this->find(['shortsha512' => $short_sha512]))); $new_entry = [ 'name' => $filename, 'p2p' => $params['p2p'], 'p2p-retention-duration' => $params['p2p-retention-duration'], 'uncompress' => $params['uncompress'], ]; $fdIn = fopen($file_tmp_name, 'rb'); if (!$fdIn) { return false; } $fdPart = null; $multiparts = []; do { clearstatcache(); if (file_exists($tmpFilepart)) { if (feof($fdIn) || filesize($tmpFilepart) >= $maxPartSize) { $part_sha512 = $this->registerFilepart( $tmpFilepart, $file_present_in_repo ); unlink($tmpFilepart); $multiparts[] = $part_sha512; } } if (feof($fdIn)) { break; } $data = fread($fdIn, 1024 * 1024); $fdPart = gzopen($tmpFilepart, 'a'); gzwrite($fdPart, $data, strlen($data)); gzclose($fdPart); } while (1); //create manifest file if (!$file_present_in_repo) { $handle = fopen( PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512, "w+" ); if ($handle) { foreach ($multiparts as $sha) { fwrite($handle, $sha . "\n"); } fclose($handle); } } //TODO: Add a new files interface to list, create, manage entities and visibility // entity on a file is just anticipated and will be fully used later if (!$file_present_in_db) { $entry = [ "name" => $filename, "filesize" => $params['filesize'], "mimetype" => $params['mime_type'], "sha512" => $sha512, "shortsha512" => $short_sha512, "comments" => "", "date_mod" => date('Y-m-d H:i:s'), "entities_id" => 0, "is_recursive" => 1 ]; $this->add($entry); } //get current package json $data = json_decode($this->getJson($params['id']), true); //add new entry $data[$this->json_name][$sha512] = $new_entry; if (!in_array($sha512, $data['jobs'][$this->json_name])) { $data['jobs'][$this->json_name][] = $sha512; } //update package $this->updateOrderJson($params['id'], $data); return true; } /** * Remove file from the repository * * @param string $sha512 sha512 of the file * @return boolean */ public function removeFileInRepo($sha512) { $pfDeployPackage = new PluginGlpiinventoryDeployPackage(); // try to find file in other packages $rows = $pfDeployPackage->find( [ ['json' => ['LIKE', '%' . substr($sha512, 0, 6) . '%']], ['json' => ['LIKE', '%' . $sha512 . '%']] ] ); //file found in other packages, do not remove parts in repo if (count($rows) > 0) { return false; } //get sha512 parts in manifest if (!file_exists(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512)) { return true; } $multiparts = file(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512); //parse all files part foreach ($multiparts as $part_sha512) { $firstdir = PLUGIN_GLPI_INVENTORY_REPOSITORY_DIR . substr($part_sha512, 0, 1) . "/"; $fulldir = PLUGIN_GLPI_INVENTORY_REPOSITORY_DIR . $this->getDirBySha512($part_sha512) . '/'; //delete file parts unlink(trim($fulldir . $part_sha512)); //delete folders if empty if (is_dir($fulldir)) { $count_second_folder = count(scandir($fulldir)) - 2; if ($count_second_folder === 0) { rmdir($fulldir); } } if (is_dir($firstdir)) { $count_first_folder = count(scandir($firstdir)) - 2; // -2 for . and .. if ($count_first_folder === 0) { rmdir($firstdir); } } } //remove manifest if (file_exists(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512)) { unlink(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512); } return true; } /** * Return all subpart path * * @param string $sha512 sha512 of the file * @return array */ public function getFilePath($sha512) { if (!$this->checkPresenceFile($sha512)) { return false; } $path = []; $handle = fopen(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512, "r"); $error = $handle === false; if ($handle) { while (($buffer = fgets($handle)) !== false) { $path[] = PLUGIN_GLPI_INVENTORY_REPOSITORY_DIR . $this->getDirBySha512($buffer) . "/" . trim($buffer, "\n"); } if (!feof($handle)) { $error = true; } fclose($handle); } if ($error) { trigger_error( sprintf('Unable to read file %s manifest.', $sha512), E_USER_WARNING ); return false; } return $path; } /** * Check if the manifest relative to the sha512 exist * * @param string $sha512 sha512 of the file * @return boolean */ public function checkPresenceManifest($sha512) { if (!file_exists(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512)) { return false; } return true; } /** * Check if the file relative to the sha512 exist * * @param string $sha512 sha512 of the file * @return boolean */ public function checkPresenceFile($sha512) { //Do not continue if the manifest is not found if (!$this->checkPresenceManifest($sha512)) { return false; } //Does the file needs to be created ? // Even if fileparts exists, we need to be sure // the manifest file is created $fileparts_ok = true; $fileparts_cnt = 0; $handle = fopen(PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $sha512, "r"); if ($handle) { while (($buffer = fgets($handle)) !== false) { $fileparts_cnt++; $path = $this->getDirBySha512($buffer) . "/" . trim($buffer, "\n"); //Check if the filepart exists if (!file_exists(PLUGIN_GLPI_INVENTORY_REPOSITORY_DIR . $path)) { $fileparts_ok = false; break; } } fclose($handle); } // Does the file is empty ? if ($fileparts_cnt == 0) { return false; } //Does the file needs to be replaced ? if (!$fileparts_ok) { return false; } //Nothing to do because the manifest and associated fileparts seems to be fine. return true; } /** * Get the maximum size the php can accept for upload file * * @return string */ public function getMaxUploadSize() { $max_upload = (int)(ini_get('upload_max_filesize')); $max_post = (int)(ini_get('post_max_size')); $memory_limit = (int)(ini_get('memory_limit')); return __('Max file size', 'glpiinventory') . " : " . min($max_upload, $max_post, $memory_limit) . __('Mio', 'glpiinventory'); } /** * List number of files not used in packages */ public function numberUnusedFiles() { echo "<table width='950' class='tab_cadre_fixe'>"; echo "<tr>"; echo "<th>"; echo __('Unused file', 'glpiinventory'); echo "</th>"; echo "<th>"; echo __('Size', 'glpiinventory'); echo "</th>"; echo "</tr>"; $a_files = $this->find(); foreach ($a_files as $data) { $cnt = countElementsInTable( 'glpi_plugin_glpiinventory_deploypackages', ['json' => ['LIKE', '%"' . $data['sha512'] . '"%']] ); if ($cnt == 0) { echo "<tr class='tab_bg_1'>"; echo "<td>"; echo $data['name']; echo "</td>"; echo "<td>"; echo round($data['filesize'] / 1000000, 1) . " " . __('Mio'); echo "</td>"; echo "</tr>"; } } echo "</table>"; } /** * Delete the files not used in packages */ public function deleteUnusedFiles() { $a_files = $this->find(); foreach ($a_files as $data) { $cnt = countElementsInTable( 'glpi_plugin_glpiinventory_deploypackages', ['json' => ['LIKE', '%"' . $data['sha512'] . '"%']] ); if ($cnt == 0) { $this->delete($data); $manifest_filename = PLUGIN_GLPI_INVENTORY_MANIFESTS_DIR . $data['sha512']; if (file_exists($manifest_filename)) { $handle = @fopen($manifest_filename, "r"); if ($handle) { while (!feof($handle)) { $buffer = trim(fgets($handle)); if ($buffer != '') { $part_path = $this->getDirBySha512($buffer) . "/" . $buffer; unlink(PLUGIN_GLPI_INVENTORY_REPOSITORY_DIR . $part_path); } } fclose($handle); } unlink($manifest_filename); } } } } }