Jump to content

Resolved - Automatic Export to Google Merchant


Dirty Butter

Recommended Posts

Today's export is named googlebase_20130611_1.txt. It's saved on my hard drive to wherever I set my browser to save downloads, and I save the file with the name plushgooglebase.txt.

 

Then I FTP the file to a folder named FEEDS on my domain root. Google automatically loads the feed from there. So if it could automatically be named plushgooglebase.txt and be saved to dirtybutter.com/FEEDS it would automate the whole process. All I'd have to do would be to remember to click on Google Export.

 

If this could be done it would need to apply ONLY to the Google export link, obviously.

Link to comment
Share on other sites

All that is chosen from the Merchant Center account part of Google. I can set the location and name to anything I want, but it has to stay consistent (and be distinguishable from the feed name for another store - estatesgooglebase.txt) - default date format CC creates won't work, and it has to be stored online to create a scheduled feed upload to Google.

 

If this is complicated it's probably not worth your time, Bsmither. There are others on the forum with much more pressing issues. But if it intrigues you, go for it.

Link to comment
Share on other sites

Well, I'm looking at this page:

/admin.php?_g=products&node=export

 

The right-most column of the table, Export URL, implies that by supplying this link to the agent that fetches the list, the agent can fetch it at any time (because it is generated on demand):

/admin.php?_g=products&node=export&page=1&per_page=5000&format=googlebase&node=export&access=XXX

where XXX is the Product Feed Access Password specified in the Store Settings, Advanced tab.

 

What are your thoughts? Do the settings in your Merchant Center require an actual txt-type filename? How do the settings in the Merchant Center distinguish between estates and plush text files? That is, does the Merchant Center know what to do with each? Does it keep the records in each file segregated somehow?

Link to comment
Share on other sites

Google takes care of the feeds separately as long as they have unique names. It's OK for them to be in the same FEEDS file. OR, if it works better to have a file for each  googlebase.txt that can be done, too.in their own store directory - that's not a problem.

 

I don't know how to use that Product Feed Password - is it the FTP password?

 

If you are scheduling your data feed, please ensure that the feed URL directly points to your feed file. If it points to your website instead, your item information will be fetched in a HTML format which will result in a feed failure. The URL must begin with either http://, https://, ftp://, or sftp://. If your file requires a username and password to access, please enter the appropriate login information to allow Google to access your file.

 

 

From Google -

When creating your data feed, remember to save your file in one of the supported filetypes with the appropriate filename extension:

  • .txt: text
  • .xml: XML
  • .gz: Gnu zip, compressed text or XML
  • .zip: Zip, compressed text or XML
  • .bz2: Bzip2, compressed text or XML
Link to comment
Share on other sites

Ok, when using the Export URL above, I get back a tab-separated value, plain text response (like when the browser requests a text file). If Google is strict about requiring there actually be a file (and named as described), I can see where an on-demand request would not work.

 

"I don't know how to use that Product Feed Password - is it the FTP password?"

No. Just pick a random sequence of letters.

Link to comment
Share on other sites

Well, try this:

 

In the file /admin/sources/products.export.inc.php, line 48, add the new line:

$image_mode = 'medium';
$feed_file_name = CC_ROOT_DIR.CC_DS.'FEEDS'.CC_DS.'plushgooglebase.txt';

Then, at around line 163, make the lines look like:

$GLOBALS['debug']->supress();
if (isset($feed_file_name) && !empty($feed_file_name)) {
  $fp = fopen($feed_file_name, "w");
  fwrite($fp, $output);
  fclose($fp);
  $GLOBALS['main']->setACPNotify("Feed File written (hopefully)");
  httpredir(currentPage(array('page','per_page','format','access')));
} elseif(!isset($_GET['access'])) {
  deliverFile(false, false, $output, $filename);

I haven't got the httpredir and currentPage functions fully figured out, and my experiments has my browser open a new browser window/tab when returning to this admin page.

 

This is hard-coded hack and won't survive an upgrade.

Link to comment
Share on other sites

Well, IF I inserted your code correctly - it crashed - no error warnings, no debug info.
 

 if ($results = $GLOBALS['db']->query($query, $per_page, $page)) {
		switch (strtolower($_GET['format'])) {
			case 'googlebase':
			case 'storeya':
				$header_fields	= array('id','link','title','description','image_link','price','condition','upc','ean','jan','isbn','gtin', 'man','brand','availability','google_product_category','product_type','shipping_weight','identifier_exists');
				$fields		= array('product_id', 'url', 'name', 'description', 'image', 'price', 'condition','upc','ean','jan','isbn', 'gtin', 'man','manufacturer','availability','google_product_category','google_category','product_weight','identifier_exists');
				$delimiter	= "t";
				$extension	= 'txt';
				$glue		= "rn";
				$field_wrapper = '"';
				$field_keys_to_wrap = array('description');
				$image_path = 'url';
				$image_mode = 'medium';
$feed_file_name = CC_ROOT_DIR.CC_DS.'FEEDS'.CC_DS.'plushgooglebase.txt';
				break;
    ## Generate Image URL
            if (($images    = $GLOBALS['db']->select('CubeCart_image_index', array('file_id'), array('main_img' => 1, 'product_id' => $result['product_id']))) !== false) {
                $result['image']    = $catalogue->imagePath($images[0]['file_id'],$image_mode,$image_path,false);
            } else {
                $result['image']    = '';
            }

            $result['currency']    = $GLOBALS['config']->get('config', 'default_currency');
            //CSV must have double quotes around strings. This is the standard and most spreasheets will behave best this way
            foreach ($fields as $field) {
                // format specialist fields e.g. 'price currency' to '9.99 USD'
                if(stristr($field, " ")) {
                    $exploded_fields = explode(' ',$field);
                    foreach($exploded_fields as $part_field) {
                        $formatted_field[] = $result[$part_field];
                    }
                    $result[$field] = implode(' ',$formatted_field);
                }
                unset($formatted_field,$exploded_fields);
                
                $data_fields[]    = (in_array($field,$field_keys_to_wrap) && isset($result[$field])) ? $field_wrapper.$result[$field].$field_wrapper : $result[$field];
            }
    
            if(isset($header_fields)) {
                $output[]    = implode($delimiter, $header_fields);
                unset($header_fields);
            }
            $output[]    = implode($delimiter, $data_fields);
            unset($data_fields);
        }

##BSMITHER AUTOMATIC FEED HACK
    $GLOBALS['debug']->supress();
if (isset($feed_file_name) && !empty($feed_file_name)) {
  $fp = fopen($feed_file_name, "w");
  fwrite($fp, $output);
  fclose($fp);
  $GLOBALS['main']->setACPNotify("Feed File written (hopefully)");
  httpredir(currentPage(array('page','per_page','format','access')));
} elseif(!isset($_GET['access'])) {
  deliverFile(false, false, $output, $filename);
            } else {
                echo $output;
            }
            exit;
        }
    } else {
        $GLOBALS['main']->setACPWarning($lang['category']['no_products']);
    }
}

#END

 Hopefully I just inserted it wrong.

Link to comment
Share on other sites

I think some too many lines got replaced. Here is a complete if block.:

        if (isset($output) && !empty($output)) {
            $filename    = $_GET['format'].'_'.date('Ymd').'_'.$_GET['page'].'.'.$extension;
            $output        = (is_array($output)) ? implode($glue, $output) : $output;
            $GLOBALS['debug']->supress();
if (isset($feed_file_name) && !empty($feed_file_name)) {
$fp = fopen($feed_file_name, "w");fwrite($fp, $output);fclose($fp);
$GLOBALS['main']->setACPNotify("Feed File written (hopefully)");
httpredir(currentPage(array('page','per_page','format','access')));
} elseif(!isset($_GET['access'])) {
                deliverFile(false, false, $output, $filename);
            } else {
                echo $output;
            }
            exit;
        }

 

 

Just going to the page, or after clicking a link?

 

If after clicking the link:

 

Make sure there is a FEEDS folder in plush's main folder.

 

And click on the Export URL link.

Link to comment
Share on other sites

  • 1 year later...

