steps to import images with a product - magento

What are the steps to import a product with images. I mean - the images, precisely.
So I have this code now:
protected function _getImages($product)
{
$importImagesDirectory = Mage::getBaseDir()."/".Mage::getStoreConfig('xmlimport/product/import_images_dir');
if(file_exists($importImagesDirectory))
{
$addImage['sku'] = (string)$product['PK_Produkt'];
$addImage['_media_image'] = $importImagesDirectory . $this->_getPresentationAttributeValue($product, '#Art="Bild" and #Rang="1"');
$addImage['_media_attribute_id'] = Mage::getSingleton('catalog/product')->getResource()->getAttribute('media_gallery')->getAttributeId();
$addImage['_media_is_disabled'] = 0;
$addImage['_media_position'] = 1;
// the following 4 lines are just acquiring string values - the name of the picture
$addImage['_media_lable'] = $this->_getPresentationAttributeValue($product, '#Art="Bild" and #Rang="1"');
$addImage['image'] = $this->_getPresentationAttributeValue($product, '#Art="Bild" and #Rang="1"');;
$addImage['small_image'] = $this->_getPresentationAttributeValue($product, '#Art="Bild" and #Rang="1"');;
$addImage['thumbnail'] = $this->_getPresentationAttributeValue($product, '#Art="Bild" and #Rang="1"');;
}
else Mage::log('Error! Image with name: ' . $importImagesDirectory . ' does not exist! ', null, 'error_image.log', true);
return $addImage;
}
So this array is being merged with the array containing the product information, that is being imported. Now, I was said that the function should also move the images from my media/import/ folder to somewhere catalog/product/ folder, because Magento looks up for images in that folder. Anf if I just import the information, but don't move the images - then no effect (which actually happens right now).
So I am asking, how does that work, is there a function from the API to make this "movement", is that the correct procedure?

As per this answer you need to use addImageToMediaGallery.
You need to have an instance of a catalog/product object. That should be easy $product = Mage::getModel('catalog/product'); and then you need to load its data from the DB for example $product->load($id);.
$product->addImageToMediaGallery($filePath, $imageType, false);
Magento stores product files in media/catalog/product/X/Y/XYfilename.ext where X and Y are the first letters of the filename. So Magento creates two levels of subfolders based on the first two letters in the filename. This logic is not present directly in addImageToMediaGallery, it's in Mage_Catalog_Model_Product_Attribute_Backend_Media::addImage().
magento_root: app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php

Related

images are saving like tmp file in public folder

hi m trying to add data in db but images saves like tmp file, m storing these pics in ecommmerce\public\images\backend_images\category_images and these real pics are not saving instead their real name in db they are saving in folder like this: https://ibb.co/CHXTm3j .. any solution . here is my code:
store function:
$category = new Category;
$category->category_name = $request->category_name;
$category->category_description = $request->category_description;
$category->category_slug = $request->category_slug;
$path = $request->file('category_image');
$image = $path->getClientOriginalName();
$path->move(public_path('images/backend_images/category_images'));
$category->category_image = $image;
$category->save();
Since you are missing the parameter for filename there. Your function to move the original file should be:
$path->move(public_path('images/backend_images/category_images'), $image);
If you do not provide that parameter, the default value would be temp name of the file rather than it's original name.

Magmi overwriting position of products in category

