PHP Sammelthread: Zend Framework und alles was dazugehört

Für solche Sachen habe ich mir einen Project_Controller geschrieben der bei mir in der library liegt. Von dem erben alle anderen Controller und dieser "Master Controller" erbt von Zend_Controller_Action.[/PHP]

Okay, diese Idee werde ich aufgreifen, vl. mit der Vererbung den Plugin-Controller nehmen, aber so eine Klasse, die vor alle geschalten wird, nehm ich mal:)

Mir fehlt aber immer noch ein Anstoß wo ich das einbinde?
 
schau nochmal in meinen letzten Post, habe dir da nochwas verlinkt.

Wie du es machen solltest?

Ein Controller-Plugin und da in die preDispatch-Methode den Check ob der User eingeloggt ist, wenn nicht den Controller und die Action des Request-Objektes abändern, dass der User beim Loginformular landet.
 
@Sebmaster

Wie Ice Schon sagt der Plugin Controller hat nix mit den normalen Action Controller zu tun.

Es gibt viele Wege die nach Rom führen ;)

Mit so einen FrontControllerPlugin kann man zB seine Bootstrap auf ein minimum reduzieren und dabei alles schön in einer Klasse kapseln. Bitte nicht die beiden verwechseln.
 
PHP:
class LoginCheckPlugin extends Zend_Controller_Plugin_Abstract {

  public function preDispatch(Zend_Controller_Request_Abstract $request) {
    if(!Zend_Auth::getInstance()->hasIdentity()) {
      $request->setControllerName('login');
      $request->setActionName('index');
    }
  }

}




$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new LoginCheckPlugin());

ich war mal so frei ;)
 
PHP:
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new LoginCheckPlugin());

ich war mal so frei ;)

Nur um diese zwei Zeilen gings mir:ugly:

EDIT:

