Kategori ağacını, ürün sayfasını düzenle sekmesinin birinde bulunan kategori ağacı olan özel uzantıya eklemeye çalışıyorum
Kategori ağacını, ürün sayfasını düzenle sekmesinin birinde bulunan kategori ağacı olan özel uzantıya eklemeye çalışıyorum
Yanıtlar:
Kendini hazırla, bu uzun olacak. İşte gidiyor.
Aşağıdaki dosyalara ihtiyacınız olacak:
app/code/local/[Namespace]/[Module]/Block/Adminhtml/[Entity]/Edit/Tab/Categories.php
- kategorileri oluşturacak sekme.
<?php
class [Namespace]_[Module]_Block_Adminhtml_[Entity]_Edit_Tab_Categories
extends Mage_Adminhtml_Block_Catalog_Category_Tree {
protected $_categoryIds = null;
protected $_selectedNodes = null;
public function __construct() {
parent::__construct();
$this->setTemplate('[namespace]_module/[entity]/edit/tab/categories.phtml');
$this->_withProductCount = false;
}
public function get[Entity](){
return Mage::registry('current_[entity]'); //use other registration key if you have one
}
public function getCategoryIds(){
if (is_null($this->_categoryIds)){
$categories = $this->get[Entity]()->getSelectedCategories();
$ids = array();
foreach ($categories as $category){
$ids[] = $category->getId();
}
$this->_categoryIds = $ids;
}
return $this->_categoryIds;
}
public function getIdsString(){
return implode(',', $this->getCategoryIds());
}
public function getRootNode(){
$root = $this->getRoot();
if ($root && in_array($root->getId(), $this->getCategoryIds())) {
$root->setChecked(true);
}
return $root;
}
public function getRoot($parentNodeCategory = null, $recursionLevel = 3){
if (!is_null($parentNodeCategory) && $parentNodeCategory->getId()) {
return $this->getNode($parentNodeCategory, $recursionLevel);
}
$root = Mage::registry('category_root');
if (is_null($root)) {
$rootId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
$ids = $this->getSelectedCategoryPathIds($rootId);
$tree = Mage::getResourceSingleton('catalog/category_tree')
->loadByIds($ids, false, false);
if ($this->getCategory()) {
$tree->loadEnsuredNodes($this->getCategory(), $tree->getNodeById($rootId));
}
$tree->addCollectionData($this->getCategoryCollection());
$root = $tree->getNodeById($rootId);
Mage::register('category_root', $root);
}
return $root;
}
protected function _getNodeJson($node, $level = 1){
$item = parent::_getNodeJson($node, $level);
if ($this->_isParentSelectedCategory($node)) {
$item['expanded'] = true;
}
if (in_array($node->getId(), $this->getCategoryIds())) {
$item['checked'] = true;
}
return $item;
}
protected function _isParentSelectedCategory($node){
$result = false;
// Contains string with all category IDs of children (not exactly direct) of the node
$allChildren = $node->getAllChildren();
if ($allChildren) {
$selectedCategoryIds = $this->getCategoryIds();
$allChildrenArr = explode(',', $allChildren);
for ($i = 0, $cnt = count($selectedCategoryIds); $i < $cnt; $i++) {
$isSelf = $node->getId() == $selectedCategoryIds[$i];
if (!$isSelf && in_array($selectedCategoryIds[$i], $allChildrenArr)) {
$result = true;
break;
}
}
}
return $result;
}
protected function _getSelectedNodes(){
if ($this->_selectedNodes === null) {
$this->_selectedNodes = array();
$root = $this->getRoot();
foreach ($this->getCategoryIds() as $categoryId) {
if ($root) {
$this->_selectedNodes[] = $root->getTree()->getNodeById($categoryId);
}
}
}
return $this->_selectedNodes;
}
public function getCategoryChildrenJson($categoryId){
$category = Mage::getModel('catalog/category')->load($categoryId);
$node = $this->getRoot($category, 1)->getTree()->getNodeById($categoryId);
if (!$node || !$node->hasChildren()) {
return '[]';
}
$children = array();
foreach ($node->getChildren() as $child) {
$children[] = $this->_getNodeJson($child);
}
return Mage::helper('core')->jsonEncode($children);
}
public function getLoadTreeUrl($expanded = null){
return $this->getUrl('*/*/categoriesJson', array('_current' => true));
}
public function getSelectedCategoryPathIds($rootId = false){
$ids = array();
$categoryIds = $this->getCategoryIds();
if (empty($categoryIds)) {
return array();
}
$collection = Mage::getResourceModel('catalog/category_collection');
if ($rootId) {
$collection->addFieldToFilter('parent_id', $rootId);
}
else {
$collection->addFieldToFilter('entity_id', array('in'=>$categoryIds));
}
foreach ($collection as $item) {
if ($rootId && !in_array($rootId, $item->getPathIds())) {
continue;
}
foreach ($item->getPathIds() as $id) {
if (!in_array($id, $ids)) {
$ids[] = $id;
}
}
}
return $ids;
}
}
app/design/adminhtml/default/default/[namespace]_[module]/[entity]/tab/edit/categories.phtml
- kategorileri oluşturmak için gereken şablon
<div class="entry-edit">
<div class="entry-edit-head">
<h4 class="icon-head head-edit-form fieldset-legend">
<?php echo Mage::helper('[module]')->__('Categories') ?>
</h4>
</div>
<fieldset id="grop_fields">
<input type="hidden" name="category_ids" id="[entity]_categories" value="<?php echo $this->getIdsString() ?>">
<div id="[entity]-categories" class="tree"></div>
</fieldset>
</div>
<?php if($this->getRootNode() && $this->getRootNode()->hasChildren()): ?>
<script type="text/javascript">
Ext.EventManager.onDocumentReady(function() {
var categoryLoader = new Ext.tree.TreeLoader({
dataUrl: '<?php echo $this->getLoadTreeUrl()?>'
});
categoryLoader.createNode = function(config) {
config.uiProvider = Ext.tree.CheckboxNodeUI;
var node;
if (config.children && !config.children.length) {
delete(config.children);
node = new Ext.tree.AsyncTreeNode(config);
}
else {
node = new Ext.tree.TreeNode(config);
}
return node;
};
categoryLoader.on("beforeload", function(treeLoader, node) {
treeLoader.baseParams.category = node.attributes.id;
});
categoryLoader.on("load", function(treeLoader, node, config) {
varienWindowOnload();
});
var tree = new Ext.tree.TreePanel('[entity]-categories', {
animate:true,
loader: categoryLoader,
enableDD:false,
containerScroll: true,
rootUIProvider: Ext.tree.CheckboxNodeUI,
selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
rootVisible: '<?php echo $this->getRootNode()->getIsVisible() ?>'
});
tree.on('check', function(node) {
if(node.attributes.checked) {
categoryAdd(node.id);
} else {
categoryRemove(node.id);
}
varienElementMethods.setHasChanges(node.getUI().checkbox);
}, tree);
var root = new Ext.tree.TreeNode({
text: '<?php echo $this->jsQuoteEscape($this->getRootNode()->getName()) ?>',
draggable:false,
checked:'<?php echo $this->getRootNode()->getChecked() ?>',
id:'<?php echo $this->getRootNode()->getId() ?>',
disabled: <?php echo ($this->getRootNode()->getDisabled() ? 'true' : 'false') ?>,
uiProvider: Ext.tree.CheckboxNodeUI
});
tree.setRootNode(root);
bildCategoryTree(root, <?php echo $this->getTreeJson() ?>);
tree.addListener('click', categoryClick.createDelegate(this));
tree.render();
root.expand();
});
function bildCategoryTree(parent, config){
if (!config) {
return null;
}
if (parent && config && config.length){
for (var i = 0; i < config.length; i++){
config[i].uiProvider = Ext.tree.CheckboxNodeUI;
var node;
var _node = Object.clone(config[i]);
if (_node.children && !_node.children.length) {
delete(_node.children);
node = new Ext.tree.AsyncTreeNode(_node);
}
else {
node = new Ext.tree.TreeNode(config[i]);
}
parent.appendChild(node);
node.loader = node.getOwnerTree().loader;
if(config[i].children){
bildCategoryTree(node, config[i].children);
}
}
}
}
function categoryClick(node, e){
if (node.disabled) {
return;
}
node.getUI().check(!node.getUI().checked());
varienElementMethods.setHasChanges(Event.element(e), e);
};
function categoryAdd(id) {
var ids = $('[entity]_categories').value.split(',');
ids.push(id);
$('[entity]_categories').value = ids.join(',');
}
function categoryRemove(id) {
var ids = $('[entity]_categories').value.split(',');
while (-1 != ids.indexOf(id)) {
ids.splice(ids.indexOf(id), 1);
}
$('[entity]_categories').value = ids.join(',');
}
</script>
<?php endif; ?>
Özel varlığınızın sekmelerini eklediğiniz form dosyanıza şunu da ekleyin:
$this->addTab('categories', array(
'label' => Mage::helper('[module]')->__('Associated categories'),
'url' => $this->getUrl('*/*/categories', array('_current' => true)),
'class' => 'ajax'
));
Özel varlığınızın yönetici kontrol biriminde, kategori isteklerini yerine getirecek olan bu 2 eylem:
public function categoriesAction(){
$this->_init[Entity]();
$this->loadLayout();
$this->renderLayout();
}
public function categoriesJsonAction(){
$this->_init[Entity]();
$this->getResponse()->setBody(
$this->getLayout()->createBlock('[module]/adminhtml_[entity]_edit_tab_categories')
->getCategoryChildrenJson($this->getRequest()->getParam('category'))
);
}
ve aynı kontrol cihazında bu yöntemin bulunduğundan emin olun:
protected function _init[Entity](){
$[entity]Id = (int) $this->getRequest()->getParam('id');
$[enity] = Mage::getModel('[module]/[entity]');
if ($[entity]Id) {
$[entity]->load($[entity]Id);
}
Mage::register('current_[entity]', $[entity]);
return $[entity];
}
Modülünüzün yönetici düzen dosyasında, kategoriler eylemi için bu tutamacı ekleyin:
<adminhtml_[module]_[entity]_categories>
<block type="core/text_list" name="root" output="toHtml">
<block type="[module]/adminhtml_[entity]_edit_tab_categories" name="[entity].edit.tab.categories"/>
</block>
</adminhtml_[module]_[entity]_categories>
Şimdi verilerinizi kaydetmeye devam edelim.
Bunun için modülünüzün kurulum / yükseltme komut dosyalarından birinde aşağıdakilere ihtiyacınız olacaktır. Bu, bağlı değerlerin depolanacağı bir tablo oluşturacaktır
$table = $this->getConnection()
->newTable($this->getTable('[module]/[entity]_category'))
->addColumn('rel_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'unsigned' => true,
'identity' => true,
'nullable' => false,
'primary' => true,
), 'Relation ID')
->addColumn('[entity]_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), '[Entity] ID')
->addColumn('category_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'unsigned' => true,
'nullable' => false,
'default' => '0',
), 'Category ID')
->addColumn('position', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
'nullable' => false,
'default' => '0',
), 'Position')
->addIndex($this->getIdxName('[module]/[entity]_category', array('category_id')), array('category_id'))
->addForeignKey($this->getFkName('[module]/[entity]_category', '[entity]_id', '[module]/[entity]', 'entity_id'), '[entity]_id', $this->getTable('[module]/[entity]'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->addForeignKey($this->getFkName('[module]/[entity]_category', 'category_id', 'catalog/category', 'entity_id'), 'category_id', $this->getTable('catalog/category'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
->addIndex(
$this->getIdxName(
'[module]/[entity]_category',
array('[entity]_id', 'category_id'),
Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE
),
array('[entity]_id', 'category_id'),
array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE))
->setComment('[Entity] to Category Linkage Table');
$this->getConnection()->createTable($table);
Masanı açıkla. Bunu etiketin config.xml
içine ekle<[module]_resource><entities>
<[entity]_category>
<table>[module]_[entity]_category</table>
</[entity]_category>
Kategorilere bağlanmak için bir modele ihtiyacınız olacak:
app/code/local/[Namespace]/[Module]/Model/[Entity]/Category.php
<?php
class [Namespace]_[Module]_Model_[Entity]_Category
extends Mage_Core_Model_Abstract {
protected function _construct(){
$this->_init('[module]/[entity]_category');
}
public function save[Entity]Relation($[entity]){
$data = $[entity]->getCategoriesData();
if (!is_null($data)) {
$this->_getResource()->save[Entity]Relation($[entity], $data);
}
return $this;
}
public function getCategoryCollection($[entity]){
$collection = Mage::getResourceModel('[module]/[entity]_category_collection')
->add[Entity]Filter($[entity]);
return $collection;
}
}
ve bir kaynak modeli app/code/local/[Namespace]/[Module]/Model/Resource/[Entity]/Category.php
:
<?php
class [Namespace]_[Module]_Model_Resource_[Entity]_Category
extends Mage_Core_Model_Resource_Db_Abstract {
protected function _construct(){
$this->_init('[module]/[entity]_category', 'rel_id');
}
public function save[Entity]Relation($[entity], $data){
if (!is_array($data)) {
$data = array();
}
$deleteCondition = $this->_getWriteAdapter()->quoteInto('[entity]_id=?', $[entity]->getId());
$this->_getWriteAdapter()->delete($this->getMainTable(), $deleteCondition);
foreach ($data as $categoryId) {
if (!empty($categoryId)){
$this->_getWriteAdapter()->insert($this->getMainTable(), array(
'[entity]_id' => $[entity]->getId(),
'category_id' => $categoryId,
'position' => 1
));
}
}
return $this;
}
}
ve bir koleksiyon kaynak modeli: app/code/local/[Namespace]/[Module]/Model/Resource/[Entity]/Category/Collection.php
<?php
class [Namespace]_[Module]_Model_Resource_[Entity]_Category_Collection
extends Mage_Catalog_Model_Resource_Category_Collection{
protected $_joinedFields = false;
public function joinFields(){
if (!$this->_joinedFields){
$this->getSelect()->join(
array('related' => $this->getTable('[module]/[entity]_category')),
'related.category_id = main_table.entity_id',
array('position')
);
$this->_joinedFields = true;
}
return $this;
}
public function add[Entity]Filter($[entity]){
if ($[entity] instanceof [Namespace]_[Module]_Model_[Entity]){
$[entity] = $[entity]->getId();
}
if (!$this->_joinedFields){
$this->joinFields();
}
$this->getSelect()->where('related.[entity]_id = ?', $[entity]);
return $this;
}
}
Şimdi yönetici kontrol cihazınızın saveAction’ında aramadan önce bu hakkı ekleyin $[entity]->save()
$categories = $this->getRequest()->getPost('category_ids', -1);
if ($categories != -1) {
$categories = explode(',', $categories);
$categories = array_unique($categories);
$[entity]->setCategoriesData($categories);
}
Varlık modelinizde bunu sınıfınızın en üstüne ekleyin: protected $_categoryInstance = null;
ve bu yöntemleri her yerde:
protected function _afterSave() {
$this->getCategoryInstance()->save[Entity]Relation($this);
return parent::_afterSave();
}
public function getCategoryInstance(){
if (!$this->_categoryInstance) {
$this->_categoryInstance = Mage::getSingleton('[module]/[entity]_category');
}
return $this->_categoryInstance;
}
public function getSelectedCategories(){
if (!$this->hasSelectedCategories()) {
$categories = array();
foreach ($this->getSelectedCategoriesCollection() as $category) {
$categories[] = $category;
}
$this->setSelectedCategories($categories);
}
return $this->getData('selected_categories');
}
public function getSelectedCategoriesCollection(){
$collection = $this->getCategoryInstance()->getCategoryCollection($this);
return $collection;
}
Bu konuda. Umarım hiçbir şeyi özlememişimdir. Kod bazı değişiklikler gerektirebilir, çünkü modülünüzün tam olarak nasıl yapıldığını bilmiyorum, ancak ana fikirler var. Bazı hata ayıklama ile işe almak gerekir.
Not: Yukarıdaki kod, Ultimate Module Creator v1.9 kullanılarak üretildi .
En azından Magento 1.9 için extJ'lerin yüklendiğinden emin olmalısınız.
Arka uçta extJS kullanımını etkinleştirmek için aşağıdaki yöntemlerden birini kullanın:
Kontrol cihazınızda bunu kullanın:
$this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
Mizanpajınızda xml bunu kullanın:
<reference name="head">
<action method="setCanLoadExtJs">
<value>1</value>
</action>
</reference>