I'm using Magmi to import products into my Magento store. Categories are created on the fly and products are imported. All is working well.
Except for one thing: each time I run a Magmi import, the position of the product in the Magento category is set to 0. This way I cannot sort my products on position.
I have searched the Magmi wiki and github for someone who has run into the same problem, but didn't find anything.
Anyone familiar with this issue and is there a way to avoid it?
I wait too long an answer and do it myself, here is a fix:
my fix works other way - category positions clear only if you add $item["category_reset"] == 1; param to product params.
:1280 sting(in current magmi version) or find the public function assignCategories($pid, $item) in magmi_productimportengine.php.
ater
$cce = $this->tablename("catalog_category_entity");
$ccpt = $this->tablename("catalog_category_product");
add next code:
$sql = "SELECT $ccpt.*
FROM $ccpt
JOIN $cce ON $cce.entity_id=$ccpt.category_id
WHERE product_id=?";
$currentPositions = $this->selectAll($sql,$pid);
then change category reset:
if (!isset($item["category_reset"]) || $item["category_reset"] == 1)
{...}
to
if (isset($item["category_reset"]) && $item["category_reset"] == 1)
{
$sql = "DELETE $ccpt.*
FROM $ccpt
JOIN $cce ON $cce.entity_id=$ccpt.category_id
WHERE product_id=?";
$this->delete($sql, $pid);
$currentPositions = array();
}
after this change block with positioning
foreach ($catids as $catdef)
{...}
to:
// find positive category assignments
if (is_array($currentPositions) && count($currentPositions)) {
foreach ($currentPositions as $currentPosition) {
$catPos[$currentPosition['category_id']] = $currentPosition['position'];
}
}
foreach ($catids as $catdef)
{
$a = explode("::", $catdef);
$catid = $a[0];
if (count($a) > 1 && $a[1] != 0) {
$catpos = $a[1];
}
else {
if (isset($catPos[$catid]) && $catPos[$catid] != 0) {
$catpos = $catPos[$catid];
}
else {
$catpos = "0";
}
}
$rel = getRelative($catid);
if ($rel == "-")
{
$ddata[] = $catid;
}
else
{
$cdata[$catid] = $catpos;
}
}
if you dont import position, your current position will save. If it 0, it stay 0.
for clear actual position - add param to product item:
$item["category_reset"] == 1;
or change string back:
if ($item["category_reset"] == 1)
{ ....}
to:
if (!isset($item["category_reset"]) || $item["category_reset"] == 1)
{...}
Only a comment but since I'm a long-time reader but never setup an account and can't leave a comment directly with no rep. I know this is an old post, but I just found it and used AlexVegas's code above (thank you!). Worked almost fine for me, but in my case I still wanted the categories to fully reset to only what was in my Magmi import but I wanted the positions to remain intact. As-is above, the categories only append to the existing unless you use the category_reset column in your import, and if you do that it also resets the position.
If you're like me and want only the position to remain intact, but allow Magmi to overwrite the categories each time, use Alex's code above but tweak it a little
Where he says to change
if (!isset($item["category_reset"]) || $item["category_reset"] == 1)
{...}
to
if (isset($item["category_reset"]) && $item["category_reset"] == 1)
{
$sql = "DELETE $ccpt.*
FROM $ccpt
JOIN $cce ON $cce.entity_id=$ccpt.category_id
WHERE product_id=?";
$this->delete($sql, $pid);
$currentPositions = array();
}
Don't change it. It's that simple. In his code it prevents the category reset unless the column is specified, which is why the if statement gets changed. If the column exists, it also wipes out the currentPositions array that stores the current positions within the categories so those get reset as well.
If you want to append to the categories unless category_reset is in your import, but don't want to overwrite the positioning, use Alex's code as it is above in his answer but leave out
$currentPositions = array();
That way it won't overwrite the array that is storing the positions within the categories
Not an actual solution-
You can try using this plugin
http://www.magentocommerce.com/magento-connect/c3-category-position-import-export-extension.html/
You can ignore UPDATE position if exist
category creator/importer v0.2.5
at line 1248 replace with
if (count($inserts) > 0) {
$sql = "INSERT IGNORE INTO $ccpt (`category_id`,`product_id`,`position`) VALUES ";
$sql .= implode(",", $inserts);
// $sql .= " ON DUPLICATE KEY IGNORE";
$this->insert($sql, $data);
unset($data);
}
The Magmi wiki specifically mentions item positioning functionality here See quoted text below. This seems to describe exactly the functionality you are looking for? I have not tested it myself.
Quote:
Item positioning
From magmi 0.7.18 , category_ids column has been enhanced with item positioning. This feature is also supported in category importer from version 0.2+ (since category importer plugin is roughly a category_ids generator)
Sample
store,sku,....,categories
admin,00001,.....,cat name with \/ in the name and positioning::3
<= here we "escaped" the tree separator with a backslash , the category will be created as "catname with / in the name and positioning"
sku 00001 will be set with position 3 in the category
End quote

