filesystem = $filesystem; $this->template_manager = $template_manager; $this->event_handler = $event_handler; } /** * Get Importers * * @return ImporterModel[] */ public function get_importers() { $result = array(); $query = new \WP_Query(array( 'post_type' => IWP_POST_TYPE, 'posts_per_page' => -1, )); foreach ($query->posts as $post) { $result[] = $this->get_importer($post); } return $result; } /** * Get Importer * * @param int $id * @return ImporterModel */ public function get_importer($id) { if ($id instanceof ImporterModel) { return $id; } if (IWP_POST_TYPE !== get_post_type($id)) { return false; } return new ImporterModel($id, $this->is_debug()); } public function is_debug() { if (defined('IWP_DEBUG') && true === IWP_DEBUG) { return true; } $uninstall_enabled = get_option('iwp_settings'); if (isset($uninstall_enabled['debug']) && true === $uninstall_enabled['debug']) { return true; } return false; } public function set_current_user($id) { $importer_model = $this->get_importer($id); $user_id = $importer_model->getUserId(); Logger::write('set_current_user -user=' . $user_id, $importer_model->getId()); if ($user_id) { return wp_set_current_user($user_id); } return false; } /** * Delete Importer * * @param int $id * @return void */ public function delete_importer($id) { $importer = $this->get_importer($id); $importer->delete(); } public function get_file($id) { $importer = $this->get_importer($id); $config = $this->get_config($importer); $parser = $importer->getParser(); if ('xml' === $parser) { return $this->get_xml_file($importer, $config); } elseif ('csv' === $parser) { return $this->get_csv_file($importer, $config); } return false; } public function get_csv_file($id, $config) { $importer = $this->get_importer($id); $file = new CSVFile($importer->getFile(), $config); $file->setDelimiter($importer->getFileSetting('delimiter')); $file->setEnclosure($importer->getFileSetting('enclosure')); $file->setEscape($importer->getFileSetting('escape', "\\")); return $file; } public function get_xml_file($id, $config) { $importer = $this->get_importer($id); $file = new XMLFile($importer->getFile(), $config); $file->setRecordPath($importer->getFileSetting('base_path')); return $file; } public function preview_csv_file($id, $fields = [], $row = 0) { $importer = $this->get_importer($id); $config = $this->get_config($importer, true); $file = $this->get_csv_file($importer, $config); $parser = new CSVParser($file); $record = $parser->getRecord($row); return $record->queryGroup(['fields' => $fields]); } public function preview_xml_file($id, $fields = [], $row = 0) { $importer = $this->get_importer($id); $config = $this->get_config($importer, true); $file = $this->get_xml_file($importer, $config); $parser = new XMLParser($file); $record = $parser->getRecord($row); return $record->queryGroup(['fields' => $fields]); } public function process_csv_file($id, $delimiter, $enclosure, $tmp = false) { $importer = $this->get_importer($id); $config = $this->get_config($importer->getId(), $tmp); $file = $this->get_csv_file($importer, $config); $file->setDelimiter($delimiter); $file->setEnclosure($enclosure); $file->processing(true); return $file->getRecordCount(); } public function process_xml_file($id, $tmp = false) { $importer = $this->get_importer($id); $config = $this->get_config($importer->getId(), $tmp); $filePath = $importer->getFile(); $file = new XMLFile($filePath, $config); $file->processing(true); $nodes = $file->get_node_list(); $results = []; foreach ($nodes as $node) { $config = $this->get_config($importer->getId(), $tmp); $file = new XMLFile($filePath, $config); $file->setRecordPath($node); // TODO: Seperate record count, to when a node has been selected. $results[$node] = 0; //$file->getRecordCount(); } return $results; } /** * Link import file to importer via post meta * * @param ImporterModel $id * @param string $file_path * @return integer Id of inserted file */ public function link_importer_file($id, $file_path) { $importer = $this->get_importer($id); $index = get_post_meta($importer->getId(), '_importer_files', true); if (!$index) { $index = 1; } $index++; // Store uploads-relative paths so site moves / open_basedir changes do not break lookups. $file_path = wp_normalize_path($file_path); $relative = Filesystem::to_uploads_relative_path($file_path); if ($relative !== '' && $relative !== $file_path) { $file_path = $relative; } update_post_meta($importer->getId(), '_importer_files', $index); update_post_meta($importer->getId(), '_importer_file_' . $index, $file_path); return $index; } public function get_importer_file_prefix($importer) { $importer = $this->get_importer($importer); $file_index = get_post_meta($importer->getId(), '_importer_files', true); if (!$file_index) { $file_index = 1; } $file_index++; return $importer->getId() . '-' . intval($file_index) . '-' . wp_generate_password(12, false, false) . '-'; } public function set_custom_upload_path($dir) { remove_filter('upload_dir', [$this, 'set_custom_upload_path']); $path = $this->filesystem->get_temp_directory(); $url = $this->filesystem->get_temp_directory(true); add_filter('upload_dir', [$this, 'set_custom_upload_path']); $path .= '/uploads'; $url .= '/uploads'; if (!is_dir($path)) { wp_mkdir_p($path); } if (!file_exists($path . '/.htaccess')) { file_put_contents($path . '/.htaccess', "# Apache 2.4+ Require all denied # Apache 2.2 and older (or when mod_authz_core isn't available) Deny from all "); } if (!file_exists($path . '/index.html')) { touch($path . '/index.html'); } return array( 'path' => $path, 'url' => $url, 'subdir' => '/importwp/uploads', ) + $dir; } public function upload_file($id, $file) { $importer = $this->get_importer($id); Logger::setId($importer->getId()); $allowed_file_types = $this->event_handler->run('importer.allowed_file_types', [$importer->getAllowedFileTypes()]); $prefix = $this->get_importer_file_prefix($importer); $prefix_upload = function ($file) use ($prefix) { $file['name'] = $prefix . $file['name']; return $file; }; add_filter('wp_handle_upload_prefilter', $prefix_upload); $result = $this->filesystem->upload_file($file, $allowed_file_types); remove_filter('wp_handle_upload_prefilter', $prefix_upload); if (is_wp_error($result)) { return $result; } $attachment_id = $this->insert_file_attachment($importer, $result['dest'], $result['type']); if (is_wp_error($attachment_id)) { return $attachment_id; } return $attachment_id; } public function remote_file($id, $source, $filetype = null) { $importer = $this->get_importer($id); Logger::setId($importer->getId()); $allowed_file_types = $this->event_handler->run('importer.allowed_file_types', [$importer->getAllowedFileTypes()]); $prefix = $this->get_importer_file_prefix($importer); try { if (preg_match('/^s?ftp?:\/\//', $source) === 1) { if (preg_match('/^(?s?ftp):\/\/(?:(?[^\:@]+)(?:\:(?[^@]+))?@)?(?[^\:\/]+)(?:\:(?[0-9]+))?(?:\/(?.*))$/', $source, $matches) !== 1) { return new \WP_Error("IM_RM_FTP_PARSE", __("Unable to parse FTP connection string", 'jc-importer')); } $protocol = isset($matches['protocol']) ? $matches['protocol'] : 'ftp'; $user = isset($matches['user']) ? urldecode($matches['user']) : ''; $pass = isset($matches['pass']) ? urldecode($matches['pass']) : ''; $host = isset($matches['host']) ? $matches['host'] : false; $port = isset($matches['port']) && !empty($matches['port']) ? $matches['port'] : intval(21); $path = isset($matches['path']) ? $matches['path'] : false; if (!$host) { return new \WP_Error("IM_RM_FTP_HOST", __("Unable to parse ftp host from connection string", 'jc-importer')); } if (!$path) { return new \WP_Error("IM_RM_FTP_HOST", __("Unable to parse ftp host from connection string", 'jc-importer')); } /** * @var \ImportWP\Common\Ftp\Ftp $ftp */ $ftp = Container::getInstance()->get('ftp'); $path = apply_filters('iwp/importer/remote_file', $path, $importer); $path = apply_filters(sprintf('iwp/importer=%d/remote_file', $importer->getId()), $path, $importer); $filter_connection_args = [ 'user' => $user, 'pass' => $pass, 'host' => $host, 'port' => $port, 'path' => $path, ]; $path = apply_filters(sprintf('iwp/importer/remote_file/source=%s', 'ftp'), $path, $importer, $filter_connection_args); $path = apply_filters(sprintf('iwp/importer=%d/remote_file/source=ftp', $importer->getId(), 'ftp'), $path, $importer, $filter_connection_args); if ($protocol == 'sftp') { // require sftp package require_once __DIR__ . '/../../../libs/autoload.php'; $sftp = new \phpseclib3\Net\SFTP($host, $port); if (!$sftp->login($user, $pass)) { return new \WP_Error('IWP_FTP_0', __("Unable to login to ftp server", 'jc-importer')); } $wp_upload_dir = wp_upload_dir(); $dest = wp_unique_filename($wp_upload_dir['path'], basename($path)); $wp_dest = $wp_upload_dir['path'] . '/' . $dest; if (!$sftp->get($path, $wp_dest)) { return new \WP_Error('IWP_FTP_2', sprintf(__('Unable to download: %s file via sftp.', 'jc-importer'), $path)); } $result = array( 'dest' => $wp_dest, 'type' => $this->filesystem->get_filetype($wp_dest), 'mime' => $this->filesystem->get_file_mime($wp_dest) ); } else { $result = $ftp->download_file($path, $host, $user, $pass, false, $port); } } else { $result = $this->filesystem->download_file($source, $filetype, $allowed_file_types, null, $prefix); } } catch (\Exception $e) { return new \WP_Error($e->getCode(), $e->getMessage()); } if (is_wp_error($result)) { return $result; } $attachment_id = $this->insert_file_attachment($importer, $result['dest'], $result['type']); if (is_wp_error($attachment_id)) { return $attachment_id; } return $attachment_id; } public function local_file($id, $source, $filetype = null) { $importer = $this->get_importer($id); Logger::setId($importer->getId()); $allowed_bases = apply_filters('iwp/importer/local_file/allowed_directories', [ realpath(WP_CONTENT_DIR) . DIRECTORY_SEPARATOR ]); $source = realpath($source); $is_allowed = false; foreach ($allowed_bases as $allowed_base) { if ($allowed_base && strpos($source, $allowed_base) === 0) { $is_allowed = true; break; } } if (!$source || !$is_allowed) { return new \WP_Error('IWP_LOCAL_FILE_1', __('Access to this file path is not allowed.', 'jc-importer')); } $allowed_file_types = $this->event_handler->run('importer.allowed_file_types', [$importer->getAllowedFileTypes()]); $prefix = $this->get_importer_file_prefix($importer); $result = $this->filesystem->copy_file($source, $allowed_file_types, null, $prefix, $filetype); if (is_wp_error($result)) { return $result; } $attachment_id = $this->insert_file_attachment($importer, $result['dest'], $result['type']); if (is_wp_error($attachment_id)) { return $attachment_id; } return $attachment_id; } /** * Add uploaded file to importer * * Insert file record in database, set as current import file. * * @param integer|ImporterModel $id Importer to attach file * @param string $file_path File location on server * @param string $file_type Type of file * * @return \WP_Error|int Id of file */ private function insert_file_attachment($id, $file_path, $file_type) { $importer_model = $this->get_importer($id); Logger::setId($importer_model->getId()); // Allow the modification of file path $file_path = wp_normalize_path($file_path); $file_path = apply_filters('iwp/importer/file_uploaded/file_path', $file_path, $importer_model); $file_id = $this->link_importer_file($id, $file_path); if (!$file_id) { return new \WP_Error('IWP_IM_01', __('Unable to link importer file', 'jc-importer')); } if (is_null($importer_model->getParser())) { $importer_model->setParser($file_type); } $importer_model->setFileId($file_id); $importer_model->save(); do_action('iwp/importer/file_uploaded', $file_path, $importer_model); return $file_id; } /** * Clear config files * * @param int $id * @return void */ public function clear_config_files($id, $tmp = false, $all = true) { $config_path = $this->get_config_path($id, $tmp); if (file_exists($config_path)) { unlink($config_path); if (true === $all) { foreach (glob($config_path . '*') as $file) { // don't remove status file if (basename($file) === basename($config_path) . '.status') { continue; } unlink($file); } } } } public function get_config($importer, $tmp = false) { $config_path = $this->get_config_path($importer, $tmp); $config = new Config($config_path); $importer = $this->get_importer($importer); $file_encoding = $importer->getFileSetting('file_encoding'); // file encoding $config->set('file_encoding', apply_filters('iwp/importer/file_encoding', $file_encoding, $importer)); return $config; } public function get_session_path($id, $session, $max_depth = 4) { $base = $this->filesystem->get_temp_directory() . DIRECTORY_SEPARATOR; $base .= str_pad($id, 2, STR_PAD_LEFT) . DIRECTORY_SEPARATOR; if (!file_exists($base)) { if (!is_writable(dirname($base)) || !mkdir($base)) { throw new \Exception(sprintf(__("Unable to create directory: %s", 'jc-importer'), $base)); } } for ($i = 0; $i < ceil(strlen($session) / 2); $i++) { $base .= substr($session, $i * 2, 2) . DIRECTORY_SEPARATOR; if (!file_exists($base)) { if (!is_writable(dirname($base)) || !mkdir($base)) { throw new \Exception(sprintf(__("Unable to create directory: %s", 'jc-importer'), $base)); } } if ($i >= $max_depth - 2) { break; } } return $base; } public function get_config_path($id, $tmp = false, $session_id = null) { $importer = $this->get_importer($id); $key = 'config-%d.json'; if ($tmp) { $key = 'temp-config-%d.json'; } $base = !is_null($session_id) ? $this->get_session_path($id, $session_id) : $this->filesystem->get_temp_directory() . DIRECTORY_SEPARATOR; return $base . sprintf($key, $importer->getId()); } public function import($id, $user, $session = null) { Logger::timer(); $importer_data = $this->get_importer($id); $importer_id = $importer_data->getId(); // store current importer iwp()->importer = $importer_data; $config_data = get_option('iwp_importer_config_' . $importer_id, []); $this->event_handler->run('importer_manager.import', [$importer_data]); $state = new ImporterState($importer_id, $user); try { Logger::debug('IM -init_state'); // 1. Set State Session, and load its state $state->init($session); // if this is a new session, clear config files if ($state->has_status('init')) { // rest importer log. Logger::clear($importer_id); Logger::debug('IM -clear_config_files'); $this->clear_config_files($importer_id, false, true); $config_data['features'] = [ 'session_table' => true ]; } Logger::debug('IM -get_config'); $config = $this->get_config($importer_data); // template Logger::debug('IM -get_importer_template'); $template = $this->get_importer_template($importer_data); Logger::debug('IM -register_hooks'); $template->register_hooks($importer_data); // permission Logger::debug('IM -permissions'); $permission = new Permission($importer_data); // mapper Logger::debug('IM -get_importer_mapper'); $mapper = $this->get_importer_mapper($importer_data, $template, $permission); // if this is a new session, build config if ($state->has_status('init')) { Logger::debug('IM -generate_config'); $config_data['data'] = $template->config_field_map($importer_data->getMap()); $config->set('data', $config_data['data']); $config_data['id'] = $state->get_session(); // This is used for storing version on imported records update_post_meta($importer_id, '_iwp_session', $config_data['id']); // Increase Version $version = get_post_meta($importer_id, '_iwp_version', true); if ($version !== false) { $version++; } else { $version = 0; } update_post_meta($importer_id, '_iwp_version', $version); $config_data['version'] = $version; /** * Fetch new file if setting is checked * @since 2.7.15 */ $run_fetch_file = $importer_data->getSetting('run_fetch') || false; $run_fetch_file = apply_filters('iwp/importer/run_fetch_file', $run_fetch_file); if ($run_fetch_file) { add_filter('upload_dir', [$this, 'set_custom_upload_path']); $datasource = $importer_data->getDatasource(); switch ($datasource) { case 'remote': $raw_source = $importer_data->getDatasourceSetting('remote_url'); $source = apply_filters('iwp/importer/datasource', $raw_source, $raw_source, $importer_data); $source = apply_filters('iwp/importer/datasource/remote', $source, $raw_source, $importer_data); $attachment_id = $this->remote_file($importer_data, $source, $importer_data->getParser()); break; case 'local': $raw_source = $importer_data->getDatasourceSetting('local_url'); $source = apply_filters('iwp/importer/datasource', $raw_source, $raw_source, $importer_data); $source = apply_filters('iwp/importer/datasource/local', $source, $raw_source, $importer_data); $attachment_id = $this->local_file($importer_data, $source, $importer_data->getParser()); break; default: // TODO: record error $attachment_id = new \WP_Error('IWP_CRON_1', sprintf(__('Unable to get new file using datasource: %s', 'jc-importer'), $datasource)); break; } remove_filter('upload_dir', [$this, 'set_custom_upload_path']); if (is_wp_error($attachment_id)) { throw new \Exception(sprintf(__('Importer Datasource: %s', 'jc-importer'), $attachment_id->get_error_message())); } } } $start = 0; // get parser if ($importer_data->getParser() === 'csv') { Logger::debug('IM -get_csv_file'); $file = $this->get_csv_file($importer_data, $config); Logger::debug('IM -load_parser'); $parser = new CSVParser($file); if (true === $importer_data->getFileSetting('show_headings')) { $start = 1; } } elseif ($importer_data->getParser() === 'xml') { Logger::debug('IM -get_xml_file'); $file = $this->get_xml_file($importer_data, $config); Logger::debug('IM -load_parser'); $parser = new XMLParser($file); } else { $parser = apply_filters('iwp/importer/init_parser', false, $importer_data, $config); } // if this is a new session, set start / end rows to state if ($state->has_status('init')) { Logger::debug('IM -get_record_count'); $end = $parser->file()->getRecordCount(); // Capture cancelled status from file processor $raw_state = ImporterState::get_state($importer_data->getId()); if ($raw_state['status'] === 'cancelled') { return $raw_state; } $config_data['start'] = $this->get_start($importer_data, $start); $config_data['end'] = $this->get_end($importer_data, $config_data['start'], $end); update_option('iwp_importer_config_' . $importer_id, $config_data); Logger::debug('IM -update_state'); $state->update(function ($state) use ($config_data) { Logger::debug('IM -update_state=running'); $state['id'] = $config_data['id']; $state['status'] = 'running'; $state['progress']['import']['start'] = $config_data['start']; $state['progress']['import']['end'] = $config_data['end']; return $state; }); Logger::debug('IM -write_status_session_to_file'); Util::write_status_session_to_file($id, $state); do_action('iwp/importer/init', $importer_data); } add_filter('iwp/importer/mapper/hash_check_enabled', function ($enabled) use ($importer_data) { return $importer_data->getSetting('hash_check'); }); Logger::debug('IM -import'); $importer = new \ImportWP\Common\Importer\Importer($config); $importer->parser($parser); $importer->mapper($mapper); $importer->from($config_data['start']); $importer->to($config_data['end']); $importer->filter($importer_data->getFilters()); $importer->import($importer_id, $user, $state); Logger::debug('IM -import_complete'); } catch (\Exception $e) { // TODO: Missing template errors are currently not being logged to history, possibly others? Logger::error('import -error=' . $e->getMessage(), $importer_id); $state->error($e); Util::write_status_session_to_file($id, $state); return $state->get_raw(); } /** * @var Properties $properties */ $properties = Container::getInstance()->get('properties'); // rotate files to not fill up server $importer_data->limit_importer_files($properties->file_rotation); $this->prune_importer_logs($importer_data, $properties->log_rotation); $template->unregister_hooks(); $this->event_handler->run('importer_manager.import_shutdown', [$importer_data]); return $state->update(function ($data) { $data['duration'] = floatval($data['duration']) + Logger::timer(); return $data; })->get_raw(); } public function pause_import($importer_id, $paused) { // TODO: set flag for paused. $state = ImporterState::get_state($importer_id); if ($paused === 'no') { ImporterState::clear_flag($importer_id); $state['status'] = 'running'; } else { ImporterState::set_paused($importer_id); $state['status'] = 'paused'; } // good chance this will be overwritten ImporterState::set_state($importer_id, $state); return $state; } public function stop_import($importer_id) { ImporterState::set_cancelled($importer_id); // good chance this will be overwritten $state = ImporterState::get_state($importer_id); $state['status'] = 'cancelled'; ImporterState::set_state($importer_id, $state); return $state; } public function get_start($importer_data, $start) { $tmp_start = $importer_data->getStartRow(); if (!is_null($tmp_start) && "" !== $tmp_start) { $tmp_start = intval($tmp_start); if ($tmp_start > $start) { $start = $tmp_start; } } return $start; } public function get_end($importer_data, $start, $end) { $tmp_max_row = $importer_data->getMaxRow(); if (!is_null($tmp_max_row) && $tmp_max_row !== '') { $tmp_end = $start + intval($tmp_max_row); if ($tmp_end < $end) { $end = $tmp_end; } } return $end; } public function get_importer_template($id) { $importer_model = $this->get_importer($id); $templates = $this->get_templates(); $template_name = $importer_model->getTemplate(); if (!isset($templates[$template_name])) { $exception_msg = sprintf(__("Unable to locate importer template: %s", 'jc-importer'), $template_name); Logger::error('import -get_importer_template=' . $exception_msg, $importer_model->getId()); throw new \Exception($exception_msg); } return $this->template_manager->load_template($templates[$template_name]); } /** * Get importer mapper * * @param int $id * @param Template $template * @param Permission $permission * @return MapperInterface */ public function get_importer_mapper($id, $template, $permission = null) { $importer = $this->get_importer($id); $mapper_name = $template->get_mapper(); $mappers = $this->get_mappers(); return isset($mappers[$mapper_name]) ? new $mappers[$mapper_name]($importer, $template, $permission) : false; } public function get_mappers() { $mappers = $this->event_handler->run('mappers.register', [[]]); // apply_filters('iwp/mappers/register', []); $mappers = array_merge($mappers, [ 'post' => PostMapper::class, 'user' => UserMapper::class, 'term' => TermMapper::class, 'attachment' => AttachmentMapper::class, 'comment' => CommentMapper::class, ]); return $mappers; } public function get_mapper($key) { $mappers = $this->get_mappers(); if (!isset($mappers[$key])) { return new \WP_Error('IWP_IM_1', sprintf(__('Unable to locate mapper: %s', 'jc-importer'), $key)); } return $mappers[$key]; } public function get_templates() { $templates = $this->event_handler->run('templates.register', [[]]); $templates = array_merge($templates, [ 'post' => PostTemplate::class, 'page' => PageTemplate::class, 'user' => UserTemplate::class, 'term' => TermTemplate::class, 'attachment' => AttachmentTemplate::class, 'comment' => CommentTemplate::class, 'custom-post-type' => CustomPostTypeTemplate::class, ]); return $templates; } public function get_template($key) { $templates = $this->get_templates(); if (!isset($templates[$key])) { return new \WP_Error('IWP_IM_1', sprintf(__('Unable to locate template: %s', 'jc-importer'), $key)); } return $templates[$key]; } public function get_importer_debug_log(ImporterModel $importer_data, $page = 0, $per_page = -1) { $file_path = Logger::getLogFile($importer_data->getId()); $line_counter = 0; $lines = []; $start = $end = -1; if ($per_page > 0) { $start = ($page - 1) * $per_page; $end = $start + $per_page; } if (file_exists($file_path)) { $fh = fopen($file_path, 'r'); if ($fh !== false) { while (($data = fgetcsv($fh)) !== false) { if ($line_counter === $end) { return $lines; } elseif ($per_page === -1 || $line_counter >= $start) { $lines[] = $data; } $line_counter++; } fclose($fh); } } return $lines; } public function prune_importer_logs($importer_model, $limit) { $limit = intval($limit); if ($limit <= -1) { return; } $file_path = Util::get_importer_status_file_path($importer_model->getId()); $tmp_file_path = Util::get_importer_status_file_path($importer_model->getId()) . '.tmp'; $lines = $this->get_importer_logs($importer_model); if (count($lines) > $limit) { require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php'); require_once(ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php'); $fileSystemDirect = new \WP_Filesystem_Direct(false); $fh = fopen($tmp_file_path, 'w'); for ($i = 0; $i < count($lines); $i++) { if ($i < count($lines) - $limit) { $log_file_path = Util::get_importer_log_file_path($importer_model->getId(), $lines[$i]['id']); if ($fileSystemDirect->exists($log_file_path)) { $fileSystemDirect->delete($log_file_path); $tmp = $log_file_path; for ($j = 0; $j < 3; $j++) { $tmp = dirname($tmp); $sub_files = $fileSystemDirect->dirlist($log_file_path); if (empty($sub_files)) { $fileSystemDirect->rmdir($tmp); } } } } else { fputs($fh, json_encode($lines[$i]) . "\n"); } } fclose($fh); if ($fileSystemDirect->move($tmp_file_path, $file_path, true)) { $fileSystemDirect->delete($tmp_file_path); } } } public function get_importer_logs(ImporterModel $importer_data, $page = 0, $per_page = -1) { $file_path = Util::get_importer_status_file_path($importer_data->getId()); $line_counter = 0; $lines = []; $start = $end = -1; if ($per_page > 0) { $start = ($page - 1) * $per_page; $end = $start + $per_page; } if (file_exists($file_path)) { $fh = fopen($file_path, 'r'); if ($fh !== false) { while (($data = fgets($fh)) !== false) { if ($data[strlen($data) - 1] === "\n") { $data = substr($data, 0, strlen($data) - 1); } if ($line_counter === $end) { return $lines; } elseif ($per_page === -1 || $line_counter >= $start) { $lines[] = json_decode($data, true); } $line_counter++; } fclose($fh); } } return $lines; } public function get_importer_log(ImporterModel $importer_data, $session_id, $page = 0, $per_page = -1) { $file_path = Util::get_importer_log_file_path($importer_data->getId(), $session_id); $line_counter = 0; $lines = []; $start = $end = -1; if ($per_page > 0) { $start = ($page - 1) * $per_page; $end = $start + $per_page; } if (file_exists($file_path)) { $fh = fopen($file_path, 'r'); if ($fh !== false) { while (($data = fgetcsv($fh)) !== false) { if ($line_counter === $end) { return $lines; } elseif ($per_page === -1 || $line_counter >= $start) { $lines[] = $data; } $line_counter++; } fclose($fh); } } return $lines; } public function get_importer_status_report(ImporterModel $immpoter_data, $session) { $logs = $this->get_importer_logs($immpoter_data); foreach ($logs as $log) { if ($log && isset($log['id']) && $log['id'] === $session) { return $log; } } return false; } }