Magento Entwicklung: Unterschied zwischen den Versionen

Aus Vosp.info
Wechseln zu:Navigation, Suche
(datenbank tabelle)
Zeile 1: Zeile 1:
 +
[[magento extension: anc_image]] - eine einfache Extension inkl. datenbanktabelle
 +
 
= Entwicklung =
 
= Entwicklung =
 
* [https://inchoo.net/ecommerce/magento/how-to-create-a-new-product-type-in-magento/ how-to-create-a-new-product-type-in-magento]
 
* [https://inchoo.net/ecommerce/magento/how-to-create-a-new-product-type-in-magento/ how-to-create-a-new-product-type-in-magento]

Version vom 13. April 2014, 20:17 Uhr

magento extension: anc_image - eine einfache Extension inkl. datenbanktabelle

Entwicklung

globale Funktionsaufrufe

dieses sind allgemeine Funktionsaufrufe, die nahe zu überall (oder Kontex bezogen) aufgerufen werden können

/**
 * hole _POST und _GET Variablen
 */
$post_get_array = Mage::app()->getRequest();

/**
 * hole aktuelle Session
 */
$session = Mage::getSingleton('checkout/session');

// was in die session schreiben
Mage::getSingleton('checkout/session')->setName('Value');

// was aus der session holen
Mage::getSingleton('checkout/session')->getName('Value');

/**
 * aktuelle url
 */
Mage::helper('core/url')->getCurrentUrl();

Model

/** 
 * product laden - achtung er lädt wirklich jedes mal neu, auf jeden fall chachen
 */
$product = Mage::getModel("catalog/product");
$product = $product->load($param_id);
$product_data = $product->getData();

// ein model laden, welches nicht über id identifiziert wird, sprich andere tabellenspalte (Achtung, auch wenn mehrere ergibt nur eins zurück )
$ncimages = Mage::getModel('kürzel_modulename/modeltabelleklasse')->load($value, 'tabellenspaltenname');

// zeige max() eines query
$quote = Mage::getSingleton('checkout/session')->getQuote();
$collection = Mage::getModel('sales/quote_item')->getCollection();
$string_sql = $collection->getSelect()->reset(Zend_Db_Select::COLUMNS)->columns('max(item_id) as last_item_id')
				    ->where("quote_id = ".$quote->getId()); 
$lastItemId = $collection->getData();

D::s($collection->getData(), '$maxItemId: '.$lastItemId[0]['last_item_id']);

Frontend: Warenkorb

/**
 * hole aktuellen Quote (Angebot)
 */
$quote = Mage::getSingleton('checkout/session')->getQuote();

            if (Mage::registry('current_product')) {
                $this->_product = Mage::registry('current_product');
            } else {
                $this->_product = Mage::getSingleton('catalog/product');
            }


/**
 * wenn mensch ein Posten im Warenkorb bearbeitet, kann sich über die Url=/checkout/cart/configure/id/751/ (_GET) die aktuelle Item ID geholt werden
 */
$getParamId = Mage::app()->getRequest()->getParam('id')

Block .... schnipsel

{{block type=”catalog/product_list” category_id=”[Ihre Kategorie ID]” template=”catalog/product/list.phtml”}}

Statische Blöcke

Admin Panel >> CMS > Statische Blöcke >> Neuer Block
  • interner Bezeichner: wichtig_dieser_wird_benutzt_um_im_Code_drauf_zuzugreifen
  • Status: aktiviert
  • der rest nach Belieben
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('wichtig_dieser_wird_benutzt_um_im_Code_drauf_zuzugreifen')->toHTML(); ?>

<!-- es kann natürlich auch die ID genommen werden, ist aber wohl ja eher unpraktisch -->
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('10')->toHTML(); ?>

Quelle




allgemein Backendend

 // um in einem template die customer url zu bekommen
 $customer_url = $this->getUrl('adminhtml/customer/edit/', array('id'=>$val));

allgemein Frontend

Links


jquery

local.xml

<block type="page/html_head" name="head" as="head">
  ...
 <action method="addJs"><script>scripts/jquery-1.6.min.js</script></action>
 <action method="addJs"><script>scripts/blogrammierer.js</script></action>
</block>

scripts/blogrammierer.js

$.noConflict();
jQuery(document).ready(function($) {     
  // Hier der eigentliche Jquery-Quellcode
});


Unterkategorien einer Kategorie inklusive Bilder und Beschreibung anzeigen

1. Statischen Block anlegen (Backend > CMS > Statische Blöcke >> Neuer Block)

  • Blocktitel: subcategory_listing_full
  • Interner Bezeichner: subcategory_listing_full
  • Status: Aktiviert
  • Inhalt (WYSIWYG Editor ausschalten): eine der folgenden Aufrufe eingen
 <!-- nur typo und template: er nimmt die Kategorie die (per url) aufgerufen wird -->
 {{block type="catalog/navigation"template="catalog/navigation/subcategory_listing_full.phtml"}}
 <!-- parameter category_id: er nimmt die Kategorie Id als Grundlage und ignoriert die Url -->
 {{block type="catalog/navigation" category_id="8" template="catalog/navigation/subcategory_listing_full.phtml"}}
 <!-- zusätzlich falls nur der Name ohne Bilder und Beschreibung angezeigt werden soll -->
 {{block type="catalog/navigation" category_id="8" only_name="1" template="catalog/navigation/subcategory_listing_full.phtml"}}

2. folgende Datei anlegen

app/design/frontend/<<OWNDESIGN>>/default/template/catalog/navigation/subcategory_listing_full.phtml

<div id="categories" class="listing">
	<?php
	
		$_maincategorylisting = $this->getCurrentCategory();
		$layer = Mage::getSingleton('catalog/layer');
		
		/**
		 *  category_id="X" im Blockaufruf angegeben wurde, dann nimm diese Kategorie als Grundlage
		 *	{{block type="catalog/navigation" category_id="8" template="catalog/navigation/subcategory_listing_full.phtml"}}
		 */
		if($this->getCategoryId()) {
			$paramCategory = Mage::getModel('catalog/category')->load($this->getCategoryId());
			$this->setCurrentCategory($paramCategory);		
			$layer->setCurrentCategory($paramCategory);
		}
		$_categories = $this->getCurrentChildCategories();
		$_helper = $this->helper('catalog/output'); 
	?>
	<?php if(count($_categories)):?>
		<?php foreach ($_categories as $_category):?>
			<?php if($_category->getIsActive()): ?>
				<?php
					$cur_category=Mage::getModel('catalog/category')->load($_category->getId());	
					$layer->setCurrentCategory($cur_category);
					$catName = $this->getCurrentCategory()->getName(); 
				?>
				<?php if(!$this->getOnlyName() && $_imageUrl=$this->getCurrentCategory()->getImageUrl()):?>
					<div class="category-image"><a href="<?php echo $this->getCategoryUrl($_category)?>"><img src="<?php echo $_imageUrl?>" height="188"></a></div>
				<?php endif;?>
				<div class="category-name"><a href="<?php echo $this->getCategoryUrl($_category)?>"> <?php echo $_category->getName()?></a></div>
				<?php if(!$this->getOnlyName() && $_description=$this->getCurrentCategory()->getDescription()): ?>
					<div class="category-description"><?php echo $_helper->categoryAttribute($_category, $_description, 'description') ?></div>
				<?php endif; ?>					
			<?php endif; ?>
		<?php endforeach?>
		<?php
			if($this->getCategoryId()) {
				$this->setCurrentCategory($_maincategorylisting);
			}
			$layer->setCurrentCategory($_maincategorylisting);  
		?> 
	<?php endif;?>
</div>

3. statischen Block einbinden

  • zb
    • über CMS > Seiten
    • oder CMS > Statische Blöcke >> Footer Links
    • oder über eine spezielle Kategorie Katalog > Kategorien verwalten >> spezielle Kategorie > Anzeige Einstellungen >> CMS Block

Quellen

interessante Links

Blog-Hints aktivieren

Admin > System > Konfiguration > Entwickleroptionen > obenlinks "Aktueller Konfig.-Bereich" > Main Website
  • Debug
    • Vorlagen Pfadhinweise: Ja
    • Blocknamen zu Hinweisen hinzufügen: Ja


Magento-Themes einfacher erstellen und modifizieren

cd Magento18/
cp -r app/design/frontend/base/default   app/design/frontend/default/my_theme
cd  app/design/frontend/default/my_theme
find -type f -exec rename -n 's/$/-disabled/' '{}' ';'     # simulation
find -type f -exec rename  's/$/-disabled/' '{}' ';'

cd ../../../../../../Magento18/
cp -r skin/frontend/base/default/ skin/frontend/default/my_theme/
cd skin/frontend/default/my_theme/
find -type f -exec rename -n 's/$/-disabled/' '{}' ';'     # simulation
find -type f -exec rename  's/$/-disabled/' '{}' ';'

cp app/design/frontend/default/my_theme/template/catalog/product/view.phtml-disabled app/design/frontend/default/my_theme/template/catalog/product/view.phtml





Extension Entwicklung

Extension Infos

  • Entwickler/Firma Kürzel: Anc
  • Modulname: Image
  • Komplett: MyImage bzw my_image
  • Extensionpfad: /var/www/Magento/AncImage/
  • Magento Installation: /var/www/Magento/Magento18

die extension erweitert im frontend für den eingeloggten kunden den "mein benutzerkonto" bereich um eine einfache bildergallerie

  • es besteht die möglichkeit per drag&drop bilder hinzuzufügen
  • sie werden auf dem server in einem ordner speziell für den eingeloggten kunden gespeichert und
  • der dateiname zusätzlich noch in einer einfachen flat tabelle gespeichert

xml Konfiguration

modul aktivierung

/var/www/Magento/AncImage/app/etc/modules/Anc_Image.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Anc_Image>
            <active>true</active>
            <codePool>local</codePool>
        </Anc_Image>
    </modules>
</config>

config.xml - konfiguration der extension

/var/www/Magento/AncImage/app/code/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <!-- versionierung des moduls -->
    <modules><Anc_Image><version>0.0.1</version></Anc_Image></modules>
    <!-- was im frontend passiert -->
    <frontend>
                <!-- einbindung der layoutkonfiguration (s.u.) -->
		<layout>
			<updates>
				<Anc_Image>
					<file>anc_image.xml</file>
				</Anc_Image>
			</updates>
		</layout>
                <!-- damit die controller funktionen über eine url erreichbar sind (s.u.) -->		
		<routers>
			<!--Umleitung bzw aktivierung der controllers-->
			<anc_image>
				<use>standard</use>
				<args>
					<module>Anc_Image</module>
					<frontName>ancimage</frontName>
				</args>				
			</anc_image>
		</routers>
    </frontend>	
    <!-- globale einstellung, derzeit die konfiguration der datenbank schnittstelle -->
	<global>
		<models>
			<anc_image>
				<class>Anc_Image_Model</class>
				<!-- folgendes ist ein verweis auf den nachfolgenden tag <anc_image_resource> -->
				<resourceModel>anc_image_resource</resourceModel>
			</anc_image>
			<anc_image_resource>
				<class>Anc_Image_Model_Resource_Mysql4</class>
				<!-- entitie's mit s hier können mehrere Tabellen(namen) untergebracht werden -->
				<entities>
					<ncimage>
						<table>anc_image_ncimage</table>
					</ncimage>
				</entities>
			</anc_image_resource>
		</models>
		<resources>
			<!-- hier verbirgt sich das installationsskript um die datenbanktabellen zu erstellen -->
			<anc_image_setup>
				<setup>
					<module>Anc_Image</module>
					<class>Mage_Sales_Model_Mysql4_Setup</class>
				</setup>
				<connection><use>core_setup</use></connection>				
			</anc_image_setup>
			<!-- datenbank verbindungen -->
			<anc_image_write><connection><use>core_write</use></connection></anc_image_write>
			<anc_image_read><connection><use>core_read</use></connection></anc_image_read>			
		</resources>
	</global>
</config>

design oberflächen einbindung

anc_image.xml wird über #config.xml - konfiguration der extension eingebunden

<frontend><layout><updates><Anc_Image><file>anc_image.xml</file></Anc_Image></updates></layout></frontend>


/var/www/Magento/AncImage/app/design/frontend/layout/anc_image.xml

<?xml version="1.0"?>
<layout version="0.1.0">
    <!-- in "meinem Benutzerkonto" wird  ein weiterer link angezeigt, der über den Controller die neue seite anzeigt -->
    <customer_account>
        <reference name="customer_account_navigation">
            <action method="addLink">
		<name>owngallery</name>
                <path>ancimage/customer/owngallery</path>
                <label>Verwalten Sie Ihre Bilder</label>
                <urlParams />
            </action>		
        </reference>
    </customer_account>	

    <!-- ansicht wird konfiguriert -->
    <anc_image_customer_owngallery>
	<!-- einbindung von javascript und css -->
		<reference name="head">
			<action method="addJs"><script>ancimage/dropzone.js</script></action>		
			<action method="addCss"><stylesheet>css/ancimage/dropzone.css</stylesheet></action>
			<action method="addJs"><script>ancimage/jquery.prettyPhoto.js</script></action>		
			<action method="addCss"><stylesheet>css/ancimage/prettyPhoto.css</stylesheet></action>			
		</reference>
	<!-- einbindung des templates -->
        	<reference name="content">
        	    <block type="core/template" name="anc_image_customer_owngallery" template="ancimage/customer_owngallery.phtml" />
        	</reference>
    </anc_image_customer_owngallery>	
	
</layout>

template

das template welches in Magento_Entwicklung#design_oberflächen_einbindung eingebunden wird, wird über den Magento_Entwicklung#Controller_-_Schnittstelle_zum_Browser Controller Aufruf (über die url) aufgerufen

    <anc_image_customer_owngallery><reference name="content"><block type="core/template" name="anc_image_customer_owngallery" template="ancimage/customer_owngallery.phtml" /></reference></anc_image_customer_owngallery>


/var/www/Magento/AncImage/app/design/frontend/template/ancimage/customer_owngallery.phtml

<?php if(Mage::getSingleton('customer/session')->isLoggedIn()): ?>
	<?php $customer = Mage::getSingleton('customer/session')->getCustomer(); ?>

	<!-- Anzeige der Daten -->

		<?php $ncimages = Mage::getModel('anc_image/ncimage')->getCollection()->addFieldToFilter('ancii_customer_id', $customer->getId());  ?>
		<?php $path = DS.'media'.DS.'anc'.DS.'image'.DS.'customer'.DS.$customer->getId().DS; ?>

		<ul class="gallery clearfix">
			<?php foreach($ncimages->getItems() as $ncimage ): ?>
				<a rel="prettyPhoto[pp_gal2]" href="<?php echo $path.$ncimage['ancii_file'] ?>" title="You can add caption to pictures.">
					<img height="50" src="<?php echo $path.$ncimage['ancii_file'] ?>" >
				</a>
			<?php endforeach; ?>
		</ul>	
	
		<script type="text/javascript">
	
			jQuery(document).ready(function($) {
				jQuery("a[rel^='prettyPhoto']").prettyPhoto({});
			});
		</script>
	
	<!-- Formular eingabe der Daten -->
		<form action="<?php echo $this->getUrl('ancimage/customer/uploadImage'); ?>" class="dropzone">
			<div class="fallback"><input name="file" type="file" multiple /></div>
		</form>
<?php else: ?>
	<h1>Bitte loggen Sie sich ein!</h1>
<?php endif; ?>

app code - die eigentliche code logik inklusive datenbank zugriff

Controller - Schnittstelle zum Browser

/var/www/Magento/AncImage/app/code/controllers/CustomerController.php

<?php
/** 
 * Controller ist dank @see app/code/etc/config.xml im <routers> tag
 * als url direkt im Browser erreichbar
 */
class Anc_Image_CustomerController extends Mage_Core_Controller_Front_Action {
    protected function _initAction() {
		$this->loadLayout();
		return $this;
    }	
	/**
	 * fnc ist in "mein Benutzerkonto" laut @see @see app/design/frontend/layout/anc_image.xml als link aufrufbar,
	 * * durch selbige anc_image.xml bekommt die fnc das template @see app/design/frontend/template/ancimage/customer_owngallery.phtml beigesteuert
	 */
	public function owngalleryAction() {
		$this->loadLayout();
		$this->getLayout()->getBlock('root')->setTemplate('page/1column.phtml');
		$this->renderLayout();
	}
	
	/**
	 * fnc wird übers formular von owngalleryAction() bzw customer_owngallery.phtml 
	 * bei einem datei upload aufgerufen und verarbeitet die post werte 
	 * * kopiert datei in entsprechendes kunden verzeichniss
	 * * speichert dateiname im model / in tabelle
	 */
	public function uploadImageAction() {
		
		if (Mage::getSingleton('customer/session')->isLoggedIn()) {

			/* Get the customer data */
			$customer = Mage::getSingleton('customer/session')->getCustomer();
			
			if(isset($_FILES['file']['name']) && $_FILES['file']['name'] != '') {
				try
				{      
					$path = Mage::getBaseDir().DS.'media'.DS.'anc'.DS.'image'.DS.'customer'.DS.$customer->getId().DS;  //desitnation directory    
					$fname = $_FILES['file']['name']; //file name                       
					$uploader = new Varien_File_Uploader('file'); //load class
					$uploader->setAllowedExtensions(array('jpg','jpeg','gif','png')); //Allowed extension for file
					$uploader->setAllowCreateFolders(true); //for creating the directory if not exists
					$uploader->setAllowRenameFiles(false); //if true, uploaded file's name will be changed, if file with the same name already exists directory.
					$uploader->setFilesDispersion(false);
					$uploader->save($path,$fname); //save the file on the specified path

					$ncimage = Mage::getModel('anc_image/ncimage');
					$ncimage->setData('ancii_customer_id',$customer->getId());
					$ncimage->setData('ancii_path', $path);
					$ncimage->setData('ancii_file',$fname);
					$ncimage->save();
					
				} catch (Exception $e) {
					echo 'Error Message: !! '.$e->getMessage();
				}
			}		 			

		} else {
			echo('nicht eingeloggt');
		}
	}
}

die datenbankverbindung

datenbank tabelle

folgende skriptdatei zur erstellung der datenbank tabelle wird (siehe #config.xml - konfiguration der extension ) über folgenden code eingebunden

	<resources>
		<anc_image_setup>
			<setup><module>Anc_Image</module><class>Mage_Sales_Model_Mysql4_Setup</class></setup>
			<connection><use>core_setup</use></connection>				
		</anc_image_setup>
	</resources>


  • sie wird übrings einmalig ausgeführt beim einfachen reload einer seite im magento backend
    • dies führt zu folgendes
      • in die tabelle: core_resource kommt ein Eintrag der extension inkl. version
      • install-0.0.1.php wird ausgeführt und tabelle erstellt
    • wenn also das skript noch mal ausgeführt werden soll, muss nicht nur die tabelle gelöscht werden, sondern auch der eintrag in der core_resource tabelle


app/code/sql/anc_image_setup/install-0.0.1.php

<?php
/**
 * @var Mage_Sales_Model_Mysql4_Setup $installer
 */
$installer = $this;
$installer->startSetup();

	$tableName = $installer->getTable('anc_image/ncimage');
	$table = $installer->getConnection()->newTable($tableName)
			->addColumn('entity_id',		Varien_Db_Ddl_Table::TYPE_INTEGER,null,array('identity' => true,'unsigned' => true,'nullable' => false,'primary' => true,),'Id')
			->addColumn('ancii_customer_id',	Varien_Db_Ddl_Table::TYPE_INTEGER,null,array('unsigned' => true,'nullable' => false,'default' => '0',),'Who Created')			
			->addColumn('ancii_created_at',		Varien_Db_Ddl_Table::TYPE_TIMESTAMP,null,array(),'When beginn')
			->addColumn('ancii_updated_at',		Varien_Db_Ddl_Table::TYPE_TIMESTAMP,null,array(),'When updated')
			->addColumn('ancii_deleted',		Varien_Db_Ddl_Table::TYPE_TINYINT,null,array('default' => '0'),'Deleted')			
			->addColumn('ancii_path',		Varien_Db_Ddl_Table::TYPE_VARCHAR,null,array(),'file path')			
			->addColumn('ancii_file',		Varien_Db_Ddl_Table::TYPE_VARCHAR,null,array(),'file')			
			->addColumn('ancii_comment',		Varien_Db_Ddl_Table::TYPE_VARCHAR,null,array(),'comment')
	;
	$installer->getConnection()->createTable($table);
	$installer->endSetup();
?>

datenbank zugriffs klassen

Anc_Image_Model_Ncimage

/var/www/Magento/AncImage/app/code/Model/Ncimage.php

class Anc_Image_Model_Ncimage extends Mage_Core_Model_Abstract {
    protected function _construct()
    {
		parent::_construct();
        $this->_init('anc_image/ncimage');
    }	
}


Anc_Image_Model_Resource_Mysql4_Ncimage

Achtung: der ort und name dieser klasse wird über #config.xml - konfiguration der extension bestimmt und ist eine so genannte Erweiterung vom Anc_Image_Model_Resource_Mysql4 string

 
<global><models><anc_image_resource><class>Anc_Image_Model_Resource_Mysql4</class></anc_image_resource></models></global>


/var/www/Magento/AncImage/app/code/Model/Resource/Mysql4/Ncimage.php

class Anc_Image_Model_Resource_Mysql4_Ncimage extends Mage_Core_Model_Mysql4_Abstract {
    protected function _construct() {
        $this->_init('anc_image/ncimage', 'entity_id');
    }	

	protected function _beforeSave(Mage_Core_Model_Abstract $ncimage) {
		if(!$ncimage->getId()) {
			$ncimage->setAnciiCreatedAt(now());
		}
		$ncimage->setAnciiUpdatedAt(now());
		return parent::_beforeSave($ncimage);
	}	
	
}
Anc_Image_Model_Resource_Mysql4_Ncimage_Collection

Achtung: der ort und name dieser klasse wird über #config.xml - konfiguration der extension bestimmt und ist eine so genannte Erweiterung vom Anc_Image_Model_Resource_Mysql4 string

 
<global><models><anc_image_resource><class>Anc_Image_Model_Resource_Mysql4</class></anc_image_resource></models></global>


/var/www/Magento/AncImage/app/code/Model/Resource/Mysql4/Ncimage/Collection.php

class Anc_Image_Model_Resource_Mysql4_Ncimage_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract{
    
    public function _construct(){
        $this->_init('anc_image/ncimage');
        parent::_construct();
    }
}

weiteres

der vollständigkeitshalber sind hier noch die externen bibliohtken aufgelistet ... diese dateien lassen sich auf den jeweiligen seiten runterladen, desweiteren muss jquery noch eingebunden werden

css

/var/www/Magento/AncImage/skin/frontend/css/dropzone.css /var/www/Magento/AncImage/skin/frontend/css/prettyPhoto.css

js

/var/www/Magento/AncImage/js/dropzone.js /var/www/Magento/AncImage/js/jquery.prettyPhoto.js

Verlinkungen

ln -s /var/www/Magento/MyImage/app/code  /var/www/Magento/Magento18/app/code/local/My/Image
ln -s /var/www/Magento/MyImage/app/etc/modules/My_Image.xml  /var/www/Magento/Magento18/app/etc/modules/My_Image.xml

#
# folgende Verknüpfung  fürs Design muss noch gemacht werden
#

# wenn base/default genommen wird, wird die extension (bzw in diesem fall das layout) in jedem design eingebunden
ln -s /var/www/Magento/MyImage/app/design/frontend/layout/my_image.xml /var/www/Magento/Magento18/app/design/frontend/base/default/layout/my_image.xml
ln -s /var/www/Magento/MyImage/app/design/frontend/template/ancimage/ /var/www/Magento/Magento18/app/design/frontend/base/default/template/myimage
 
# folgendes führt dazu das die extension ausschließlich im default/default design eingebunden wird
ln -s /var/www/Magento/MyImage/app/design/frontend/layout/my_image.xml /var/www/Magento/Magento18/app/design/frontend/default/default/layout/my_image.xml
ln -s /var/www/Magento/MyImage/app/design/frontend/template/ancimage/ /var/www/Magento/Magento18/app/design/frontend/default/default/template/myimage

Quellen