typo3 query: ORDER BY RAND()

30. Januar 2015

Ich brauchte eine Abfrage, die mir 5 beliebige Items zurückliefert. Meine Lösung:

  1. //fetch 5 IDs from the mm table
  2. $idArr = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( 'uid_local', 'tx_something_user_userarticles_article_mm','', '', 'RAND()', '5' );
  3. $ids = array();
  4. //save the IDs to $ids
  5. foreach($idArr as $k => $v){
  6. $ids[] = $v['uid_local'];
  7. }
  8. //now for the real query
  9. $query = $this->createQuery();
  10. $constraints = array(
  11. $query->in('uid', $ids),
  12. );
  13. $query->matching($query->logicalAnd($constraints));
  14. return $query->execute();

Funktioniert. Ob es bessere Lösungen gibt, kann ich natürlich nicht sagen.

Typo3 extbase: repository query ausgeben

30. Januar 2015

Wenn ich mir die entstandene Query zumindest so einigermaßen ansehen will, mache ich das hier:

  1. $queryParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser');
  2. \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->parseQuery($query));

Das gibt zwar nicht die query selbst aus, aber zumindest alle Teile und die Informationen in tables, fields und where sind schonmal einiges wert.

Nachtrag: In typo3 8 funktioniert das ganze dann wieder anders.

Typo3: die merkwürdige Geisterspalte für 1:n relationen

29. Januar 2015

Heute habe ich Stunden damit zugebracht, zu rätseln warum eine Relation einfach nicht funktionieren wollte. Ich habe eine Tabelle comments und eine Tabelle fe_users, und ein user kann Kommentare schreiben, also user:comment => 1:n Ich hatte auch in der TCA.php alles eingerichtet, meine entities stimmten eigentlich, aber $user->getComments() wollte nicht funktionieren. Nun, für diese Relationen benötigt das dumme Typo3 ja immer noch diese Geisterspalte, die so heißt wie die relation (“comments” in meinem Fall), wo aber nix drinsteht. Ich dachte ja, was in der Spalte steht ist völlig wurscht. Stellt sich raus: wenn NULL drinsteht, geht nix! Es muss 0 sein!

Symfony: cookies gehen im iframe verloren im Internet Explorer

21. Januar 2015

Ich habe ein Formular mit einem iframe als target. Die Url die dort aufgerufen wird ist die login_check von Symfony, der ich _username und _password schicke, in der Hoffnung, sofort eingeloggt zu werden. Problem: der Internet Explorer verliert die cookies im iframe. Also muss ich den entsprechenden Header setzen, und um das zu vereinfachen setze ich ihn einfach überall indem ich einen Listener einbaue:

  1. namespace Package\SomeBundle\EventListener;
  2. use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
  3. class ResponseListener{
  4. public function onKernelResponse(FilterResponseEvent $event){
  5. $event->getResponse()->headers->set('P3P', 'CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
  6. }
  7. }

Und registriert wird das ganze in der services.yml:

  1. user.filter_response_listener
  2. class: Package\SomeBundle\EventListener\ResponseListener
  3. tags:
  4. - {name: kernel.event_listener, event: kernel.response, method: onKernelResponse}

Symfony: neues Objekt mit Klassennamen aus einer Variable

13. Januar 2015

Ich habe eine Superklasse User, von der sich ein paar Subtypen ableiten:

  1. class Admin extends User { ... }
  2. class Redakteur extends User { ... }
  3. class Noob extends User { ... }

Im Controller beim Anlegen eines neuen Objektes weiß ich anhand der Auswahl schon, welches neue Objekt erstellt werden muss. Ich wollte das ganze aber nicht mit Switch bzw. einer if-Abfrage machen wollte. Meine verschiedenen Usertypen gibt es als Tabelle mit einem Usertyp pro Zeile. Der hat eine ID, einen Namen und, wichtig, eine Spalte “classname”.

classname

id name
1 Administrator Admin
2 Redakteur Redakteur
3 Darf gar nichts Noob

Und damit ich nun das neue Objekt anhand dieser classnames erstellen kann, benutze ich die ReflectionClass:

  1. $tmp2 = new \ReflectionClass('Pack\UserBundle\Entity\\'.$group->getClassname());
  2. $user = $tmp2->newInstance($exists);

Und $user ist damit vom jeweiligen Typ des $group Eintrags.

Symfony: im dev Modus das ewige assets:install vermeiden

12. Januar 2015

Früher habe ich nach jedem ändern von js und css Dateien immer ein assets:install ausgeführt, einfach weil ich es nicht besser wusste. Offenbar kann man das im dev modus ganz einfach via symlink umgehen:

  1. php ./console assets:install ../web --env=dev --symlink