%PDF- %PDF-
Direktori : /home/vacivi36/ava/admin/tool/customlang/classes/local/ |
Current File : /home/vacivi36/ava/admin/tool/customlang/classes/local/importer.php |
<?php // This file is part of Moodle - http://moodle.org/ // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. /** * Custom lang importer. * * @package tool_customlang * @copyright 2020 Ferran Recio <ferran@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace tool_customlang\local; use tool_customlang\local\mlang\phpparser; use tool_customlang\local\mlang\logstatus; use tool_customlang\local\mlang\langstring; use core\output\notification; use stored_file; use coding_exception; use moodle_exception; use core_component; use stdClass; /** * Class containing tha custom lang importer * * @package tool_customlang * @copyright 2020 Ferran Recio <ferran@moodle.com> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class importer { /** @var int imports will only create new customizations */ public const IMPORTNEW = 1; /** @var int imports will only update the current customizations */ public const IMPORTUPDATE = 2; /** @var int imports all strings */ public const IMPORTALL = 3; /** * @var string the language name */ protected $lng; /** * @var int the importation mode (new, update, all) */ protected $importmode; /** * @var string request folder path */ private $folder; /** * @var array import log messages */ private $log; /** * Constructor for the importer class. * * @param string $lng the current language to import. * @param int $importmode the import method (IMPORTALL, IMPORTNEW, IMPORTUPDATE). */ public function __construct(string $lng, int $importmode = self::IMPORTALL) { $this->lng = $lng; $this->importmode = $importmode; $this->log = []; } /** * Returns the last parse log. * * @return logstatus[] mlang logstatus with the messages */ public function get_log(): array { return $this->log; } /** * Import customlang files. * * @param stored_file[] $files array of files to import */ public function import(array $files): void { // Create a temporal folder to store the files. $this->folder = make_request_directory(false); $langfiles = $this->deploy_files($files); $this->process_files($langfiles); } /** * Deploy all files into a request folder. * * @param stored_file[] $files array of files to deploy * @return string[] of file paths */ private function deploy_files(array $files): array { $result = []; // Desploy all files. foreach ($files as $file) { if ($file->get_mimetype() == 'application/zip') { $result = array_merge($result, $this->unzip_file($file)); } else { $path = $this->folder.'/'.$file->get_filename(); $file->copy_content_to($path); $result = array_merge($result, [$path]); } } return $result; } /** * Unzip a file into the request folder. * * @param stored_file $file the zip file to unzip * @return string[] of zip content paths */ private function unzip_file(stored_file $file): array { $fp = get_file_packer('application/zip'); $zipcontents = $fp->extract_to_pathname($file, $this->folder); if (!$zipcontents) { throw new moodle_exception("Error Unzipping file", 1); } $result = []; foreach ($zipcontents as $contentname => $success) { if ($success) { $result[] = $this->folder.'/'.$contentname; } } return $result; } /** * Import strings from a list of langfiles. * * @param string[] $langfiles an array with file paths */ private function process_files(array $langfiles): void { $parser = phpparser::get_instance(); foreach ($langfiles as $filepath) { $component = $this->component_from_filepath($filepath); if ($component) { $strings = $parser->parse(file_get_contents($filepath)); $this->import_strings($strings, $component); } } } /** * Try to get the component from a filepath. * * @param string $filepath the filepath * @return stdCalss|null the DB record of that component */ private function component_from_filepath(string $filepath) { global $DB; // Get component from filename. $pathparts = pathinfo($filepath); if (empty($pathparts['filename'])) { throw new coding_exception("Cannot get filename from $filepath", 1); } $filename = $pathparts['filename']; $normalized = core_component::normalize_component($filename); if (count($normalized) == 1 || empty($normalized[1])) { $componentname = $normalized[0]; } else { $componentname = implode('_', $normalized); } $result = $DB->get_record('tool_customlang_components', ['name' => $componentname]); if (!$result) { $this->log[] = new logstatus('notice_missingcomponent', notification::NOTIFY_ERROR, null, $componentname); return null; } return $result; } /** * Import an array of strings into the customlang tables. * * @param langstring[] $strings the langstring to set * @param stdClass $component the target component */ private function import_strings(array $strings, stdClass $component): void { global $DB; foreach ($strings as $newstring) { // Check current DB entry. $customlang = $DB->get_record('tool_customlang', [ 'componentid' => $component->id, 'stringid' => $newstring->id, 'lang' => $this->lng, ]); if (!$customlang) { $customlang = null; } if ($this->can_save_string($customlang, $newstring, $component)) { $customlang->local = $newstring->text; $customlang->timecustomized = $newstring->timemodified; $customlang->outdated = 0; $customlang->modified = 1; $DB->update_record('tool_customlang', $customlang); } } } /** * Determine if a specific string can be saved based on the current importmode. * * @param stdClass $customlang customlang original record * @param langstring $newstring the new strign to store * @param stdClass $component the component target * @return bool if the string can be stored */ private function can_save_string(?stdClass $customlang, langstring $newstring, stdClass $component): bool { $result = false; $message = 'notice_success'; if (empty($customlang)) { $message = 'notice_inexitentstring'; $this->log[] = new logstatus($message, notification::NOTIFY_ERROR, null, $component->name, $newstring); return $result; } switch ($this->importmode) { case self::IMPORTNEW: $result = empty($customlang->local); $warningmessage = 'notice_ignoreupdate'; break; case self::IMPORTUPDATE: $result = !empty($customlang->local); $warningmessage = 'notice_ignorenew'; break; case self::IMPORTALL: $result = true; break; } if ($result) { $errorlevel = notification::NOTIFY_SUCCESS; } else { $errorlevel = notification::NOTIFY_ERROR; $message = $warningmessage; } $this->log[] = new logstatus($message, $errorlevel, null, $component->name, $newstring); return $result; } }