src/Resources/contao/classes/Backup.php
/**
	 * This function takes one item from table 'tl_isobackup' which has the status 'prepared'
	 * i.e. its XML-data was already parsed but not compared against the content of Contao's database.
	 *
	 * - The found item is put into status 'analysing'.
	 * - The function looks for a corresponding product in table 'tl_iso_product' and memorises its ID
	 *   in the item's field 'isotope_id'. If no product can be found the action 'import-everything'
	 *   is saved for the item.
	 * - The item is analysed; all found differences to the product will be arranged
	 *   in two arrays 'supported' and 'unsupported' and then stored in the item's field 'actions'.
	 * - At the end the item's status becomes 'analysed'.
	 *
	 * The 'supported' differences contain SQL-statements and text-information describing the needed
	 * changes to Contao's database,
	 *      e.g.  'group' => 'name',
	 *              'sql' => ['UPDATE ... WHERE id = ?', ..., 16],
	 *             'text' => ['Change the %s of the product ...', 'name', ...]
	 *
	 * The 'unsupported' actions contain raw-data about the differences between the imported item
	 * and Contao's data,
	 *      e.g.  'type' => 'update',
	 *             'key' => 'group',
	 *            'path' => ['main'],
	 *             'old' => 'Geldwechsler',
	 *             'new' => 'Geld-Wechsler',
	 *     'contao-data' => ['id' => '16', ...]
	 *
	 * When unexpected problems occur, the function may throw an Error.
	 * In case of recognisable problems those will be stored with $this->analysisAddError().
	 *
	 * @return
	 *		The return value represents the rate of already analysed items as a float-value between 0 and 1,
	 *			e.g. if there are 100 items in total and 65 were already analysed the function will return 0.65
	 *			i.e. the return-value will be 1 iff no more items need to be analysed.
	 */
This function takes one item from table 'tl_isobackup' which has the status 'prepared'
i.e. its XML-data was already parsed but not compared against the content of Contao's database.

- The found item is put into status 'analysing'.

The 'supported' differences contain SQL-statements and text-information describing the needed
changes to Contao's database,
e.g.

The 'unsupported' actions contain raw-data about the differences between the imported item
and Contao's data,
e.g.

When unexpected problems occur, the function may throw an Error.
In case of recognisable problems those will be stored with $this->analysisAddError().

@return
The return value represents the rate of already analysed items as a float-value between 0 and 1,
e.g. if there are 100 items in total and 65 were already analysed the function will return 0.65
i.e. the return-value will be 1 iff no more items need to be analysed.
This function takes one item from table ' tl_isobackup ' which has the status ' prepared ' i . e . its XML - data was already parsed but not compared against the content of Contao ' s database . - The found item is put into status ' analysing ' . The ' supported ' differences contain SQL - statements and text - information describing the needed changes to Contao ' s database e . g . The ' unsupported ' actions contain raw - data about the differences between the imported item and Contao ' s data e . g . When unexpected problems occur the function may throw an Error . In case of recognisable problems those will be stored with $this - > analysisAddError () . @return The return value represents the rate of already analysed items as a float - value between 0 and 1 e . g . if there are 100 items in total and 65 were already analysed the function will return 0 . 65 i . e . the return - value will be 1 iff no more items need to be analysed .
protected function importAnalyseNextItem() {
		$item_count = $this->importCountItems('prepared', 'analysed');
		if (array_search('analysing', $item_count['other_states']) !== false) {
			throw new \Error('Unexpected import-item with state \'analysing\' found.');
		}
		if ($item_count['progress'] == 1) {
			return 1;
		}
		$item = $this->Database->execute('SELECT id, import_id, data FROM tl_isobackup WHERE status = "prepared" AND import_id IS NOT NULL LIMIT 1')->first();
		if (!$item) {
			throw new \Error('Failed to grab waiting import-item out of database.');
		}
		if (!$item->data) {
			$this->analysisAddError('empty-import-data', null, $item->id);
			return $item_count['progress_next'];
		}
		if (!$this->Database->prepare('UPDATE tl_isobackup SET status = "analysing" WHERE id = ?')->execute($item->id)) {
			throw new \Error('Failed to update status of current import-item.');
		}
		$id = explode(':', $item->import_id, 2);
		if (!is_array($id) || count($id) != 2 || $id[0] == '' || $id[1] == '') {
			$this->analysisAddError('invalid-import-id', null, $item->id);
			return $item_count['progress_next'];
		}
		switch ($id[0]) {
			case 'alias':
			case 'sku':
			case 'name':
				$isotope = $this->Database->prepare("SELECT id FROM tl_iso_product WHERE NOT pid > 0 AND {$id[0]} = ?")->execute($id[1])->first();
				break;
			default:
				$this->analysisAddError('invalid-import-id', null, $item->id);
				return $item_count['progress_next'];
		}
		if (!$isotope) {
			if (
				!$this->Database
					->prepare('UPDATE tl_isobackup SET actions = ?, status = "analysed" WHERE id = ?')
					->execute(json_encode(['import-everything']), $item->id)
			) {
				throw new \Error('Failed to save needed actions with current import-item.');
			}
			return $item_count['progress_next'];
		}
		else if ($isotope->count() != 1) {
			$this->analysisAddError('too-many-product-matches', null, $item->id);
			if (!$this->Database->prepare('UPDATE tl_isobackup SET status = "failed" WHERE id = ?')->execute($item->id)) {
				throw new \Error('Problems setting current import-item into state "failed".');
			}
			return $item_count['progress_next'];
		}
		if (
			!$this->Database
				->prepare('UPDATE tl_isobackup SET isotope_id = ? WHERE id = ?')
				->execute($isotope->id, $item->id)
		) {
			$this->Database->prepare('UPDATE tl_isobackup SET status = "failed" WHERE id = ?')->execute($item->id);
			throw new \Error('Failed to save found Isotope-id with current import-item.');
		}
		$this->importCollectActions(
			json_decode($item->data, true),
			$this->collectCompleteProductData($isotope->id, true)
		);
		$this->importParseActions();
		if (
			!$this->Database
				->prepare('UPDATE tl_isobackup SET actions = ?, status = "analysed" WHERE id = ?')
				->execute((is_array($this->importActions) && count($this->importActions)) ? json_encode($this->importActions) : null, $item->id)
		) {
			throw new \Error('Failed to update current import-item.');
		}
		return $item_count['progress_next'];
	}