Can't get image out with appended numbering - CodeIgniter

its a silly question but I'm really bad in escaping quotes :/.
I'm using the table class to generate a table of products, and in that table each row has an image to be displayed for that product. The images are stored using their product_id as a name with an appended "_x" because there's more than one image per product, so an example of an image name is 193_1.
This is how I'm generating my rows for the table:
$table_row = array();
foreach ($r->result() as $p)
{
$table_row = NULL;
$table_row[] = "<img src='http://localhost/CI/photos/$p->product_id\"1\".jpg' height='150' width='150'/>";
$table_row[] = $p->product_id;
$table_row[] = $p->title;
$table_row[] = $p->description;
$table_row[] = $p->price;
$table_row[] = $p->stock;
$this->table->add_row($table_row);
}
But the image won't show, even when I've escaped the '1'. I only want to display the first image as that is the main one, so that's why I've hard-coded the number. Could someone please help? I've tried multiple ways i.e.
"<img src='http://localhost/CI/photos/$p->product_id '1' .jpg' height='150' width='150'/>"
"<img src='http://localhost/CodeIgniter/photos/<?php echo $p->product_id; ?>1.jpg' height='150' width='150'/>";
But the image still doesn't show. The table is being generated in my Controller which is a PHP file so I don't really think I need to use php tags
"<img src='http://localhost/CodeIgniter/images/" . $product->product_id . "_1.jpg' height='100' width='100'/>";

Magento - cms/page collection - apply filter to return only pages which are unique to a given store id (ie not also assigned to other stores)

