Commit 065af6da authored by Penny Leach's avatar Penny Leach
Browse files

Another Leap2A refactor - this commit includes:



- Breaking up of the validation into two stages:
    - Performed by the importtransport object, before moving files
      around
    - Performed by the import class, after the files are transported

To this end I changed the importtransport objects to take the
importqueue record (or a fake one) in their constructor, so they have
the same data available as the importer would.
Signed-off-by: default avatarPenny Leach <penny@mjollnir.org>
parent d297fa2e
......@@ -193,17 +193,25 @@ function adduser_validate(Pieform $form, $values) {
$date = time();
$niceuser = preg_replace('/[^a-zA-Z0-9_-]/', '-', $values['username']);
safe_require('import', 'leap');
$TRANSPORTER = new LocalImporterTransport($values['leap2afile']['tmp_name'], $values['leap2afile']['name'], $niceuser . '-' . $date);
$fakeimportrecord = (object)array(
'data' => array(
'importfile' => $values['leap2afile']['tmp_name'],
'importfilename' => $values['leap2afile']['name'],
'importid' => $niceuser . '-' . $date,
)
);
$TRANSPORTER = new LocalImporterTransport($fakeimportrecord);
try {
if ($values['leap2afile']['type'] == 'application/octet-stream') {
// the browser wasn't sure, so use mime_content_type to guess
$mimetype = mime_content_type($values['leap2afile']['filename']);
$mimetype = mime_content_type($values['leap2afile']['tmp_name']);
}
else {
$mimetype = $values['leap2afile']['type'];
}
$TRANSPORTER->extract_file($mimetype);
PluginImportLeap::validate_import_data($TRANSPORTER->files_info());
PluginImportLeap::validate_transported_data($TRANSPORTER);
}
catch (Exception $e) {
$form->set_error('leap2afile', $e->getMessage());
......
......@@ -321,16 +321,21 @@ function send_content_ready($token, $username, $format, $importdata, $fetchnow=f
}
$queue->format = $format;
$class = null;
$queue->data = serialize($importdata);
update_record('import_queue', $queue);
$tr = new MnetImporterTransport($queue);
try {
$class = PluginImport::class_from_format($format);
$tr->validate_import_data();
} catch (Exception $e) {
throw new ImportException(null, "Invalid format $format");
throw new ImportException(null, 'Invalid importdata: ' . $e->getMessage());
}
$class = null;
try {
call_static_method($class, 'validate_import_data', $importdata);
$class = PluginImport::class_from_format($format);
} catch (Exception $e) {
throw new ImportException(null, 'Invalid importdata: ' . $e->getMessage());
throw new ImportException(null, "Invalid format $format");
}
if (!array_key_exists('totalsize', $importdata)) {
......@@ -343,16 +348,17 @@ function send_content_ready($token, $username, $format, $importdata, $fetchnow=f
throw $e;
}
$queue->data = serialize($importdata);
update_record('import_queue', $queue);
$result = new StdClass;
if ($fetchnow && PluginImport::import_immediately_allowed()) {
// either immediately spawn a curl request to go fetch the file
$tr = new MnetImporterTransport($queue);
$importer = PluginImport::create_importer($queue->id, $tr, $queue);
$importer->prepare();
try {
$importer->validate_transported_data($tr);
} catch (Exception $e) {
throw new ImportException(null, 'Invalid importdata: ' . $e->getMessage());
}
$importer->process();
$importer->cleanup();
delete_records('import_queue', 'id', $queue->id);
......
......@@ -38,23 +38,12 @@ class PluginImportFile extends PluginImport {
public function __construct($id, $record=null) {
parent::__construct($id, $record);
$data = $this->get('data');
self::validate_import_data($data);
$this->manifest = $data['filesmanifest'];
$this->zipfilesha1 = $data['zipfilesha1'];
}
public static function validate_import_data($importdata) {
if (empty($importdata) ||
!is_array($importdata) ||
!array_key_exists('filesmanifest', $importdata) ||
!is_array($importdata['filesmanifest']) ||
count($importdata['filesmanifest']) == 0) {
throw new ImportException($this, 'Missing files manifest in import data');
}
if (!array_key_exists('zipfilesha1', $importdata)) {
throw new ImportException($this, 'Missing zipfile sha1 in import data');
}
return true;
public static function validate_transported_data(ImporterTransport $transport) {
return true; // nothing to do , we're just importing files to the file artefact plugin
}
public function process() {
......
......@@ -66,7 +66,8 @@ class PluginImportLeap extends PluginImport {
const STRATEGY_IMPORT_AS_VIEW = 1;
public static function validate_import_data($importdata) {
public static function validate_transported_data(ImporterTransport $transport) {
$importdata = $transport->files_info();
if (!$file = self::find_file($importdata)) {
throw new ImportException(null, 'Missing leap xml file');
}
......
......@@ -170,10 +170,15 @@ abstract class PluginImport extends Plugin {
}
/**
* validate the import data (usually what files_info returns
* validate the import data that we have after the file has been fetched.
* This is static, because the data may need to be validated earlier than setting up everything else
* For example, in the case of the administrator adding a user manually from a leap2a file,
* we want to validate the leap data before creating the user record.
*
* @param array $importdata usually what ImportTransporter::files_info returns
* @throws ImportException
*/
public static abstract function validate_import_data($importdata);
public static abstract function validate_transported_data(ImporterTransport $transporter);
/**
* Whether imports are allowed immediately or if they must be queued
......@@ -278,6 +283,14 @@ abstract class ImporterTransport {
/** the mimetype of the file we are importing */
protected $mimetype;
/** the import queue record **/
protected $importrecord;
/**
* @param stdclass $import the import record. This should correspond to a record in import_queue, but can be faked
*/
public abstract function __construct($import);
/**
* figure out the temporary directory to use
* and make sure it exists, etc
......@@ -393,6 +406,11 @@ abstract class ImporterTransport {
throw new ImportException($this, 'Failed to unzip the file recieved from the transport object');
}
}
/**
* validate data to be imported
*/
public abstract function validate_import_data();
}
/**
......@@ -400,12 +418,26 @@ abstract class ImporterTransport {
*/
class LocalImporterTransport extends ImporterTransport {
public function __construct($importfile, $importfilename, $importid) {
$this->importfile = $importfile;
$this->importfilename = $importfilename;
$this->importid = $importid;
/**
* @param stdclass $import the import record
*/
public function __construct($import) {
$this->importrecord = $import;
$importdata = $import->data;
if (is_string($importdata)) {
$importdata = unserialize($importdata);
}
foreach (array('importfile', 'importfilename', 'importid') as $reqkey) {
if (!array_key_exists($reqkey, $importdata)) {
throw new ImportException("Missing required information $reqkey");
}
$this->{$reqkey} = $importdata[$reqkey];
}
}
public function validate_import_data() { }
// nothing to do, uploaded files live in /tmp
public function cleanup() { }
......@@ -429,6 +461,7 @@ class MnetImporterTransport extends ImporterTransport {
* @param stdclass $import the import record
*/
public function __construct($import) {
$this->importrecord = $import;
$this->host = get_record('host', 'wwwroot', $import->host);
$this->importid = $import->id; // since we have an import record, use the id
}
......@@ -479,6 +512,24 @@ class MnetImporterTransport extends ImporterTransport {
public function get_description() {
return get_string('remotehost', 'mahara', $this->host->name);
}
public function validate_import_data() {
$importdata = $this->importrecord->data;
if (is_string($importdata)) {
$importdata = unserialize($importdata);
}
if (empty($importdata) ||
!is_array($importdata) ||
!array_key_exists('filesmanifest', $importdata) ||
!is_array($importdata['filesmanifest']) ||
count($importdata['filesmanifest']) == 0) {
throw new ImportException($this, 'Missing files manifest in import data');
}
if (!array_key_exists('zipfilesha1', $importdata)) {
throw new ImportException($this, 'Missing zipfile sha1 in import data');
}
return true;
}
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment