Giter VIP home page Giter VIP logo

magento1-ho_import's Introduction

H&O Importer

A Magento module and extension of the AvS_FastSimpleImport module which allows you to map fields and import all sorts of file formats, data sources and data entities.

The module consists of various downloaders (http), source adapters (csv, spreadsheets, database or xml) and supports all entities that AvS_FastSimpleImport supports (products, categories, customers) and last but not least allows you to field map all fields in from each format to the magento format.

All this configuration can be done using XML. You add the config to a config.xml and you can run the profile. The idea is that you set all the configuration in the XML and that you or the cron will run it with the perfect options.

Since the original target for the module was an import that could process thousands of products it is build with this in mind. It is able to process large CSV or XML files while using very little memory (think a few MB memory increase for processing a 1GB CSV file). See Use cases

We have chosen to do all configuration in XML, this makes the import profile way more maintainable, especially important when doing multiple imports for a single project.

To increase development and debugging speed there is a extensive shell tool that allows you to easily create new fieldmaps, add a downloader and start working.

Terminal Preview Terminal Preview

Example config for a customer import (this is added to the <config><global><ho_import> node:

<my_customer_import>
    <entity_type>customer</entity_type>
    <downloader model="ho_import/downloader_http">
        <url>http://google.nl/file.xml</url>
    </downloader>
    <decompressor model="ho_import/decompressor_zip">
        <source>var/import/Archief.zip</source>
        <target>var/import/extracted</target>
    </decompressor>
    <source model="ho_import/source_adapter_xml">
        <file>var/import/Klant.xml</file>
        <!--<rootNode>FMPDSORESULT</rootNode>-->
    </source>
    <import_options>
        <!--<continue_after_errors>1</continue_after_errors>-->
        <!--<ignore_duplicates>1</ignore_duplicates>-->
    </import_options>
    <events>
        <!--<source_row_fieldmap_before helper="ho_importinktweb/product::prepareRowCategory"/>-->
        <!--<import_before/>-->
        <!--<import_after/>-->
    </events>
    <fieldmap>
        <email field="Email"/>
        <_website helper="ho_import/import::getAllWebsites"/>
        <group_id helper="ho_import/import::getFieldMap">
            <field field="Status"/>
            <mapping>
                <particulier from="Particulier" to="1"/>
                <zakelijk from="Zakelijk" to="2"/>
            </mapping>
        </group_id>
        <prefix field="Voorletters"/>
        <firstname field="Voornaam" defaultvalue="ONBEKEND"/>
        <middlename field="Tussenvoegsel" />
        <lastname field="Achternaam" required="1"/>
        <company field="Bedrijfsnaam"/>
        <created_in value="old shop name"/>
        <taxvat field="BTWnummer" />
        <password field="cWachtWoord" />
        <gender helper="ho_import/import::getFieldMap">
            <field field="Geslacht"/>
            <mapping>
                <male from="M" to="male"/>
                <female from="V" to="female"/>
                <male_female from="M+V" to="male+female"/>
            </mapping>
        </gender>
    </fieldmap>
</my_customer_import>

Installation

You can install the module via modman:

modman clone [email protected]:ho-nl/magento1-Ho_Import.git

Or you can download the latest release it and place it in you Magento root.

Getting started

1. Create a module

The idea is that you create a very light weight module for each project or import. This module has all the config for that specific import.

_Need help creating an empty module for your installation, use a module creator.

Example config (More import examples)

<config>
	<modules>
		<Ho_ImportJanselijn>
			<version>0.1.0</version>
		</Ho_ImportJanselijn>
	</modules>
	<global>
		<helpers>
            <ho_importjanselijn>
                <class>Ho_ImportJanselijn_Helper</class>
            </ho_importjanselijn>
        </helpers>

        <!-- ... -->

        <ho_import>
            <profile_name>
				<entity_type>customer</entity_type>
				<!-- ... the rest of the config -->
            </profile_name>
        </ho_import>
    </global>
</config>

2. Add the default config

This section assumes that you place these config values in <config><global><ho_import><my_import_name>

Add something like the following to your profile (see chapters below for detailed configuration):

<entity_type>customer</entity_type>
<downloader model="ho_import/downloader_http">
    <url>http://google.nl/file.xml</url>
</downloader>
<source model="ho_import/source_adapter_xml">
    <file>var/import/Klant.xml</file>
    <!--<rootNode>FMPDSORESULT</rootNode>-->
</source>
<import_options>
    <!--<continue_after_errors>1</continue_after_errors>-->
    <!--<ignore_duplicates>1</ignore_duplicates>-->
    <partial_indexing>1</partial_indexing>
</import_options>
<!--<memory_limit>4096M</memory_limit> Optional, default is 2048M--> 

3. Run the line shell utility

Make sure you have cache disabled, because all XML is cached in Magento

php hoimport.php -action line -profile profile_name

You'll see something like: Terminal Preview

The first table shows the first line from the source file and the second table shows the results how they would be imported into Magento. It shows the error on each line where they are represented.

Note that it is not safe to run multiple imports simulteneously. When manually running an import via the command shell, ensure that there is no other import running via (for example) a cron job.

4. Expand all the fieldmaps to your liking

Grab an example that is most to your liking from the docs/imports folder and copy those fields to your config.

Now continue to map all your fields until you are satisfied.

5. Run the actual import

You can now import the complete set.

php hoimport.php -action import -profile profile_name -dryrun 1

To just test if the import would run, add -dryrun 1 to the command

You will probably run into errors the first try. When the importer runs into errors it will return the faulty row. It will return the row that is imported (unfortunately it won't return the source row since that row isn't know at this point of the import).

If a specific sku, for example, is giving you trouble, you can run the line utility and do a search.

php hoimport.php -action line -profile profile_name -search sku=abd

6. Schedule an import (cronjob)

If you are satisfied with the import you can add a schedule to it, this will add it to the cron scheduler and run it at your configured time:

Terminal Preview

As you can see, we have a ho_import_schedule cron which add the imports to the the cron and cleans up the cron if imports are removed/renamed. To speed up this process, you can run it manually.

Config documentation

This section assumes that you place these config values in <config><global><ho_import><my_import_name>

Supported Entity Types

All the entities of the AvS_FastSimpleImport are supported:

  • catalog_product
  • customer
  • catalog_category
  • catalog_category_product

Example Config:

<entity_type>customer</entity_type>

Cron schedule

Use the same formatting as the default cron setup.

Using a cron expression:

<schedule><cron_expr>0 2 * * *</cron_expr></schedule>

Using a config path:

<schedule><config_path>configuration/path/cron_expr</config_path></schedule>

Import Options

All the options that are possible with the AvS_FastSimpleImport are possible here as well:

<import_options>
    <skip_download>1</skip_download>
    <lock_attributes>1</lock_attributes>
    <archive_import_files>1</archive_import_files> <!-- archive files for later reference -->

    <!-- below are AvS_FastSimpleImport options. See http://avstudnitz.github.io/AvS_FastSimpleImport/options.html for more information and extra options. -->
	<error_limit>10000</error_limit>
    <continue_after_errors>1</continue_after_errors>
    <ignore_duplicates>1</ignore_duplicates>
    <allow_rename_files>0</allow_rename_files>
    <partial_indexing>1</partial_indexing>
    <dropdown_attributes>
        <country>country</country>
    </dropdown_attributes>
    <multiselect_attributes>
        <show_in_collection>show_in_collection</show_in_collection>
        <condition>condition</condition>
        <condition_label>condition_label</condition_label>
    </multiselect_attributes>
</import_options>

Lock product/category attributes in backend

When you enable this option, a store admin can't edit the attributes that are imported by the importer. Ho_Import is smart about this, it save the profile name with the product/category, so it only locks the attributes which are set by the current importer. It also knows about store view specific values imported.

Exampe config:

<import_options>
    <lock_attributes>1</lock_attributes>
</import_options>

When importing the name of a product it shows the attribute is locked Lock Attributes

If you switch to a store view you can override the field: Lock Attributes

Archive import files

After starting a new import the old import file gets renamed so it wont get deleted, easy for later referencing and debugging.

<import_options>
    <archive_import_files>1</archive_import_files>
</import_options>

Clean entities that are not in the source

Be able to automatically delete, hide or disable products and categories after importing. When enabled, if a product or category isn't in the source anymore it gets automatically deleted. Ho_Import tracks the entities from which profile they came from:

Profile information

If a product for example isn't in the source any more AND it is the only associated profile with the entity it can be cleaned up.

<clean>
    <mode>hide</mode> <!-- options are delete, hide, disable -->
</clean>

Multiple imports for the same product

If you have multiple imports for the same product (product information and stock information for example), you have to define the profile associated with the product manually.

In your <fieldmap> node, add the following:

<ho_import_profile value="profile_one,profile_two"/>

If you have only one profile with lock_attributes enabled, this field gets filled automatically.

Downloaders

The supported downloaders are HTTP and FTP.

HTTP Example (Low Memory)

<downloader model="ho_import/downloader_http">
    <url>http://google.nl/file.xml</url>

    <!-- the downloader defaults to var/import -->
    <!--<target>custom/download/path/filename.xml</target>-->
</downloader>

FTP Example (Low Memory)

<downloader model="ho_import/downloader_ftp">
    <host>ftp.website.com</host>
    <port>2121</port> <!-- Optional: Default setting is 21 -->
    <username>userr</username>
    <password>supersecurepassword</password>
    <file>httpdocs/file.xml</file> <!-- Relative path on the server, relative from the login -->
    <target>var/import/file.xml</target> <!-- Path relative from the Magento root -->
    <timeout>10</timeout> <!-- Optional: How long should we wait to connect -->
    <passive>0</passive> <!-- Optional: FTP transfer mode, by default it is set to passive, usually correct -->
    <ssl>1</ssl> <!-- Optional: For FTP with implicit SSL, this is NOT SFTP, which is FTP over SSH -->
    <file_mode>1</file_mode><!-- Optional: For FTP_ASCII or FTP_TEXT set value to 1, for FTP_BINARY or FTP_IMAGE leave empty. -->
</downloader>

Temporarily disable a download:

<import_options>
	<skip_download>1</skip_download>
</import_options>

Decompressors

Decompress a file that has just been downloaded.

Zip Example (Low Memory)

<decompressor model="ho_import/decompressor_zip">
    <source>var/import/Archief.zip</source>
    <target>var/import/extracted</target> <!-- this is a folder, files inside the archive will be placed here -->
</decompressor>

Sources

A source is a source reader. The source allows us to read data from a certain source. This could be a file or it even could be a database.

CSV Source (Low Memory)

The CSV source is an implementation of PHP's fgetcsv

<source model="ho_import/source_adapter_csv">
    <file>var/import/customer.csv</file>

    <!-- the delimmiter and enclosure aren't required -->
    <delimiter>;</delimiter>
    <enclosure></enclosure>
    
    <!-- if the CSV has no header information, you can specify the column names -->
    <columns>
    	<sku/>
    	<other_columns/>
    </columns>
</source>

XML Source (Low Memory)

The XML source is loosely based on XmlStreamer.

<source model="ho_import/source_adapter_xml">
    <file>var/import/products.xml</file>

    <!-- If there is only one type of entity in the XML the custom rootNode isn't required. -->
    <rootNode>customRootNode</rootNode>

    <!-- You have the ability to define a custom childNode if the childNode isn't the direct ascendent of the rootNode -->
	<childNode>customChildNode</childNode>
</source>

Note: It isn't tested if the childNode/rootNode is way down the document. The code is in place, but isn't tested. If you get the chance to test this please create an issue and let us know what you found.

Example:

If you have the following XML file and you want to retrieve all the <ARTICLE> nodes:

<?xml version="1.0" encoding="utf-8"?>
<ARTICLES>
	<BODY>
		<COMPANY-NR>
			<COMPANY>10</COMPANY>
			<SHOP>
				<SHOPNR>2</SHOPNR>
				<ARTICLE>
					<!-- ... -->
				</ARTICLE>
				<ARTICLE>
                    <!-- ... -->
                </ARTICLE>
			</SHOP>
		</COMPANY-NR>
		<COMPANY-NR>
			<COMPANY>10</COMPANY>
            <SHOP>
                <SHOPNR>3</SHOPNR>
                <ARTICLE>
                    <!-- ... -->
                </ARTICLE>
            </SHOP>
		</COMPANY-NR>
	</BODY>
</ARTICLES>

This would result in the following configuration:

<source model="ho_import/source_adapter_xml">
    <file>path/to/you/file.xml</file>
    <rootNode>BODY</rootNode>
	<rootNode>ARTICLE</rootNode>
</source>

Spreadsheet Source (Low Memory)

The Spreadsheet Source is an implementation of spreadsheet-reader and therefor supports

So far XLSX, ODS and text/CSV file parsing should be memory-efficient. XLS file parsing is done with php-excel-reader from http://code.google.com/p/php-excel-reader/ which, sadly, has memory issues with bigger spreadsheets, as it reads the data all at once and keeps it all in memory.

<source model="ho_import/source_adapter_spreadsheet">
    <file>var/import/products.xml</file>

    <!-- If the first line has headers you can use that one, else the columns will only be numbered -->
    <!-- <has_headers>1</has_headers> -->
</source>

Database Source

The Database source is an implementation of Zend_Db_Table_Rowset and allows all implentation of Zend_Db_Adapter_Abstract as a source. It supports MSSQL, MySQL, PostgreSQL, SQLite and many others. For all possible supported databases take a look in /lib/Zend/Db/Adapter.

The current implementation isn't low memory because it executes the query and loads everything in memory.

<source model="ho_import/source_adapter_db">
    <host><![CDATA[hostname]]></host>
    <username><![CDATA[username]]></username>
    <password><![CDATA[password]]></password>
    <dbname><![CDATA[database]]></dbname>
    <model><![CDATA[Zend_Db_Adapter_Pdo_YourFavoriteDatabase]]></model>
    <pdoType>dblib</pdoType>
    <query><![CDATA[SELECT * FROM Customer]]></query>
    <!--<limit>10</limit>-->
    <!--<offset>10</offset>-->
</source>

If your PDO driver doesn't support pdoType then simply remove that node. If you wish to pass more config parameters to the PDO driver then add more nodes like for PGSQL: <sslmode>require</sslmode>

Events

All events work with a transport object which holds the data for that line. This a Varien_Object with the information set.

<events>
	<process_before helper="ho_import/import_product::prepareSomeData"/>
	<import_before helper="ho_import/import_product::callWifeIfItIsOk"/>
	<source_row_fieldmap_before helper="ho_import/import_product::checkIfValid"/>
	<source_row_fieldmap_after helper="ho_import/import_product::extractData"/>
	<source_fieldmap_after helper="ho_import/import_product::appendExtraData"/>
	<import_after helper="ho_import/import_product::reindexStuff"/>
	<process_after helper="ho_import/import_product::cleanupSomeData"/>
</events>

Event: import_before

  • object: instance of AvS_FastSimpleImport_Model_Import

Event: source_row_fieldmap_before

It has one field items set. This can be replaced, extended etc. to manipulate the data. Optionally you can set the key skip to 1 to skip this source row all together.

Event: import_after

  • object: instance of AvS_FastSimpleImport_Model_Import
  • errors: array of errors

Fieldmap

This is where the magic of the module happens. Map a random source formatting to the Magento format.

The idea is that you specify the Magento format here and load the right values for each Magento field, manipulate the data, etc. There is a syntax to handle the most easy cases and have the ability to call an helper if that isn't enough.

Reusing fieldmapped data.
When importing mutations and having a complete import happens (complete runs every night for example, mutations every 15 minutes). You might want to use a different profile's fieldmapping. To do this you only need add <fieldmap use="name_of_other_profile" />.

This section assumes that you place these config values in <config><global><ho_import><my_import_name><fieldmap>

Value

<tax_class_id value="2"/>

Field

<email field="Email"/>

In multi-level files like XML you can get a deeper value with a /

<email field="Customer/Email"/>

If there are attributes available, you can reach them with @attributes.

<sku field="@attributes/RECORDID"/>

Helper

Have the ability to call a helper method that generates the value. The contents of the field are the arguments passed to the helper.

<_website helper="ho_import/import::getAllWebsites"><limit>1</limit></_website>

Calls the method in the class Ho_Import_Helper_Import with the first argument being the line and the rest of the arguments being the contents in the node, in this case the limit.

/**
 * Import the product to all websites, this will return all the websites.
 * @param array $line
 * @param $limit
 * @return array|null
 */
public function getAllWebsites($line, $limit) {
    if ($this->_websiteIds === null) {
        $this->_websiteIds = array();
        foreach (Mage::app()->getWebsites() as $website) {
            /** @var $website Mage_Core_Model_Website */

            $this->_websiteIds[] = $website->getCode();
        }
    }

    if ($limit) {
        return array_slice($this->_websiteIds, 0, $limit);
    }

    return $this->_websiteIds;
}

For more available helpers please see Integrated helper methods and Custom helper methods

Use

Sometimes you want the same value multiple times in multiple fields. This loads the config of the other fields and returns the result of that.

<image_label use="name"/>

Default value

<firstname field="First_Name" defaultvalue="UNKNOWN"/>

If field value

<company iffieldvalue="Is_Company" field="Company_Name"/>

Unless field value

The opposite of iffieldvalue

<firstname unlessfieldvalue="Is_Company" field="Customer_Name"/>

Required

Some fields are always required by the importer for each row. For example for products it is required that you have the sku field always present.

<sku field="sku" required="1"/>

Setting store view specific data

With simple additions to the config it is possible to set store view specific data. You have the exact same abilities as with normal fields, you only have to provide the <store_view> element with the fields for each storeview.

<description field="description_en">
    <store_view>
        <pb_de field="description_de"/>
        <pb_es field="description_es"/>
        <pb_fr field="description_fr"/>
        <pb_it field="description_it"/>
        <pb_nl field="description_nl"/>
    </store_view>
</description>

Integrated helper methods

There are a few helper methods already defined which allows you to do some common manipulation without having to write your own helpers

getAllWebsites

<_website helper="ho_import/import::getAllWebsites">
	<limit>1</limit> <!-- optional -->
</_website>

findReplace

<short_description helper="ho_import/import::findReplace">
	<value field="sourceField"/>
    <findReplace>
        <doubleat find="@@" replace="@"/>
        <nbsp from="&nbsp;" replace=" "/>
    </findReplace>
    <trim>1</trim> <!-- optional -->
</short_description>

parsePrice

<price helper="ho_import/import::parsePrice">
    <pricefield field="PrijsVerkoop"/>
</price>

formatField

Implementation of vsprinf

<meta_description helper="ho_import/import::formatField">
    <format>%s - For only โ‚ฌ%s at Shop.com</format>
    <fields>
        <description field="Info"/>
        <price field="PrijsVerkoop"/>
    </fields>
</meta_description>

truncate

<description helper="ho_import/import::truncate">
    <value field="Info"/>
    <length>125</length>
    <etc>โ€ฆ</etc>
</description>

stripHtmlTags

<description helper="ho_import/import::stripHtmlTags">
    <value field="A_Xtratxt"/>
    <allowed><![CDATA[<p><a><br>]]></allowed>
</description>

getHtmlComment

Get a simple HTML comment (can't be added through XML due to XML limitations).

<description helper="ho_import/import::getHtmlComment">empty</description>

getFieldBoolean

<is_in_stock helper="ho_import/import::getFieldBoolean">
	<value field="stock"/>
</is_in_stock>

getFieldMultiple

Allow you to load multiple fields. Each field has the same abilities as a normal field (allows you to call a helper, value, field, iffieldvalue, etc.

<_address_prefix helper="ho_import/import::getFieldMultiple">
    <fields>
        <billing iffieldvalue="FactAdres" field="Voorvoegsel"/>
        <shipping iffieldvalue="BezAdres" field="Voorvoegsel"/>
    </fields>
</_address_prefix>

getFieldLimit

Implements array_slice.

<image helper="ho_import/import::getFieldLimit">
    <field use="_media_image"/>
    <limit value="1"/> <!-- optional -->
    <offset value="1"/> <!-- optional -->
</image>

getFieldCombine

Get multiple fields and glue them together

<sku helper="ho_import/import::getFieldCombine">
    <fields>
        <prefix value="B"/>
        <number field="BmNummer"/>
    </fields>
    <glue>-</glue> <!-- optional, defaults to a space -->
</sku>

getFieldSplit

Split a field into multiple pieces

<_category helper="ho_import/import::getFieldSplit">
    <field field="category"/>
    <split>***</split>
</_category>

getFieldMap

<gender helper="ho_import/import::getFieldMap">
    <value field="Geslacht"/>
    <mapping>
        <male from="M" to="male"/>
        <female from="V" to="female"/>
    </mapping>
</gender>

getFieldCounter

<_media_position helper="ho_import/import::getFieldCounter">
    <countfield field="cImagePad"/>
</_media_position>

ifFieldsValue

You can normally define iffieldvalue='fieldname' to do simple value checking. Something you need to check multiple fields.

<billing_first_name helper="ho_postbeeldproduct/import_customer::ifFieldsValue">
    <fields>
        <billing_first_name field="billing_first_name"/>
        <billing_last_name field="billing_last_name"/>
        <billing_address field="billing_address"/>
        <billing_city field="billing_city"/>
        <billing_country_code field="billing_country_code"/>
    </fields>
    <billing field="billing_first_name"/>
</billing_first_name>

getMediaAttributeId (@deprecated in 1.5, use getAttributeId)

Usually used in combination with a counter to set the correct getMediaAttributeId

<_media_attribute_id helper="ho_import/import::getFieldCounter">
    <countfield field="cImagePad"/>
    <fieldvalue helper="ho_import/import::getMediaAttributeId"/>
</_media_attribute_id>

getAttributeId

Get an attribute's ID.

<field helper="ho_import/import::getAttributeId">
    <attribute value="media_gallery"/>
</field>

getMediaImage

Download the image from a remote URL and place it in the media/import folder.

<image helper="ho_import/import::getMediaImage">
    <imagefield field="cImagePad"/> <!-- URL to image -->
    <limit>1</limit>
    <filename use="sku"/> <!-- optional, when the server doesn't give back readable image names -->
    <extension value="jpg"/> <!-- optional, when the URL doesn't end in a filename -->
</image>

Download images from FTP:

ftp://username:[email protected]/path/on/ftp/image.png

timestampToDate

Parse a timestamp and output in the Magento running format, just specify in which timezone the current date is. Add an offset with one of the Relative Formats.

<news_to_date helper="ho_import/import::timestampToDate">
    <field field="entry_date"/>
    <timezoneFrom>Europe/Amsterdam</timezoneFrom>
    <offset>3 day</offset>
</news_to_date>

getCurrentDate

Returns the current date

<news_from_date helper="ho_import/import::getCurrentDate"/>

Product: getUrlKey

<url_key helper="ho_import/import_product::getUrlKey">
    <fields>
        <name field="Titel"/>
    </fields>
    <glue>-</glue>
</url_key>

Product: getAvailableUrlKey

Get an URL key that does not exist. The first 2 parameters will always be used. Every parameter after the second one is optional. On the first attempt, the first 2 parameters will be combined, if this url key isn't available anymore, it will try a second attempt with the third parameter. This process will continue until all parameters have been used or an available url key has been found.

<url_key helper="ho_import/import_product::getAvailableUrlKey">โ€จ
    <ident use="sku"/>โ€จ
    <name use="name"/>โ€จ
    <!-- additional fields -->โ€จ
    <ean field="ean"/>โ€จ
</url_key>

getSpecialFromDate

Give the price and the special_price and it returns the current date if the special_price is lower that the price (and not empty).

<special_from_date helper="ho_import/import_product::getSpecialFromDate">
    <price use="price"/>
    <special_price use="special_price"/>
</special_from_date>

getSpecialPrice

Give the price and the special_price and it returns the special_price if the special_price is lower that the price (and not empty).

<special_price helper="ho_import/import_product::getSpecialPrice">
    <price use="price"/>
    <special_price field="special_price"/>
</special_price>

Category: getUrlKey

<url_key helper="ho_import/import_category::getUrlKey">
    <fields>
        <name field="Titel"/>
    </fields>
    <glue>-</glue>
</url_key>

Customer: mapCountryIso3ToIso2

<billing helper="ho_import/import_customer::mapCountryIso3ToIso2">
    <field field="billing_country_code"/>
</billing>

Customer: mapCountryIso2ToIso3

<billing helper="ho_import/import_customer::mapCountryIso2ToIso3">
    <field field="billing_country_code"/>
</billing>

Combining helper methods

The output of a helper method can be used as the input of another helper. This way you can combine multiple helpers to achieve your task.

Example:
In the following example we have multiple fields that are used for the _media_image field:

<_media_image helper="ho_import/import::getMediaImage">
    <!-- We use the result of getFieldMultiple as the first argument for the `getMediaImage` helper. -->
    <images helper="ho_import/import::getFieldMultiple">
        <fields>
            <field field="image"/>
            <!-- we are using the result of getFieldSplit as the input for getFieldMultiple -->
            <media_gallery helper="ho_import/import::getFieldSplit"> 
                <field field="media_gallery"/>
                <split>,</split>
            </media_gallery>
            <awards helper="ho_import/import::getFieldSplit">
                <field field="awards"/>
                <split>,</split>
            </awards>
        </fields>
    </images>
    <limit/>
    <!-- We use result of `getUrlKey` as the third argument for the `getMediaImage` helper. -->
    <!-- We make sure the name of the image is the same as the SKU of the product, gets automatically appended with -1, -2, etc. -->
    <filename helper="ho_import/import_product::getUrlKey">
        <fields><name use="sku"/></fields>
        <glue>-</glue>
    </filename>
</_media_image>

Custom helper methods

Not every situation is a simple value processing and more complex logic might have to be used. You have the ability to easily create your own helper methods for each project. Simply create your own helper class and call that class.

Example: To determine if an address is a default address we create the two fields:

<_address_default_billing_  helper="ho_importjanselijn/import_customer::getAddressDefaultBilling"/>
<_address_default_shipping_ helper="ho_importjanselijn/import_customer::getAddressDefaultShipping"/>

And create a helper class which with the methods:

class Ho_ImportJanselijn_Helper_Import_Customer extends Mage_Core_Helper_Abstract
{

    public function getAddressDefaultBilling($line) {
        if ($line['InvAddress']) { //there is a billing and shipping address
            return array(1,0);
        } else { //there is only a shipping address
            return 1;
        }
    }

    public function getAddressDefaultShipping($line) {
        if ($line['InvAddress']) { //there is a billing and shipping address
            return array(0,1);
        } else { //there is only a shipping address
            return 1;
        }
    }
}

As you can see it sometimes returns an array of values and sometimes just returns a value. If you helper method returns an array of values Ho_Imports internally rewrites those multiple values to multiple import rows.

Pricing

Group pricing

Simple example of how to add group pricing to your product. Helpers can be used to calculate different prices for different websites.

<_group_price_website helper="ho_import/import::getFieldMultiple">
    <fields>
        <eu value="all"/>
        <int value="all"/>
    </fields>
</_group_price_website>
<_group_price_customer_group helper="ho_import/import::getFieldMultiple">
    <fields>
        <eu value="2"/>
        <int value="3"/>
    </fields>
</_group_price_customer_group>
<_group_price_price helper="ho_import/import::getFieldMultiple">
    <fields>
        <eu field="price"/>
        <int field="price"/>
    </fields>
</_group_price_price>

Configurable products

It is possible to create configurable products using Ho_Import.

<fieldmap...>
<configurable_builder>
    <sku helper="ho_intersteelimport/import_configurable::getSku"> 
        <simpleSku field="artikelnummer"/>
        <titel field="titel_product"/>
    </sku>
    <attributes helper="ho_intersteelimport/import_configurable::getAttributes"> <!-- returns an array of the attributes used to create the configurable -->
        <simpleName field="titel_product"/>
    </attributes>
    <calculate_price>1</calculate_price>
    <calculate_price_in_stock>1</calculate_price_in_stock>
    <fieldmap>
        <name helper="ho_intersteelimport/import_configurable::getName">
            <simpleName field="titel_product"/>
            <pcmaat use="pcmaat"/>
        </name>
        <description use="description"/>
        <url_key helper="ho_import/import_product::getAvailableUrlKey">
            <ident use="sku"/>
            <url_key helper="ho_import/import::getFieldCombine">
                <fields>
                    <sku use="sku"/>
                    <productgroup field="productgroup"/>
                </fields>
                <glue> </glue>
            </url_key>
            <!-- additional fields -->
            <ean field="ean_nummer"/>
        </url_key>
        <_type value="configurable"/>
        <visibility value="4"/>
        <is_in_stock value="1"/>
    </fieldmap>
</configurable_builder>

You might have noticed that we used the use attribute here as well. The use attribute will use the value from your fieldmapping, not the the value from the configurable builder.

sku

This will determine the SKU value for the configurable product

attributes

This option will combine the simple products into a configurable products. The value of this attribute will be configurable.
Multiple attributes are allowed.

calculate_price

Set this option to 1 and Ho_Import will try and determine the lowest price for your configurable product.

calculate_price_in_stock

Note: The calculate_price option has to be enabled in order to use this.

Set this option to 1 and Ho_Import will try and determine the lowest price based on products in stock for your configurable product.

CLI / Shell Utility

The importer comes with a shell utility where you'll be spending most of your time. You may want to access the individual configuration settings to disable custom helpers (useful when dryrun is active). This can be done by using:

Mage::helper('ho_import/import')->getConfig();

line

php hoimport.php  -action line
	-profile profile_name             Available profiles:    [list of profiles]
	-skip_download 1                  Skip the download
	-skip_decompress 1                Skip the decompressing of the downloaded file
	-line 1,2,3                       Commaseparated list of lines to be checked
	-search sku=abd                   Search for the value of a field.

import

php hoimport.php -action import
	-profile profile_name             Available profiles:    [list of profiles]
	-skip_download 1                  Skip the download
	-skip_decompress 1                Skip the decompressing of files
	-dryrun 1                         Validate all data agains the Magento validator, but do not import anything

importCsv

php hoimport.php -action csv
	Debug method: doesn't fieldmap, only imports the current csv
	-profile profile_name             Available profiles:    [list of profiles]
	-dryrun 1                         Validate all data agains the Magento validator, but do not import anything

Logging

There are two logging modes: CLI and cron mode. In the CLI mode it always logs to the CLI and tries to add nice colors, etc. In the cron-mode it will log to the the log files and can also log to the messages inbox in the admin panel.

Calling importer in your code

This is pretty easy to do:

protected function _importCustomers($memberIds) {
    Mage::getModel('ho_import/import')
        ->setProfile('postbeeld_customers')
        ->setSourceOptions(array('member_id' => implode(',', $memberIds)))
        ->process();

    Mage::helper('ho_import/log')->done();
    return $this;
}

File logging

Every import run by the cron is saved in var/ho_import.log.

Admin Panel notification

Sometimes you want to put a message in the Admin panel if an error pops up. By default the system only creates an admin panel message if there is a warning.

EMERG   = 0;  // Emergency: system is unusable
ALERT   = 1;  // Alert: action must be taken immediately
CRIT    = 2;  // Critical: critical conditions
ERR     = 3;  // Error: error conditions
WARN    = 4;  // Warning: warning conditions
NOTICE  = 5;  // Notice: normal but significant condition
INFO    = 6;  // Informational: informational messages
DEBUG   = 7;  // Debug: debug messages
SUCCESS = 8;  // Success: When everything is going well.

Place these config values in <config><global><ho_import><my_import_name> to change the level when and admin panel message will be added.

<log_level>6</log_level>

Use cases

At the time of release we have this tool running for multiple clients, multiple types of imports:

  • Multiple sources per product Example config
  • One time product / category imports from an old datasource Example config
  • Periodic category import with values for multiple store views Example config
  • 15 minute inventory only updates
  • Nightly complete inventory updates Example config
  • Nightly price updates
  • Incremental category/product updates from ERP systems
  • Customer import Example config
  • Customer import with billing and shipping address Example config

Performance

We don't have actual benchmarks at the moment, but the time spend fieldmapping is an order of magnitude faster than the actual import its self.

License

OSL - Open Software Licence 3.0

Support

If you need help with the module, create an issue in the GitHub issue tracker.

Author

The module is written by Paul Hachmang (twitter: @paales, email: [email protected]) build for Reach Digital, we make Magento Webshops (website: https://www.reachdigital.nl/, email: [email protected], twitter: @ho_nl).

Why build it and open source it?

After having build multiple product, category and customer imports I was never really satisfied with the available projects. After implementing a project with bare code we came to the conclusion that it was pretty difficult to create an import, make sure al the fields are correctly set for Magento to accept them, the development iteration was to slow, etc.

After building this we think we made a pretty good module that has value for a lot of Magento developers, so releasing it open source was natural. And with the combined effort of other developers, we can improve it even further, fix bugs, add new features etc.

magento1-ho_import's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

magento1-ho_import's Issues

Customer import is_subscribed not working

Hi,

The function is_subscribed with a value of 0 or 1 is not working. Al customers that are imported get 0 als value for the is_subscribed.

            <fieldmap>
                <_website helper="ho_import/import::getAllWebsites"><limit>1</limit></_website>
                <group_id value="1"/>
                <email field="email"/>
                <firstname field="Voornaam" defaultvalue="ONBEKEND"/>
                <lastname field="Achternaam" required="1"/>
                <password field="wachtwoord" />

                <is_subscribed field="Nieuwsbrief"/>

            </fieldmap>

Regards,
Joost

Import of configurable products

I'm trying to import a configurable product.

I created config.xml similar to this.

CSV file has 3 lines: two for simple products and one for configurable product that is associated with these two products.

All products are imported properly, but they are not associated.

CSV that I used:

"sku","_type","color","short_description","description","price","name","tax_class","visibility","weight","category_ids","_super_attribute_code","_super_attribute_option","_super_attribute_price_corr"
"test1","simple","Black","Test 1","Test 1 Product",10,"Test 1 Product Name",0,4,,3,"color","Black",
"test2","simple","White","Test 2","Test 2 Product","123,99","Test 2 Product Name",0,,1,"3,4","color","White",
"test0","configurable",,"Test Conf","Test Conf",0,"Test Conf",0,4,0,3,"color",,

Is it possible to import configurable products with this extension? Is any field missing in CSV file that I used? Could you provide any sample configuration for import of configurable products?

Error while constructing Spreadsheet adapter

I get an error while trying to import a profile: Recoverable Error: Argument 1 passed to Ho_Import_Model_Source_Adapter_Spreadsheet::__construct() must be of the type array, string given

The problem lies in the combination of two things:

  • Ho_Import_Model_Import::getSourceAdapter() passes a string with only the filename to the source adapter if there's only one argument
  • Ho_Import_Model_Source_Adapter_Spreadsheet has a type hint on it's constructor: __construct(array $config). In the first line of the constructor, the type gets checked though and if it's a string it gets converted to an array with a 'file' key.

Currently I work around it by defining another dummy option to the <source> tag so there are multiple arguments to pass to the source adapter but that's not a very constructive solution :)

<source model="ho_import/source_adapter_spreadsheet">
    <file>var/import/products_language.xlsx</file>
    <foo>bar</foo>
</source>

I think the best and easiest way is to just remove the type hint from the constructor of Ho_Import_Model_Source_Adapter_Spreadsheet.

Upgrade of spreadsheet-reader

I see you use your own fork of the spreadsheet-reader. Not a bad idea. But could you update that repository? There's a bug in the currently forked version.

I got an exception while trying to load an Excel document: Warning: include(SpreadsheetReader/XLSX.php): failed to open stream: No such file or directory in /var/www/magentics/dlight.magentics.net/lib/Varien/Autoload.php.

This is caused by SpreadsheetReader (in /lib/spreadsheet-reader):

if (!class_exists('SpreadsheetReader_'.$Type))
{
    require(dirname(__FILE__).DIRECTORY_SEPARATOR.'SpreadsheetReader_'.$Type.'.php');
}

class_exists() by default tries to load the class if it doesn't exist. Because the file can't be autoloaded by Varien_Autoload, it generates a warning. This bug was fixed in the upstream version: nuovo/spreadsheet-reader@d311aee

Evil bug when connection to PDO datasources

Class Ho_Import_Model_Source_Adapter_Db has to many unsetted parameters in the $config array which will be used for creating the DSN.

I can only connect to a PDO PGSQL source when using that modified constructor:

    /**
     * Constructor.
     * @param array $config
     */
    public function __construct(array $config)
    {
        $logHelper = Mage::helper('ho_import/log');
        $model = $config['model'];
        $query = $config['query'];
        //$config['readOnly'] = true;

        unset($config['model']);
        unset($config['query']);
        $config2 = $config;
        unset($config2['type']);
        unset($config2['pdoType']);

        /** @var Zend_Db_Adapter_Abstract $db */
        $db = new $model($config2);

        if (isset($config['limit']) || isset($condig['offset'])) {
            $limit  = (int) isset($config['limit']) ? $config['limit'] : 0;
            $offset = (int) isset($config['offset']) ? $config['offset'] : 0;
            $logHelper->log($logHelper->__('Setting limit to %s and offset to %s', $limit, $offset), Zend_Log::NOTICE);
            $query = $db->limit($query, $config['limit'], $offset);
            $logHelper->log($query, Zend_Log::DEBUG);
        }

        $logHelper->log('Fetching data...');
        $result = $db->fetchAll($query);
        $logHelper->log('Done');
        $config['data'] = &$result;

        return parent::__construct($config);
    }

So type, pdotype and readonly needs to be removed for connection to a DSN source.

I'm currently unsure why readOnly=true is at the top and where it is needed. Same with type and pdoType ... so therefore I haven't attached a PR.
Maybe you could have a look and fix that.

Cyrill

Warning: min(): Array must contain at least one element in /home/admin/domains/**/public_html/app/code/community/Ho/Import/Model/Source/Adapter/Xml.php on line 376

When i use the following: command php hoimport.php -action line -profile profile_name
I get the following error: Warning: min(): Array must contain at least one element in /home/admin/domains/**/public_html/app/code/community/Ho/Import/Model/Source/Adapter/Xml.php on line 376

I'm looking into the field mapping output, there was the value _store not filled in. This was in the config file: <_store value="admin" required="1โ€/>

config file:

<?xml version="1.0"?>
<config>
    <modules>
        <Trinos_Import>
            <version>0.1.0</version>
        </Trinos_Import>
    </modules>
    <global>
        <helpers>
            <import>
                <class>Xml_Import_Trinos</class>
            </import>
        </helpers>

        <ho_import>

            <profile_name>

                <entity_type>catalog_product</entity_type>          

                <downloader model="ho_import/downloader_http">
                    <url>http://www.*****.xml</url>
                </downloader>

                <source model="ho_import/source_adapter_xml">
                    <file>/home/admin/domains/****/public_html/var/test.xml</file>
                </source>

                <import_options>
            <!--<continue_after_errors>1</continue_after_errors>-->
            <!--<ignore_duplicates>1</ignore_duplicates>-->
            <partial_indexing>1</partial_indexing>
            </import_options>


                <fieldmap>

                    <!-- GENERAL PRODUCT INFORMATION -->

                        <_store value="admin" required="1"/>
                        <_type value="simple"/>
                        <_attribute_set value="Default"/>
                        <_product_websites value="base"/>

                        <name field="name"/>


                        <description value="findReplaceniks"/>


                        <short_description field="description_short"/>
                        <status value="1"/>
                        <visibility value="4"/>
                        <sku field="productId" required="1"/>

                        <price helper="ho_import/import::parsePrice">
                            <pricefield field="price"/>
                        </price>

                        <tax_class_id value="2"/>


                    <!-- USER DEFINED FIELDS -->

                        <merk field="brand"/>

                    <!-- MEDIA FIELDS -->



                    <!-- INVENTORY -->
                         <qty field="stock"/>
                        <!--<min_qty value="0"/>-->
                        <!--<use_config_min_qty value="1"/>-->
                        <!--<is_qty_decimal value="0"/>-->
                        <!--<backorders value="1" />-->
                        <!--<use_config_backorders value="1"/>-->
                        <!--<min_sale_qty value="1"/>-->
                        <!--<use_config_min_sale_qty value="1"/>-->
                        <!--<max_sale_qty value="10000"/>-->
                        <!--<use_config_max_sale_qty value="1"/>-->
                        <is_in_stock value="yes"/>
                        <!--<notify_stock_qty value=""/>-->
                        <!--<use_config_notify_stock_qty value="1"/>-->
                        <!--<manage_stock value="1"/>-->
                        <!--<use_config_manage_stock value="1"/>-->
                        <!--<stock_status_changed_auto value="0"/>-->
                        <!--<qty_increments value="1"/>-->
                        <!--<use_config_qty_increments value="1"/>-->
                        <!--<enable_qty_increments value="0"/>-->
                        <!--<use_config_enable_qty_inc value="1" />-->
                        <!--<is_decimal_divided value="0"/>-->



                </fieldmap>

            </profile_name>

        </ho_import>

    </global>

</config>

ISSUE: Invalid value for Attribute Set column

Hello,
It was not clear at all that I needed to set the default _attribute_set. I would have assumed since it was not doc'd that it would have just been set to the default attribute set. I did figured it out that you do need to add <_attribute_set value="Default"/> in the end.

It's also worth noting that the instructions should say that you must have all the required fields that AvS_FastSimpleImport has and that this doesn't provide a default if the node is not in the config, like the <_attribute_set value="Default"/> example. I ended up with

| Required attribute 'description' has an empty value       | ERROR     |
| Required attribute 'short_description' has an empty value | ERROR     |
| Required attribute 'media_gallery' has an empty value     | ERROR     |
| Required attribute 'tax_class_id' has an empty value      | ERROR     |

so it would have need good to have a note about this. Cheers and good stuff here.

Un-/Reinstall the Magento Module (Duplicate Entry)

Hi,

i get errors when i try to uninstall (modman remove) and later again install the module modman clone & (modman depoy).
The Setup-Script is executed again then. That implicates that the "import-profile" EAV-Attribute ist trying to be created again. Throws an Duplicate-Entry Error in MySQL. Result: Shop doesn't work any more.

So what would be a clean way to uninstall Ho_Import including the EAV-Attribute it creates ?

Error with catalog_category_product

I'm not sure if this is a bug. Magento give this error after a successful Category-product relation import.

exception 'Mage_Core_Exception' with message 'Invalid entity_type specified: catalog_category_product' in /home/user/domains/domain.com/public_html/berto/app/Mage.php:595
#0 /home/user/domains/domain.com/public_html/berto/app/code/core/Mage/Eav/Model/Config.php(328): Mage::throwException('Invalid entity_...')
#1 /home/user/domains/domain.com/public_html/berto/app/code/community/Ho/Import/Model/Import.php(1005): Mage_Eav_Model_Config->getEntityType('catalog_categor...')
#2 /home/user/domains/domain.com/public_html/berto/app/code/community/Ho/Import/Model/Import.php(1091): Ho_Import_Model_Import->_getEntityTypeId()

From Ho Import function, row 1005

    protected function _getEntityTypeId()
    {
        /** @var Mage_Eav_Model_Entity_Type $entityType */
        $entityType = Mage::getSingleton('eav/config')->getEntityType((string) $this->_getEntityType());

        return $entityType->getId();
    }

Profile code in config.xml:

<!-- CATEGORY PRODUCT RELATION IMPORT -->
            <category_products>
                <entity_type>catalog_category_product</entity_type>
                <source model="ho_import/source_adapter_xml">
                    <file>var/import/source.xml</file>
                </source>
                <import_options>
                    <partial_indexing>1</partial_indexing>
                </import_options>
                <fieldmap>
                    <_root value="Default Category" />
                    <_category helper="ho_import/import::formatField">
                        <format>%s/%s</format>
                        <fields>
                            <father field="Categoria_x0020_Descrizione" />
                            <child field="Tipologia_x0020_Descrizione" />
                        </fields>
                    </_category>
                    <_sku helper="ho_import/import::formatField">
                        <format>%s-%s</format>
                        <fields>
                            <sku field="barcode" />
                            <size field="tg" />
                        </fields>
                    </_sku>
                    <position value="0" />
                </fieldmap>
            </category_products>

ho_import.log

2015-07-07T09:08:03+00:00 INFO (6): Processing 53 rows from temp csv file (/home/user/domains/domain.com/public_html/berto/var/import/category_products.csv)
2015-07-07T09:08:03+00:00 INFO (6): Start profile /home/user/domains/domain.com/public_html/berto/var/import/category_products.csv
2015-07-07T09:08:03+00:00 INFO (6): Profile category_products done in 0.27 seconds, 196.3 entities/s, 196.3 rows/s.
2015-07-07T09:08:03+00:00 INFO (6): Clean entity link table

Stable version of Ho_Import uses functionality of unstable version of AvS_FastSimpleImport

Hi

I just tried using Ho_Import v1.6.1 for a new import we are starting. I also use AvS_FastSimpleImport v0.6.4
But when trying to run an import, I get this error:

PHP Fatal error:  Call to undefined method AvS_FastSimpleImport_Model_Import_Entity_Product::getEntityBySku() in app/code/community/Ho/Import/Model/Observer.php on line 53

Now, I can see the method getEntityBySku was added in the develop branch of AvS_FastSimpleImport.
So what's the best thing to do right now?

  1. Wait until AvS_FastSimpleImport gets a new stable release. How long will this take?
  2. Use the develop branch of AvS_FastSimpleImport. Is it stable enough right now?
  3. Go back to Ho_Import v1.5?
  4. Something else?

Please advice :)

set default for media_gallery attribute

when I use the fastsimpleimport/import it will scream if you don't have media_gallery set, which it is currently doing now. It would be handy that if it's not set and that it defaults with

Mage::getSingleton('catalog/product')->getResource()->getAttribute('media_gallery') ->getAttributeId();

Intermediate CSV file not created automatically

It's a follow-up to the last issue I created (#65) since it's been closed.

@paales I won't bother you too much with it since a manual copy of the orignal file to var/import/ is enough to make the script work, but from what I see there's no CSV file created automatically. No error logged in any log file or from the shell script output. Can you point me to the part of the script taking care of that? I then could make a little debug session to see what's wrong.

Cheers

Import customers into specific Store

Hi!

I'm not sure if I should see it as a bug or feature. It may be coded by design, but not keeping all usecases in mind.

$flatRow['_store'] = $store == 'admin' ? '' : $store;

It looks like the condition was meant for product imports, where you like to force it to admin and map storeview-data via <store_view>.
On the other hand, if you import customers, you may force whole records to go into store-views. Therefore you specify a "_store" column in you CSV-datasource. This it not possible, because it gets overriden by the mentioned statement above.

See Model/Import.php:593

                if ($flatRow) {
                    //if a column is required we add it here.
                    foreach ($allFieldConfig[$store] as $key => $column) {
                        if (!isset($flatRow[$key]) && isset($column['@']) && isset($column['@']['required'])) {
                            $flatRow[$key] = '';
                        }
                    }

                    $flatRow['_store'] = $store == 'admin' ? '' : $store;
                    $flattenedRows[]   = $flatRow;
                }

In my opinion it should read like:

                    if(!isset($flatRow['_store'])){
                        $flatRow['_store'] = $store == 'admin' ? '' : $store;
                    }
                    $flattenedRows[]   = $flatRow;

The only drawback I see, you can "override" the store for product imports in your datasource and this could mess things up.

Column names is empty or is not an array

The import always looks for fields in first tag in root element.

I have an XML like this;

<?xml version="1.0" encoding="UTF-8"?>
<channel xmlns:g="http://base.google.com/ns/1.0">
<title><![CDATA[Pricelist]]></title>
<description/>
<link>http://www.webshop.com</link>
<item>
... fields ...
</item>
<item>
... fields ...
</item>
<item>
... fields ...
</item>
<item>
... fields ...
</item>
</channel>

When I start the import, it gives me;
"Column names is empty or is not an array"

This is because it tries to look for the product data fields in the first tag it encounters, which is <title> and not <item>. Maybe adding a field that sets the name of the item that contains all the product data is an idea?

So te source tag becomes something like this;

<source model="ho_import/source_adapter_xml">
          <file>var/import/gxml-feed.xml</file>
          <rootNode>channel</rootNode>
          <productNode>item</productNode>
</source>

Ho_Import breaks standard import

Observer of Ho_Import prevents default Magento import to work in adminpanel:

PHP Fatal error:  Call to undefined method Mage_ImportExport_Model_Import_Entity_Product::getEntityBySku() in .../Ho_Import/app/code/community/Ho/Import/Model/Observer.php on line 53

Reason: $adapter in Ho_Import_Model_Observer::linkProductsToProfile() is supposed to be instance of AvS_FastSimpleImport_Model_Import_Entity_Product

Fix: Check if ($adapter instanceof AvS_FastSimpleImport_Model_Import_Entity_Product)

Warning: array_combine(): Both parameters should have an equal number of elements

I've been trying to get this working for the past couple days, and almost have it functioning properly, but have an issue. I am now getting the following error when I run the -dryrun:

Warning: array_combine(): Both parameters should have an equal number of elements in /Users/Graphics/Sites/Magento/app/code/community/Ho/Import/Model/Source/Adapter/Csv.php on line 220

I've tried everything I can think of with no luck. It seems as though it's not finding the first line in my CSV file after the header line. When I run a line -search command it cannot find the SKU in the first row, but it can find the SKU of the second row, third row, etc. When I run the -action line -profile profile_name command it shows the second row of data, not the first. I'm stumped.

how to import multiple tier prices?

I'm importing my products from my erp system and was wondering if it's possible to import multiple tier prices for one product? I'm using an CSV-file with this value as tier_price:
image. It represents the quantity and discount percentage. I also can calculate the discount myself on generating the CSV-file.

But here is my question. How can I map this in my config xml?

Split on ***

10:-25% (or calculate price)
20:-30% (or calculate price)
50:-35% (or calculate price)

to this? 

<_tier_price_website/>
<_tier_price_customer_group/>
<_tier_price_qty/>
<_tier_price_price/>

Having trouble determining proper XML config format for image import

I'm working on an import that contains a URL to download the image from. I couldn't find a clear example of this, so I've tried a few different things. The closest I've gotten is the images download to the import folder correctly, but they are never imported into Magento. Here's my latest attempt:

<!-- MEDIA FIELDS -->
<_media_image helper="ho_import/import_product::getMediaImage"/>
<image helper="ho_import/import_product::getMediaImage"><image field="image"/></image>
<image_label use="name"/>
<small_image helper="ho_import/import_product::getMediaImage"><image field="small_image"/></small_image>
<small_image_label use="name"/>
<thumbnail helper="ho_import/import_product::getMediaImage"><image field="thumbnail"/></thumbnail>
 <thumbnail_label use="name"/>
<gallery/>
<media_gallery value="none"/>

The images appear as a URL in a column named 'image' in a CSV file. The rest of the CSV file imports fine. The URL is a valid URL - I'm able to download the images manually, and I did have at least one version of this XML that grabbed the images and then populated the image field with '/.jpg' as expected, but the image never actually appeared on the product.

XML entities aren't converted

Hi

We have an issue when trying to map the a category name where the to name contains an &amp;

For example, we have this in our import definition:

<_category helper="ho_import/import::getFieldMap">
    <field field="CAT"/>
    <mapping>
        <TOPS from="TOPS" to="Default Category/Tops &amp; T-shirts/Tops"/>
    </mapping>
</_category>

But the &amp; isn't converted to & which makes the importer complain, as it can't find the category:

โžœ php hoimport.php -action line -profile product_import
11:45:50 - 22MB Getting source adapter ho_import/source_adapter_db
11:45:50 - 22MB Fetching data...
11:45:50 - 40MB Done
...
11:45:52 - 55MB
+--------------------------+-------------------------------------------+
| key                      | 1:1                                       |
+--------------------------+-------------------------------------------+
| _type                    | simple                                    |
| _attribute_set           | Default                                   |
| _category                | Default Category/Tops &amp; T-shirts/Tops |
| ...                      |                                           |
| Category does not exists | ERROR                                     |
+--------------------------+-------------------------------------------+

Have the ability to delete entities that aren't in the import-source.

We for example have a feed of products. When products get removed from the feed it should delete/disable the products in Magento.

  • The idea is that an import-source is responsible for the products it imports. We create a product/customer/category attribute ho_import_profile and a datetime field that marks the last import date ho_import_updated_at.
  • We add an option to the import that allows you to delete products or disable products when they aren't available in the feed. Maybe this can be easily implemented using an event.
  • Implement the delete functionality in a fast mannor (just run a DELETE query on the entity tables and let the foreign key contraints do the rest or is there another fast way to do this?)
  • Run the delete indexer?

-dryRun 1 imports the data

I created a simple import and ran this command in the shell:

 php hoimport.php -action import -profile catalog_product_example01 -dryRun 1

The output was

2014-01-31 11:47:27 - 8.5MB Mapping source fields and saving to temp csv file (/path/to/magento/var/import/catalog_product_example01.csv)
2014-01-31 11:47:27 - 8.5MB Getting source adapter ho_import/source_adapter_csv
2014-01-31 11:47:27 - 8.5MB Fieldmapping catalog_product_example01 with 5 rows (done in 0 seconds, 5 rows/s)
2014-01-31 11:47:27 - 8.5MB Processing 5 rows from temp csv file (/path/to/magento/var/import/catalog_product_example01.csv)
2014-01-31 11:47:27 - 8.5MB Setting option action to import
2014-01-31 11:47:27 - 8.5MB Setting option profile to catalog_product_example01
2014-01-31 11:47:27 - 8.5MB Setting option dryRun to 1
2014-01-31 11:47:27 - 8.5MB Start import catalog_product
2014-01-31 11:47:27 - 16.75MB Import catalog_product_example01 done in 0.4 seconds, 12.5 rows/s, 12.5 items/s.
2014-01-31 11:47:27 - 16.75MB No errors found in 5 rows
2014-01-31 11:47:27 - 16.75MB Done

The data was imported. Did I miss something? I tested on a vanilla CE 1.8.0.0 installation.

Problem with importing media files and using dryrun option

Hi

When trying to import media images during a product import, and using the dryrun option:
โžœ php shell/hoimport.php -action import -profile product_import -dryrun 1
or
โžœ php shell/hoimport.php -action csv -profile product_import -dryrun 1

We get this error:

09:59:41 - 16MB Dry run 16799 rows from temp csv file (var/import/product_import.csv)
PHP Fatal error:  Call to undefined method Mage_ImportExport_Model_Import_Adapter_Csv::unsetValue() in app/code/community/AvS/FastSimpleImport/Model/Import/Entity/Product.php on line 348
PHP Stack trace:
PHP   1. {main}() shell/hoimport.php:0
PHP   2. Ho_Import_Shell_Productimport->run() shell/hoimport.php:197
PHP   3. Ho_Import_Shell_Productimport->importAction() shell/hoimport.php:45
PHP   4. Ho_Import_Model_Import->process() shell/hoimport.php:101
PHP   5. Ho_Import_Model_Import->_dryRun() app/code/community/Ho/Import/Model/Import.php:96
PHP   6. AvS_FastSimpleImport_Model_Import->dryrunProductImport() app/code/community/Ho/Import/Model/Import.php:690
PHP   7. AvS_FastSimpleImport_Model_Import->validateSource() app/code/community/AvS/FastSimpleImport/Model/Import.php:154
PHP   8. Mage_ImportExport_Model_Import_Entity_Abstract->isDataValid() app/code/community/AvS/FastSimpleImport/Model/Import.php:506
PHP   9. AvS_FastSimpleImport_Model_Import_Entity_Product->validateData() app/code/core/Mage/ImportExport/Model/Import/Entity/Abstract.php:597
PHP  10. AvS_FastSimpleImport_Model_Import_Entity_Product->_preprocessImageData() app/code/community/AvS/FastSimpleImport/Model/Import/Entity/Product.php:159

This only happens when using dryrun, if you don't use it, the import works as expected.
I'm not sure if this is a bug in Ho_Import or in Avs_FastSimpleImport or in Mage_ImportExport though ...

Btw: I first got an error about the undefined method setValue for the _media_is_disabled and _media_position attributes on line 313 and 316 of the same file as the above, but I got around those by explicitly defining a value in the import profile for them.

Base image, Thumbnail, Small image not set with cronjob

When the import is done by cronjob the base image, thumbnail and small image is not set. See screenshot:

screen shot 2014-09-11 at 16 47 09

When we do the import with SSH; the base image, thumbnail and small image is wel set right.

This is the part of the config for images.

                <_media_attribute_id helper="ho_import/import::getMediaAttributeId"/>
                <_media_image helper="trinos_import/data::getMediaImage">
                    <imagefield field="image_path"/>
                </_media_image>

                <_media_lable/>
                <_media_position value="0"/>
                <_media_is_disabled value="1"/>

                <image use="_media_image"/> 
                <image_lable use="name"/>

                <thumbnail use="_media_image"/>
                <thumbnail_lable use="name"/>

                <small_image use="_media_image"/>
                <small_image_lable use="name"/>

                <_media_lable use="name"/>
                <_media_position value="0"/>
                <_media_is_disabled value="1"/>

Error after correct catalog_category_product entity import

With Magento 1.9.1.1 after correct Category-product relation import, critical error occurs:

2015-07-08T19:06:50+00:00 INFO (6): Setting option ignore_duplicates to 1
2015-07-08T19:06:50+00:00 INFO (6): Setting option partial_indexing to 1
2015-07-08T19:06:50+00:00 INFO (6): Mapping source fields and saving to temp csv file (/home/username/domains/domain.com/public_html/berto/var/import/category_products.csv)
2015-07-08T19:06:50+00:00 INFO (6): Getting source adapter ho_import/source_adapter_xml
2015-07-08T19:06:50+00:00 INFO (6): Loading source file var/import/accord/ArtModa.xml
2015-07-08T19:06:50+00:00 INFO (6): Fieldmapping category_products with 53 rows, 53 entities (done in 0.03 seconds, 1766.67 rows/s)
2015-07-08T19:06:50+00:00 INFO (6): Processing 53 rows from temp csv file (/home/username/domains/domain.com/public_html/berto/var/import/category_products.csv)
2015-07-08T19:06:50+00:00 INFO (6): Start profile /home/username/domains/domain.com/public_html/berto/var/import/category_products.csv
2015-07-08T19:06:52+00:00 INFO (6): Profile category_products done in 1.75 seconds, 30.29 entities/s, 30.29 rows/s.
2015-07-08T19:06:52+00:00 INFO (6): Clean entity link table
2015-07-08T19:06:52+00:00 CRIT (2): #0 /home/username/domains/domain.com/public_html/berto/app/code/core/Mage/Eav/Model/Config.php(328): Mage->throwException('entity_type specificato non valido: catalog_category_product')
#1 /home/username/domains/domain.com/public_html/berto/app/code/community/Ho/Import/Model/Import.php(1005): Mage_Eav_Model_Config->getEntityType('catalog_category_product')
#2 /home/username/domains/domain.com/public_html/berto/app/code/community/Ho/Import/Model/Import.php(1091): Ho_Import_Model_Import->_getEntityTypeId()
#3 /home/username/domains/domain.com/public_html/berto/app/code/community/Ho/Import/Model/Import.php(126): Ho_Import_Model_Import->_cleanEntityLinkTable()
#4 /home/username/domains/domain.com/public_html/berto/app/code/community/Ho/Import/Model/Observer.php(107): Ho_Import_Model_Import->process()
#5 (): Ho_Import_Model_Observer->process(Mage_Cron_Model_Schedule)
#6 /home/username/domains/domain.com/public_html/berto/app/code/core/Mage/Cron/Model/Observer.php(325): call_user_func_array(Array, Array)
#7 /home/username/domains/domain.com/public_html/berto/app/code/core/Mage/Cron/Model/Observer.php(72): Mage_Cron_Model_Observer->_processJob(Mage_Cron_Model_Schedule, Mage_Core_Model_Config_Element)
#8 /home/username/domains/domain.com/public_html/berto/app/code/core/Mage/Core/Model/App.php(1338): Mage_Cron_Model_Observer->dispatch(Varien_Event_Observer)
#9 /home/username/domains/domain.com/public_html/berto/app/code/core/Mage/Core/Model/App.php(1317): Mage_Core_Model_App->_callObserverMethod(Mage_Cron_Model_Observer, 'dispatch', Varien_Event_Observer)
#10 /home/username/domains/domain.com/public_html/berto/app/Mage.php(448): Mage_Core_Model_App->dispatchEvent('default', Array)
#11 /home/username/domains/domain.com/public_html/berto/cron.php(76): Mage->dispatchEvent('default')

After this import, Magento admin shows "One or more of the Indexes are not up to date". Is there an error with partial indexing?

Magento 1.9.1.1, Ho_import (master branch), AvS_FastSimpleImport (develop branch)

extra media import

Hi,

is there a way to import more than the 3 basic media (thumb,small, base) ?

Warning: json_encode(): Invalid UTF-8 sequence in argument

When we do a import from a XML we get the following error.

Warning: json_encode(): Invalid UTF-8 sequence in argument  in /home/admin/domains/speeltoys.nl/public_html/lib/Zend/Json.php on line 146

The CSV that the tool has made is Western (Windows Latin 1) encoding.

Reimplement the fieldmapper as SeekableIterator so that the importer can use it directly.

Currently we use an intermediate file when importing. It saves to CSV and that CSV is imported. If we could import without this immediate step we do not need to 'prepare' the import, we can just run it.

Advantages:

  • Debug the actual source line in addition to the current imported line.
  • Progress indicators
  • No intermediate file, less possible encoding errors
  • No writing to disk while importing

Import of multiple product images

I have the following code in the XML

                        <_media_attribute_id helper="ho_import/import::getAttributeId">
                            <attribute value="media_gallery"/>
                        </_media_attribute_id>

                        <_media_image helper="ho_import/import::getFieldSplit">
                            <field field="afbeeldingen"/>
                            <split>,</split>
                        </_media_image>

                        <_media_lable use="name"/> <!-- the spelling mistake is in the core, so we use it here -->
                        <_media_position value="0"/>
                        <_media_is_disabled value="0"/>

                        <image field="hoofdafbeelding"/>
                        <image_label use="name"/>

                        <thumbnail use="image"/>
                        <thumbnail_label use="name"/>

                        <small_image use="image"/>
                        <small_image_label use="name"/>

But i can't import more then one image. The Media attribute ID is not working for the second image.

screen shot 2015-04-07 at 13 39 39

Fix HO_Import minimum stability

Would you please remove the dev-master entry in the required magento-hackathon/magento-composer-installer directive to allow also other versions of the magento-hackathon/magento-composer-installer besides the dev-master version :-)

I know you don't use composer ;-)

new composer.json:

   "require": {
      "magento-hackathon/magento-composer-installer": "*"
   }

Deprecated functionality: preg_replace(): The /e modifier is deprecated

I'm using PHP 5.5 which throws that error/warning:
Deprecated functionality: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /Users/xxx/Sites/zookal-site/htdocs/lib/Zend/Filter/PregReplace.php on line 171

In class Ho_Import_Model_Import your are using class Zend_Filter_Word_UnderscoreToCamelCase which generates that error in class Zend_Filter_Word_SeparatorToCamelCase

Create a custom method without using the /e modifier?

Incorrect rowCount when using skip flag in source_row_fieldmap_before event

Hi again

I believe there is a bug in Ho_Import_Model_Import::_createImportCsv on line 403:
https://github.com/ho-nl/Ho_Import/blob/bd1d407e1054568baf51b55a5f9b8e79bff07a9d/app/code/community/Ho/Import/Model/Import.php#L403

I think the $rowCount++; shouldn't be there.

We ran into an issue where we skipped all rows of a source, so no data should be imported, but since the rowCount was still saying there were more then 300 lines to be imported, it continued with the import and ran into exceptions further down the line.

If I remove this particular line, the problem seems to be fixed.

1452 Cannot add or update a child row: a foreign key constraint fails

I have a problem with importing around 8000 products. Get the following error:

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`speel_db2`.`cataloginventory_stock_item`, CONSTRAINT `FK_CATINV_STOCK_ITEM_PRD_ID_CAT_PRD_ENTT_ENTT_ID` FOREIGN KEY (`product_id`) REFERENCES `catalog_product_entity` (`entity_id`) ON DELETE )

The first what i did was a clean install of a new Magento shop. But problem get back. This is the config.xml

<config>
  <modules>
    <Company_Import>
      <version>0.1.0</version>
    </Company_Import>
  </modules>
  <global>
    <helpers>
      <company_import>
        <class>Company_Import_Helper</class>
      </company_import>
    </helpers>
    <ho_import>
            <speel_toys>
                <entity_type>catalog_product</entity_type>

                <downloader model="ho_import/downloader_ftp">
                    <host>XXX</host>
                    <username>XXXX</username>
                    <password>XXXX</password>
                    <file>XXX.csv</file> 
                    <target>var/import</target>
                    <timeout>10</timeout> 
                    <passive>1</passive> 
                    <ssl>0</ssl>
                    <file_mode>1</file_mode>
                </downloader>


                <source model="ho_import/source_adapter_csv">
                     <file>var/import/XXX.csv</file>
                     <delimiter>;</delimiter>
                </source>

                <import_options>
                    <error_limit>50</error_limit>
                    <continue_after_errors>1</continue_after_errors>
                    <ignore_duplicates>1</ignore_duplicates>
                    <dropdown_attributes>
                        <country>merk</country>
                    </dropdown_attributes>
                </import_options>


                <fieldmap>

                    <_type value="simple"/>
                    <_attribute_set value="Default"/>
                    <_product_websites helper="ho_import/import::getAllWebsites"/>

                    <name field="9 Pocket pages"/>
                    <description field="9 Pocket pages"/>
                    <short_description field="9 Pocket pages"/>         
                    <sku field="9POC170100" required="1"/>

                    <price helper="ho_import/import::parsePrice">
                        <pricefield field="0,10"/>
                    </price>

                    <special_price helper="ho_import/import::parsePrice">
                        <special_pricefield field="0,25"/>
                    </special_price>

                    <image helper="ho_import/import::getMediaImage">
                        <imagefield field="9POC170100"/>
                        <limit>1</limit>
                        <filename field="9POC170100"/> 
                        <extension value="jpg"/>
                    </image>
                    <image_label field="9 Pocket pages"/>

                    <tax_class_id helper="ho_import/import::getFieldMap">
                       <value field="21%"/>
                       <mapping>
                           <hoogbtw from="21%" to="2"/>
                           <laagbtw from="6%" to="2"/>
                        </mapping>
                    </tax_class_id>

                    <_category value="Overige"/>

                    <merk field="Trading cards"/>

                    <qty value="100"/>
                    <is_in_stock helper="ho_import/import::getFieldBoolean">
                        <value field="100"/>
                    </is_in_stock>


                </fieldmap>

            </speel_toys>

        </ho_import>
  </global>
</config>

Customer CSV Import: Two path for the same file?

Hi,

I'm currently using Ho_Import to import customers into a Magento instance and it works great! But there's something I don't understand.

I configured a profile named "import_customers", setting a CSV file as source :

<source model="ho_import/source_adapter_csv">
    <file>var/import/customers/customers.csv</file>
    <delimiter>,</delimiter>
    <enclosure>"</enclosure>
</source>

Then, when I run the profile from command line, here's what coming up :

$ php ../../shell/hoimport.php -action csv -profile import_customers
13MB Mapping source fields and saving to temp csv file (/home/user/httpdocs/var/import/import_customers.csv)
13MB Getting source adapter ho_import/source_adapter_csv
13MB Loading source file /home/user/httpdocs/var/import/customers/customers.csv
13MB Processing  rows from temp csv file (/home/user/httpdocs/var/import/import_customers.csv)
13MB Start profile /home/user/httpdocs/var/import/import_customers.csv

So the module wants me to have the CSV file at :

  • /home/user/httpdocs/var/import/customers/customers.csv
  • /home/user/httpdocs/var/import/import_customers.csv

Could you tell me why the module asks me to put the same file in two different locations? Is there a way to only keep the first path?

Anyway, thanks for all the hard work. Beside that little interrogation, the module is perfect, full of documentation, useful reports and highly flexible. To think that a few hours ago I was still banging my head with Dataflow...

Better support for XML parsing

At this moment there is an array passed to all the methods, there isn't any actual raw XML passed.

I'd like to add some xpath-like, maybe css-style array parsing to it becomes very easy to select the element you need.

Defining multiple helpers for one field

Hi

I was wondering if it is somehow possible to define multiple helpers for one field in the xml import profile?

For example: we want to use both the ho_import/import::getFieldSplit and ho_import/import::getMediaImage for one field.
Right now we solve this by writing our own helper which extends from the ho_import/import helper and then calls those two functions, but it is a bit tedious to do it like this.

So, it would be great if you could add a feature where you can add multiple helper calls, in a specific order, to one field in the xml import profile I believe.

How to deal with duplicate SKUs?

I'm trying to get my product importer working again by using your module. My experience with the module is that the mapping is really easy to use, but really powerful as well.

Apparently I seem to have duplicate products in my feed, producing duplicate SKUs. I tried to use the getFieldCombine helper like this:

<sku helper="ho_import/import::getFieldCombine">
    <fields>
        <prefix field="sku"/>
        <ordercode field="bestelcode"/>
    </fields>
    <glue>-</glue>
</sku>

The sku's it generates are fine, but still there appear duplicates.

Now here's my actual question: What's the best way to deal with duplicate products in the feed within this module? Do I write my own helper to prevent it?

how to add store_view values to a dropdown attribute?

I'm trying to add some translations to a dropdown attribute but each translation is added as an option. I'm I doing something wrong?

<import_options>
    <dropdown_attributes>
        <manufacturer>manufacturer</manufacturer>
        <gender>gender</gender>
        <product_type>product_type</product_type>
        <product_line>product_line</product_line>
        <size>size</size>
    </dropdown_attributes>
    <multiselect_attributes>
        <colors>colors</colors>
        <extra_colors>extra_colors</extra_colors>
    </multiselect_attributes>
</import_options>
<gender field="gender">
    <store_view>
        <nl_website_be field="gender_nl" />
        <fr_website_be field="gender_fr" />
        <website_nl field="gender_nl" />
        <website_fr field="gender_fr" />
        <website_com field="gender_en" />
        <website_de field="gender_de" />
    </store_view>
</gender>


<colors helper="ho_import/import::getFieldSplit">
    <field field="colors"/>
    <split>,</split>
    <store_view>
        <nl_website_be helper="ho_import/import::getFieldSplit">
            <field field="colors_nl"/>
            <split>,</split>
        </nl_website_be>
        <fr_website_be helper="ho_import/import::getFieldSplit">
            <field field="colors_fr"/>
            <split>,</split>
        </fr_website_be>
        <website_nl helper="ho_import/import::getFieldSplit">
            <field field="colors_nl"/>
            <split>,</split>
        </website_nl>
        <website_fr helper="ho_import/import::getFieldSplit">
            <field field="colors_fr"/>
            <split>,</split>
        </website_fr>
        <website_com helper="ho_import/import::getFieldSplit">
            <field field="colors_en"/>
            <split>,</split>
        </website_com>
        <website_de helper="ho_import/import::getFieldSplit">
            <field field="colors_de"/>
            <split>,</split>
        </website_de>
    </store_view>
</colors>

Import translations per store.

Hi,

I was wondering if it's possible to import translations of a category or a product by "_store"? I'm building my csv dynamically like this:

image

Is that possilbe to only update the stock?

Hi,
I try to just use "store,websites,sku,qty" these fields to update the existing products stock.
When using it
And try "php hoimport.php -action line -profile products_profile " it told
| Invalid value for Attribute Set column (set does not exists?) | ERROR |
and
| Required attribute 'name' has an empty value | ERROR |
| Required attribute 'price' has an empty value | ERROR |
| Required attribute 'short_description' has an empty value | ERROR |
| Required attribute 'tax_class_id' has an empty value | ERROR |
+-----------------------------------------------------------+------------------+

I think it should not needed when update the stock only.
Or does Ho_Import only support create ,not support update products?

getFieldMap throws an error

Hi!
I have an error when trying the example:

I try to map some fields like mentioned in the example:

                    <gender helper="ho_import/import::getFieldMap">
                        <field field="Geschlecht"/>
                        <mapping>
                            <male from="M" to="male"/>
                            <female from="F" to="female"/>
                        </mapping>
                    </gender>

But now I get following error

Notice: Undefined index: @  in .../app/code/community/Ho/Import/Helper/Import.php on line 375

That is because Ho_Import_Model_Mapper::mapItem does not return the correct mapping. That happens in the Method mapItem in line 150:

$attributes = isset($fieldConfig['@']) ? $fieldConfig['@'] : array();

At this moment, fieldConfig has not the correct format. I appended an image how the array $fieldConfig looks like. So $fieldConfig['@'] does not exist.
fieldconfig in mapitem

The method finally returns null and so these values cannot get mapped. How to solve this?

Kind regards, Rokko

tput: command not found AND setItem() must be an array, boolean given

I'm having an issue when running the shell. While running a -action line test I get tout: command not found AFTER Mapping 'profile':1.

Also, when running a -dryrun and actual import I get the following message:

Recoverable Error: Argument 1 passed to Ho_Import_Model_Mapper::setItem() must be an array, boolean given, called in /app/code/community/Ho/Import/Model/Import.php on line 457 and defined in /app/code/community/Ho/Import/Model/Mapper.php on line 46

Any pointers would be greatly appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.