protected function importAnalyseNextItem ( ) { $ item_count = $ this -> importCountItems ( 'prepared' , 'analysed' ) ; if ( array_search ( 'analysing' , $ item_count [ 'other_states' ] ) !== false ) { throw new \ Error ( 'Unexpected import-item with state \'analysing\' found.' ) ; } if ( $ item_count [ 'progress' ] == 1 ) { return 1 ; } $ item = $ this -> Database -> execute ( 'SELECT id, import_id, data FROM tl_isobackup WHERE status = "prepared" AND import_id IS NOT NULL LIMIT 1' ) -> first ( ) ; if ( ! $ item ) { throw new \ Error ( 'Failed to grab waiting import-item out of database.' ) ; } if ( ! $ item -> data ) { $ this -> analysisAddError ( 'empty-import-data' , null , $ item -> id ) ; return $ item_count [ 'progress_next' ] ; } if ( ! $ this -> Database -> prepare ( 'UPDATE tl_isobackup SET status = "analysing" WHERE id = ?' ) -> execute ( $ item -> id ) ) { throw new \ Error ( 'Failed to update status of current import-item.' ) ; } $ id = explode ( ':' , $ item -> import_id , 2 ) ; if ( ! is_array ( $ id ) || count ( $ id ) != 2 || $ id [ 0 ] == '' || $ id [ 1 ] == '' ) { $ this -> analysisAddError ( 'invalid-import-id' , null , $ item -> id ) ; return $ item_count [ 'progress_next' ] ; } switch ( $ id [ 0 ] ) { case 'alias' : case 'sku' : case 'name' : $ isotope = $ this -> Database -> prepare ( " SELECT id FROM tl_iso_product WHERE NOT pid > 0 AND  { $ id [ 0 ] }  = ? " ) -> execute ( $ id [ 1 ] ) -> first ( ) ; break ; default : $ this -> analysisAddError ( 'invalid-import-id' , null , $ item -> id ) ; return $ item_count [ 'progress_next' ] ; } if ( ! $ isotope ) { if ( ! $ this -> Database -> prepare ( 'UPDATE tl_isobackup SET actions = ?, status = "analysed" WHERE id = ?' ) -> execute ( json_encode ( [ 'import-everything' ] ) , $ item -> id ) ) { throw new \ Error ( 'Failed to save needed actions with current import-item.' ) ; } return $ item_count [ 'progress_next' ] ; } else if ( $ isotope -> count ( ) != 1 ) { $ this -> analysisAddError ( 'too-many-product-matches' , null , $ item -> id ) ; if ( ! $ this -> Database -> prepare ( 'UPDATE tl_isobackup SET status = "failed" WHERE id = ?' ) -> execute ( $ item -> id ) ) { throw new \ Error ( 'Problems setting current import-item into state "failed".' ) ; } return $ item_count [ 'progress_next' ] ; } if ( ! $ this -> Database -> prepare ( 'UPDATE tl_isobackup SET isotope_id = ? WHERE id = ?' ) -> execute ( $ isotope -> id , $ item -> id ) ) { $ this -> Database -> prepare ( 'UPDATE tl_isobackup SET status = "failed" WHERE id = ?' ) -> execute ( $ item -> id ) ; throw new \ Error ( 'Failed to save found Isotope-id with current import-item.' ) ; } $ this -> importCollectActions ( json_decode ( $ item -> data , true ) , $ this -> collectCompleteProductData ( $ isotope -> id , true ) ) ; $ this -> importParseActions ( ) ; if ( ! $ this -> Database -> prepare ( 'UPDATE tl_isobackup SET actions = ?, status = "analysed" WHERE id = ?' ) -> execute ( ( is_array ( $ this -> importActions ) && count ( $ this -> importActions ) ) ? json_encode ( $ this -> importActions ) : null , $ item -> id ) ) { throw new \ Error ( 'Failed to update current import-item.' ) ; } return $ item_count [ 'progress_next' ] ; }
This function takes one item from table 'tl_isobackup' which has the status 'prepared'
 i.e.
This function takes one item from table ' tl_isobackup ' which has the status ' prepared ' i . e .
// Get next import-item and its prepared data: // Set the item's status to 'analysing': // Look for matching Isotope-product: // Compare import-data with product-data: // Update import-item: