Magento sort by entity_id - magento

Does anyone know how to make entity_id visible on the frontend as a sortable attribute? I went to manage attributes and I can't add entity_id as an attribute as it says
"The attribute code 'entity_id' is reserved by system. Please try another attribute code"
So I tried to do a search in the whole database I had Magento on using the following SQL CMD:
select attribute_id from eav_attribute where attribute_code = 'updated_at';
and it returned zero results, I tried other attributes and those showed...
Does anyone know how I can add entity_id as an attribute, as I can't even make it visible because I have no idea what the attribute_id # is even while searching the whole database for that value.
Here is the code I use to make a attribute visible on the admin section of magento:
UPDATE `catalog_eav_attribute`
SET `is_visible` = '1'
WHERE `catalog_eav_attribute`.`attribute_id` = 105;
I've tried searching high and low for days, and trying different variations - so stuck at this point, any help would be great.
I'm using Magento Enterprise 12.2 if that helps, but to be honest the DB is not much different than the community version the only differences are the added modules but when it comes to products it's pretty much the same.

This is surprisingly nasty - I can't see a way to do this simply in the DB, as entity_id isn't a standard attribute (it's really just a key field) and the core code repeats the same logic in three place (urgh).
It's also changed a lot since the older versions of Magento, so many of the tutorials and forum posts on this no longer apply.
What you can do is add "entity_id" in as a new sorting option, similar to the way "Best Value" exists as a sorting option. In the following example I've labelled it "Newest"
The usual caveats apply: You should do this in an extension (or at the least in /local/ overrides) but the three core file methods that need overriding in Community Edition 1.7 are:
Mage_Adminhtml_Model_System_Config_Source_Catalog_ListSort
public function toOptionArray()
{
$options = array();
$options[] = array(//benz001
'label' => Mage::helper('catalog')->__('Newest'),
'value' => 'entity_id'
); //end benz001
$options[] = array(
'label' => Mage::helper('catalog')->__('Best Value'),
'value' => 'position'
);
foreach ($this->_getCatalogConfig()->getAttributesUsedForSortBy() as $attribute) {
$options[] = array(
'label' => Mage::helper('catalog')->__($attribute['frontend_label']),
'value' => $attribute['attribute_code']
);
}
return $options;
}
Then Mage_Catalog_Model_Category_Attribute_Source_Sortby
/**
* Retrieve All options
*
* #return array
*/
public function getAllOptions()
{
if (is_null($this->_options)) {
$this->_options = array(
array(//benz001
'label' => Mage::helper('catalog')->__('Newest'),
'value' => 'entity_id'
), //end benz001
array(
'label' => Mage::helper('catalog')->__('Best Value'),
'value' => 'position'
));
foreach ($this->_getCatalogConfig()->getAttributesUsedForSortBy() as $attribute) {
$this->_options[] = array(
'label' => Mage::helper('catalog')->__($attribute['frontend_label']),
'value' => $attribute['attribute_code']
);
}
}
return $this->_options;
}
And then Mage_Catalog_Model_Config
public function getAttributeUsedForSortByArray()
{
$options = array(
'entity_id' => Mage::helper('catalog')->__('Newest'), //benz001
'position' => Mage::helper('catalog')->__('Position'),
);
foreach ($this->getAttributesUsedForSortBy() as $attribute) {
/* #var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
$options[$attribute->getAttributeCode()] = $attribute->getStoreLabel();
}
return $options;
}
With those in place, flush the cache and refresh and you can then select to sort by Newest/entity_id in the config and on the category page and on the frontend.
Note: even if you have caching turned off it's still a good idea to flush the cache - parts of the admin are cached even when caching is disabled.

Related

Save TCA changes in TYPO3 on select box

I created I new field in my TCA. I want to list all articles and select one, to set the article as top-article.
The articles have a UID and the database a column called istoparticle.
tx_vendor_domain_model_article is the table with all infos of the article.
I added a TCAcolumn.
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tt_content', array(
'tx_test_istoparticle' => array(
'exclude' => 1,
'onChange' => 'reload',
'label' => 'Top Article',
'l10n_mode' => 'exclude',
'config' => array(
'type' => 'select',
'itemsProcFunc' => \Vendor\MyArticles\Hooks\Backend\Preview\ArticleRenderer::class . '->getArticleTitle',
)
),
));
With a userfunction
public function getTopArticles($param){
$pid = $param['row']['pid'];
$articles = $this->getArticles($pid);
foreach ($articles as $article) {
$record = BackendUtility::getRecord('tx_vendor_domain_model_article', $article->getUid());
$title = $record['header'];
$param['items'][][] = $title;
}
}
BTW:$record has all infos that I need, UID, bodytext and so on. But I can only store the header in the array!?
Now I got all the titles listed in my selectbox in the backend.
What do I have to do, to save my toparticle If I select an article in the backend?
Is there a onChange method for the TCA? And how can I get the infos like the Uid if I select one?
Items in TCA configuration should have at least two elements - first one is the label and second is the value. There are more options, but I think not needed in your case. You can read about them here: https://docs.typo3.org/typo3cms/TCAReference/8.7/ColumnsConfig/Type/Select.html#items
It means your usefFunc should look like that:
public function getTopArticles(&$param){
$pid = $param['row']['pid'];
$teasers = $this->getArticles($pid);
foreach ($articles as $article) {
$record = BackendUtility::getRecord('tx_vendor_domain_model_article', $article->getUid());
$param['items'][] = [
$record['header'],
$record['uid'],
]
}
}
And yes, there is onChange functionality in TCA:
https://docs.typo3.org/typo3cms/TCAReference/8.7/Columns/Index.html?highlight=onchange#onchange
If you are using older TYPO3 than 8.6 you would need to look for requestUpdate according to: https://docs.typo3.org/typo3cms/extensions/core/8.7/Changelog/8.6/Deprecation-78899-TCACtrlFieldRequestUpdateDropped.html

ajax call in magento 2

I have created a custom module in Magento2 where currently I'm selecting a customer and entered multiple order numbers, it will saved into a custom table in the database.
Currently I have to entered order numbers in a textarea but now I want to display all orders after choosing the customer which are not in Complete status.
From this section admin choose orders by clicking on the right side checkbox and Saved it.
Can anyone help me to solve this problem?
Existing Module’s Layout
Want to modify the above layout to the following one: In this desired system when admin change the customer name order numbers associated with that customer will be listed.
New invoice
Code I have used to create the customer dropdown field:
$fieldset->addField('customer_id', 'select', array(
'label' => __('Customer'),
'name' => 'customer_id',
'title' => __('Customer'),
'values' => $this->getCustomerOptionArray()
));
protected function getCustomerOptionArray()
{
$options = array();
$options[] = array(
'value' => 0,
'label' => __('Select Customer'),
);
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerObj = $objectManager->create('Magento\Customer\Model\Customer')->getCollection();
foreach ($customerObj as $customerObjdata ){
$options[] = array(
'value' => $customerObjdata->getId(),
'label' => $customerObjdata->getName(),
);
}
return $options;
}

Creating configurable products programmatically - pricing_value not saved

I have a custom xml file and I make a massive import of the products. I have some simples products under configurables ones. All is working well, configurable products are created with the simple products the "associated products" tab but one last thing still doesn't work : the price of each product.
Actually, Each simple product has its own price and the correct value is well saved in its attribute but in the "super product attribute configuration" panel, the values are empty.
When I fill the price fields manually, it works but it obviously must be done by the script, programmatically.
Here is my function to create the configurable product :
protected function createConfigurableProductFromSimpleProduct($product, $flagshipID)
{
$configurableProduct = $product->duplicate();
$configurableProduct->getResource()->save($configurableProduct);
$configurableProduct= Mage::getModel('catalog/product')->load($configurableProduct->getId());
$configurableProduct->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)
->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->setSku($flagshipID)
->setDefRef($product_id)
->getTypeInstance()->setUsedProductAttributeIds(array($this->getAttributeId('root_colors'))); //attribute ID of attribute 'root_colors' in my store
$configurableProduct->setName($configurableProduct->getName());
$configurableProduct->setStatus(1);
$configurableProduct->setStockData(array(
'is_in_stock' => 1
));
$configurableProduct->setUrlKey($configurableProduct->getName());
$configurableProduct->save();
return $configurableProduct;
}
And here is the code for linking simple products to this configurable product :
protected function linkSimpleProductsToConfigurableProduct($simpleProducts, $configurableProduct)
{
$configurableProductsData = array();
foreach ($simpleProducts as $_product) {
$_product->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE);
$_product->getResource()->save($_product);
$configurableProductsData[$_product->getId()] = array( //[id] = id of a simple product associated with this configurable
'0' => array(
'label' => $this->getAttributeRawValue($this->getAttributeId('root_colors'), $_product->getRoot()), //attribute label
'attribute_id' => $this->getAttributeId('root_colors'), //attribute ID of discriminator attribute in my store
'value_index' => $_product->getColor(),
'pricing_value' => $_product->getPrice(),
'is_percent' => '0'
)
);
}
$configurableAttributesData = $configurableProduct->getTypeInstance()->getConfigurableAttributesAsArray();
$configurableProduct->setCanSaveConfigurableAttributes(true);
$configurableProduct->setConfigurableAttributesData($configurableAttributesData);
$configurableProduct->setConfigurableProductsData($configurableProductsData);
var_dump('saving configurable product after having link some simple products');
$configurableProduct->save();
}
Any help is welcome, thank you !
Hy all! After reading thousand of answer i solved it!
$cProduct->setCanSaveConfigurableAttributes(true);
$cProduct->setCanSaveCustomOptions(true);
$cProductTypeInstance = $cProduct->getTypeInstance();
$cProductTypeInstance->setUsedProductAttributeIds(array($attribute_id));
$attributes_array = $cProductTypeInstance->getConfigurableAttributesAsArray();
foreach($attributes_array as $key => $attribute_array) {
$attributes_array[$key]['use_default'] = 0;
$attributes_array[$key]['position'] = 0;
if (isset($attribute_array['frontend_label'])) {
$attributes_array[$key]['label'] = $attribute_array['frontend_label'];
} else {
$attributes_array[$key]['label'] = $attribute_array['attribute_code'];
}
}
$dataArray = array();
foreach ($simpleProducts as $simpleArray) {
$dataArray[$simpleArray['id']] = array(
"label" => $simpleArray['label'],
"attribute_id" => $simpleArray['attr_id'],
"value_index" => $simpleArray['value'],
"is_percent" => '0',
"pricing_value" => $simpleArray['price']
);
}
// MAIN MOD! Here i prepare an array for attributesData.
$valuesArray = array();
foreach($dataArray as $data){
$valuesArray[] = $data;
}
// MAIN MOD!
// this is not the best, but in my case I've only one attribute.
$attributes_array[0]['values'] = $valuesArray;
$cProduct->setConfigurableProductsData($dataArray);
$cProduct->setConfigurableAttributesData($attributes_array);
I dont post all the codes, but i see that with these little modification it solve the problem!
I'm having the exact same issue and suspect this is due to something in Magento 1.9. I've tried a couple of code workarounds, but none of them work yet. Hmm, same bummer as you are suffering from.
Instead of providing further comments, I'll just provide an answer instead ;)
I digged into this a little bit deeper and found that the setConfigurableProductsData() call is designed to set product information, but the flag "pricing_value" simply does not work (at least it doesn't work in Magento 1.9). The call is only used to identify the Simple Products that are part of this Configurable Product. Instead the setConfigurableAttributesData() call needs to be used to define the relationship between Simple Products and pricing.
The following code worked for me: It moves the definition of specific option values (identified with value_index) with specific prices (pricing_value) as part of the attribute-data and not the product-data.
$configurableAttributeSizeValues = array();
foreach($simpleProducts as $simpleProduct) {
$configurableAttributeSizeValues[] = array(
'label' => $simpleProduct->getAttributeText('size'),
'value_index' => $simpleProduct->getSize(),
'is_percent' => false,
'pricing_value' => $simpleProduct->getPrice(),
);
}
$configurableAttributeSize = array(
'id' => null,
'label' => 'Size',
'frontend_label' => 'Size',
'attribute_id' => $attribute->getId(),
'attribute_code' => 'size',
'values' => $configurableAttributeSizeValues,
'position' => 0,
);
$configurableAttributesData = array($configurableAttributeSize);
$configurableProductsIds = array();
foreach($simpleProducts as $simpleProduct) {
$configurableProductsIds[$simpleProduct->getId()] = $simpleProduct->getId();
}
$product->setConfigurableProductsData($configurableProductsIds);
$product->setConfigurableAttributesData($configurableAttributesData);
$product->setCanSaveConfigurableAttributes(true);
Before this code is put to use, I've loaded a product-collection called $simpleProducts and a single attribute $attribute. If you want to load multiple attributes to the same product, you can by adding them to the $configurableAttributesData array.
The original $configurableProductsData that you created in your code can still be used, however because most of its purpose is moved to the attributes-array instead, you can also just create a simple array of Simple Product IDs instead. That's what I did with $configurableProductsIds.
Hope this helps you out as well.
Here is what worked for me (some code repeated for clarity). Both setConfigurableProductsData and setConfigurableAttributesData need to be used for pricing_value to be saved.
$configurableAttributesData = $product->getTypeInstance()->getConfigurableAttributesAsArray();
$product->getTypeInstance()->setUsedProductAttributeIds(array($attribute->getId()));
$product->setCanSaveConfigurableAttributes(true);
$configurableProductsData[$childId] = array(
$childProductId => array(
'label' => $childProduct->getAttributeText($attribute->getAttributeCode()),
'attribute_id' => $attribute->getId(),
'value_index' => $optionId,
'is_percent' => false,
'pricing_value' => $childProduct->getPrice()
)
);
$configurableAttributesData[0]['values'][] = array(
'label' => $childProduct->getAttributeText($attribute->getAttributeCode()),
'attribute_id' => $attribute->getId(),
'value_index' => $optionId,
'is_percent' => false,
'pricing_value' => $childProduct->getPrice()
);
$configurableAttributesData[0]['attribute_id'] = $attribute->getId();
$product->setConfigurableProductsData($configurableProductsData);
$product->setConfigurableAttributesData($configurableAttributesData);
$product->save();

Add my custom attribute to customer object in Magento (1.7.x)

I have created an custom attribute using the Magento installer script below:
$installer = new Mage_Eav_Model_Entity_Setup();
$installer->startSetup();
$installer->addAttribute('customer', 'organisation_id', array(
'input' => 'select', //or select or whatever you like
'type' => 'int', //or varchar or anything you want it
'label' => 'Organisation ID',
'visible' => 1,
'required' => 0, //mandatory? then 1
'user_defined' => 1,
'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
));
$installer->endSetup();
On the onepage checkout screen I have a dropdown where a customer selects an organisation from a dropdown menu - once they click the 'Continue' button it posts an ajax request and goes to the next step 'Billing' e.g the post request looks like this..
org[organisation_id] - 12345
org[name] - ACME Inc
My function that deals with this is follows - can anyone assist how to add this to the customer & order object?
public function saveOrgAction()
{
if ($this->_expireAjax()) {
return;
}
if ($this->getRequest()->isPost()) {
$data = $this->getRequest()->getPost('org', array());
// todo:hook up saving the org id passed here to customer & order object
// UPDATE... I believe this is correct?
$customer = Mage::getSingleton('customer/session')->getCustomer(); // get customer object
$customer->setOrganisationId($org_id)->save();
if (!isset($result['error'])) {
$result['goto_section'] = 'billing';
}
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
}
}
What is the best way to add this 'organisation_id' attribute to the customer object (note I am using Magento 1.7.2)
$customer->setOrganisationId('123')->save();
if you need it in the order you have to set it in the current quote object
via
$quote->setOrganisationId('123');
and use this explanation to push the attribute automatically through quote to order conversion. But dont forget to create the correct labled column in sales_flat_order!
explanation how to push any attribute automatically through quote to order conversion

How to add categories in Joomla 2.5

Does anyone know how to properly insert new content categories to the DB programatically?
For each post in the categories table, there is also a post saved in the assets table with lft and rgt set.
Is there any native Joomla class I can use for this instead of plain SQL?
Please Please Only use the native classes, which categories will handle for you seamlessly. As soon as you add categories the whole thing will be handled automagically. Just look at any core component to see how.
It is not easy to update the assets table using sql, it is all very specifically managed and part of a complex series of foreign keyed tables.
Extend JTable or JTableContent to handle this.
Here is some code I just whipped together that just uses the JTableCategory class, so it can be used simply on the front or admin side of Joomla
$table = JTable::getInstance('category');
$data = array();
// name the category
$data['title'] = $title;
// set the parent category for the new category
$data['parent_id'] = $parent_id;
// set what extension the category is for
$data['extension'] = $extension;
// Set the category to be published by default
$data['published'] = 1;
// setLocation uses the parent_id and updates the nesting columns correctly
$table->setLocation($data['parent_id'], 'last-child');
// push our data into the table object
$table->bind($data);
// some data checks including setting the alias based on the name
if ($table->check()) {
// and store it!
$table->store();
// Success
} else {
// Error
}
Naturally you would want to get the data pieces set correctly, but these are the core ones to set.
Here is a function I've created just for this purpose, after some digging & experimenting.
It uses core classes, so it needs an access to them (for me it's basically a part of Joomla component).
Mind, it's for Joomla 3, for Joomla 2.5 and before, you need to change JModelLegacy to JModel.
function createCategory( $name, $parent_id, $note )
{
JTable::addIncludePath( JPATH_ADMINISTRATOR . '/components/com_categories/tables' );
$cat_model = JModelLegacy::getInstance( 'Category', 'CategoriesModel' );
$data = array (
'id' => 0,
'parent_id' => $parent_id,
'extension' => 'com_content',
'title' => $name,
'alias' => '',
'note' => $note,
'description' => '',
'published' => '1',
'access' => '1',
'metadesc' => '',
'metakey' => '',
'created_user_id' => '0',
'language' => '*',
'rules' => array(
'core.create' => array(),
'core.delete' => array(),
'core.edit' => array(),
'core.edit.state' => array(),
'core.edit.own' => array(),
),
'params' => array(
'category_layout' => '',
'image' => '',
),
'metadata' => array(
'author' => '',
'robots' => '',
),
);
if( !$cat_model->save( $data ) )
{
return NULL;
}
$categories = JCategories::getInstance( 'Content' );
$subcategory = $categories->get( $cat_model->getState( "category.id" ) );
return $subcategory;
}
You can perhaps use the save() in category.php file.
File location: root\administrator\components\com_categories\models\category.php
It saves the form data supplied to it!
The JOS_assets table is to store the ACL for each asset that is created.
If you do not update this table while programatically creating the category, the default ACL will apply. And when later you open and save the category in the administrative panel, the ACL will be updated as it should have been by core Joomla!.
You can create an SQL query very easily though and update the asset table as well. Its easy to understand once you open the table's content in phpmyadmin.

Resources