<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Matthias Büsing - MB-tec</title>
	
	<link>http://www.mb-tec.eu</link>
	<description>Internetdienstleistungen</description>
	<lastBuildDate>Sun, 03 Jul 2011 16:43:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mb-tec" /><feedburner:info uri="mb-tec" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Einblenden von Eingabefeldern im Magento Admin Panel</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/L3QRiC3gEIc/</link>
		<comments>http://www.mb-tec.eu/magento/einblenden-von-eingabefeldern-im-magento-admin-panel/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 16:12:46 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[Admin Panel]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=864</guid>
		<description><![CDATA[Ziel ist es in der System Konfiguration des Magento Admin Panels ein Textfeld in Abhängigkeit von einem Select ein- bzw. auszublenden. Datei etc/system.xml &#60;?xml version="1.0"?&#62; &#60;config&#62; &#60;tabs&#62; &#60;mbtec translate="label" module="mbtec_test"&#62; &#60;label&#62;Mbtec&#60;/label&#62; &#60;sort_order&#62;450&#60;/sort_order&#62; &#60;/mbtec&#62; &#60;/tabs&#62; &#60;sections&#62; &#60;mbtec_test translate="label" module="mbtec_test"&#62; &#60;label&#62;Test&#60;/label&#62; &#60;tab&#62;mbtec&#60;/tab&#62; &#60;sort_order&#62;100&#60;/sort_order&#62; &#60;show_in_default&#62;1&#60;/show_in_default&#62; &#60;show_in_website&#62;1&#60;/show_in_website&#62; &#60;show_in_store&#62;1&#60;/show_in_store&#62; &#60;groups&#62; &#60;settings translate="label"&#62; &#60;label&#62;Settings&#60;/label&#62; &#60;frontend_type&#62;text&#60;/frontend_type&#62; &#60;sort_order&#62;100&#60;/sort_order&#62; &#60;show_in_default&#62;1&#60;/show_in_default&#62; &#60;show_in_website&#62;0&#60;/show_in_website&#62; &#60;show_in_store&#62;0&#60;/show_in_store&#62; &#60;fields&#62; &#60;option_one [...]]]></description>
			<content:encoded><![CDATA[<p>Ziel ist es in der System Konfiguration des Magento Admin Panels ein Textfeld in Abhängigkeit von einem Select ein- bzw. auszublenden.<span id="more-864"></span><br />
<a href="http://www.mb-tec.eu/wp-content/uploads/2011/07/magento_options_1.png"><img class="alignnone size-medium wp-image-871" title="magento_options_1" src="http://www.mb-tec.eu/wp-content/uploads/2011/07/magento_options_1-300x95.png" alt="Magento Admin Panel System Konfiguration" width="300" height="95" /></a><br/><br />
<a href="http://www.mb-tec.eu/wp-content/uploads/2011/07/magento_options_21.png"><img class="alignnone size-medium wp-image-873" title="magento_options_2" src="http://www.mb-tec.eu/wp-content/uploads/2011/07/magento_options_21-300x111.png" alt="" width="300" height="111" /></a> Datei <strong>etc/system.xml</strong></p>
<pre class="brush:xml">&lt;?xml version="1.0"?&gt;

&lt;config&gt;
  &lt;tabs&gt;
    &lt;mbtec translate="label" module="mbtec_test"&gt;
      &lt;label&gt;Mbtec&lt;/label&gt;
      &lt;sort_order&gt;450&lt;/sort_order&gt;
    &lt;/mbtec&gt;
  &lt;/tabs&gt;
  &lt;sections&gt;
    &lt;mbtec_test translate="label" module="mbtec_test"&gt;
      &lt;label&gt;Test&lt;/label&gt;
      &lt;tab&gt;mbtec&lt;/tab&gt;
      &lt;sort_order&gt;100&lt;/sort_order&gt;
      &lt;show_in_default&gt;1&lt;/show_in_default&gt;
      &lt;show_in_website&gt;1&lt;/show_in_website&gt;
      &lt;show_in_store&gt;1&lt;/show_in_store&gt;
      &lt;groups&gt;
        &lt;settings translate="label"&gt;
          &lt;label&gt;Settings&lt;/label&gt;
          &lt;frontend_type&gt;text&lt;/frontend_type&gt;
          &lt;sort_order&gt;100&lt;/sort_order&gt;
          &lt;show_in_default&gt;1&lt;/show_in_default&gt;
          &lt;show_in_website&gt;0&lt;/show_in_website&gt;
          &lt;show_in_store&gt;0&lt;/show_in_store&gt;
          &lt;fields&gt;
            &lt;option_one translate="label,comment"&gt;
              &lt;label&gt;Options&lt;/label&gt;
              &lt;comment&gt;
                &lt;![CDATA[Please select one option.]]&gt;
              &lt;/comment&gt;
              &lt;frontend_type&gt;select&lt;/frontend_type&gt;
              &lt;source_model&gt;
                adminhtml/system_config_source_yesno
              &lt;/source_model&gt;
              &lt;sort_order&gt;10&lt;/sort_order&gt;
              &lt;show_in_default&gt;1&lt;/show_in_default&gt;
              &lt;show_in_website&gt;0&lt;/show_in_website&gt;
              &lt;show_in_store&gt;0&lt;/show_in_store&gt;
            &lt;/option_one&gt;
            &lt;option_two translate="label"&gt;
              &lt;label&gt;Eingabe Feld&lt;/label&gt;
              &lt;frontend_type&gt;text&lt;/frontend_type&gt;
              &lt;sort_order&gt;20&lt;/sort_order&gt;
              &lt;show_in_default&gt;1&lt;/show_in_default&gt;
              &lt;show_in_website&gt;0&lt;/show_in_website&gt;
              &lt;show_in_store&gt;0&lt;/show_in_store&gt;
              &lt;depends&gt;&lt;option_one&gt;1&lt;/option_one&gt;&lt;/depends&gt;
            &lt;/option_two&gt;
          &lt;/fields&gt;
        &lt;/settings&gt;
      &lt;/groups&gt;
    &lt;/mbtec_test&gt;
  &lt;/sections&gt;
&lt;/config&gt;</pre>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/L3QRiC3gEIc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/magento/einblenden-von-eingabefeldern-im-magento-admin-panel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/magento/einblenden-von-eingabefeldern-im-magento-admin-panel/</feedburner:origLink></item>
		<item>
		<title>Select oder Multiselect mit eigenen Optionen im Magento Admin Panel</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/AAmoJaKvHpw/</link>
		<comments>http://www.mb-tec.eu/magento/select-oder-multiselect-mit-eigenen-optionen-im-magento-admin-panel/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 15:33:52 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[Admin Panel]]></category>
		<category><![CDATA[Konfiguration]]></category>
		<category><![CDATA[Multiselect]]></category>
		<category><![CDATA[Select]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=807</guid>
		<description><![CDATA[Ziel ist es, im Magento Admin Panel ein Select oder Multiselect mit frei definierbaren Optionen zur Verfügung zu stellen. Die Optionen können beispielsweise noch über ein Resource Model aus der Datenbank geladen werden. De typische Verzeichnisstruktur eines Magento Moduls magento `-- app   `-- code &#124;-- community     &#124;-- core     `-- local [...]]]></description>
			<content:encoded><![CDATA[<p>Ziel ist es, im Magento Admin Panel ein Select oder Multiselect mit frei definierbaren Optionen zur Verfügung zu stellen. Die Optionen können beispielsweise noch über ein Resource Model aus der Datenbank geladen werden.<span id="more-807"></span></p>
<div id="attachment_822" class="wp-caption alignnone" style="width: 310px"><a href="http://www.mb-tec.eu/wp-content/uploads/2011/07/magento_backend_options.png"><img class="size-medium wp-image-822" title="magento_backend_options" src="http://www.mb-tec.eu/wp-content/uploads/2011/07/magento_backend_options-300x195.png" alt="" width="300" height="195" /></a><p class="wp-caption-text">Magento Backend Options</p></div>
<p>De typische Verzeichnisstruktur eines Magento Moduls</p>
<pre>magento
`-- app
    `-- code
        |-- community
        |-- core
        `-- local
            `-- Mbtec
                |-- Test
                |-- etc
                |   |-- config.xml
                |   `-- system.xml
                |-- Helper
                |   `-- Data.php
                `-- Model
                    `-- Adminhtml
                        `-- System
                            `-- Config
                                `-- Source
                                    `-- Options.php</pre>
<p>&nbsp;</p>
<pre>Die Modulkonfiguration
Datei <strong>etc/config.xml</strong>
<pre class="brush:xml">&lt;?xml version="1.0"?&gt;
&lt;config&gt;
  &lt;modules&gt;
    &lt;mbtec_test&gt;
      &lt;version&gt;0.0.1&lt;/version&gt;
    &lt;/mbtec_test&gt;
  &lt;/modules&gt;
  &lt;global&gt;
    &lt;models&gt;
      &lt;mbtec_test&gt;
        &lt;class&gt;Mbtec_Test_Model&lt;/class&gt;
      &lt;/mbtec_test&gt;
    &lt;/models&gt;
    &lt;helpers&gt;
      &lt;mbtec_test&gt;
        &lt;class&gt;Mbtec_Test_Helper&lt;/class&gt;
      &lt;/mbtec_test&gt;
    &lt;/helpers&gt;
  &lt;/global&gt;
  &lt;adminhtml&gt;
    &lt;acl&gt;
      &lt;resources&gt;
        &lt;admin&gt;
          &lt;children&gt;
            &lt;system&gt;
              &lt;children&gt;
                &lt;config&gt;
                  &lt;children&gt;
                    &lt;mbtec_test&gt;
                      &lt;title&gt;Test&lt;/title&gt;
                    &lt;/mbtec_test&gt;
                  &lt;/children&gt;
                &lt;/config&gt;
              &lt;/children&gt;
            &lt;/system&gt;
          &lt;/children&gt;
        &lt;/admin&gt;
      &lt;/resources&gt;
    &lt;/acl&gt;
  &lt;/adminhtml&gt;
&lt;/config&gt;</pre>
<p>Die Systemkonfiguration mit der die Selects zum Admin Panel hinzugefügt werden.<br />
Datei <strong>etc/system.xml</strong></p>
<pre class="brush:xml">&lt;?xml version="1.0"?&gt;
&lt;config&gt;
  &lt;tabs&gt;
    &lt;mbtec translate="label" module="mbtec_test"&gt;
      &lt;label&gt;Mbtec&lt;/label&gt;
      &lt;sort_order&gt;450&lt;/sort_order&gt;
    &lt;/mbtec&gt;
  &lt;/tabs&gt;
  &lt;sections&gt;
    &lt;mbtec_test translate="label" module="mbtec_test"&gt;
      &lt;label&gt;Test&lt;/label&gt;
      &lt;tab&gt;mbtec&lt;/tab&gt;
      &lt;sort_order&gt;100&lt;/sort_order&gt;
      &lt;show_in_default&gt;1&lt;/show_in_default&gt;
      &lt;show_in_website&gt;1&lt;/show_in_website&gt;
      &lt;show_in_store&gt;1&lt;/show_in_store&gt;
      &lt;groups&gt;
        &lt;settings translate="label"&gt;
          &lt;label&gt;Settings&lt;/label&gt;
          &lt;frontend_type&gt;text&lt;/frontend_type&gt;
          &lt;sort_order&gt;100&lt;/sort_order&gt;
          &lt;show_in_default&gt;1&lt;/show_in_default&gt;
          &lt;show_in_website&gt;0&lt;/show_in_website&gt;
          &lt;show_in_store&gt;0&lt;/show_in_store&gt;
          &lt;fields&gt;
            &lt;optionselect translate="label,comment"&gt;
              &lt;label&gt;Options&lt;/label&gt;
              &lt;comment&gt;
                &lt;![CDATA[Please select one option.]]&gt;
              &lt;/comment&gt;
              &lt;frontend_type&gt;select&lt;/frontend_type&gt;
              &lt;source_model&gt;
                mbtec_test/adminhtml_system_config_source_options
              &lt;/source_model&gt;
              &lt;sort_order&gt;10&lt;/sort_order&gt;
              &lt;show_in_default&gt;1&lt;/show_in_default&gt;
              &lt;show_in_website&gt;0&lt;/show_in_website&gt;
              &lt;show_in_store&gt;0&lt;/show_in_store&gt;
            &lt;/optionselect&gt;
            &lt;optionmultiselect translate="label,comment"&gt;
              &lt;label&gt;Options&lt;/label&gt;
              &lt;comment&gt;
                &lt;![CDATA[Please select one option.]]&gt;
              &lt;/comment&gt;
              &lt;frontend_type&gt;multiselect&lt;/frontend_type&gt;
              &lt;source_model&gt;
                mbtec_test/adminhtml_system_config_source_options
              &lt;/source_model&gt;
              &lt;sort_order&gt;20&lt;/sort_order&gt;
              &lt;show_in_default&gt;1&lt;/show_in_default&gt;
              &lt;show_in_website&gt;0&lt;/show_in_website&gt;
              &lt;show_in_store&gt;0&lt;/show_in_store&gt;
            &lt;/optionmultiselect&gt;
          &lt;/fields&gt;
        &lt;/settings&gt;
      &lt;/groups&gt;
    &lt;/mbtec_test&gt;
  &lt;/sections&gt;
&lt;/config&gt;</pre>
<p>Der leere Helper-Stub welcher für die Translations notwendig ist.<br />
Datei <strong>Helper/Data.php</strong></p>
<pre class="brush:php">&lt;?php

class Mbtec_Test_Helper_Data extends Mage_Core_Helper_Abstract
{

}</pre>
<p>Die Datenquelle für die Selects.<br />
Datei: <strong>Models/Adminhtml/System/Config/Source/Options</strong></p>
<pre class="brush:php">&lt;?php

class Mbtec_Test_Model_Adminhtml_System_Config_Source_Options
{
    /**
     * Options getter
     *
     * @return array
     */
    public function toOptionArray()
    {
        $helper = Mage::helper('mbtec_test');
        return array(
            array(
                'value' =&gt; 'foo',
                'label'=&gt; $helper-&gt;__('Foo')
            ),
            array(
                'value' =&gt; 'bar',
                'label'=&gt; $helper-&gt;__('Bar')
            ),
            array(
                'value' =&gt; 'baz',
                'label'=&gt; $helper-&gt;__('Baz')
            )
        );
    }
}</pre>
<p>Die Konfigurationswerte können dann ausgelesen werden mit</p>
<pre class="brush:php">$option = Mage::getStoreConfig(
    'mbtec_test/settings/optionselect'
);

$multioption = Mage::getStoreConfig(
    'mbtec_test/settings/optionmultiselect'
);</pre>
<p><strong>Hinweis: Cache löschen nicht vergessen</strong> <img src='http://www.mb-tec.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </pre>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/AAmoJaKvHpw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/magento/select-oder-multiselect-mit-eigenen-optionen-im-magento-admin-panel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/magento/select-oder-multiselect-mit-eigenen-optionen-im-magento-admin-panel/</feedburner:origLink></item>
		<item>
		<title>Zend Framework mit Smarty als Template Engine</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/-u-V4HfPI5U/</link>
		<comments>http://www.mb-tec.eu/zend-framework/zend-framework-mit-smarty-als-template-engine/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 13:00:26 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Smarty]]></category>
		<category><![CDATA[View]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=731</guid>
		<description><![CDATA[Der Einsatz von Smarty als Template Engine hat sich in meinen Augen als sinnvolle Erweiterung zu nativem PHP bewährt. Es erleichtert die Erstellung von Templates und macht diese &#220;bersichtlicher. &#220;ber Smarty Download Smarty von www.smarty.net Im ersten Schritt erweitern wir die Klasse Zend_View_Abstract mit unserer eigenen Smarty Logik. Wir erstellen also eine neue Datei mit [...]]]></description>
			<content:encoded><![CDATA[<p>Der Einsatz von Smarty als Template Engine hat sich in meinen Augen als sinnvolle Erweiterung zu nativem PHP bewährt. Es erleichtert die Erstellung von Templates und macht diese &Uuml;bersichtlicher. <a href="http://www.smarty.net/about_smarty" target="_blank" rel="nofollow">&Uuml;ber Smarty</a></p>
<p>Download Smarty von <a href="http://www.smarty.net/" target="_blank" rel="nofollow">www.smarty.net</a></p>
<p>Im ersten Schritt erweitern wir die Klasse Zend_View_Abstract mit unserer eigenen Smarty Logik. Wir erstellen also eine neue Datei mit dem Namen Smarty.php unter library/Mbtec/View/</p>
<p>Die Verzeichnisstruktur sollte der hier &auml;hneln</p>
<pre class="brush:plain">
...
/myapp
    /application
        /configs
            application.ini
        /doctrine
        /modules
        /smarty
            /compile
                ...
            /cache
                ...
    Bootstrap.php
    /library
        /doctrine
        /Mbtec
            /Controller
            /Resource
            /View
                Smarty.php
        /Smarty
            /plugins
            /sysplugins
            /debug.tpl
            Smarty.class.php
        /Zend
    /public
    /var
</pre>
<p>Hier nun der Smarty Wrapper für den View</p>
<pre class="brush:php">
&lt;?php

/**
 * Smarty template engine integration into Zend Framework
 * Some ideas borrowed from
 * http://devzone.zend.com/article/120
 * Most ideas borrowed from
 * http://www.gediminasm.org/article/smarty-3-extension-for-zend-framework
 */

class Mbtec_View_Smarty extends Zend_View_Abstract
{
    /**
     * Instance of Smarty
     * @var Smarty
     */
    protected $_smarty = null;

    /**
     * Template explicitly set to render in this view
     * @var string
     */
    protected $_customTemplate = '';

    /**
     * Smarty config
     * @var array
     */
    private $_config = null;

    /**
     * Class definition and constructor
     *
     * Let's start with the class definition and the
     * constructor part. My class Travello_View_Smarty
     * is extending the Zend_View_Abstract class.
     * In the constructor the parent constructor from
     * Zend_View_Abstract is called first. After that a
     * Smarty object is instantiated, configured and stored
     * in a private attribute.
     * Please note that I use a configuration object from
     * the object store to get the configuration data for
     * Smarty.
     *
     * @param array $smartyConfig
     * @param array $config
     */
    public function __construct($sConfig, $config = array())
    {
        $this->_config = $sConfig;
        parent::__construct($config);
        $this->_loadSmarty();
    }

    /**
     * Return the template engine object
     *
     * @return Smarty
     */
    public function getEngine()
    {
        return $this->_smarty;
    }

    /**
     * Implement _run() method
     *
     * The method _run() is the only method that needs to be
     * implemented in any subclass of Zend_View_Abstract.
     * It is called automatically within the render() method.
     * My implementation just uses the display() method from
     * Smarty to generate and output the template.
     *
     * @param string $template
     * @return void
     */
    protected function _run()
    {
        $file = func_num_args() > 0 &#038;&#038;
                  file_exists(func_get_arg(0))
                      ? func_get_arg(0)
                      : '';
        if ($this->_customTemplate || $file) {
            $template = $this->_customTemplate;
            if (!$template) {
                $template = $file;
            }

            $this->_smarty->display($template);
        }
        else {
            throw new Zend_View_Exception(
                'Cannot render view without any template
                 being assigned or file does not exist'
            );
        }
    }

    /**
     * Overwrite assign() method
     *
     * The next part is an overwrite of the assign() method
     * from Zend_View_Abstract, which works in a similar
     * way. The big difference is that the values are
     * assigned to the Smarty object and not to the
     * $this->_vars variables array of Zend_View_Abstract.
     *
     * @param string|array $var
     * @return void
     */
    public function assign($var, $value = null)
    {
        if (is_string($var)) {
            $this->_smarty->assign($var, $value);
        }
        elseif (is_array($var)) {
            foreach ($var as $key => $value) {
                $this->assign($key, $value);
            }
        }
        else {
            throw new Zend_View_Exception(
                'assign() expects a string or array, got '
              . gettype($var)
            );
        }
    }

    /**
     * Overwrite escape() method
     *
     * The next part is an overwrite of the escape() method
     * from Zend_View_Abstract. It works both for string
     * and array values and also uses the escape() method
     * from the Zend_View_Abstract. The advantage of this
     * is that I don't have to care about each value of an
     * array to get properly escaped.
     *
     * @param mixed $var
     * @return mixed
     */
    public function escape($var)
    {
        if (is_string($var)) {
            return parent::escape($var);
        }

        if (is_array($var)) {
            foreach ($var as $key => $val) {
                $var[$key] = $this->escape($val);
            }
        }

        return $var;
    }

    /**
     * Use Smarty caching
     *
     * The last two methods were created to simply integrate
     * the Smarty caching mechanism in the View class.
     * With the first one you can check for cached template
     * and with the second one you can set the caching
     * on or off.
     *
     * @param string $template
     * @return bool
     */
    public function isCached($template)
    {
        return $this->_smarty->is_cached($template);
    }

    /**
     * Enable/disable caching
     *
     * @param bool $caching
     * @return void
     */
    public function setCaching($caching)
    {
        $this->_smarty->caching = $caching;
    }

    /**
     * Template getter (return file path)
     * @return string
     */
    public function getTemplate()
    {
        return $this->_customTemplate;
    }

    /**
     * Template filename setter
     * @param string
     * @return void
     */
    public function setTemplate($tpl)
    {
        $this->_customTemplate = $tpl;
    }

    /**
     * Magic setter for Zend_View compatibility.
     * Performs assign()
     *
     * @param string $key
     * @param mixed $val
     */
    public function __set($key, $val)
    {
        $this->assign($key, $val);
    }

    /**
     * Magic getter for Zend_View compatibility.
     * Retrieves template var
     *
     * @param string $key
     * @return mixed
     */
    public function __get($key)
    {
        return $this->_smarty->getTemplateVars($key);
    }

    /**
     * Magic getter for Zend_View compatibility.
     * Removes template var
     *
     * @see View/Zend_View_Abstract::__unset()
     * @param string $key
     * @return void
     */
    public function __unset($key)
    {
        $this->_smarty->clearAssign($key);
    }

    /**
     * Allows testing with empty() and isset() to work
     * Zend_View compatibility. Checks template var for
     * existance
     *
     * @param string $key
     * @return boolean
     */
    public function __isset($key)
    {
        return
            (null !== $this->_smarty->getTemplateVars($key));
    }

    /**
     * Zend_View compatibility. Retrieves all template vars
     *
     * @see Zend_View_Abstract::getVars()
     * @return array
     */
    public function getVars()
    {
        return $this->_smarty->getTemplateVars();
    }

    /**
     * Updates Smarty's template_dir field with new value
     *
     * @param string $dir
     * @return void
     */
    public function setTemplateDir($dir)
    {
        $this->_smarty->setTemplateDir($dir);
    }

    /**
     * Adds another Smarty template_dir to scan for templates
     *
     * @param string $dir
     * @return void
     */
    public function addTemplateDir($dir)
    {
        $this->_smarty->addTemplateDir($dir);
    }

    /**
     * Adds another Smarty plugin directory to scan
     * for plugins
     *
     * @param string $dir
     * @return void
     */
    public function addPluginDir($dir)
    {
        $this->_smarty->addPluginsDir($dir);
    }

    /**
     * Zend_View compatibility. Removes all template vars
     *
     * @see View/Zend_View_Abstract::clearVars()
     * @return void
     */
    public function clearVars()
    {
        $this->_smarty->clearAllAssign();
        $this->assign('this', $this);
    }

    /**
     * Magic clone method, on clone create diferent
     * smarty object
     * @return void
     */
    public function __clone()
    {
        $this->_loadSmarty();
    }

    /**
     * Initializes the smarty and populates config params
     *
     * @throws Zend_View_Exception
     * @return void
     */
    private function _loadSmarty()
    {
        if (!class_exists('Smarty', true)) {
            require_once 'Smarty/Smarty.class.php';
        }

        $this->_smarty = new Smarty();

        if ($this->_config === null) {
            throw new Zend_View_Exception(
                "Could not locate Smarty config"
            );
        }

        $this->_smarty->caching
            = $this->_config['caching'];
        $this->_smarty->cache_lifetime
            = $this->_config['cache_lifetime'];
        $this->_smarty->template_dir
            = $this->_config['template_dir'];
        $this->_smarty->compile_dir
            = $this->_config['compile_dir'];
        $this->_smarty->config_dir
            = $this->_config['config_dir'];
        $this->_smarty->cache_dir
            = $this->_config['cache_dir'];
        $this->_smarty->left_delimiter
            = $this->_config['left_delimiter'];
        $this->_smarty->right_delimiter
            = $this->_config['right_delimiter'];
        $this->assign('this', $this);
    }
}
</pre>
<p>Wir konfigurieren Smarty in der application.ini</p>
<pre class="brush:plain">
; --- Smarty ---

smarty.caching = 1
smarty.cache_lifetime = 14400 ; 4 hours
smarty.template_dir
    = APPLICATION_PATH "/modules/default/views/scripts/"
smarty.compile_dir = APPLICATION_PATH "/smarty/compile/"
smarty.config_dir = ""
smarty.cache_dir = APPLICATION_PATH "/smarty/cache/"
smarty.left_delimiter = "{"
smarty.right_delimiter = "}"
</pre>
<p>Wir initialisieren Smarty in der Bootstrap.php</p>
<pre class="brush:php">
...
/**
 * Bootstrap Smarty view
 * @return Mbtec_View_Smarty
 */
protected function _initView()
{
    // initialize smarty view
    $view = new Mbtec_View_Smarty($this->getOption('smarty'));

    // setup viewRenderer with suffix and view
    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
    $viewRenderer->setViewSuffix('tpl');
    $viewRenderer->setView($view);

    // ensure we have layout bootstraped
    $this->bootstrap('layout');

    // set the tpl suffix to layout also
    $layout = Zend_Layout::getMvcInstance();
    $layout->setViewSuffix('tpl');

    return $view;
}
...
</pre>
<p>Hiermit sind die Vorbereitungen schon abgeschlossen und Smarty sollte aktiv sein. Smarty benutzt standardm&auml;&szlig;ig die Dateiendung .tpl &#8211; also d&uuml;rfen die Templates nicht mehr mit .phtml enden.</p>
<p>Hier ein kleines Beispiel mit Controller und View:</p>
<p>Datei indexController.php</p>
<pre class="brush:php">
    ....
    public function indexAction()
    {
        $em = Zend_Registry::get('em');
        $items = $em->createQueryBuilder()
                    ->select('i')
                    ->from('Entities\Item', 'i')
                    ->orderBy('i.foo', 'ASC')
                    ->getQuery()
                    ->getResult();
        $this->view->assign('items', $items);
    }
    ....
</pre>
<p>Datei index.tpl</p>
<pre class="brush:php">
{include 'header.tpl' head1='Station' head2='Liste'}

{foreach $this->items as $item}
    &lt;a href="{$this->url([
        'controller' => 'items',
        'action' => 'edit',
        'id' => $item->getId()])}"&gt;
        {$this->escape($item->getFoo())}
    &lt;/a&gt;
    {$this->escape($item->getBar())}
    {$this->escape($item->getBaz())}
{/foreach}
</pre>
<p>Datei header.tpl</p>
<pre class="brush:php">
<h1>{$head1}</h1>
<h2>{$head2}</h2>

{$this->flashMessenger()}
</pre>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/-u-V4HfPI5U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/zend-framework/zend-framework-mit-smarty-als-template-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/zend-framework/zend-framework-mit-smarty-als-template-engine/</feedburner:origLink></item>
		<item>
		<title>MySql Datenverzeichnis ändern verursacht Ärger mit AppArmor</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/EGnJMSkIk0k/</link>
		<comments>http://www.mb-tec.eu/linux/mysql-datenverzeichnis-andern-verursacht-arger-mit-apparmor/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 13:29:12 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[AppArmor]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=711</guid>
		<description><![CDATA[Möchte man unter Linux / Ubuntu das Datenverzeichnis verändern so geht das ganz einfach über die Konsole.
Nach dieser Änderung kann es passieren, daß der MySql Dienst nicht wieder gestartet werden kann, weil AppArmor das geänderte Datenverzeichnis nicht kennt und daher die Ausführung des Dienstes verweigert. Abhilfe ist ganz einfach. Man muss AppArmor das neue Datenverzeichnis bekannt geben.]]></description>
			<content:encoded><![CDATA[<p>Möchte man unter Linux / Ubuntu das Datenverzeichnis verändern so geht das ganz einfach über die Konsole:</p>
<pre class="brush:plain">sudo vim /etc/mysql/my.cnf</pre>
<p>Hier wird dann die folgende Zeile editiert:</p>
<pre class="brush:plain">#datadir = /var/lib/mysql
datadir = /home/matthias/mysql</pre>
<p>Nach dieser Änderung kann es passieren, daß der MySql Dienst nicht wieder gestartet werden kann, weil <a title="Wikipedia: AppArmor" rel="nofollow" href="http://de.wikipedia.org/wiki/AppArmor" target="_blank">AppArmor</a> das geänderte Datenverzeichnis nicht kennt und daher die Ausführung des Dienstes verweigert. Im syslog sieht das dann etwa so aus:</p>
<pre>Jan 31 14:07:32 Server kernel: [17462.035561] type=1400
audit(1296479252.398:421): apparmor="DENIED" operation="open" parent=1
profile="/usr/sbin/mysqld" name="/home/matthias/mysql/ibdata1"
pid=14807 comm="mysqld" requested_mask="rw" denied_mask="rw"
fsuid=115 ouid=115</pre>
<p>Abhilfe ist ganz einfach. Man muss AppArmor das neue Datenverzeichnis bekannt geben.</p>
<pre class="brush:plain">sudo vim /etc/apparmor.d/usr.sbin.mysqld</pre>
<p>Man ergänzt die folgenden Zeilen:</p>
<pre class="brush:plain">/home/matthias/mysql/ r,
/home/matthias/mysql/** rwk,</pre>
<p>Nach einem Neustart von AppArmor</p>
<pre class="brush:plain">sudo /etc/init.d/apparmor restart</pre>
<p>sollte der Mysql Dienst</p>
<pre class="brush:plain">sudo /etc/init.d/mysql restart</pre>
<p>dann wieder starten.</p>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/EGnJMSkIk0k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/linux/mysql-datenverzeichnis-andern-verursacht-arger-mit-apparmor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/linux/mysql-datenverzeichnis-andern-verursacht-arger-mit-apparmor/</feedburner:origLink></item>
		<item>
		<title>Debugging von Magento mit ChromePHP</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/7L3ItmSaJCs/</link>
		<comments>http://www.mb-tec.eu/zend-framework/debugging-mit-chromephp/#comments</comments>
		<pubDate>Thu, 20 Jan 2011 09:28:16 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Magento]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[ChromePHP]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=688</guid>
		<description><![CDATA[Um z.B. Magento debuggen zu können, benötigt man das <a href="https://chrome.google.com/extensions/detail/noaneddfkdjfnfdakjjmocngnfkfehhd" target="_blank">ChromePHP - Plugin</a> für den Client sowie ein kleines <a href="https://github.com/ccampbell/chromephp" target="_blank">serverseitiges PHP-Script</a>.]]></description>
			<content:encoded><![CDATA[<p>Firefox war lange Zeit mein Hauptentwicklungsbrowser, da das Debugging in Verbindung mit Firebug, Firecookie und FirePHP schon ziemlich gut funktionierte.<br />
Nun habe ich aber aus Gründen der Performanz umgestellt auf Google Chrome. Dieser Webbrowser bringt schon von sich aus einige Werkzeuge mit die den Entwickleralltag deutlich vereinfachen.<br />
Diese sogenannten Entwicklertools ruft man ( unter Linux ) mit Shift + Strg + I auf. Im Prinzip ist also bei Chrome schon alles dabei, was man im Firebug erst noch nachrüsten muss.</p>
<p>Um z.B. Magento debuggen zu können, benötigt man das <a href="https://chrome.google.com/extensions/detail/noaneddfkdjfnfdakjjmocngnfkfehhd" target="_blank">ChromePHP &#8211; Plugin</a> für den Client sowie ein kleines <a href="https://github.com/ccampbell/chromephp" target="_blank">serverseitiges PHP-Script</a>.</p>
<p>Im Mangento Root Ordner wird ein Verzeichnis &#8220;tools&#8221; angelegt, in welches das PHP-Script kopiert wird. Danach erweitern wir die index.php um ein paar Zeilen. Um es einfach zu halten, führe ich eine globale Funktion &#8220;debug&#8221; ein, die als Wrapper für die ChromePHP Methode log dient.</p>
<pre class="brush:php">
...
// ChromePHP Ext
$filepathChromePhp = 'tools/ChromePhp.php';
if ( is_readable($filepathChromePhp) ) {
    include_once $filepathChromePhp;
}

...
function debug($output)
{
    if ( class_exists('ChromePhp') ) {
        ChromePhp::log($output);
    }
}
</pre>
<p>So kann in jedem Script eine Debug-Ausgabe erfolgen:</p>
<pre class="brush:php">
debug($var);
</pre>
<p>Man sollte jetzt eine solche Ausgabe sehen können:<br />
<img src="http://www.mb-tec.eu/wp-content/uploads/2011/01/chromephp-debug-output.png" alt="ChromePHP Debugging Outputfenster" title="chromephp-debug-output" width="636" height="274" class="alignnone size-full wp-image-698" /><br />
<br/><br />
<strong>Wichtig: Das ChromePHP Plugin muss aktiv sein, sonst funktioniert es nicht. </strong> Das Symbol oben rechts muss blau leuchten. <img src="http://www.mb-tec.eu/wp-content/uploads/2011/01/chromephp-icon.png" alt="Icon ChromePHP" title="chromephp-icon" width="95" height="31" class="alignnone size-full wp-image-702" /></p>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/7L3ItmSaJCs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/zend-framework/debugging-mit-chromephp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/zend-framework/debugging-mit-chromephp/</feedburner:origLink></item>
		<item>
		<title>USING BTREE Fehler bei einem MySQL Import</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/Y7Ah9S5yUd4/</link>
		<comments>http://www.mb-tec.eu/linux/using-btree-fehler-bei-einem-mysql-import/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 10:51:38 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[btree]]></category>
		<category><![CDATA[fehler]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=680</guid>
		<description><![CDATA[Wurde ein Datenbankdump mit einer MySQL Version 5.1 erzeugt und soll dieser in einer MySQL Datenbank der Version 5.0 importiert werden, so kann es zu dem folgenden Fehler kommen: ERROR 1064 (42000) at line 1561: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the [...]]]></description>
			<content:encoded><![CDATA[<p>Wurde ein Datenbankdump mit einer MySQL Version 5.1 erzeugt und soll dieser in einer MySQL Datenbank der Version 5.0 importiert werden, so kann es zu dem folgenden Fehler kommen: </p>
<p><strong>ERROR 1064 (42000) at line 1561: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near &#8216;USING BTREE, &#8230;</strong></p>
<p>Schuld daran ist das veränderte SQL Syntax der Version 5.1.<br />
Aufgrund eines fehlenden Kompatibilitätsschalters beim Export ( wie zum Beispiel mysqldump -comptability=mysql50 ) bleibt hier nur die Möglichkeit, den Dump an das 5.0 Syntax anzupassen.<br />
Unter Linux geht dies über die Konsole:</p>
<pre class="brush:plain">sed -i -r 's/\(([^)]+)\) USING BTREE/USING BTREE (\1)/g' mydump.sql</pre>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/Y7Ah9S5yUd4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/linux/using-btree-fehler-bei-einem-mysql-import/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/linux/using-btree-fehler-bei-einem-mysql-import/</feedburner:origLink></item>
		<item>
		<title>Nicht gefundene Übersetzungen per eMail melden</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/GucQrmAC3xs/</link>
		<comments>http://www.mb-tec.eu/zend-framework/nicht-gefundene-ubersetzungen-per-email-melden/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 12:55:32 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Mail]]></category>
		<category><![CDATA[Translate]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=621</guid>
		<description><![CDATA[Nicht immer sind für die in den Scripten zu übersetzenden Strings auch die entsprechenden Übersetzungen vorhanden. Um dieses so schnell wie möglich ausbessern zu können, lasse ich mir hier als Webseitenbetreuer eine entsprechende Informations eMail zusenden.]]></description>
			<content:encoded><![CDATA[<p>Nicht immer sind für die in den Scripten zu übersetzenden Strings auch die entsprechenden Übersetzungen vorhanden. Um dieses so schnell wie möglich ausbessern zu können, lasse ich mir hier als Webseitenbetreuer eine entsprechende Informations eMail zusenden.</p>
<p>application/configs/application.ini</p>
<pre class="brush:plain">; General
project.identifier = "Testprojekt"
project.maintainer.email = "info@mb-tec.eu"
project.emails.sender.defaults.email = "info@mb-tec.eu"
project.emails.sender.defaults.name	= "Matthias Büsing"

resources.frontController.plugins.initTranslator = "Mbtec_Controller_Plugin_InitTranslator"

; Hier steht wirklich nichts mehr rechts vom Gleichzeichen (=).
; Diese Zeile darf aber auf keinen Fall weggelassen werden,
; da sonst die Ressource nicht geladen wird.
resources.log = </pre>
<p>library/Mbtec/Resource/Log.php</p>
<pre class="brush:php">class Mbtec_Resource_Log extends Zend_Application_Resource_ResourceAbstract
{
  public function init()
  {
    $options = $this-&gt;getOptions();
    $config = Zend_Registry::get('config');

    // Mail writer
    $mail = new Zend_Mail();
    $mail-&gt;setFrom($config-&gt;project-&gt;emails-&gt;sender-&gt;defaults-&gt;email)
           -&gt;addTo($config-&gt;project-&gt;maintainer-&gt;email);
    $writer = new Zend_Log_Writer_Mail($mail);
    $writer-&gt;setSubjectPrependText(
      'Error in Project ' . $config-&gt;project-&gt;identifier
    );
    $logEmail = new Zend_Log($writer);

    Zend_Registry::set('Zend_Log_Email', $logEmail);
  }
}</pre>
<p>library/Mbtec/Controller/Plugin/InitTranslator.php</p>
<pre class="brush:php">class Mbtec_Controller_Plugin_InitTranslator extends Zend_Controller_Plugin_Abstract
{
  public function routeShutdown(Zend_Controller_Request_Abstract $request)
  {
    // In jedem Modul-Verzeichnis liegt ein Unterorder 'translations'
    // Hier liegen die Übersetzungs CSVs
    $moduleDir = Zend_Controller_Front::getInstance()-&gt;getModuleDirectory();

    // Eine fest eingestellte Sprache
    // Hier müsste noch eine Logik implementiert werden falls mehrere Sprachen verwendet werden sollen.
    $language = 'de';
    $translateParams = array(
      'adapter'         =&gt; Zend_Translate::AN_CSV,
      'content'         =&gt; $moduleDir . '/translations/de.csv',
      'locale'          =&gt; $language,
      'log'             =&gt; Zend_Registry::get('Zend_Log_Email'),
      'logUntranslated' =&gt; true,
      'disableNotices'  =&gt; false
    );
    Zend_Registry::set(
      'Zend_Translate',
      new Zend_Translate($translateParams)
    );
  }
}</pre>
<p>Selbstverständlich kann der Email Writer auch für andere wichtige Meldungen benutzt werden. Mit</p>
<pre class="brush:php">Zend_Registry::get('Zend_Log_Email')-&gt;info('Nachricht');</pre>
<p>kann an jeder beliebigen Stelle im Script eine eMail versandt werden.</p>
<p>Bitte hierzu auch den Artikel <a title="Weiter zum Artikel Der Versand von eMails über SMTP mit Zend_Mail" href="http://www.mb-tec.eu/zend-framework/der-versand-von-emails-uber-smtp-mit-zend_mail/">Der Versand von eMails über SMTP mit Zend_Mail</a> beachten.</p>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/GucQrmAC3xs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/zend-framework/nicht-gefundene-ubersetzungen-per-email-melden/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/zend-framework/nicht-gefundene-ubersetzungen-per-email-melden/</feedburner:origLink></item>
		<item>
		<title>Der Versand von eMails über SMTP mit Zend_Mail</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/rSSAgm7dx10/</link>
		<comments>http://www.mb-tec.eu/zend-framework/der-versand-von-emails-uber-smtp-mit-zend_mail/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 12:15:01 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=623</guid>
		<description><![CDATA[Bei dem Versand von eMails mit Zend_Mail lässt sich wählen, welchen Transportweg das Zend Framework benutzen soll. Zur Auswahl stehen derzeit das SMTP Protokoll sowie die PHP internen Funktion mail(). Bei Benutzung des SMTP Protokolls werden die zu versendenden eMails an einen Mailserver übergeben der sich dann eigenständig um den Versand derselben kümmert. Die eigentliche [...]]]></description>
			<content:encoded><![CDATA[<p>Bei dem Versand von eMails mit Zend_Mail lässt sich wählen, welchen Transportweg das Zend Framework benutzen soll. Zur Auswahl stehen derzeit das SMTP Protokoll sowie die PHP internen Funktion mail().<br />
Bei Benutzung des SMTP Protokolls werden die zu versendenden eMails an einen Mailserver übergeben der sich dann eigenständig um den Versand derselben kümmert. Die eigentliche Arbeit wird also vom Mailserver übernommen.<br />
Werden eMails über den mail() Befehl verschickt, so ist die PHP Instanz zuständig für den kompletten Versand, angefangen von der DNS Auflösung des Empfängerhosts bis zum Versand. Beim Versand von Massenmailings kann es zu Verzögerungen und stark erhöhten Scriptlaufzeiten kommen.<br />
Wie leicht zu erkennen ist, ist SMTP die bessere Wahl und sollte daher Vorzug genießen.</p>
<p>application.ini</p>
<pre class="brush:plain">project.emails.transport.type          = "smtp"
project.emails.transport.smtp.host     = "[SMTP Host z.B. mb-tec.eu]"
project.emails.transport.smtp.username = "[SMTP Username]"
project.emails.transport.smtp.password = "[SMTP Passwort]"
project.emails.sender.defaults.email   = "info@mb-tec.eu"</pre>
<p>PHP</p>
<pre class="brush:php">$conf = Zend_Registry::get('config')->project->emails;

switch ( $conf->transport->type ) {
  case 'smtp':
    $smtpConf = array(
      'auth' => 'login',
        'username' => $conf->transport->smtp->username,
       	'password' => $conf->transport->smtp->password
    );
    $transport =
    new Zend_Mail_Transport_Smtp(
      $conf->transport->smtp->host,
      $smtpConf
    );
    break;
  default:
    $transport =
    new Zend_Mail_Transport_Sendmail(
      '-f' . $conf->sender->defaults->email
    );
  }

$mail = new Zend_Mail('UTF-8');
//
// ...
//
$mail->send($transport);</pre>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/rSSAgm7dx10" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/zend-framework/der-versand-von-emails-uber-smtp-mit-zend_mail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/zend-framework/der-versand-von-emails-uber-smtp-mit-zend_mail/</feedburner:origLink></item>
		<item>
		<title>Zend Framework mit PLESK</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/pREPxCAuEp0/</link>
		<comments>http://www.mb-tec.eu/zend-framework/zend-framework-mit-plesk/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 12:43:31 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[DocumentRoot]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[PLESK]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=603</guid>
		<description><![CDATA[Wer das Glück hat ein Projekt mit Zend Framework in einer PLESK Umgebung aufsetzen zu müssen, kommt an einer Frage nicht vorbei. Wie setzt man das DocumentRoot Verzeichnis direkt auf den public Ordner, ohne die httpd.conf editieren zu müssen?]]></description>
			<content:encoded><![CDATA[<p>Wer das Glück hat ein Projekt mit Zend Framework in einer PLESK Umgebung aufsetzen zu müssen, kommt an einer Frage nicht vorbei. Wie setzt man das DocumentRoot Verzeichnis direkt auf den public Ordner, ohne die httpd.conf editieren zu müssen?</p>
<p>Es funktioniert sehr einfach.<br />
Im ersten Schritt meldet man sich per SSH Konsole als root auf dem Server an.<br />
Man wechselt in das Konfigurationsverzeichnis der betreffenden Domain</p>
<pre class="brush:bash">cd /var/www/vhosts/domain.tld/conf/</pre>
<p>bzw. der Subdomain.</p>
<pre class="brush:bash">cd /var/www/vhosts/domain.tld/subdomains/name_der_subdomain/conf/</pre>
<p>Hier wird jetzt eine neue Konfigurationsdatei angelegt und mit einem Texteditor editiert.</p>
<pre class="brush:bash">touch vhost.conf
vi vhost.conf</pre>
<p>Es wird nun der Pfad zum neuen DocumentRoot Verzeichnis angegeben</p>
<pre class="brush:plain">DocumentRoot /var/www/vhosts/domain.tld/subdomains/name_der_subdomain/httpdocs/public</pre>
<p>Die Datei wird nun abgespeichert und anschließend muss das PLESK die Änderungen noch übernehmen.</p>
<pre class="brush:bash">/usr/local/psa/admin/sbin/websrvmng --reconfigure-vhost --vhost-name=domain.tld</pre>
<p>Als Letztes wird die neue Konfiguration noch in den Apache Webserver übernommen.</p>
<pre class="brush:bash">/etc/init.d/apache2 reload</pre>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/pREPxCAuEp0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/zend-framework/zend-framework-mit-plesk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/zend-framework/zend-framework-mit-plesk/</feedburner:origLink></item>
		<item>
		<title>Sichere Passwort Speicherung</title>
		<link>http://feedproxy.google.com/~r/mb-tec/~3/SJQgdaNM1w0/</link>
		<comments>http://www.mb-tec.eu/zend-framework/sichere-passwort-speicherung/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 12:25:50 +0000</pubDate>
		<dc:creator>Matthias</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[MD5]]></category>
		<category><![CDATA[Passwort]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Salt]]></category>
		<category><![CDATA[SHA1]]></category>
		<category><![CDATA[SHA256]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://www.mb-tec.eu/?p=540</guid>
		<description><![CDATA[Benutzerpassworte in der Datenbank abzulegen ist ein heikles weil sicherheitsrelevantes Thema. Die Passworte im Klartext zu speichern ist nicht akzeptabel, denn im Falle eines Einbruchs auf dem Server wird mit hoher Wahrscheinlichkeit auch die Datenbank kompromittiert. Solch eine Offenlegung der Passworte werden verhindert, indem die Passworte als Hashwerte in der Datenbank abgelegt werden. Hashwerte und [...]]]></description>
			<content:encoded><![CDATA[<p>Benutzerpassworte in der Datenbank abzulegen ist ein heikles weil sicherheitsrelevantes Thema. Die Passworte im Klartext zu speichern ist nicht akzeptabel, denn im Falle eines Einbruchs auf dem Server wird mit hoher Wahrscheinlichkeit auch die Datenbank kompromittiert. Solch eine Offenlegung der Passworte werden verhindert, indem die Passworte als <a title="Weiter zu Wikipedia: Hashfunktion" rel="nofollow" href="http://de.wikipedia.org/wiki/Hashfunktion" target="_blank">Hashwerte</a> in der Datenbank abgelegt werden. Hashwerte und die dazugehörigen Funktionen sind (zumindest theoretisch) nicht umkehrbare Prüfsummen die bei einer gleich bleibenden Eingabe stets das selbe Resultat liefern. Vereinfacht gesagt, kann man leicht aus einem Passwort einen Hashwert bilden, nicht aber &#8211; oder zumindest nicht in einer vernünftigen Zeitspanne &#8211; aus einem Hashwert das ursprüngliche Passwort. Dieses Verfahren wird auch <a title="Weiter zu Wikipedia Einwegfunktionen" rel="nofollow" href="http://de.wikipedia.org/wiki/Einwegfunktion" target="_blank">Einwegfunktionen</a> genannt.<br />
Tatsächlich existieren aber schon Tabellen, so genannte <a title="Weiter zu Wikipedia Rainbow Tables" rel="nofollow" href="http://de.wikipedia.org/wiki/Rainbow_Tables" target="_blank">Rainbow Tables</a>, mit denen die gebräuchlichsten Passwort dekodiert werden können.<br />
Als Folge dessen ist es notwendig, eine starre Passwort Hashwert Beziehung zu aufzugeben und einen zufälligen Chiffrierungsfaktor, auch <a title="Weiter zu Wikipedia Salt" rel="nofollow" href="http://de.wikipedia.org/wiki/Salt_%28Kryptologie%29" target="_blank">Salt</a> genannt, hinzuzufügen, welcher die Benutzung von Rainbow Tables unmöglich macht.</p>
<p>Die Grundidee besteht darin, ein gegebenes Passwort mit einem Hauptpasswort und dem Salt zu ergänzen und von dieser Kombination mehrfach rekursiv den Hashwert zu bilden. Dabei muss jedoch der Salt zusätzlich zum Haswert gespeichert werden, da sonst eine Prüfung nicht möglich wäre.</p>
<p>Als erstes legen wir in der application.ini das Hauptpasswort, die Anzahl der Hashingdurchgänge und die Läge des Salts fest. Einmal festgelegt, dürfen sich diese Werte niemals ändern, da sonst alle Passworte nicht mehr prüfbar wären.</p>
<pre class="brush:plain">; !!! DON'T CHANGE
security.passwordStorage.masterPassword = "h?qHs8(b"
security.passwordStorage.rounds = 2000
security.passwordStorage.saltLength = 10
; !!! DON'T CHANGE</pre>
<p>So wird geprüft ob ein eingegebenes Passwort ($password) mit dem Hashwert aus der Datenbank ($hash) überein stimmt.</p>
<pre class="brush:php">if ( $this-&gt;_helper-&gt;password-&gt;compare($password, $hash) ) {
  // Passwort stimmt überein
}
else {
  // Das Passwort ist falsch
}</pre>
<p>Hiermit wird der Hashwert aus einem gegebenem Passwort erzeugt.</p>
<pre class="brush:php">$hash = $this-&gt;_helper-&gt;password($password);</pre>
<p>Und hier der dazugehörige Action Helper</p>
<pre class="brush:php">class Mbtec_Controller_Action_Helper_Password extends Zend_Controller_Action_Helper_Abstract
{
  const SEPARATOR = ';';

  public function direct($pwd)
  {
    return $this-&gt;password($pwd);
  }

  public function password($pwd)
  {
    return $this-&gt;_generateHash($pwd);
  }

  // Passwirt und Hash vergleichen
  public function compare($pwd = '', $hash = '')
  {
    if ( 1 != substr_count($hash, self::SEPARATOR) ) {
      return false;
    }

    list($salt, $value) = explode(self::SEPARATOR, $hash);

    return ( $this-&gt;_generateHash($pwd, $salt) == $hash );
  }

  // Hash erzeugen
  private function _generateHash($password = '', $salt = null)
  {
    $config = Zend_Registry::get('config')-&gt;security-&gt;password;

    if ( null === $salt ) {
      $salt = self::_generateSalt($config-&gt;saltLength);
    }

    $hashAlgo = self::_getHashAlgo();
    $hash = hash_hmac(
      $hashAlgo, $salt . $password, $config-&gt;password-&gt;masterPassword
    );
    $rounds = (int) $config-&gt;password-&gt;rounds;

    if ( 1 &gt; $rounds ) {
      $rounds = 2000;
    }

    for ( $i = 0; $i &lt; $rounds; ++$i ) {
      $hash = hash($hashAlgo, $hash);
    }

    return $salt . self::SEPARATOR . $hash;
  }

  // Einen zufälligen Salt generieren
  protected function _generateSalt($length = 10)
  {
    $chars = array_merge(
      range('a', 'z'), range('A', 'Z'), range('0', '9')
    );
    $charsQty = count($chars);
    $salt = '';

    for ( $i = 0; $i &lt; $length; ++$i ) {
      shuffle($chars);
      $rndId = mt_rand(0, $charsQty - 1);
      $salt .= $chars[$rndId];
    }

    return $salt;
  }

  // Welcher Hashing Algorithmus kann benutzt werden
  protected function _getHashAlgo()
  {
    $algos = hash_algos();

    if ( in_array('sha256', $algos) ) {
      return 'sha256';
    }
    elseif ( in_array('sha1', $algos) ) {
      return 'sha1';
    }

    return 'md5';
  }
}</pre>
<p>In der Datenbank sieht der Hashwert mit SHA256 und 10 stelligem Salt so aus:<br />
UmXioVNsRu;f9b47bd49fd303c4712dd6393f3fd929e350be743497a251ff0399a6376f1096</p>
<img src="http://feeds.feedburner.com/~r/mb-tec/~4/SJQgdaNM1w0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.mb-tec.eu/zend-framework/sichere-passwort-speicherung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.mb-tec.eu/zend-framework/sichere-passwort-speicherung/</feedburner:origLink></item>
	</channel>
</rss>

