/** * @param eZINI $importINI * @return void */ public static function init(eZINI $importINI) { $extDir = eZSys::rootDir() . '/extension/'; //Get generated mapping config file $jsonFile = $extDir . $importINI->variable('XMLImportSettings', 'MappingConfigGeneratedFile'); $jsonString = file_get_contents($jsonFile); $mapGenerated = json_decode($jsonString, true); //Get fixed mapping config file $jsonFile = $extDir . $importINI->variable('XMLImportSettings', 'MappingConfigFixedFile'); $jsonString = file_get_contents($jsonFile); $mapFixed = json_decode($jsonString, true); //Merge both file self::$mapping = $mapGenerated + $mapFixed; }
/** * @param XMLField[]|XMLField $xmlField * @return mixed */ public function getFieldContent($xmlField) { $rootImport = $this->importINI->variable( 'XMLImportSettings', 'RootImport' ); if (is_array($xmlField)) { /* @type $xmlField XMLField[] */ $mapping = XMLImportMapping::getByFieldName($xmlField[0]->getParentType(), $xmlField[0]->internalFieldName); } elseif (is_null($xmlField->fieldNode)) return false; else $mapping = XMLImportMapping::getByFieldName($xmlField->getParentType(), $xmlField->internalFieldName); /* @type $xmlField XMLField */ switch ($mapping['type']) { case 'text': { /* @type $xmlField XMLField */ $fieldContent = strip_tags(trim($xmlField->fieldNode->nodeValue)); $returnContent = $fieldContent; } break; case 'image': case 'video': case 'pdf': case 'audio': case 'contact': case 'file': case 'media_content': case 'html_media': { if (!is_array($xmlField)) { try { $xmlFieldBuilder = new XMLFieldBuilder($this->xmlParser, $this->importINI, $xmlField->fieldNode); $xmlFieldMixer = new self($xmlFieldBuilder, $this->xmlParser, $this->importINI, $this->publisherInfos, $this->rootImportFolder); $fieldContent = $xmlFieldMixer->process($mapping['type']); if ( !isset($fieldContent['language']) ) { $emulatedXMLField = new stdClass(); $emulatedXMLField->calculatedValue = $this->publisherInfos['default_language']; $emulatedXMLField->internalFieldName = 'language'; $fieldContent['language'] = $emulatedXMLField; $illustrativeMediaFields = XMLImportMapping::getByFieldName('illustrative_media', $xmlField->internalFieldName); if ( $illustrativeMediaFields === false && $this->publisherInfos['default_language_medias'] == 0 ) XMLImportMonitor::log($xmlField->internalFieldName . ' : The Field\'s language has been defaulted to ' . $this->publisherInfos['default_language'] . ', publisher settings says it shouldn\'t have.', 'warning'); } $returnContent = $fieldContent; } catch (MandatoryException $e) { XMLImportMonitor::log($xmlField->internalFieldName . ' : ' . $e->getMessage(), 'warning'); } } else { $returnContent = false; /* @type $xmlField XMLField[] */ foreach ($xmlField as $index => $field) { if (is_null($field->fieldNode)) continue; try { $xmlFieldBuilder = new XMLFieldBuilder($this->xmlParser, $this->importINI, $field->fieldNode); $xmlFieldMixer = new self($xmlFieldBuilder, $this->xmlParser, $this->importINI, $this->publisherInfos, $this->rootImportFolder); $fieldContent = $xmlFieldMixer->process($mapping['type']); if (is_array($fieldContent) && count($fieldContent) > 0) { if ( !isset($fieldContent['language']) ) { $emulatedXMLField = new stdClass(); $emulatedXMLField->calculatedValue = $this->publisherInfos['default_language']; $emulatedXMLField->internalFieldName = 'language'; $fieldContent['language'] = $emulatedXMLField; $illustrativeMediaFields = XMLImportMapping::getByFieldName('illustrative_media', $field->internalFieldName); if ( $illustrativeMediaFields === false && $this->publisherInfos['default_language_medias'] == 0 ) XMLImportMonitor::log($field->internalFieldName . ' : The Field\'s language has been defaulted to ' . $this->publisherInfos['default_language'] . ', publisher settings says it shouldn\'t have.', 'warning'); } $field->calculatedValue = $fieldContent; $returnContent = true; } else unset($xmlField[$index]); $this->blobedFiles = array_merge($this->blobedFiles, $xmlFieldMixer->blobedFiles); } catch (MandatoryException $e) { XMLImportMonitor::log($field->internalFieldName . ':' . $e->getMessage(), 'warning'); unset($xmlField[$index]); } } } } break; case 'richtext': { $fieldContent = str_replace(array( "\n\r", "\n", "\r" ), array( ' ', ' ', ' ' ), trim($xmlField->fieldNode->nodeValue) ); $returnContent = $fieldContent; } break; case 'taxonomy': { $fieldContent = str_replace( ' ', '', trim($xmlField->fieldNode->nodeValue) ); $contentArray = explode('|', $fieldContent); if ($contentArray !== false && $contentArray != "") { $mmDB = MMDB::instance(); foreach ($contentArray as $key => $value) { $value = trim($value); if ($value != "") { //Check if key exists in table 'taxonomy' $result = $mmDB->arrayQuery('SELECT 1 FROM mm_taxonomy WHERE code = "' . $contentArray[$key] . '"'); if (empty($result)) { XMLImportMonitor::log('The taxonomy {' . $contentArray[$key] . '} in field {' . $xmlField->fieldName . '} doesn\'t exists', 'notice'); unset($contentArray[$key]); } else $contentArray[$key] = $value; } else unset($contentArray[$key]); } if (count($contentArray)) { $returnContent = array_unique($contentArray); } } } break; case 'integer': { $fieldContent = filter_var(trim($xmlField->fieldNode->nodeValue), FILTER_VALIDATE_INT); if ($fieldContent !== false) $returnContent = $fieldContent; } break; case 'date': { $fieldContent = trim($xmlField->fieldNode->nodeValue); $datePattern = "/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2}) (?P<hour>\d{2}):(?P<minute>\d{2})/"; if (preg_match($datePattern, $fieldContent, $m)) $returnContent = "{$m['year']}-{$m['month']}-{$m['day']} {$m['hour']}:{$m['minute']}:00"; } break; case 'filename': { $folderMap = array( 'image' => 'images', 'html' => 'html', 'pdf' => 'pdf', 'audio' => 'audio', 'video' => 'videos', 'link' => 'link', 'file' => 'file', 'html_media' => 'html' ); if ( trim($xmlField->fieldNode->nodeValue) != "" ) { $fieldContent = trim($xmlField->fieldNode->nodeValue); if (isset($folderMap[$xmlField->getParentType()])) $folder = $folderMap[$xmlField->getParentType()]; else break; $filepathFromRootImport = "{$this->rootImportFolder}/{$this->publisherInfos['path']}/$folder/$fieldContent"; if ( file_exists( "$rootImport/$filepathFromRootImport" ) || file_exists ( "$rootImport/{$this->rootImportFolder}/{$this->publisherInfos['path']}/archived/$folder/$fieldContent" ) ) { if ($mapping['specialProcess'] == 'storeBlob') $returnContent = "$rootImport/$filepathFromRootImport"; else $returnContent = $filepathFromRootImport; } else $fieldContent = "{$this->rootImportFolder}/{$this->publisherInfos['path']}/$folder/$fieldContent"; } } break; case 'wxh': { $fieldContent = trim($xmlField->fieldNode->nodeValue); if (preg_match("/(\d+)\s*[xX\s]\s*(\d+)/", $fieldContent, $match)) $returnContent = "{$match[1]}x{$match[2]}"; } break; case 'email': { $fieldContent = filter_var(trim($xmlField->fieldNode->nodeValue), FILTER_VALIDATE_EMAIL); if ($fieldContent !== false) $returnContent = $fieldContent; } break; case 'media_type': { /* @type $availableRelatedContent array */ $fieldContent = strtolower(trim($xmlField->fieldNode->nodeValue)); $availableRelatedContent = $this->importINI->variable('XMLImportSettings', 'AvailableRelatedContent'); if (in_array($fieldContent, $availableRelatedContent)) $returnContent = $fieldContent; } break; case 'enum': { $fieldContent = strtolower(trim($xmlField->fieldNode->nodeValue)); $enumMapping = XMLImportMapping::getByFieldName('enum_values', $xmlField->internalFieldName); if ( $enumMapping !== false && in_array($fieldContent, $enumMapping) ) $returnContent = $fieldContent; } break; case 'boolean': { $fieldContent = filter_var(trim($xmlField->fieldNode->nodeValue), FILTER_VALIDATE_BOOLEAN); $returnContent = ($fieldContent === false) ? 0 : 1; } break; case 'reference_article_id': { $fieldContent = trim($xmlField->fieldNode->nodeValue); $returnContent = $fieldContent; } break; default: { XMLImportMonitor::log('The field {' . $xmlField->fieldName . '} has an unknown type : {' . $mapping['type'] . '}', 'error'); return false; } } if (!isset($returnContent)) { if (!empty($fieldContent) && (is_string($fieldContent) || is_numeric($fieldContent))) { $reportValue = $fieldContent; XMLImportMonitor::log('The field {' . $xmlField->fieldName . '} of type {' . $mapping['type'] . '} has an incorrect value : {' . $reportValue . '}', 'warning'); } return false; } if (!is_array($xmlField)) $xmlField->calculatedValue = $returnContent; return $returnContent; }
/** * Main method to process current row returned by getNextRow() method. * You may throw an exception if something goes wrong. It will be logged but won't break the import process * @param array $row Depending on your data format, can be DOMNode, SimpleXMLIterator, SimpleXMLElement, CSV row... * @throws Exception * @return void */ public function process( $row ) { $rootImport = $this->importINI->variable( 'XMLImportSettings', 'RootImport' ); $publisherInfos = $this->fileHandler->getPublisherInfosFromFolderName( $row['publisher'] ); if ( empty( $publisherInfos['default_language'] ) ) { $publisherInfos['default_language'] = 'eng-GB'; } $filePath = eZSys::rootDir() . "/$rootImport/{$this->fileHandler->rootImportFolder}/{$publisherInfos['path']}/{$row['file']}"; XMLImportMonitor::initFile( $row['file'], $publisherInfos['path'], $publisherInfos['id'], md5_file($filePath) ); try { if ( empty( $row['file'] ) || empty( $publisherInfos['path'] ) ) return; try { $xmlOptions = new SQLIXMLOptions( array( 'xml_path' => $filePath, 'xml_parser' => 'dom' ) ); $sqliXmlParser = new SQLIXMLParser( $xmlOptions ); $this->xmlParser = $sqliXmlParser->parse(); } catch ( SQLIXMLException $e ) { $this->triggerException( $row['file'], $publisherInfos['path'], $e, 4 ); } $xslProcess = XMLImportMapping::getByFieldName('xsl_process', $publisherInfos['path']); if ( $xslProcess !== false ) { if ( !isset($this->xmlTransformers[$publisherInfos['path']]) ) { try { $xslFolder = $this->importINI->variable('XMLImportSettings', 'XSLTFolder'); $xmslOptions = new SQLIXMLOptions( array( 'xml_path' => eZSys::rootDir() . '/extension/' . $xslFolder . '/' . $xslProcess, 'xml_parser' => 'dom' ) ); $sqliXmlTransformer = new SQLIXMLParser( $xmslOptions ); $path = $publisherInfos['path']; $this->xmlTransformers[$path] = $sqliXmlTransformer->parse(); } catch ( SQLIXMLException $e ) { $this->triggerException( $row['file'], $publisherInfos['path'], $e, 4 ); } } // Configure the transformer $proc = new XSLTProcessor; $proc->importStyleSheet($this->xmlTransformers[$publisherInfos['path']]); $this->xmlParser = $proc->transformToDoc($this->xmlParser); } try { $xmlFieldBuilder = new XMLFieldBuilder( $this->xmlParser, $this->importINI ); } catch ( RootNodeException $e ) { $this->triggerException( $row['file'], $publisherInfos['path'], $e, 4 ); } try { $xmlFieldMixer = new XMLFieldMixer( $xmlFieldBuilder, $this->xmlParser, $this->importINI, $publisherInfos, $this->rootImportFolder ); $fieldArray = $xmlFieldMixer->process(); } catch ( MandatoryException $e ) { $this->triggerException( $row['file'], $publisherInfos['path'], $e, 3 ); } try { XMLImportDataHandler::updateMdd( $fieldArray ); } catch ( XMLImportDBException $e ) { XMLImportDB::rollbackQuery(); $e = new Exception( $e->getMessage() . "\n" . 'SQL action failed - Transaction will be rollbacked - Error Message : ' . XMLImportDB::getErrorMessage() ); $this->triggerException( $row['file'], $publisherInfos['path'], $e, 5 ); } //Archive XML and blobed files $this->fileHandler->archiveFiles( $publisherInfos['path'], $row['file'], $xmlFieldMixer->blobedFiles ); } catch ( Exception $e ) { XMLImportMonitor::commitFile(); throw $e; } $this->fileHandler->dataSourcesCompleted++; XMLImportMonitor::commitFile(); }
/** * @param array $fieldArray * @param string $type * @return string */ public static function getAdjustedType( $fieldArray, $type ) { /* @type $availableRelatedContent array */ $availableRelatedContent = self::$importINI->variable( 'XMLImportSettings', 'AvailableRelatedContent' ); if ( $type == 'article' ) $realType = $type; elseif ( $type == 'media_content' ) { $mediaTypeField = is_array($fieldArray['media_type'])?$fieldArray['media_type'][0]:$fieldArray['media_type']; if ( $mediaTypeField ) $realType = $mediaTypeField->fieldNode->nodeValue; else { $fieldMapping = XMLImportMapping::getByFieldName( $type, 'media_type' ); $realType = $fieldMapping['default']; } } elseif ( in_array( $type, $availableRelatedContent ) ) $realType = $type; else $realType = false; return $realType; }