Hmm :(
Das macht einen irgendwie sehr mutlos, wenn man in diesen Thread kommt, u.U. nen Doppelpost machen muss, um dann immer wieder nur Fragen zu stellen :-?

Derweil hab ich die nächste:

Einloggen funktioniert, aber wenn ein Fehler aufgetreten ist, würde ich gern auf eine extra Action weiterleiten, ansonsten aber die momentane weiter benutzen.

Wie realisieren?
Ich hab _forward gefunden, aber das ist ja protected, soll ich einfach public reinschreiben, oder gibt es eine bessere Methode?
 
Zuletzt bearbeitet:
Du kannst doch einfach
PHP:
$this->_forward(...); 
//oder 
$this->_redirect('....')

Nicht den Elan verlieren, des wird schon, is verdammt kniffelig manchmal, aber es wird.

Als kleines Beispiel mal eine meiner Action´s:
PHP:
	/**
	 * contactAction
	 * 
	 * Display the Contact-Form and when it was send
	 * validate the Form-Values.
	 * When the Validation was succeed, save a Ticket in DB and
	 * redirect to {@link indexAction()}.
	 * 
	 * @return void
	 */
	public function contactAction()
	{
		$objForm = $this->_helper->getForm('contact');
		if($this->_request->isPost()) {
			if($objForm->isValid($this->_request->getPost())) {
				if($this->_helper->getModel('Index')->saveTicket($objForm->getValues())) {
					$this->_helper->FlashMessenger($this->_('send_successful'));
					$this->_redirect('/');
				} else {
					$this->_helper->FlashMessenger($this->_('send_error'));
					$this->_redirect('index/contact');
				}
			}
		}
		$this->setTitle($this->_('title'));
		$this->view->form = $objForm;
	}

Nun habe ich auch mal noch ne Frage und zwar bezüglich TMX Translation und scanDirectory:
Meine initTranslate vom Plugin sieht so aus:
PHP:
	/**
	 * init Zend Translate for multilanguage support
	 * @return object Project_Plugin_Initializer
	 * @access protected
	 */
	protected function initTranslate()
	{
		$arrConfig = $this->_configHelper->getConfig('translate')->toArray();
Zend_Debug::dump(self::_setRoot($arrConfig));
		if((bool)$arrConfig['usingCache']) {
			Zend_Translate::setCache($this->_getCacheInstance());
		}

		// register and init the Translateclass
		$objTranslate = new Zend_Translate(strtolower($arrConfig['fileType']), self::_setRoot($arrConfig['scanDirectory']));
		Zend_Registry::set('Zend_Translate', $objTranslate);
		Zend_Validate_Abstract::setDefaultTranslator($objTranslate);
		return $this;
	}

Das Zend Debug gibt mir folgendes aus:
local xampp schrieb:
array(3) {
["usingCache"] => string(5) "FALSE"
["fileType"] => string(3) "tmx"
["scanDirectory"] => string(52) "G:\xampp\htdocs_northern-lands/application/languages"
}
testweise Server schrieb:
array(3) {
["usingCache"] => string(5) "FALSE"
["fileType"] => string(3) "tmx"
["scanDirectory"] => string(58) "/home/web0/domains/northern-lands.de/application/languages"
}

Auf dem localen Xampp macht er es richtig aber auf dem Server macht er es falsch, er nimmt auf dem Server einfach das falsche File.
Hier noch meine language Verzeichnissstruktur:
Code:
[B]languages
  modules
     controller[/B]
        action(file)
  flashMessenger.tmx
Fettgeschriebenes sind Verzeichnisse die wie die View`s benannt sind.
 
Zuletzt bearbeitet:
Du kannst doch einfach
PHP:
$this->_forward(...); 
//oder 
$this->_redirect('....')

Nicht den Elan verlieren, des wird schon, is verdammt kniffelig manchmal, aber es wird.

Als kleines Beispiel mal eine meiner Action´s:
...

Hmm, das Problem ist, dass ich das von einem Plugin (in dem Fall Einloggen) forwareden will, aber das Plugin wird nicht durch Zend_Controller_Action erweitert, sondern durch Zend_Controller_Plugin_Abstract :-?

Und auf das Plugin verzichten will ich eig. auch nicht, weil ich sonst wieder auf eine fixe Action gehen muss, wodurch der User wieder von vorne anfangen muss:roll:

Weiß jemand was zum entkniffeln?:ugly:
 
Zuletzt bearbeitet:
Dann setze einfach ein neuen Request Object "oder wie des heist" und lasse des abarbeiten. Ich schau gleich mal ob ich das entsprechende im Manual finde.

*edit
Habe es nicht im Manual gefunden, aber ich habe hier gleich ein fertiges Beispiel, achte auf die Post´s ab dem 6.!
 
Zuletzt bearbeitet:
*edit
Habe es nicht im Manual gefunden, aber ich habe hier gleich ein fertiges Beispiel, achte auf die Post´s ab dem 6.!

Boah, danke Strolch008O

Ich hab schon selbst im Manual gesucht, aber hatte stehen:

PHP:
Zend_Controller_Request_Abstract::set...Name = "";
:ugly:

Eine aller aller letzte Frage noch:

Wie bekomm ich vom Plugin eine Ausgabe in den View?

Habs mit
PHP:
$this->view->foo = 'bla';
probiert, aber dann ist im View
PHP:
$this->view
leer:(

Btw: Wir könnten ja eig. auch in ICQ über solche Lapalien diskutieren (bzw. ich mit Fragen "nerven" :-?)
 
Ich hab schon selbst im Manual gesucht, aber hatte stehen:

PHP:
Zend_Controller_Request_Abstract::set...Name = "";
:ugly:
das habe ich doch in meinem Beispiel dir schon umgesetzt.

Wie bekomm ich vom Plugin eine Ausgabe in den View?

Habs mit
PHP:
$this->view->foo = 'bla';
probiert, aber dann ist im View
PHP:
$this->view
leer:(
öhm diese Aufgabe hat ein Plugin nicht.
Das Problem warum du das brauchst, solltest du vllt mal genauer erklären.
 
Eig. will ich dem User nur erklären, was er denn überhaupt falsch gemacht hat, wobei ich merke, dass es sogar noch geschickter wäre, die Meldung in den Controller zu bringen, soweit möglich.:-?

Für sowas gibt es je nach Anwendungsfall Zend_Validate (auch als Bestandteil von Zend_Form) oder eben einen Error-Controller.
Bei Zend_Form im Zusammenspiel mit Zend_Validate reicht es sogar zu prüfen ob das Form valide ist ($form->isValid()) und es gegebenenfalls nochmals zu rendern - die Fehler stehen dann automatisch da.
 
Bei Zend_Form im Zusammenspiel mit Zend_Validate reicht es sogar zu prüfen ob das Form valide ist ($form->isValid()) und es gegebenenfalls nochmals zu rendern - die Fehler stehen dann automatisch da.

Aber nur weil das Form valide ist, heißt das doch nicht, dass der User überhaupt existiert?

Und bzgl. Error Controller:
Wäre prizipiell möglich, allerdings müsste ich dann doch für jeden anderen Fehler einen neuen View machen, oder?
 
Für sowas schreibt man einfach seinen eigenen Validator, welcher checkt ob der User existiert oder nicht. Das ist gar nicht so schwer, In Zend_Form einen Model Instance übergeben und im Validator selber mit Hilfe des Models checken ob ein User existiert. Kann bei Bedarf mal meinen posten, ist aber nicht sonderlich toll kommentiert.

*edit
Ein Form ist nur Valid wenn alle Validatoren TRUE zurückgegeben haben.
 
[Action/Helper] Problem mit FlashMessenger

Hey Leute,

wie ihr oben schon lesen könnt quäle ich mich grad wieder mal mit dem Helper rum.

Ich wollte die Messages mal ein bisschen trennen in Fehler und Erfolgsmeldungen dazu habe ich mir folgendes Code überlegt.

MasterController:
PHP:
	public function init()
	{
		$this->view->flash_messages 				= array();
		if($this->_helper->FlashMessenger->setNamespace('errors')->hasMessages()) {
			$this->view->flash_messages['errors']		= $this->_helper->FlashMessenger->getMessages();
		}
		if($this->_helper->FlashMessenger->setNamespace('confirmations')->hasMessages()) {
			$this->view->flash_messages['confirmations']	= $this->_helper->FlashMessenger->getMessages();
		}
	}
eine Action wo er verwendet wird:
PHP:
	public function loginAction()
	{
		$objForm = $this->_helper->getForm('Login');
		if($this->_request->isPost()) {
			if($objForm->isValid($this->_request->getPost())) {
				if(!$this->_helper->getModel('Application')->handleLogin($objForm->getValues())) {
					$this->_helper->FlashMessenger->setNamespace('confirmations')->addMessage('login_error');
					$this->_redirect('user/login');
				}
				// all ok ==> redirect to last requested uri
				$this->_redirect($this->_request->getParam('_requestUri'));
			}
		}
		$this->setTitle($this->_('title'));
		$this->view->form = $objForm;
	}
layout.phtml Ausschnitt:
PHP:
      <div id="head<?php if(array_key_exists('errors', $this->flash_messages) || array_key_exists('confirmations', $this->flash_messages)):?>_messages<?php endif; ?>">
<?php if(array_key_exists('errors', $this->flash_messages)):?>
      <!-- flash messages -->
        <ul id="system_errors">
<?php foreach($this->flash_messages['errors'] AS $strMessage): ?>
          <li><?php echo $strMessage; ?></li>
<?php endforeach; ?>
        </ul>
<?php endif; ?>
<?php if(array_key_exists('confirmations', $this->flash_messages)):?>
        <ul id="system_confirmations">
<?php foreach($this->flash_messages['confirmations'] AS $strMessage): ?>
          <li><?php echo $strMessage; ?></li>
<?php endforeach; ?>
        </ul>
      <!-- flash messages end -->
<?php endif; ?>

Meine Errormeldung:
Notice: Indirect modification of overloaded property Zend_Session_Namespace::$errors has no effect in /home/web0/domains/northern-lands/library/Zend/Controller/Action/Helper/FlashMessenger.php on line 143

Das komische an dieser Meldung ist wiedermal das Problem das sich mein Xampp anders als mein Server verhält, warum weiß der Geier, die config Files habe ich gerad gecheckt und diese sind auch im groben und ganzen identisch.

Außerdem, was soll das sein, der Helper hat doch extra eine Methode um so eine Art Gruppierung zu machen, indem man den Session Namespace ändert.
Aber was soll bedeuten das es keinen Effekt hatte. Zumal in der Zeile wo die Message eigentlich dem Namespace angehängt wird.

Bin so langsam echt verwirrt und Ratlos.
 
Das komische an dieser Meldung ist wiedermal das Problem das sich mein Xampp anders als mein Server verhält, warum weiß der Geier, die config Files habe ich gerad gecheckt und diese sind auch im groben und ganzen identisch.

Benutzt du zufällig PHP 5.2.0 auf deinem xampp und eine aktuellere / andere Version auf deinem Server? Das könnte das Verhalten evtl. erklären. Hier noch was Spezifisches zum FlashMessenger, aber ich denke auf den ersten Blick das läuft aufs Gleiche raus.
 
Ah danke euch Leute, das hatte ich gestern nach dem Posten auch gefunden dachte nur nicht das es doch so trivial sein kann. Dann werde ich mal nen update auf dem Server machen ;). Danke nochmal.
 
Hallo :)

Ich habe nochmal ein Problem und hoffe ihr könnt mir helfen.

Ich versuche ein Adminmenü für meine Seite zu realisieren, und habe dafür 2 zusätzliche controller angelegt.
Zum einen den AdminController über den man sich einloggen können soll und den ControlcenterController über den ich nach dem Login zugriff auf die Adminfunktionen habe.
Den Usernamen und das Passwort habe ich in einer Ini Datei gespeichert.

nun wollte ich mittels Zend_Session bei erfolgreichem Login eine Session starten. Danach wird auf den ControlcenterController weitergeleitet.

Nach der Weiterleitung versuche ich die definierte Sessionvariable auszugeben, stattdessen bekomme ich aber folgendes:
Notice: Undefined variable: logged in /www/htdocs/../application/controllers/ControlcenterController.php on line 7

Notice: Trying to get property of non-object in /www/htdocs/../application/controllers/ControlcenterController.php on line 7

hier der code:
AdminController (ausschnitt):
PHP:
            //validate
            if($values['name'] === $admin->adminname && $values[passwd] === $admin->adminpasswd){
                //success - set session data and redirect
                $logged = new Zend_Session_Namespace('logged');
                $logged->logged = 1;
                return $this->_redirect('/controlcenter');
            }

ControlcenterController:
PHP:
  echo $logged->logged;

Habe ich den Namespace vllt falsch gesetzt oder sowas in der Art?
Bin für Hilfe dankbar :)

mfg Raze
 
In $logged->logged wird wie ich sehe nur eine 1 geschrieben, wenn der Login erfolgreich war.
Definiere die Variable logged mal in der Klasse selber, denn der Fehler bedeutet ja, dass auf eine undefinierte Variable zugegriffen wird ;)


EDIT: Ah, ne. Durch die zweite Meldung denke ich das $logged undefiniert ist... Ich kenne mich mit Zend noch nicht aus, aber ich kann mir vorstellen dass man die Variable $logged noch irgendwie aus dem Zend_Session_Namespace "laden" muss?