I can use:
Mage::getModel('cms/page')->getCollection()->addStoreFilter($store_id);
to retrieve a collection of CMS pages filtered by Store Id.
But how do I get it to remove ones which are also assigned to other stores?
ie: I do not want it to return items which have 'All Store Views' as the Store View. (Or any other additional store id assigned to that CMS page.) It has to only return pages unique to that one store.
I am extending the Aitoc permissions module, so that Store Admins cant view or edit CMS pages and static blocks which might impact other stores. This involves filtering those items from the grid.
There's no native collection method to do this, so you'll need to
Query the cms_page_store table for pages unique to a given store
Use the results from above in your filter
I didn't fully test the following, but it should work (and if it doesn't, it'll give you a good start on your own query)
$page = Mage::getModel('cms/page');
$resource = $page->getResource();
$read = $resource->getReadConnection();
#$select = $read->query('SELECT page_id FROM ' . $resource->getTable('cms/page_store') . ' GROUP BY store_id');
//set total count to look for. 1 means the page only appears once.
$total_stores_count_to_look_for = '1';
//get the table name. Need to pass through getTable to ensure any prefix used is added
$table_name = $resource->getTable('cms/page_store');
//aggregate count select from the cmd_page_store database
//greater than 0 ensures the "all stores" pages aren't selected
$select = $read->query('SELECT page_id as total
FROM '.$table_name.'
WHERE store_id > 0
GROUP BY page_id
HAVING count(page_id) = ?',array($total_stores_count_to_look_for));
//fetch all the rows, which will be page ids
$ids = $select->fetchAll();
//query for pages using IDs from above
$pages = Mage::getModel('cms/page')->getCollection()->addFieldToFilter('page_id',array('in'=>$ids));
foreach($pages as $page)
{
var_dump($page->getData());
}
If you have thousands and thousands of CMS pages it may be worth it to alter the cms/page collection's select to join in aggregate table data. I'll leave that as an exercise for the reader, as those sorts of joins can get tricky.
$collection = Mage::getModel('cms/page')->getCollection();
$collection->getSelect()
->join(
array('cps' => $collection->getTable('cms/page_store')),
'cps.page_id = main_table.page_id AND cps.store_id != 0',
array('store_id')
)
->columns(array('stores_count' => new Zend_Db_Expr('COUNT(cps.store_id)')))
->group('main_table.page_id')
->having('stores_count = ?', 1)
->having('cps.store_id = ?', $storeId)
;
Fusing some elements of the solutions proposed by Alan and Vitaly with my own cumbersome understanding, I achieved what I needed with the following code.
To put into context, I was extending the Aitoc permissions module, so that Store Admins cant view or edit CMS pages and static blocks which might impact other stores. This involved filtering those items from the grid.
$collection = Mage::getModel('cms/page')->getCollection();
$collection->addStoreFilter(Mage::helper('aitpermissions')->getStoreIds());
$conn = Mage::getSingleton('core/resource')->getConnection('core_read');
$page_ids = array();
foreach($collection as $key=>$item) {
$page_id = $item->getId();
$results = $conn->fetchAll("SELECT * FROM cms_page_store
WHERE page_id = ".$page_id.";");
$count = 0;
$arr_stores = array();
foreach($results as $row) {
$arr_stores[] = $row['store_id'];
$count++;
}
//We dont want to show the item if any of the following are true:
//The store id = 0 (Means its assigned to All Stores)
//There is more than one store assigned to this CMS page
if( in_array('0',$arr_stores) || $count>1) {
//This removes results from the grid (but oddly not the paging)
$collection->removeItemByKey($key);
}
else {
//build an array which we will use to remove results from the paging
$page_ids[] = $page_id;
}
}
//This removes results from paging (but not the grid)
$collection->addFieldToFilter('page_id',array('in'=>$page_ids));
I'm not sure why I needed to use two different methods to filter from the paging and the grid.
The site uses magento 1.5 so perhaps there is an issue related to that.
Either way, this solution worked for me.
My solution to add field store_id to pages collection via join, and use collection method addFieldToFilter().
$pages = Mage::getModel('cms/page')->getCollection();
$pages->getSelect()->joinInner(
array('cms_page_store' => 'cms_page_store'),
'main_table.page_id = cms_page_store.page_id',
array()
);
$pages->addFieldToFilter('store_id', ['in' => [1, 2]]);

Sphinx wildcard searching won't work

I have used the following code:
function searchSphinx2($tofind,$jobtype_id,$payper_id,$onetimeBounds)
{
$this->load->library('session');
$this->load->library('sphinxclient');
global $result;
global $functionresult;
$functionresult=array();
$this->sphinxclient->setServer('localhost', 3312);
$this->sphinxclient->SetMatchMode( SPH_MATCH_ANY );
$this->sphinxclient->SetIndexWeights( array("jobs_index_main"=>10, "jobs_index_delta"=>10,"jobs_index_prefix_main"=>1,"jobs_index_prefix_delta"=>1,"jobs_index_infix_main"=>1,"jobs_index_infix_delta"=>1) );
$this->sphinxclient->ResetFilters();
$this->sphinxclient->SetFilter('jobtype_id',$jobtype_id,TRUE);
$this->sphinxclient->SetFilter('payper_id',$payper_id,TRUE);
$this->sphinxclient->SetFilterFloatRange('payamount', $ontimeBounds[0], $ontimeBounds[1], FALSE);
$this->sphinxclient->AddQuery("$tofind", "jobs_index_main;jobs_index_delta");
$this->sphinxclient->AddQuery("*$tofind*", "jobs_index_main_prefix;jobs_index_delta_prefix");
$this->sphinxclient->AddQuery("*$tofind*", "jobs_index_main_infix;jobs_index_delta_infix");
$result = $this->sphinxclient->RunQueries();
In my data base there is a job with title "Intern" However, if I search for "inter" I do not get any results.
The indices in my confi file are set up as follows:
index jobs_index_prefix_main
{
source = jobs_main
path = /var/newsphinx/index/main_prefix
morphology = stem_en
min_stemming_len = 4
min_word_len = 3
min_prefix_len = 3
prefix_fields = title, contactname
enable_star =1
}
Can anyone tell me why I am not getting partial word results?
I've never found Sphinx to return partial matches without using stars. I agree that it's not particularly intuitive (surely if the prefixes are being indexed, there's a match?), but if you want to ensure you always get results, add a star to the end of each word.

Resources