Revisiting this for v6 with its Google_Base plugin. I'd like to get the feed automated again if possible. Getting the images to come from the source was easy.

 

I have used the code from #11 in products.export.inc.php

 

But I'm at a loss as to how to use the $feed_file_name = CC_ROOT_DIR/'FEEDS'/'plushgooglebase.txt'; in the plugin to over-ride the date feed naming system in products.export.inc.php. I tried using it as the last line in admin.product.import.format.php - but it did not use the file name or save it to the FEED folder.
 

Link to comment
Share on other sites

Hi

We have a V3 and V4 mod (that we never got around to rewriting for V5 / V6) that does this but also can be run automatically by cron so it can be produced daily, weekly without any intervention. It wouldnt be too much extra work to add the extra code to enable this plus it would be better if it was standalone rather than modifying core code again

Ian

Link to comment
Share on other sites

I have it set to run by cron via Cpanel, but Google only uploads the feed automatically once a day. I use BeyondCompare3 to bring edits into an upgrade. For now I'm OK, but this is certainly tempting. If you end up making the plugin I would certainly consider it. And maybe others would read this thread and be interested, too.

Link to comment
Share on other sites

  • 2 months later...

I tried to use this same process to setup a storeya.txt feed. But for Storeya I need to have In Stock only in the feed. I've tried changing Store Settings to use in stock only, but the feed still shows all items, including out of stock.

So is there a way to modify the admin.product.import.format.php for storeya to include in stock only?

Link to comment
Share on other sites

Ok, I see what's happening.

You are wanting any inventory item that is at zero stock level to not be included in the list?

Would you like for this to be a setting on the StoreYa settings panel?

In the meantime, we will use the StoreYa hook file /hooks/admin.product.import.format.php. There is no hook we can exploit when the export code queries for each item's stock level (Catalogue->getProductStock). So, we can either re-query the database with a modified WHERE clause (looking only at the base stock level - not stock levels per options - to start with), or work through the already available list of items removing any that have zero stock. That can be a module setting as well.

Let's re-query the database:

After:
if($_GET['format'] = 'storeya') {

Add:
$query = sprintf('SELECT I.* FROM %1$sCubeCart_inventory AS I LEFT JOIN %1$sCubeCart_category AS C ON I.cat_id = C.cat_id WHERE I.status = 1 AND I.stock_level > 0', $GLOBALS['config']->get('config', 'dbprefix'));
$results = $GLOBALS['db']->query($query, $per_page, $page);
if ($results === false) $results = array();

 

Link to comment
Share on other sites

Odd behavior that I can't find a reason for:

I had previously tweaked the code you had provided, so the validation message would show which feed file had been successful:

 if (isset($output) && !empty($output)) {
            $filename    = $_GET['format'].'_'.date('Ymd').'_'.$_GET['page'].'.'.$extension;
            $output        = (is_array($output)) ? implode($glue, $output) : $output;
            $GLOBALS['debug']->supress();
if (isset($feed_file_name) && !empty($feed_file_name)) {
$fp = fopen($feed_file_name, "w");fwrite($fp, $output);fclose($fp);
$GLOBALS['main']->setACPNotify("($filename) written");
httpredir(currentPage(array('page','per_page','format','access')));
} elseif(!isset($_GET['access'])) {
                deliverFile(false, false, $output, $filename);
            } else {
                echo $output;
            }
            exit;
        }

This was working very well. Then I added the Storeya plugin. The Storeya plugin, with your addition of the code for in-stock only works perfectly. All my other feeds are working perfectly. And I've checked, the feeds themselves are correct.

BUT, as long as the Storeya plugin is enabled, the $filename in the success validation message ALWAYS has the storeya.txt filename in it, no matter which feed is created. Clearing cache manually or via Admin does not change this behavior. I've also compared with BeyondCompare3 to be sure the only differences in the Storeya plugin and the others is what is necessary. And I've tried it without the in-stock tweak.

I'm reasonably sure the filenames in the success message were working correctly yesterday. I am now on last night's v6-master. Can you think of any 6.0.5 GitHub change that could explain this persistent filename?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...